static gchar **device_filter = NULL;
static gchar **nodevice_filter = NULL;
+#if defined TIZEN_EXT
+static DBusConnection *connection;
+#endif
+
enum connman_pending_type {
PENDING_NONE = 0,
PENDING_ENABLE = 1,
char *last_network;
struct connman_network *network;
GHashTable *networks;
+#if defined TIZEN_EXT
+ time_t last_user_selection_time;
+ char *last_user_selection_ident;
+ char *last_connected_ident;
+ DBusMessage *pending_reply;
+ int max_scan_ssids;
+ bool is_5_0_ghz_supported;
+#endif
};
static void clear_pending_trigger(struct connman_device *device)
{
+#if defined TIZEN_EXT
+ if (device->pending_reply) {
+ dbus_message_unref(device->pending_reply);
+ device->pending_reply = NULL;
+ }
+#endif
if (device->pending_timeout > 0) {
g_source_remove(device->pending_timeout);
device->pending_timeout = 0;
if (device_service_type == CONNMAN_SERVICE_TYPE_UNKNOWN)
return true;
+#if defined TIZEN_EXT_WIFI_MESH
+ if (device_service_type == CONNMAN_SERVICE_TYPE_MESH)
+ return service_type != CONNMAN_SERVICE_TYPE_MESH;
+#endif
+
if (device_service_type == CONNMAN_SERVICE_TYPE_WIFI) {
return service_type == CONNMAN_SERVICE_TYPE_WIFI ||
service_type == CONNMAN_SERVICE_TYPE_P2P;
DBG("device %p", device);
+#if defined TIZEN_EXT
+ DBusMessage *reply;
+
+ /* Power request timed out, send ETIMEDOUT. */
+ if (device->pending_reply) {
+ reply = __connman_error_failed(device->pending_reply, ETIMEDOUT);
+ if (reply)
+ g_dbus_send_message(connection, reply);
+
+ dbus_message_unref(device->pending_reply);
+ device->pending_reply = NULL;
+ }
+#endif
/* Power request timedout, reset power pending state. */
device->pending_timeout = 0;
device->powered_pending = PENDING_NONE;
g_free(device->last_network);
+#if defined TIZEN_EXT
+ g_free(device->last_user_selection_ident);
+ g_free(device->last_connected_ident);
+#endif
+
g_free(device);
}
+#if defined TIZEN_EXT
+static void device_send_changed(const char *ifname, enum connman_service_type type,
+ const char *key, bool state)
+{
+ DBusMessage *signal;
+ DBusMessageIter iter, dict;
+ dbus_bool_t value = state;
+ const char *tech_path = connman_techonology_get_path(type);
+
+ if (!tech_path || !ifname)
+ return;
+
+ DBG("%s %s %s", ifname, key, state ? "TRUE" : "FALSE");
+
+ signal = dbus_message_new_signal(tech_path,
+ CONNMAN_TECHNOLOGY_INTERFACE, "DeviceChanged");
+ if (!signal)
+ return;
+
+ dbus_message_iter_init_append(signal, &iter);
+
+ connman_dbus_dict_open(&iter, &dict);
+ connman_dbus_dict_append_basic(&dict, "Ifname",
+ DBUS_TYPE_STRING,
+ &ifname);
+ connman_dbus_dict_append_basic(&dict, key,
+ DBUS_TYPE_BOOLEAN,
+ &value);
+ connman_dbus_dict_close(&iter, &dict);
+
+ dbus_connection_send(connection, signal, NULL);
+ dbus_message_unref(signal);
+}
+
+static void device_send_reply(struct connman_device *device)
+{
+ if (device->pending_reply) {
+ g_dbus_send_reply(connection,
+ device->pending_reply, DBUS_TYPE_INVALID);
+ dbus_message_unref(device->pending_reply);
+ device->pending_reply = NULL;
+ }
+}
+#endif
+
/**
* connman_device_create:
* @node: device node name (for example an address)
if (device->powered == powered)
return -EALREADY;
+#if defined TIZEN_EXT
+ device_send_reply(device);
+#endif
+
clear_pending_trigger(device);
device->powered_pending = PENDING_NONE;
type = __connman_device_get_service_type(device);
+#if defined TIZEN_EXT
+ device_send_changed(device->interface, type, "Powered", powered);
+ technology_save_device(device);
+#endif
+
if (!device->powered) {
__connman_technology_disabled(type);
return 0;
return 0;
}
+#if defined TIZEN_EXT
+bool connman_device_set_last_user_selection_time(struct connman_device *device,
+ time_t time)
+{
+ if (device->last_user_selection_time != time) {
+ device->last_user_selection_time = time;
+ return true;
+ }
+
+ return false;
+}
+
+time_t connman_device_get_last_user_selection_time(struct connman_device *device)
+{
+ return device->last_user_selection_time;
+}
+
+bool connman_device_set_last_user_selection_ident(struct connman_device *device,
+ const char *ident)
+{
+ if (g_strcmp0(device->last_user_selection_ident, ident) != 0) {
+ g_free(device->last_user_selection_ident);
+ device->last_user_selection_ident = g_strdup(ident);
+
+ return true;
+ }
+
+ return false;
+}
+
+const char *connman_device_get_last_user_selection_ident(struct connman_device *device)
+{
+ return device->last_user_selection_ident;
+}
+
+bool connman_device_set_last_connected_ident(struct connman_device *device,
+ const char *ident)
+{
+ if (g_strcmp0(device->last_connected_ident, ident) != 0) {
+ g_free(device->last_connected_ident);
+ device->last_connected_ident = g_strdup(ident);
+
+ return true;
+ }
+
+ return false;
+}
+
+const char *connman_device_get_last_connected_ident(struct connman_device *device)
+{
+ return device->last_connected_ident;
+}
+
+void connman_device_save_last_user_selection(struct connman_device *device)
+{
+ GKeyFile *keyfile;
+ gchar *get_str;
+ gchar *selection_str;
+
+ keyfile = __connman_storage_load_ins();
+
+ selection_str = g_strdup_printf("%s:%ld",
+ device->last_user_selection_ident, device->last_user_selection_time);
+
+ if (!keyfile) {
+ keyfile = g_key_file_new();
+
+ g_key_file_set_string(keyfile, device->interface, "LastUserSelection", selection_str);
+ DBG("%s", selection_str);
+ __connman_storage_save_ins(keyfile);
+
+ } else {
+ get_str = g_key_file_get_string(keyfile, device->interface, "LastUserSelection", NULL);
+ if (!get_str || g_strcmp0(get_str, selection_str) != 0) {
+ g_key_file_set_string(keyfile, device->interface, "LastUserSelection", selection_str);
+ DBG("%s -> %s", get_str, selection_str);
+ __connman_storage_save_ins(keyfile);
+ }
+
+ g_free(get_str);
+ }
+
+ g_free(selection_str);
+ g_key_file_free(keyfile);
+}
+
+void connman_device_load_last_user_selection(struct connman_device *device)
+{
+ GKeyFile *keyfile;
+ gchar *get_str;
+ char **selection_str;
+
+ keyfile = __connman_storage_load_ins();
+ if (!keyfile)
+ return;
+
+ get_str = g_key_file_get_string(keyfile, device->interface, "LastUserSelection", NULL);
+ if (get_str) {
+ selection_str = g_strsplit(get_str, ":", 0);
+ if (selection_str) {
+ time_t ref_time;
+ struct tm* timeinfo;
+ time_t last_user_selection_time;
+
+ /* Only events that occur within 8 hours are counted. */
+ ref_time = time(NULL);
+ timeinfo = localtime(&ref_time);
+ timeinfo->tm_hour -= 8;
+ ref_time = mktime(timeinfo);
+
+ last_user_selection_time = strtol(selection_str[1], NULL, 10);
+
+ if (last_user_selection_time > ref_time) {
+ if (g_strcmp0(selection_str[0], device->last_user_selection_ident) != 0) {
+ g_free(device->last_user_selection_ident);
+ device->last_user_selection_ident = g_strdup(selection_str[0]);
+ }
+
+ device->last_user_selection_time = last_user_selection_time;
+
+ DBG("%s %ld", device->last_user_selection_ident, device->last_user_selection_time);
+ }
+
+ g_strfreev(selection_str);
+ }
+
+ g_free(get_str);
+ }
+
+ g_key_file_free(keyfile);
+}
+
+void connman_device_save_last_connected(struct connman_device *device)
+{
+ GKeyFile *keyfile;
+ gchar *get_str;
+
+ if (!device->last_connected_ident)
+ return;
+
+ keyfile = __connman_storage_load_ins();
+
+ if (!keyfile) {
+ keyfile = g_key_file_new();
+
+ g_key_file_set_string(keyfile, device->interface, "LastConnected", device->last_connected_ident);
+ DBG("%s", device->last_connected_ident);
+ __connman_storage_save_ins(keyfile);
+
+ } else {
+ get_str = g_key_file_get_string(keyfile, device->interface, "LastConnected", NULL);
+ if (!get_str || g_strcmp0(get_str, device->last_connected_ident) != 0) {
+ g_key_file_set_string(keyfile, device->interface, "LastConnected", device->last_connected_ident);
+ DBG("%s -> %s", get_str, device->last_connected_ident);
+ __connman_storage_save_ins(keyfile);
+ }
+
+ g_free(get_str);
+ }
+
+ g_key_file_free(keyfile);
+}
+
+void connman_device_load_last_connected(struct connman_device *device)
+{
+ GKeyFile *keyfile;
+ gchar *get_str;
+
+ keyfile = __connman_storage_load_ins();
+ if (!keyfile)
+ return;
+
+ get_str = g_key_file_get_string(keyfile, device->interface, "LastConnected", NULL);
+ if (get_str) {
+ if (g_strcmp0(get_str, device->last_connected_ident) != 0) {
+ g_free(device->last_connected_ident);
+ device->last_connected_ident = g_strdup(get_str);
+ }
+
+ DBG("%s", device->last_connected_ident);
+
+ g_free(get_str);
+ }
+
+ g_key_file_free(keyfile);
+}
+#endif
+
static void mark_network_available(gpointer key, gpointer value,
gpointer user_data)
{
__connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+#if defined TIZEN_EXT_WIFI_MESH
+ if (type == CONNMAN_SERVICE_TYPE_MESH)
+ __connman_mesh_auto_connect();
+#endif
+
return 0;
}
return g_hash_table_lookup(device->networks, identifier);
}
+#if defined TIZEN_EXT
+struct connman_network *connman_device_get_default_network(
+ struct connman_device *device)
+{
+ return device->network;
+}
+
+void connman_device_set_pending_reply(struct connman_device *device,
+ DBusMessage *msg)
+{
+ device->pending_reply = dbus_message_ref(msg);
+}
+
+void connman_device_send_connected_signal(struct connman_device *device,
+ bool connected)
+{
+ enum connman_service_type type;
+
+ if (!device)
+ return;
+
+ type = __connman_device_get_service_type(device);
+ device_send_changed(device->interface, type, "Connected", connected);
+}
+
+void connman_device_set_max_scan_ssids(struct connman_device *device,
+ int max_scan_ssids)
+{
+ device->max_scan_ssids = max_scan_ssids;
+}
+
+int connman_device_get_max_scan_ssids(struct connman_device *device)
+{
+ return device->max_scan_ssids;
+}
+
+void connman_device_set_wifi_5ghz_supported(struct connman_device *device,
+ bool is_5_0_ghz_supported)
+{
+ device->is_5_0_ghz_supported = is_5_0_ghz_supported;
+}
+
+bool connman_device_get_wifi_5ghz_supported(struct connman_device *device)
+{
+ return device->is_5_0_ghz_supported;
+}
+#endif
+
/**
* connman_device_remove_network:
* @device: device structure
__connman_technology_notify_regdom_by_device(device, result, alpha2);
}
+#if defined TIZEN_EXT
+static int device_specific_scan(enum connman_service_type type,
+ struct connman_device *device,
+ int scan_type, GSList *specific_scan_list)
+{
+ if (!device->driver || !device->driver->specific_scan)
+ return -EOPNOTSUPP;
+
+ if (!device->powered)
+ return -ENOLINK;
+
+ return device->driver->specific_scan(type, device, scan_type,
+ specific_scan_list, NULL);
+}
+
+int __connman_device_request_specific_scan(enum connman_service_type type,
+ const char *ifname, int scan_type, GSList *specific_scan_list)
+{
+ bool success = false;
+ int last_err = -ENOSYS;
+ GSList *list;
+ int err;
+
+ switch (type) {
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ case CONNMAN_SERVICE_TYPE_GPS:
+ case CONNMAN_SERVICE_TYPE_VPN:
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ return -EOPNOTSUPP;
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ case CONNMAN_SERVICE_TYPE_P2P:
+#if defined TIZEN_EXT_WIFI_MESH
+ case CONNMAN_SERVICE_TYPE_MESH:
+#endif
+ break;
+ }
+
+ for (list = device_list; list; list = list->next) {
+ struct connman_device *device = list->data;
+ enum connman_service_type service_type =
+ __connman_device_get_service_type(device);
+
+ if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
+ if (type == CONNMAN_SERVICE_TYPE_P2P) {
+ if (service_type != CONNMAN_SERVICE_TYPE_WIFI)
+ continue;
+ } else if (service_type != type)
+ continue;
+ }
+
+ if (ifname && g_strcmp0(device->interface, ifname) != 0)
+ continue;
+
+ err = device_specific_scan(type, device, scan_type, specific_scan_list);
+ if (err == 0 || err == -EINPROGRESS) {
+ success = true;
+ } else {
+ last_err = err;
+ DBG("device %p err %d", device, err);
+ }
+ }
+
+ if (success)
+ return 0;
+
+ return last_err;
+}
+
+int connman_device_request_device_scan(enum connman_service_type type,
+ const char * ifname, bool force_full_scan)
+{
+ bool success = false;
+ int last_err = -ENOSYS;
+ GSList *list;
+ int err;
+
+ switch (type) {
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ case CONNMAN_SERVICE_TYPE_GPS:
+ case CONNMAN_SERVICE_TYPE_VPN:
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ return -EOPNOTSUPP;
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ case CONNMAN_SERVICE_TYPE_P2P:
+#if defined TIZEN_EXT_WIFI_MESH
+ case CONNMAN_SERVICE_TYPE_MESH:
+#endif
+ break;
+ }
+
+ for (list = device_list; list; list = list->next) {
+ struct connman_device *device = list->data;
+
+ if (!device_has_service_type(device, type))
+ continue;
+
+ if (g_strcmp0(device->interface, ifname) != 0)
+ continue;
+
+ err = device_scan(type, device, force_full_scan);
+
+ if (err == 0 || err == -EINPROGRESS) {
+ success = true;
+ } else {
+ last_err = err;
+ DBG("device %p err %d", device, err);
+ }
+ break;
+ }
+
+ if (success)
+ return 0;
+
+ return last_err;
+}
+
+#if defined TIZEN_EXT_WIFI_MESH
+static int device_abort_scan(enum connman_service_type type,
+ struct connman_device *device)
+{
+ if (!device->driver || !device->driver->scan)
+ return -EOPNOTSUPP;
+
+ if (!device->powered)
+ return -ENOLINK;
+
+ return device->driver->abort_scan(type, device);
+}
+
+int __connman_device_abort_scan(enum connman_service_type type)
+{
+ GSList *list;
+ int err = -EINVAL;
+
+ if (type != CONNMAN_SERVICE_TYPE_MESH)
+ return -EINVAL;
+
+ for (list = device_list; list; list = list->next) {
+ struct connman_device *device = list->data;
+ enum connman_service_type service_type =
+ __connman_device_get_service_type(device);
+
+ if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
+ if (type == CONNMAN_SERVICE_TYPE_MESH)
+ if (service_type != CONNMAN_SERVICE_TYPE_WIFI)
+ continue;
+
+ if (!device->scanning) {
+ err = -EEXIST;
+ continue;
+ }
+
+ err = device_abort_scan(type, device);
+ }
+ }
+ return err;
+}
+
+static int device_mesh_specific_scan(enum connman_service_type type,
+ struct connman_device *device, const char *name,
+ unsigned int freq)
+{
+ if (!device->driver || !device->driver->mesh_specific_scan)
+ return -EOPNOTSUPP;
+
+ if (!device->powered)
+ return -ENOLINK;
+
+ return device->driver->mesh_specific_scan(type, device, name, freq, NULL);
+}
+
+int __connman_device_request_mesh_specific_scan(enum connman_service_type type,
+ const char *name,
+ unsigned int freq)
+{
+ bool success = false;
+ int last_err = -ENOSYS;
+ GSList *list;
+ int err;
+
+ if (type != CONNMAN_SERVICE_TYPE_MESH)
+ return -EINVAL;
+
+ for (list = device_list; list; list = list->next) {
+ struct connman_device *device = list->data;
+ enum connman_service_type service_type =
+ __connman_device_get_service_type(device);
+
+ if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
+ if (type == CONNMAN_SERVICE_TYPE_MESH)
+ if (service_type != CONNMAN_SERVICE_TYPE_WIFI)
+ continue;
+ }
+
+ err = device_mesh_specific_scan(type, device, name, freq);
+ if (err == 0 || err == -EALREADY || err == -EINPROGRESS) {
+ success = true;
+ } else {
+ last_err = err;
+ DBG("device %p err %d", device, err);
+ }
+ }
+
+ if (success)
+ return 0;
+
+ return last_err;
+}
+#endif /* TIZEN_EXT_WIFI_MESH */
+#endif
+
static int connman_device_request_scan(enum connman_service_type type,
bool force_full_scan)
{
return -EOPNOTSUPP;
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_P2P:
+#if defined TIZEN_EXT_WIFI_MESH
+ case CONNMAN_SERVICE_TYPE_MESH:
+#endif
break;
}
continue;
err = device_scan(type, device, force_full_scan);
+#if defined TIZEN_EXT
+ /* When Scan is already in progress then return Error so that
+ * wifi-manager can block the scan-done signal to be sent to
+ * application and start requested scan after scan already in progress
+ * is completed then notify to application about the scan event */
+ if (err == 0 || err == -EINPROGRESS) {
+#else
if (err == 0 || err == -EALREADY || err == -EINPROGRESS) {
+#endif
success = true;
} else {
last_err = err;
}
}
+#if defined TIZEN_EXT
+char *index2ident(int index, const char *prefix)
+#else
static char *index2ident(int index, const char *prefix)
+#endif
{
struct ifreq ifr;
struct ether_addr eth;
return str;
}
+#if defined TIZEN_EXT
+char *index2addr(int index)
+#else
static char *index2addr(int index)
+#endif
{
struct ifreq ifr;
struct ether_addr eth;
connman_device_set_index(device, index);
connman_device_set_interface(device, devname);
+#if defined TIZEN_EXT
+ connman_device_load_last_connected(device);
+ connman_device_load_last_user_selection(device);
+#endif
if (ident) {
connman_device_set_ident(device, ident);
DBG("cleaning up %s index %d", interfaces[i], index);
+#if defined TIZEN_EXT
+ if (strcmp(interfaces[i], "wlan0") != 0)
+#endif
connman_inet_ifdown(index);
/*
{
DBG("");
+#if defined TIZEN_EXT
+ connection = connman_dbus_get_connection();
+#endif
+
if (device)
device_filter = g_strsplit(device, ",", -1);
g_strfreev(nodevice_filter);
g_strfreev(device_filter);
+
+#if defined TIZEN_EXT
+ dbus_connection_unref(connection);
+#endif
}