#include "netsupplicant.h"
#include "log.h"
#include "util.h"
+#include "wifi-config.h"
#include "wifi-netlink-scan.h"
#include <netlink/genl/genl.h>
#include <netlink/genl/family.h>
return NL_SKIP;
}
-static int __netconfig_request_netlink_scan(struct nl_sock *socket, int if_index, int id, char *ssid)
+static int __netconfig_request_netlink_scan(struct nl_sock *socket,
+ int if_index, int id, GVariant *params)
{
struct netconfig_netlink_scan_results results = { .done = 0, .aborted = 0 };
struct nl_msg *msg = NULL;
struct nl_msg *ssids = NULL;
int err = 0;
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");
nl_socket_add_membership(socket, mcid);
/** Set nl message and callback functions. */
genlmsg_put(msg, 0, 0, id, 0, 0, NL80211_CMD_TRIGGER_SCAN, 0);
nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_index);
- if (!ssid)
+
+ 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);
+
+ nla_put(ssids, 1, strlen(ssid), ssid);
+ g_free(ssid);
+ }
+ } 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);
+ }
+ }
+ }
+ g_variant_iter_free(iter);
+
+ if (!ssid_found)
nla_put(ssids, 1, 0, "");
- else
- nla_put(ssids, 1, strlen(ssid), ssid);
nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
nlmsg_free(ssids);
+ 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]);
+ nla_put(msg, NL80211_ATTR_IE, ies_len, ies);
+ }
+
+ err = 1;
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, __netconfig_netlink_scan_reply, &results);
nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
/** Send NL80211_CMD_TRIGGER_SCAN to start the scan. */
- err = 1;
ret = nl_send_auto_complete(socket, msg);
DBG("Sent %d bytes to the kernel", ret);
+ ssid_found = FALSE;
+
while (err > 0)
ret = nl_recvmsgs(socket, cb);
return 0;
}
-int handle_netlink_scan(Wifi *wifi, GDBusMethodInvocation *context)
+int handle_netlink_scan(Wifi *wifi, GDBusMethodInvocation *context, GVariant *params)
{
DBG("");
netconfig_nl_global global = {
int ret = __netconfig_initialize_nl80211(&global);
if (ret < 0) {
DBG("__netconfig_initialize_nl80211() failed, error %d", ret);
- wifi_complete_netlink_specific_scan(wifi, context);
+ wifi_complete_netlink_scan(wifi, context);
return ret;
}
/** Request NL80211_CMD_TRIGGER_SCAN to the kernel. */
- ret = __netconfig_request_netlink_scan(global.socket, global.if_index, global.id, NULL);
+ 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);
wifi_complete_netlink_scan(wifi, context);
ret = __netconfig_initialize_nl_msg(&global);
if (ret < 0) {
DBG("__netconfig_initialize_nl_msg() failed, error %d", ret);
- wifi_complete_netlink_specific_scan(wifi, context);
+ wifi_complete_netlink_scan(wifi, context);
return ret;
}
wifi_complete_netlink_scan(wifi, context);
return 1;
}
-
-int handle_netlink_specific_scan(Wifi *wifi, GDBusMethodInvocation *context, gchar *ssid)
-{
- DBG("ssid: %s", ssid);
- netconfig_nl_global global = {
- .id = -1,
- .if_index = -1,
- .socket = NULL,
- .msg = NULL,
- };
-
- /** Initialize netlink socket */
- int ret = __netconfig_initialize_nl80211(&global);
- if (ret < 0) {
- DBG("__netconfig_initialize_nl80211() failed, error %d", ret);
- wifi_complete_netlink_specific_scan(wifi, context);
- return ret;
- }
-
- /** Request NL80211_CMD_TRIGGER_SCAN to the kernel. */
- ret = __netconfig_request_netlink_scan(global.socket, global.if_index, global.id, ssid);
- if (ret != 0) {
- DBG("__netconfig_request_netlink_scan() failed, error %d", ret);
- wifi_complete_netlink_specific_scan(wifi, context);
- return ret;
- }
-
- ret = __netconfig_initialize_nl_msg(&global);
- if (ret < 0) {
- DBG("__netconfig_initialize_nl_msg() failed, error %d", ret);
- wifi_complete_netlink_specific_scan(wifi, context);
- return ret;
- }
-
- 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);
- if (ret < 0) {
- DBG("nl_recvmsgs_default() failed. ret: %d (error: %s)", ret, nl_geterror(-ret));
- wifi_complete_netlink_specific_scan(wifi, context);
- return ret;
- }
-
- wifi_complete_netlink_specific_scan(wifi, context);
- return 1;
-}