mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-11-01 10:57:47 +00:00
263 lines
9.2 KiB
Diff
263 lines
9.2 KiB
Diff
--- a/hostapd/ctrl_iface.c
|
|
+++ b/hostapd/ctrl_iface.c
|
|
@@ -3145,6 +3145,25 @@ static int hostapd_ctrl_iface_signal_mon
|
|
return -1;
|
|
}
|
|
|
|
+static int hostapd_ctrl_iface_signal_txrate(struct hostapd_data *hapd,
|
|
+ char *cmd)
|
|
+{
|
|
+ char *pos;
|
|
+ unsigned int low_thold = 0, high_thold = 0;
|
|
+
|
|
+ pos = os_strstr(cmd, "LOW=");
|
|
+ if (pos)
|
|
+ low_thold = atoi(pos + 4);
|
|
+
|
|
+ pos = os_strstr(cmd, "HIGH=");
|
|
+ if (pos)
|
|
+ high_thold = atoi(pos + 5);
|
|
+
|
|
+ if (hapd->driver->signal_txrate)
|
|
+ return hapd->driver->signal_txrate(hapd->drv_priv, low_thold,
|
|
+ high_thold);
|
|
+ return -1;
|
|
+}
|
|
|
|
static int hostapd_ctrl_driver_flags(struct hostapd_iface *iface, char *buf,
|
|
size_t buflen)
|
|
@@ -3791,6 +3810,9 @@ static int hostapd_ctrl_iface_receive_pr
|
|
} else if (os_strncmp(buf, "SIGNAL_MONITOR", 14) == 0) {
|
|
if (hostapd_ctrl_iface_signal_monitor(hapd, buf + 14))
|
|
reply_len = -1;
|
|
+ } else if (os_strncmp(buf, "SIGNAL_TXRATE", 13) == 0) {
|
|
+ if (hostapd_ctrl_iface_signal_txrate(hapd, buf + 13))
|
|
+ reply_len = -1;
|
|
} else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
|
|
reply_len = hostapd_ctrl_iface_get_capability(
|
|
hapd, buf + 15, reply, reply_size);
|
|
--- a/hostapd/hostapd_cli.c
|
|
+++ b/hostapd/hostapd_cli.c
|
|
@@ -1505,6 +1505,12 @@ static int hostapd_cli_cmd_reload_wpa_ps
|
|
}
|
|
|
|
|
|
+static int hostapd_cli_cmd_signal_txrate(struct wpa_ctrl *ctrl, int argc,
|
|
+ char *argv[])
|
|
+{
|
|
+ return hostapd_cli_cmd(ctrl, "SIGNAL_TXRATE", 0, argc, argv);
|
|
+}
|
|
+
|
|
struct hostapd_cli_cmd {
|
|
const char *cmd;
|
|
int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
|
|
@@ -1680,6 +1686,9 @@ static const struct hostapd_cli_cmd host
|
|
"<addr> = poll a STA to check connectivity with a QoS null frame" },
|
|
{ "signal_monitor", hostapd_cli_cmd_signal_monitor, NULL,
|
|
"= set signal monitor parameters" },
|
|
+ { "signal_txrate", hostapd_cli_cmd_signal_txrate, NULL,
|
|
+ "= set signal tx rate parameters: signal_txrate "
|
|
+ "LOW=<> HIGH=<>" },
|
|
{ "req_beacon", hostapd_cli_cmd_req_beacon, NULL,
|
|
"<addr> [req_mode=] <measurement request hexdump> = send a Beacon report request to a station" },
|
|
{ "reload_wpa_psk", hostapd_cli_cmd_reload_wpa_psk, NULL,
|
|
--- a/src/drivers/driver.h
|
|
+++ b/src/drivers/driver.h
|
|
@@ -4412,6 +4412,20 @@ struct wpa_driver_ops {
|
|
*/
|
|
int (*get_peer_inactive_time)(void *priv, const u8 *addr);
|
|
|
|
+ /**
|
|
+ * signal_txrate - Set signal monitoring parameters
|
|
+ * @priv: Private driver interface data
|
|
+ * @low_thold: Low threshold value for signal txrate events; 0 = disabled
|
|
+ * @high_thold: High threshold value for signal txrate events; 0 = disabled
|
|
+ * Returns: 0 on success, -1 on failure (or if not supported)
|
|
+ *
|
|
+ * This function can be used to configure monitoring of signal tx rate
|
|
+ * with the current AP. Whenever txrate drops below the low_thold
|
|
+ * or increases above high_thold.
|
|
+ */
|
|
+ int (*signal_txrate)(void *priv, const u32 low_thold,
|
|
+ u32 high_thold);
|
|
+
|
|
/**
|
|
* update_connect_params - Update the connection parameters
|
|
* @priv: Private driver interface data
|
|
--- a/src/drivers/driver_nl80211.c
|
|
+++ b/src/drivers/driver_nl80211.c
|
|
@@ -8268,6 +8268,29 @@ static int nl80211_signal_monitor(void *
|
|
return send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
|
}
|
|
|
|
+static int nl80211_signal_txrate(void *priv, const u32 low_thold,
|
|
+ u32 high_thold)
|
|
+{
|
|
+ struct i802_bss *bss = priv;
|
|
+ struct wpa_driver_nl80211_data *drv = bss->drv;
|
|
+ struct nl_msg *msg;
|
|
+ struct nlattr *cqm;
|
|
+
|
|
+ if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_CQM)) ||
|
|
+ !(cqm = nla_nest_start(msg, NL80211_ATTR_CQM)) ||
|
|
+ nla_put_u32(msg, NL80211_ATTR_CQM_LOW_TX_RATE_THOLD,
|
|
+ low_thold) ||
|
|
+ nla_put_u32(msg, NL80211_ATTR_CQM_HIGH_TX_RATE_THOLD,
|
|
+ high_thold)) {
|
|
+ nlmsg_free(msg);
|
|
+ wpa_printf(MSG_WARNING, "nl80211: Signal txrate returning");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ nla_nest_end(msg, cqm);
|
|
+
|
|
+ return send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
|
+}
|
|
|
|
static int get_channel_width(struct nl_msg *msg, void *arg)
|
|
{
|
|
@@ -11725,6 +11748,7 @@ const struct wpa_driver_ops wpa_driver_n
|
|
.deinit_p2p_cli = wpa_driver_nl80211_deinit_p2p_cli,
|
|
.resume = wpa_driver_nl80211_resume,
|
|
.signal_monitor = nl80211_signal_monitor,
|
|
+ .signal_txrate = nl80211_signal_txrate,
|
|
.signal_poll = nl80211_signal_poll,
|
|
.channel_info = nl80211_channel_info,
|
|
.set_param = nl80211_set_param,
|
|
--- a/src/drivers/driver_nl80211_event.c
|
|
+++ b/src/drivers/driver_nl80211_event.c
|
|
@@ -1274,12 +1274,15 @@ static void nl80211_cqm_event(struct wpa
|
|
[NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
|
|
[NL80211_ATTR_CQM_BEACON_LOSS_EVENT] = { .type = NLA_FLAG },
|
|
[NL80211_ATTR_CQM_RSSI_LEVEL] = { .type = NLA_U32 },
|
|
+ [NL80211_ATTR_CQM_TX_RATE_THRESHOLD_EVENT] =
|
|
+ { .type = NLA_U32 },
|
|
};
|
|
struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
|
|
- enum nl80211_cqm_rssi_threshold_event event;
|
|
+ enum nl80211_cqm_rssi_threshold_event rssi_event;
|
|
+ enum nl80211_cqm_tx_rate_threshold_event txrate_event;
|
|
union wpa_event_data ed;
|
|
struct wpa_signal_info sig;
|
|
- int res, rssi_level;
|
|
+ int res, rssi_level, txrate_level;
|
|
u8 *addr = NULL;
|
|
|
|
if (tb[NL80211_ATTR_CQM] == NULL ||
|
|
@@ -1324,19 +1327,41 @@ static void nl80211_cqm_event(struct wpa
|
|
return;
|
|
}
|
|
|
|
+ if (tb[NL80211_ATTR_MAC])
|
|
+ addr = nla_data(tb[NL80211_ATTR_MAC]);
|
|
+
|
|
+ if (cqm[NL80211_ATTR_CQM_TX_RATE_THRESHOLD_EVENT]) {
|
|
+ txrate_event =
|
|
+ nla_get_u32(cqm[NL80211_ATTR_CQM_TX_RATE_THRESHOLD_EVENT]);
|
|
+ txrate_level =
|
|
+ nla_get_u32(cqm[NL80211_ATTR_CQM_TX_RATE_LEVEL]);
|
|
+
|
|
+ if (txrate_event == NL80211_CQM_TX_RATE_THRESHOLD_EVENT_HIGH) {
|
|
+ wpa_msg(drv->ctx, MSG_INFO, "nl80211: CQM TXRATE HIGH "
|
|
+ "event for "MACSTR " txrate :%d",
|
|
+ MAC2STR(addr), txrate_level);
|
|
+ } else if (txrate_event ==
|
|
+ NL80211_CQM_TX_RATE_THRESHOLD_EVENT_LOW) {
|
|
+ wpa_msg(drv->ctx, MSG_INFO, "nl80211: CQM TXRATE LOW "
|
|
+ "event for "MACSTR " txrate :%d",
|
|
+ MAC2STR(addr), txrate_level);
|
|
+ } else {
|
|
+ wpa_msg(drv->ctx, MSG_INFO, "Unknown CQM TXRATE "
|
|
+ " threshold event :%d", txrate_event);
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL) {
|
|
wpa_printf(MSG_DEBUG,
|
|
"nl80211: Not a CQM RSSI threshold event");
|
|
return;
|
|
}
|
|
- event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
|
|
-
|
|
- if (tb[NL80211_ATTR_MAC])
|
|
- addr = nla_data(tb[NL80211_ATTR_MAC]);
|
|
+ rssi_event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
|
|
|
|
rssi_level = (s32) nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_LEVEL]);
|
|
|
|
- if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
|
|
+ if (rssi_event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
|
|
if (addr) {
|
|
wpa_msg(drv->ctx, MSG_INFO, "nl80211: CQM RSSI HIGH "
|
|
"event for "MACSTR " RSSI :%d", MAC2STR(addr),
|
|
@@ -1346,7 +1371,7 @@ static void nl80211_cqm_event(struct wpa
|
|
wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
|
|
"event: RSSI high");
|
|
ed.signal_change.above_threshold = 1;
|
|
- } else if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
|
|
+ } else if (rssi_event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
|
|
if (addr) {
|
|
wpa_msg(drv->ctx, MSG_INFO, "nl80211: CQM RSSI LOW "
|
|
"event for "MACSTR " RSSI :%d", MAC2STR(addr),
|
|
@@ -1359,7 +1384,7 @@ static void nl80211_cqm_event(struct wpa
|
|
} else {
|
|
wpa_printf(MSG_DEBUG,
|
|
"nl80211: Unknown CQM RSSI threshold event: %d",
|
|
- event);
|
|
+ rssi_event);
|
|
return;
|
|
}
|
|
|
|
--- a/src/drivers/nl80211_copy.h
|
|
+++ b/src/drivers/nl80211_copy.h
|
|
@@ -4792,6 +4792,17 @@ enum nl80211_ps_state {
|
|
* loss event
|
|
* @NL80211_ATTR_CQM_RSSI_LEVEL: the RSSI value in dBm that triggered the
|
|
* RSSI threshold event.
|
|
+ * @NL80211_ATTR_CQM_LOW_TX_RATE_THOLD: TX_RATE threshold in Kbps. This value
|
|
+ * specifies the low threshold for the TX_RATE level at which an event will be
|
|
+ * sent. Zero to disable. Events will be sent when the TX_RATE value goes
|
|
+ * lesser than this threshold.
|
|
+ * @NL80211_ATTR_CQM_HIGH_TX_RATE_THOLD: TX RATE in Kbps. This value
|
|
+ * specifies the high threshold for the TX_RATE level at which an event will
|
|
+ * be sent. Zero to diable. Event will be sent when the TX_RATE values goes
|
|
+ * greater than this threshold.
|
|
+ * @NL80211_ATTR_CQM_TX_RATE_THRESHOLD_EVENT: TX_RATE threshold event
|
|
+ * @NL80211_ATTR_CQM_TX_RATE_LEVEL: the tx rate value in Kbps that triggered the
|
|
+ * TX_RATE threshold event.
|
|
* @__NL80211_ATTR_CQM_AFTER_LAST: internal
|
|
* @NL80211_ATTR_CQM_MAX: highest key attribute
|
|
*/
|
|
@@ -4806,7 +4817,10 @@ enum nl80211_attr_cqm {
|
|
NL80211_ATTR_CQM_TXE_INTVL,
|
|
NL80211_ATTR_CQM_BEACON_LOSS_EVENT,
|
|
NL80211_ATTR_CQM_RSSI_LEVEL,
|
|
-
|
|
+ NL80211_ATTR_CQM_LOW_TX_RATE_THOLD,
|
|
+ NL80211_ATTR_CQM_HIGH_TX_RATE_THOLD,
|
|
+ NL80211_ATTR_CQM_TX_RATE_THRESHOLD_EVENT,
|
|
+ NL80211_ATTR_CQM_TX_RATE_LEVEL,
|
|
/* keep last */
|
|
__NL80211_ATTR_CQM_AFTER_LAST,
|
|
NL80211_ATTR_CQM_MAX = __NL80211_ATTR_CQM_AFTER_LAST - 1
|
|
@@ -4820,13 +4834,17 @@ enum nl80211_attr_cqm {
|
|
* configured threshold
|
|
* @NL80211_CQM_RSSI_BEACON_LOSS_EVENT: (reserved, never sent)
|
|
*/
|
|
+
|
|
enum nl80211_cqm_rssi_threshold_event {
|
|
NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
|
|
NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
|
|
NL80211_CQM_RSSI_BEACON_LOSS_EVENT,
|
|
};
|
|
|
|
-
|
|
+enum nl80211_cqm_tx_rate_threshold_event {
|
|
+ NL80211_CQM_TX_RATE_THRESHOLD_EVENT_LOW = 1,
|
|
+ NL80211_CQM_TX_RATE_THRESHOLD_EVENT_HIGH,
|
|
+};
|
|
/**
|
|
* enum nl80211_tx_power_setting - TX power adjustment
|
|
* @NL80211_TX_POWER_AUTOMATIC: automatically determine transmit power
|