summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiraj Kumar Goit <niraj.g@samsung.com>2017-08-14 14:15:43 (GMT)
committerNiraj Kumar Goit <niraj.g@samsung.com>2017-08-16 11:31:22 (GMT)
commitcf6aa0ecbb0b0fe5c06bd5fc87eaa58e2ab47573 (patch)
tree54898c6d015c6fb9743d16b45076329b8b47482a
parentb5fc09779a7aa3173b926e901e954d7246832b46 (diff)
downloadconnman-submit/tizen/20170817.042132.zip
connman-submit/tizen/20170817.042132.tar.gz
connman-submit/tizen/20170817.042132.tar.bz2
Change-Id: Ib8f446164242caeb7fbc29c2917eff4b8a5b8bf7 Signed-off-by: Niraj Kumar Goit <niraj.g@samsung.com>
-rwxr-xr-xinclude/device.h5
-rwxr-xr-xplugins/wifi.c122
-rwxr-xr-xsrc/connman.h4
-rwxr-xr-xsrc/device.c67
-rwxr-xr-xsrc/technology.c73
5 files changed, 271 insertions, 0 deletions
diff --git a/include/device.h b/include/device.h
index 57b925c..dafdca2 100755
--- a/include/device.h
+++ b/include/device.h
@@ -130,6 +130,11 @@ struct connman_device_driver {
const char *security, void *user_data);
int (*set_regdom) (struct connman_device *device,
const char *alpha2);
+#if defined TIZEN_EXT
+ int (*specific_scan) (enum connman_service_type type,
+ struct connman_device *device, int scan_type,
+ GSList *specific_scan_list, void *user_data);
+#endif
};
int connman_device_driver_register(struct connman_device_driver *driver);
diff --git a/plugins/wifi.c b/plugins/wifi.c
index 2471141..7f99ace 100755
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -1831,6 +1831,125 @@ static int p2p_find(struct connman_device *device)
return ret;
}
+#if defined TIZEN_EXT
+static void specific_scan_callback(int result, GSupplicantInterface *interface,
+ void *user_data)
+{
+ struct connman_device *device = user_data;
+ struct wifi_data *wifi = connman_device_get_data(device);
+ bool scanning;
+
+ DBG("result %d wifi %p", result, wifi);
+
+ if (wifi && wifi->scan_params) {
+ g_supplicant_free_scan_params(wifi->scan_params);
+ wifi->scan_params = NULL;
+ }
+
+ scanning = connman_device_get_scanning(device);
+ if (scanning) {
+ connman_device_set_scanning(device,
+ CONNMAN_SERVICE_TYPE_WIFI, false);
+ connman_device_unref(device);
+ }
+}
+
+static int wifi_specific_scan(enum connman_service_type type,
+ struct connman_device *device, int scan_type,
+ GSList *specific_scan_list, void *user_data)
+{
+ GSList *list = NULL;
+ char *ssid = NULL;
+ struct wifi_data *wifi = connman_device_get_data(device);
+ GSupplicantScanParams *scan_params = NULL;
+ struct scan_ssid *scan_ssid;
+ bool scanning;
+ int ret;
+ int freq;
+ int count = 0;
+
+ if (!wifi)
+ return -ENODEV;
+
+ if (wifi->p2p_device)
+ return 0;
+
+ if (type == CONNMAN_SERVICE_TYPE_P2P)
+ return p2p_find(device);
+
+ if (wifi->tethering)
+ return 0;
+
+ scanning = connman_device_get_scanning(device);
+ if (scanning)
+ return -EALREADY;
+
+ DBG("scan_type: %d", scan_type);
+ if (scan_type == 1) { /* ssid based scan */
+ scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
+ if (!scan_params)
+ return -ENOMEM;
+
+ scan_ssid = g_try_new0(struct scan_ssid, 1);
+ if (!scan_ssid) {
+ g_free(scan_params);
+ return -ENOMEM;
+ }
+ for (list = specific_scan_list; list; list = list->next) {
+ ssid = (char *)list->data;
+ int ssid_len = strlen(ssid);
+
+ memcpy(scan_ssid->ssid, ssid, (ssid_len + 1));
+ DBG("scan ssid %s len: %d", scan_ssid->ssid, ssid_len);
+ scan_ssid->ssid_len = ssid_len;
+ scan_params->ssids = g_slist_prepend(scan_params->ssids, scan_ssid);
+ count++;
+ }
+ scan_params->num_ssids = count;
+
+ } else if (scan_type == 2) { /* frequency based scan */
+
+ scan_params = g_try_malloc0(sizeof(GSupplicantScanParams));
+ if (!scan_params)
+ return -ENOMEM;
+
+ scan_params->freqs = g_try_new0(uint16_t, 1);
+ if (!scan_params->freqs) {
+ g_free(scan_params);
+ return -ENOMEM;
+ }
+ count = 0;
+ for (list = specific_scan_list; list; list = list->next) {
+ freq = (int)list->data;
+ DBG("freq: %d", freq);
+ scan_params->freqs[count] = freq;
+ count++;
+ }
+ scan_params->num_freqs = count;
+
+ } else {
+ DBG("Invalid scan");
+ return -EINVAL;
+ }
+
+ reset_autoscan(device);
+ connman_device_ref(device);
+
+ ret = g_supplicant_interface_scan(wifi->interface, scan_params,
+ specific_scan_callback, device);
+
+ if (ret == 0) {
+ connman_device_set_scanning(device,
+ CONNMAN_SERVICE_TYPE_WIFI, true);
+ } else {
+ g_supplicant_free_scan_params(scan_params);
+ connman_device_unref(device);
+ }
+
+ return ret;
+}
+#endif
+
/*
* Note that the hidden scan is only used when connecting to this specific
* hidden AP first time. It is not used when system autoconnects to hidden AP.
@@ -2009,6 +2128,9 @@ static struct connman_device_driver wifi_ng_driver = {
.disable = wifi_disable,
.scan = wifi_scan,
.set_regdom = wifi_set_regdom,
+#if defined TIZEN_EXT
+ .specific_scan = wifi_specific_scan,
+#endif
};
static void system_ready(void)
diff --git a/src/connman.h b/src/connman.h
index dcd8c7f..5e257bf 100755
--- a/src/connman.h
+++ b/src/connman.h
@@ -576,6 +576,10 @@ int __connman_device_request_hidden_scan(struct connman_device *device,
const char *ssid, unsigned int ssid_len,
const char *identity, const char *passphrase,
const char *security, void *user_data);
+#if defined TIZEN_EXT
+int __connman_device_request_specific_scan(enum connman_service_type type,
+ int scan_type, GSList *specific_scan_list);
+#endif
bool __connman_device_isfiltered(const char *devname);
diff --git a/src/device.c b/src/device.c
index aff0fa9..acd68da 100755
--- a/src/device.c
+++ b/src/device.c
@@ -1077,6 +1077,73 @@ void connman_device_regdom_notify(struct connman_device *device,
__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,
+ 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:
+ 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;
+ }
+
+ err = device_specific_scan(type, device, scan_type, specific_scan_list);
+ 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
+
int __connman_device_request_scan(enum connman_service_type type)
{
bool success = false;
diff --git a/src/technology.c b/src/technology.c
index 29707f9..fb39d34 100755
--- a/src/technology.c
+++ b/src/technology.c
@@ -1173,6 +1173,77 @@ static DBusMessage *scan(DBusConnection *conn, DBusMessage *msg, void *data)
}
#if defined TIZEN_EXT
+static DBusMessage *specific_scan(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+ struct connman_technology *technology = data;
+ GSList *specific_scan_list = NULL;
+ int scan_type = 0;
+ const char *name = NULL;
+ unsigned int freq = 0;
+ DBusMessageIter iter, dict;
+ int err;
+
+ DBG("technology %p request from %s", technology,
+ dbus_message_get_sender(msg));
+
+ if (!dbus_message_iter_init(msg, &iter))
+ return __connman_error_invalid_arguments(msg);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
+ return __connman_error_invalid_arguments(msg);
+
+ dbus_message_iter_recurse(&iter, &dict);
+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, value2;
+ const char *key;
+ int type;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+ return __connman_error_invalid_arguments(msg);
+
+ dbus_message_iter_get_basic(&entry, &key);
+ dbus_message_iter_next(&entry);
+
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
+ return __connman_error_invalid_arguments(msg);
+
+ dbus_message_iter_recurse(&entry, &value2);
+ type = dbus_message_iter_get_arg_type(&value2);
+ if (g_str_equal(key, "SSID")) {
+ if (type != DBUS_TYPE_STRING)
+ return __connman_error_invalid_arguments(msg);
+
+ scan_type = 1; /* SSID based scan */
+ dbus_message_iter_get_basic(&value2, &name);
+ DBG("name %s", name);
+ specific_scan_list = g_slist_append(specific_scan_list, g_strdup(name));
+ } else if (g_str_equal(key, "Frequency")) {
+ if (type != DBUS_TYPE_UINT16) {
+ g_slist_free_full(specific_scan_list, g_free);
+ return __connman_error_invalid_arguments(msg);
+ }
+
+ scan_type = 2; /* Frequency based scan */
+ dbus_message_iter_get_basic(&value2, &freq);
+ DBG("freq %d", freq);
+ specific_scan_list = g_slist_append(specific_scan_list, GINT_TO_POINTER(freq));
+ }
+ dbus_message_iter_next(&dict);
+ }
+
+ dbus_message_ref(msg);
+ technology->scan_pending =
+ g_slist_prepend(technology->scan_pending, msg);
+
+ err = __connman_device_request_specific_scan(technology->type, scan_type, specific_scan_list);
+ if (err < 0)
+ reply_scan_pending(technology, err);
+
+ g_slist_free_full(specific_scan_list, g_free);
+ return NULL;
+}
+
static DBusMessage *get_scan_state(DBusConnection *conn, DBusMessage *msg, void *data)
{
DBusMessage *reply;
@@ -1216,6 +1287,8 @@ static const GDBusMethodTable technology_methods[] = {
GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
NULL, set_property) },
{ GDBUS_ASYNC_METHOD("Scan", NULL, NULL, scan) },
+ { GDBUS_ASYNC_METHOD("SpecificScan", GDBUS_ARGS({ "specificscan", "a{sv}" }),
+ NULL, specific_scan) },
#if defined TIZEN_EXT
{ GDBUS_METHOD("GetScanState", NULL, GDBUS_ARGS({ "scan_state", "a{sv}" }),
get_scan_state) },