ubus_complete_request_async(ubus_ctx, &ln->req);
}
+static void
+usteer_local_node_request_link_measurement(struct usteer_local_node *ln)
+{
+ unsigned int min_count = DIV_ROUND_UP(config.link_measurement_interval, config.local_sta_update);
+ struct usteer_node *node;
+ struct sta_info *si;
+
+ node = &ln->node;
+
+ if (ln->link_measurement_tries < min_count) {
+ ln->link_measurement_tries++;
+ return;
+ }
+
+ ln->link_measurement_tries = 0;
+
+ if (!config.link_measurement_interval)
+ return;
+
+ list_for_each_entry(si, &node->sta_info, node_list) {
+ if (si->connected != STA_CONNECTED)
+ continue;
+
+ usteer_ubus_trigger_link_measurement(si);
+ }
+}
+
static void
usteer_local_node_update(struct uloop_timeout *timeout)
{
uloop_timeout_set(&ln->req_timer, 1);
usteer_local_node_kick(ln);
usteer_band_steering_perform_steer(ln);
+ usteer_local_node_request_link_measurement(ln);
+
uloop_timeout_set(timeout, config.local_sta_update);
}
config.band_steering_interval = 120000;
config.band_steering_min_snr = -60;
+ config.link_measurement_interval = 30000;
+
config.roam_kick_delay = 10000;
config.roam_process_timeout = 5 * 1000;
config.roam_scan_tries = 3;
bool req_pending;
bool status_complete;
} netifd;
+
+ unsigned int link_measurement_tries;
};
struct interface;
# steered to a higher frequency band
#option band_steering_min_snr -60
+ # Interval (ms) the device is sent a link-measurement request to help assess
+ # the bi-directional link quality. Setting the interval to 0 disables link-measurements.
+ #option link_measurement_interval 30000
+
# Script to run after bringing up a node
#option node_up_script ''
roam_kick_delay roam_scan_tries roam_scan_timeout \
roam_scan_snr roam_scan_interval \
roam_trigger_snr roam_trigger_interval \
- band_steering_interval band_steering_min_snr \
+ band_steering_interval band_steering_min_snr link_measurement_interval \
load_kick_threshold load_kick_delay load_kick_min_clients \
load_kick_reason_code
do
_cfg(U32, load_kick_reason_code), \
_cfg(U32, band_steering_interval), \
_cfg(I32, band_steering_min_snr), \
+ _cfg(U32, link_measurement_interval), \
_cfg(ARRAY_CB, interfaces), \
_cfg(STRING_CB, node_up_script), \
_cfg(ARRAY_CB, event_log_types), \
return ubus_invoke(ubus_ctx, ln->obj_id, "wnm_disassoc_imminent", b.head, NULL, 0, 100);
}
+int usteer_ubus_trigger_link_measurement(struct sta_info *si)
+{
+ struct usteer_local_node *ln = container_of(si->node, struct usteer_local_node, node);
+
+ if (!usteer_sta_supports_link_measurement(si))
+ return 0;
+
+ blob_buf_init(&b, 0);
+ blobmsg_printf(&b, "addr", MAC_ADDR_FMT, MAC_ADDR_DATA(si->sta->addr));
+ blobmsg_add_u32(&b, "tx-power-used", 5);
+ blobmsg_add_u32(&b, "tx-power-max", 10);
+ return ubus_invoke(ubus_ctx, ln->obj_id, "link_measurement_req", b.head, NULL, 0, 100);
+}
+
int usteer_ubus_trigger_client_scan(struct sta_info *si)
{
struct usteer_local_node *ln = container_of(si->node, struct usteer_local_node, node);
uint32_t band_steering_interval;
int32_t band_steering_min_snr;
+ uint32_t link_measurement_interval;
+
uint32_t initial_connect_delay;
bool load_kick_enabled;
struct usteer_measurement_report *
usteer_measurement_report_add(struct sta *sta, struct usteer_node *node, uint8_t rcpi, uint8_t rsni, uint64_t timestamp);
+
+int usteer_ubus_trigger_link_measurement(struct sta_info *si);
#endif