return NL_SKIP;
}
-static int __netconfig_request_netlink_scan(struct nl_sock *socket,
- int if_index, int id, GVariant *params)
+static int __netconfig_trigger_netlink_scan(struct nl_sock *socket,
+ int if_index, int id, GSList *ssid_list, char *vsie)
{
struct netconfig_netlink_scan_results results = { .done = 0, .aborted = 0 };
struct nl_msg *msg = NULL;
int ret = 0;
unsigned char ies[NETCONFIG_MAX_VSIE_LEN+1] = {0x00, };
int ies_len = 0;
- GVariantIter *iter;
- GVariant *value;
- gchar *key;
- gboolean ssid_found = FALSE;
int mcid = __netconfig_get_multicast_id(socket, "nl80211", "scan");
+ DBG("");
ret = nl_socket_add_membership(socket, mcid);
if (ret < 0) {
DBG("Failed to add membership, error: (%s)", nl_geterror(-ret));
goto out;
}
- g_variant_get(params, "a{sv}", &iter);
- while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
- if (g_strcmp0(key, "SSID") == 0) {
- if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
- char *ssid = g_strdup(g_variant_get_string(value, NULL));
- ssid_found = TRUE;
- DBG("ssid [%s]", ssid);
-
- ret = nla_put(ssids, 1, strlen(ssid), ssid);
- g_free(ssid);
- if (ret < 0) {
- DBG("Failed to add ssid to netlink message, error: (%s)", nl_geterror(-ret));
- g_variant_iter_free(iter);
- goto out;
- }
- }
- } else if (g_strcmp0(key, "VSIE") == 0) {
- if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
- char *vsie = g_strdup(g_variant_get_string(value, NULL));
- int vsie_len = strlen(vsie);
- DBG("vsie: %s vsie_len: %d", vsie, vsie_len);
-
- ies_len = (vsie_len % 2) ? ((vsie_len / 2) + 1) : (vsie_len / 2);
- __netconfig_hex_str_to_bin(vsie, ies, ies_len);
- g_free(vsie);
- }
+ for (GSList *i = ssid_list; i; i = i->next) {
+ char *ssid = (char *)i->data;
+ ret = nla_put(ssids, 1, strlen(ssid), ssid);
+ if (ret < 0) {
+ DBG("Failed to add ssid to netlink message, error: (%s)", nl_geterror(-ret));
+ goto out;
}
}
- g_variant_iter_free(iter);
- if (!ssid_found) {
+ if (g_slist_length(ssid_list) == 0) {
+ DBG("Scan with no ssids");
ret = nla_put(ssids, 1, 0, "");
if (ret < 0) {
DBG("nla_put error: (%s)", nl_geterror(-ret));
}
nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
+ if (vsie) {
+ int vsie_len = strlen(vsie);
+ DBG("vsie: %s vsie_len: %d", vsie, vsie_len);
+ ies_len = (vsie_len % 2) ? ((vsie_len / 2) + 1) : (vsie_len / 2);
+ __netconfig_hex_str_to_bin(vsie, ies, ies_len);
+ }
+
if (ies[0] == NETCONFIG_VENDOR_SPECIFIC_ID && ies[1] >= 4) {
DBG("ies_len: %d ies: %02x %02x %02x %02x %02x %02x %02x", ies_len,
ies[0], ies[1], ies[2], ies[3], ies[4], ies[5], ies[6]);
}
DBG("Sent %d bytes to the kernel", ret);
- ssid_found = FALSE;
while (err > 0) {
ret = nl_recvmsgs(socket, cb);
return 0;
}
+static int __netconfig_netlink_scan(netconfig_nl_global *global, GSList *ssid_list, char *vsie)
+{
+ DBG("");
+ int ret = __netconfig_trigger_netlink_scan(global->socket, global->if_index, global->id, ssid_list, vsie);
+ if (ret == -NLE_AGAIN) {
+ DBG("Try Again");
+ ret = __netconfig_trigger_netlink_scan(global->socket, global->if_index, global->id, ssid_list, vsie);
+ }
+ return ret;
+}
+
static int __netconfig_initialize_nl80211(netconfig_nl_global *global)
{
int err = 0;
return 0;
}
+static void __netconfig_get_netlink_scan_parameters(GVariant *params, GSList *ssid_list, char **vsie)
+{
+ GVariantIter *iter;
+ GVariant *value;
+ gchar *key;
+ g_variant_get(params, "a{sv}", &iter);
+ while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
+ if (g_strcmp0(key, "SSID") == 0) {
+ if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+ char *ssid = g_strdup(g_variant_get_string(value, NULL));
+ DBG("ssid [%s]", ssid);
+ ssid_list = g_slist_append(ssid_list, ssid);
+ }
+ } else if (g_strcmp0(key, "VSIE") == 0) {
+ if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING))
+ *vsie = g_strdup(g_variant_get_string(value, NULL));
+ }
+ }
+ g_variant_iter_free(iter);
+}
+
+static int __netconfig_get_scan_results(netconfig_nl_global *global)
+{
+ int ret = __netconfig_initialize_nl_msg(global);
+ if (ret < 0) {
+ DBG("__netconfig_initialize_nl_msg() failed, error %d", ret);
+ return ret;
+ }
+
+ ret = nl_send_auto_complete(global->socket, global->msg);
+ if (ret < 0) {
+ DBG("nl_send_auto_complete() failed, error %d", ret);
+ return ret;
+ }
+ DBG("NL80211_CMD_GET_SCAN sent %d bytes to the kernel", ret);
+
+ /** Receive the kernel message. */
+ ret = nl_recvmsgs_default(global->socket);
+ nlmsg_free(global->msg);
+ if (ret < 0) {
+ DBG("nl_recvmsgs_default() failed. ret: %d (error: %s)", ret, nl_geterror(-ret));
+ return ret;
+ }
+ return 0;
+}
+
int handle_netlink_scan(Wifi *wifi, GDBusMethodInvocation *context, GVariant *params)
{
DBG("");
return TRUE;
}
+ GSList *ssid_list = NULL;
+ char *vsie = NULL;
+ __netconfig_get_netlink_scan_parameters(params, ssid_list, &vsie);
/** Request NL80211_CMD_TRIGGER_SCAN to the kernel. */
- ret = __netconfig_request_netlink_scan(global.socket, global.if_index, global.id, params);
- if (ret == -NLE_AGAIN) {
- DBG("Try Again");
- ret = __netconfig_request_netlink_scan(global.socket, global.if_index, global.id, params);
- }
- if (ret < 0) {
- DBG("__netconfig_request_netlink_scan() failed, error %d", ret);
- netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "AccessDenied");
- wifi_complete_netlink_scan(wifi, context);
- return TRUE;
- }
+ ret = __netconfig_netlink_scan(&global, ssid_list, vsie);
+ g_slist_free_full(ssid_list, g_free);
+ g_free(vsie);
- ret = __netconfig_initialize_nl_msg(&global);
if (ret < 0) {
- DBG("__netconfig_initialize_nl_msg() failed, error %d", ret);
+ DBG("__netconfig_netlink_scan() failed, error %d", ret);
netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "AccessDenied");
wifi_complete_netlink_scan(wifi, context);
return TRUE;
}
- ret = nl_send_auto_complete(global.socket, global.msg);
- DBG("NL80211_CMD_GET_SCAN sent %d bytes to the kernel", ret);
-
- /** Receive the kernel message. */
- ret = nl_recvmsgs_default(global.socket);
- nlmsg_free(global.msg);
+ ret = __netconfig_get_scan_results(&global);
if (ret < 0) {
- DBG("nl_recvmsgs_default() failed. ret: %d (error: %s)", ret, nl_geterror(-ret));
netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "AccessDenied");
wifi_complete_netlink_scan(wifi, context);
return TRUE;