scan: Add scan_active_full
Add a version of scan_active that accepts a struct with the scan parameters so we can more easily add new parameters. Since the genl message is now built within scan_active_start the extra_ie memory can be freed by the caller at any time.
This commit is contained in:
parent
ada054cc30
commit
ed1538d5bb
148
src/scan.c
148
src/scan.c
|
@ -66,8 +66,7 @@ struct scan_request {
|
|||
scan_destroy_func_t destroy;
|
||||
bool passive:1; /* Active or Passive scan? */
|
||||
bool triggered:1;
|
||||
uint8_t *extra_ie;
|
||||
size_t extra_ie_size;
|
||||
struct l_genl_msg *start_cmd;
|
||||
};
|
||||
|
||||
struct scan_context {
|
||||
|
@ -106,6 +105,7 @@ static void scan_request_free(void *data)
|
|||
{
|
||||
struct scan_request *sr = data;
|
||||
|
||||
l_genl_msg_unref(sr->start_cmd);
|
||||
free(sr);
|
||||
}
|
||||
|
||||
|
@ -166,45 +166,17 @@ bool scan_ifindex_remove(uint32_t ifindex)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool __scan_passive_start(struct l_genl_family *nl80211,
|
||||
uint32_t ifindex,
|
||||
static bool scan_send_start(struct l_genl_msg **msg,
|
||||
scan_func_t callback, void *user_data)
|
||||
{
|
||||
struct l_genl_msg *msg;
|
||||
if (!l_genl_family_send(nl80211, *msg, callback,
|
||||
user_data, NULL)) {
|
||||
l_error("Sending NL80211_CMD_TRIGGER_SCAN failed");
|
||||
|
||||
msg = l_genl_msg_new_sized(NL80211_CMD_TRIGGER_SCAN, 16);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &ifindex);
|
||||
|
||||
if (!l_genl_family_send(nl80211, msg, callback, user_data, NULL)) {
|
||||
l_error("Starting passive scan failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __scan_active_start(struct l_genl_family *nl80211,
|
||||
uint32_t ifindex,
|
||||
uint8_t *extra_ie, size_t extra_ie_size,
|
||||
scan_func_t callback, void *user_data)
|
||||
{
|
||||
struct l_genl_msg *msg;
|
||||
|
||||
msg = l_genl_msg_new_sized(NL80211_CMD_TRIGGER_SCAN,
|
||||
32 + extra_ie_size);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &ifindex);
|
||||
l_genl_msg_enter_nested(msg, NL80211_ATTR_SCAN_SSIDS);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_SSID, 0, NULL);
|
||||
l_genl_msg_leave_nested(msg);
|
||||
|
||||
if (extra_ie && extra_ie_size)
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_IE, extra_ie_size,
|
||||
extra_ie);
|
||||
|
||||
if (!l_genl_family_send(nl80211, msg, callback, user_data, NULL)) {
|
||||
l_error("Starting active scan failed");
|
||||
return false;
|
||||
}
|
||||
*msg = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -214,7 +186,6 @@ static void start_next_scan_request(void *userdata)
|
|||
uint32_t ifindex = L_PTR_TO_UINT(userdata);
|
||||
struct scan_context *sc;
|
||||
struct scan_request *sr;
|
||||
bool r;
|
||||
|
||||
sc = l_queue_find(scan_contexts, scan_context_match,
|
||||
L_UINT_TO_PTR(ifindex));
|
||||
|
@ -224,16 +195,7 @@ static void start_next_scan_request(void *userdata)
|
|||
|
||||
sr = l_queue_peek_head(sc->requests);
|
||||
|
||||
if (sr->passive)
|
||||
r = __scan_passive_start(nl80211, ifindex, scan_done, sc);
|
||||
else
|
||||
r = __scan_active_start(nl80211, ifindex,
|
||||
sr->extra_ie, sr->extra_ie_size,
|
||||
scan_done, sc);
|
||||
|
||||
if (!r) {
|
||||
l_error("Could not send CMD_TRIGGER_SCAN");
|
||||
|
||||
if (!scan_send_start(&sr->start_cmd, scan_done, sc)) {
|
||||
if (sr->destroy)
|
||||
sr->destroy(sr->userdata);
|
||||
|
||||
|
@ -287,15 +249,37 @@ static void scan_done(struct l_genl_msg *msg, void *userdata)
|
|||
sr->trigger(0, sr->userdata);
|
||||
}
|
||||
|
||||
static struct l_genl_msg *scan_build_cmd(uint32_t ifindex, bool passive,
|
||||
const struct scan_parameters *params)
|
||||
{
|
||||
struct l_genl_msg *msg;
|
||||
|
||||
msg = l_genl_msg_new_sized(NL80211_CMD_TRIGGER_SCAN,
|
||||
32 + params->extra_ie_size);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &ifindex);
|
||||
|
||||
if (!passive) {
|
||||
l_genl_msg_enter_nested(msg, NL80211_ATTR_SCAN_SSIDS);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_SSID, 0, NULL);
|
||||
l_genl_msg_leave_nested(msg);
|
||||
}
|
||||
|
||||
if (params->extra_ie && params->extra_ie_size)
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_IE,
|
||||
params->extra_ie_size,
|
||||
params->extra_ie);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
static uint32_t scan_common(uint32_t ifindex, bool passive,
|
||||
uint8_t *extra_ie, size_t extra_ie_size,
|
||||
const struct scan_parameters *params,
|
||||
scan_trigger_func_t trigger,
|
||||
scan_notify_func_t notify, void *userdata,
|
||||
scan_destroy_func_t destroy)
|
||||
{
|
||||
struct scan_context *sc;
|
||||
struct scan_request *sr;
|
||||
bool r;
|
||||
|
||||
sc = l_queue_find(scan_contexts, scan_context_match,
|
||||
L_UINT_TO_PTR(ifindex));
|
||||
|
@ -309,28 +293,25 @@ static uint32_t scan_common(uint32_t ifindex, bool passive,
|
|||
sr->userdata = userdata;
|
||||
sr->destroy = destroy;
|
||||
sr->passive = passive;
|
||||
sr->extra_ie = extra_ie;
|
||||
sr->extra_ie_size = extra_ie_size;
|
||||
sr->id = ++next_scan_request_id;
|
||||
|
||||
sr->start_cmd = scan_build_cmd(ifindex, passive, params);
|
||||
if (!sr->start_cmd)
|
||||
goto error;
|
||||
|
||||
if (l_queue_length(sc->requests) > 0)
|
||||
goto done;
|
||||
|
||||
if (sc->state != SCAN_STATE_NOT_RUNNING)
|
||||
goto done;
|
||||
|
||||
if (passive)
|
||||
r = __scan_passive_start(nl80211, ifindex, scan_done, sc);
|
||||
else
|
||||
r = __scan_active_start(nl80211, ifindex,
|
||||
extra_ie, extra_ie_size,
|
||||
scan_done, sc);
|
||||
if (scan_send_start(&sr->start_cmd, scan_done, sc))
|
||||
goto done;
|
||||
|
||||
if (!r) {
|
||||
error:
|
||||
scan_request_free(sr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
done:
|
||||
l_queue_push_tail(sc->requests, sr);
|
||||
|
||||
|
@ -341,20 +322,32 @@ uint32_t scan_passive(uint32_t ifindex, scan_trigger_func_t trigger,
|
|||
scan_notify_func_t notify, void *userdata,
|
||||
scan_destroy_func_t destroy)
|
||||
{
|
||||
return scan_common(ifindex, true, NULL, 0, trigger, notify,
|
||||
struct scan_parameters params = {};
|
||||
|
||||
return scan_common(ifindex, true, ¶ms, trigger, notify,
|
||||
userdata, destroy);
|
||||
}
|
||||
|
||||
/*
|
||||
* @extra_ie data is passed by reference. So it must be valid at least until
|
||||
* the @trigger callback is called.
|
||||
*/
|
||||
uint32_t scan_active(uint32_t ifindex, uint8_t *extra_ie, size_t extra_ie_size,
|
||||
scan_trigger_func_t trigger,
|
||||
scan_notify_func_t notify, void *userdata,
|
||||
scan_destroy_func_t destroy)
|
||||
{
|
||||
return scan_common(ifindex, false, extra_ie, extra_ie_size,
|
||||
struct scan_parameters params = {};
|
||||
|
||||
params.extra_ie = extra_ie;
|
||||
params.extra_ie_size = extra_ie_size;
|
||||
|
||||
return scan_common(ifindex, false, ¶ms,
|
||||
trigger, notify, userdata, destroy);
|
||||
}
|
||||
|
||||
uint32_t scan_active_full(uint32_t ifindex,
|
||||
const struct scan_parameters *params,
|
||||
scan_trigger_func_t trigger, scan_notify_func_t notify,
|
||||
void *userdata, scan_destroy_func_t destroy)
|
||||
{
|
||||
return scan_common(ifindex, false, params,
|
||||
trigger, notify, userdata, destroy);
|
||||
}
|
||||
|
||||
|
@ -436,6 +429,23 @@ static void scan_periodic_done(struct l_genl_msg *msg, void *user_data)
|
|||
sc->sp.trigger(0, sc->sp.userdata);
|
||||
}
|
||||
|
||||
static bool scan_periodic_send_start(struct scan_context *sc)
|
||||
{
|
||||
struct scan_parameters params = {};
|
||||
struct l_genl_msg *msg;
|
||||
|
||||
msg = scan_build_cmd(sc->ifindex, true, ¶ms);
|
||||
if (!msg)
|
||||
return false;
|
||||
|
||||
if (!scan_send_start(&msg, scan_periodic_done, sc)) {
|
||||
l_genl_msg_unref(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void scan_periodic_start(uint32_t ifindex, scan_trigger_func_t trigger,
|
||||
scan_notify_func_t func, void *userdata)
|
||||
{
|
||||
|
@ -461,7 +471,7 @@ void scan_periodic_start(uint32_t ifindex, scan_trigger_func_t trigger,
|
|||
sc->sp.retry = false;
|
||||
sc->sp.rearm = false;
|
||||
|
||||
__scan_passive_start(nl80211, ifindex, scan_periodic_done, sc);
|
||||
scan_periodic_send_start(sc);
|
||||
}
|
||||
|
||||
bool scan_periodic_stop(uint32_t ifindex)
|
||||
|
@ -501,7 +511,8 @@ static void scan_periodic_timeout(struct l_timeout *timeout, void *user_data)
|
|||
l_debug("scan_periodic_timeout: %u", sc->ifindex);
|
||||
|
||||
sc->sp.interval *= 2;
|
||||
__scan_passive_start(nl80211, sc->ifindex, scan_periodic_done, sc);
|
||||
|
||||
scan_periodic_send_start(sc);
|
||||
}
|
||||
|
||||
static void scan_periodic_rearm(struct scan_context *sc)
|
||||
|
@ -925,8 +936,7 @@ static void get_scan_done(void *user)
|
|||
l_idle_oneshot(start_next_scan_request,
|
||||
L_UINT_TO_PTR(sc->ifindex), NULL);
|
||||
} else if (sc->sp.retry) {
|
||||
__scan_passive_start(nl80211, sc->ifindex,
|
||||
scan_periodic_done, sc);
|
||||
if (scan_periodic_send_start(sc))
|
||||
sc->sp.retry = false;
|
||||
} else if (sc->sp.rearm) {
|
||||
scan_periodic_rearm(sc);
|
||||
|
|
|
@ -64,6 +64,11 @@ struct scan_bss {
|
|||
bool cap_rm_neighbor_report : 1;
|
||||
};
|
||||
|
||||
struct scan_parameters {
|
||||
const uint8_t *extra_ie;
|
||||
size_t extra_ie_size;
|
||||
};
|
||||
|
||||
uint32_t scan_passive(uint32_t ifindex, scan_trigger_func_t trigger,
|
||||
scan_notify_func_t notify, void *userdata,
|
||||
scan_destroy_func_t destroy);
|
||||
|
@ -71,6 +76,10 @@ uint32_t scan_active(uint32_t ifindex, uint8_t *extra_ie, size_t extra_ie_size,
|
|||
scan_trigger_func_t trigger,
|
||||
scan_notify_func_t notify, void *userdata,
|
||||
scan_destroy_func_t destroy);
|
||||
uint32_t scan_active_full(uint32_t ifindex,
|
||||
const struct scan_parameters *params,
|
||||
scan_trigger_func_t trigger, scan_notify_func_t notify,
|
||||
void *userdata, scan_destroy_func_t destroy);
|
||||
bool scan_cancel(uint32_t ifindex, uint32_t id);
|
||||
|
||||
void scan_periodic_start(uint32_t ifindex, scan_trigger_func_t trigger,
|
||||
|
|
Loading…
Reference in New Issue