Add current signal strength into signal quality change events

This commit is contained in:
Jouni Malinen 2010-08-27 16:58:06 +03:00
parent 9c77ad1889
commit 60a972a68d
7 changed files with 72 additions and 10 deletions

View file

@ -2452,6 +2452,7 @@ union wpa_event_data {
*/ */
struct signal_change { struct signal_change {
int above_threshold; int above_threshold;
int current_signal;
} signal_change; } signal_change;
}; };

View file

@ -946,6 +946,53 @@ static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
} }
static int get_link_signal(struct nl_msg *msg, void *arg)
{
struct nlattr *tb[NL80211_ATTR_MAX + 1];
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
static struct nla_policy policy[NL80211_STA_INFO_MAX + 1] = {
[NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
};
int *sig = arg;
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
if (!tb[NL80211_ATTR_STA_INFO] ||
nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
tb[NL80211_ATTR_STA_INFO], policy))
return NL_SKIP;
if (!sinfo[NL80211_STA_INFO_SIGNAL])
return NL_SKIP;
*sig = (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
return NL_SKIP;
}
static int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
int *sig)
{
struct nl_msg *msg;
*sig = -9999;
msg = nlmsg_alloc();
if (!msg)
return -ENOMEM;
genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
0, NL80211_CMD_GET_STATION, 0);
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
return send_and_recv_msgs(drv, msg, get_link_signal, sig);
nla_put_failure:
return -ENOBUFS;
}
static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv, static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
struct nlattr *tb[]) struct nlattr *tb[])
{ {
@ -957,6 +1004,7 @@ static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1]; struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
enum nl80211_cqm_rssi_threshold_event event; enum nl80211_cqm_rssi_threshold_event event;
union wpa_event_data ed; union wpa_event_data ed;
int sig, res;
if (tb[NL80211_ATTR_CQM] == NULL || if (tb[NL80211_ATTR_CQM] == NULL ||
nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM], nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM],
@ -982,6 +1030,12 @@ static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
} else } else
return; return;
res = nl80211_get_link_signal(drv, &sig);
if (res == 0) {
ed.signal_change.current_signal = sig;
wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm", sig);
}
wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed); wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
} }

View file

@ -111,8 +111,10 @@ void bgscan_notify_beacon_loss(struct wpa_supplicant *wpa_s)
} }
void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, int above) void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, int above,
int current_signal)
{ {
if (wpa_s->bgscan && wpa_s->bgscan_priv) if (wpa_s->bgscan && wpa_s->bgscan_priv)
wpa_s->bgscan->notify_signal_change(wpa_s->bgscan_priv, above); wpa_s->bgscan->notify_signal_change(wpa_s->bgscan_priv, above,
current_signal);
} }

View file

@ -27,7 +27,8 @@ struct bgscan_ops {
int (*notify_scan)(void *priv, struct wpa_scan_results *scan_res); int (*notify_scan)(void *priv, struct wpa_scan_results *scan_res);
void (*notify_beacon_loss)(void *priv); void (*notify_beacon_loss)(void *priv);
void (*notify_signal_change)(void *priv, int above); void (*notify_signal_change)(void *priv, int above,
int current_signal);
}; };
#ifdef CONFIG_BGSCAN #ifdef CONFIG_BGSCAN
@ -37,7 +38,8 @@ void bgscan_deinit(struct wpa_supplicant *wpa_s);
int bgscan_notify_scan(struct wpa_supplicant *wpa_s, int bgscan_notify_scan(struct wpa_supplicant *wpa_s,
struct wpa_scan_results *scan_res); struct wpa_scan_results *scan_res);
void bgscan_notify_beacon_loss(struct wpa_supplicant *wpa_s); void bgscan_notify_beacon_loss(struct wpa_supplicant *wpa_s);
void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, int above); void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, int above,
int current_signal);
#else /* CONFIG_BGSCAN */ #else /* CONFIG_BGSCAN */
@ -62,7 +64,7 @@ static inline void bgscan_notify_beacon_loss(struct wpa_supplicant *wpa_s)
} }
static inline void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s, static inline void bgscan_notify_signal_change(struct wpa_supplicant *wpa_s,
int above) int above, int current_signal)
{ {
} }

View file

@ -546,7 +546,8 @@ static void bgscan_learn_notify_beacon_loss(void *priv)
} }
static void bgscan_learn_notify_signal_change(void *priv, int above) static void bgscan_learn_notify_signal_change(void *priv, int above,
int current_signal)
{ {
struct bgscan_learn_data *data = priv; struct bgscan_learn_data *data = priv;
@ -555,7 +556,7 @@ static void bgscan_learn_notify_signal_change(void *priv, int above)
return; return;
wpa_printf(MSG_DEBUG, "bgscan learn: signal level changed " wpa_printf(MSG_DEBUG, "bgscan learn: signal level changed "
"(above=%d)", above); "(above=%d current_signal=%d)", above, current_signal);
if (data->scan_interval == data->long_interval && !above) { if (data->scan_interval == data->long_interval && !above) {
wpa_printf(MSG_DEBUG, "bgscan learn: Trigger immediate scan " wpa_printf(MSG_DEBUG, "bgscan learn: Trigger immediate scan "
"and start using short bgscan interval"); "and start using short bgscan interval");

View file

@ -167,7 +167,8 @@ static void bgscan_simple_notify_beacon_loss(void *priv)
} }
static void bgscan_simple_notify_signal_change(void *priv, int above) static void bgscan_simple_notify_signal_change(void *priv, int above,
int current_signal)
{ {
struct bgscan_simple_data *data = priv; struct bgscan_simple_data *data = priv;
@ -176,7 +177,7 @@ static void bgscan_simple_notify_signal_change(void *priv, int above)
return; return;
wpa_printf(MSG_DEBUG, "bgscan simple: signal level changed " wpa_printf(MSG_DEBUG, "bgscan simple: signal level changed "
"(above=%d)", above); "(above=%d current_signal=%d)", above, current_signal);
if (data->scan_interval == data->long_interval && !above) { if (data->scan_interval == data->long_interval && !above) {
wpa_printf(MSG_DEBUG, "bgscan simple: Trigger immediate scan " wpa_printf(MSG_DEBUG, "bgscan simple: Trigger immediate scan "
"and start using short bgscan interval"); "and start using short bgscan interval");

View file

@ -1752,7 +1752,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
break; break;
case EVENT_SIGNAL_CHANGE: case EVENT_SIGNAL_CHANGE:
bgscan_notify_signal_change( bgscan_notify_signal_change(
wpa_s, data->signal_change.above_threshold); wpa_s, data->signal_change.above_threshold,
data->signal_change.current_signal);
break; break;
case EVENT_INTERFACE_ENABLED: case EVENT_INTERFACE_ENABLED:
wpa_printf(MSG_DEBUG, "Interface was enabled"); wpa_printf(MSG_DEBUG, "Interface was enabled");