Skip to content

Commit

Permalink
Steering support for associated STA!
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikita-Hakai authored and soumyasmunshi committed Dec 20, 2024
1 parent 7add8f7 commit eb894ed
Show file tree
Hide file tree
Showing 19 changed files with 760 additions and 20 deletions.
2 changes: 2 additions & 0 deletions inc/dm_easy_mesh_agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class dm_easy_mesh_agent_t : public dm_easy_mesh_t {
int analyze_channel_pref_query(em_bus_event_t *evt, em_cmd_t *pcmd[]);
int analyze_channel_sel_req(em_bus_event_t *evt, wifi_bus_desc_t *desc,bus_handle_t *bus_hdl);
int analyze_sta_link_metrics(em_bus_event_t *evt, em_cmd_t *pcmd[]);
int analyze_btm_request_action_frame(em_bus_event_t *evt, wifi_bus_desc_t *desc,bus_handle_t *bus_hdl);
int analyze_btm_response_action_frame(em_bus_event_t *evt, em_cmd_t *pcmd[]);

static webconfig_error_t webconfig_dummy_apply(webconfig_subdoc_t *doc, webconfig_subdoc_data_t *data);

Expand Down
4 changes: 4 additions & 0 deletions inc/em_agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class em_agent_t : public em_mgr_t {
void handle_action_frame(struct ieee80211_mgmt *frame);
void handle_public_action_frame(struct ieee80211_mgmt *frame);
void handle_vendor_public_action_frame(struct ieee80211_mgmt *frame);
void handle_btm_request_action_frame(em_bus_event_t *evt);
void handle_btm_response_action_frame(em_bus_event_t *evt);

public:

Expand Down Expand Up @@ -72,6 +74,7 @@ class em_agent_t : public em_mgr_t {
void handle_channel_pref_query(em_bus_event_t *evt);
void handle_channel_sel_req(em_bus_event_t *evt);
void handle_sta_link_metrics(em_bus_event_t *evt);
void handle_steer_sta(em_bus_event_t *evt);

em_cmd_t& get_command(char *in);

Expand All @@ -89,6 +92,7 @@ class em_agent_t : public em_mgr_t {
static int sta_cb(char *event_name, raw_data_t *data);
static int onewifi_cb(char *event_name, raw_data_t *data);
static int assoc_stats_cb(char *event_name, raw_data_t *data);
static int mgmt_action_frame_cb(char *event_name, raw_data_t *data);
void *get_assoc(void*);
void io(void *data, bool input = true);
bool agent_input(void *data);
Expand Down
51 changes: 46 additions & 5 deletions inc/em_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -719,9 +719,8 @@ typedef struct {
unsigned char target_bssid[6];
}__attribute__((__packed__)) em_steering_btm_rprt_t;


typedef struct {
unsigned char bssid[6];
bssid_t bssid;
unsigned char req_mode : 1;
unsigned char btm_dissoc_imminent : 1;
unsigned char btm_abridged : 1;
Expand All @@ -731,11 +730,38 @@ typedef struct {
unsigned char sta_list_count;
mac_address_t sta_mac_addr;
unsigned char target_bssid_list_count;
unsigned char target_bssids[6];
bssid_t target_bssids;
unsigned char target_bss_op_class;
unsigned char target_bss_channel_num;
}__attribute__((__packed__)) em_steering_req_t;

typedef struct {
unsigned char pref_candidate_list_inc : 1;
unsigned char btm_abridged : 1;
unsigned char btm_disassoc_imminent : 1;
unsigned char bss_termination_inc : 1;
unsigned char ess_disassoc_imminent : 1;
unsigned char reserved : 3;
}__attribute__((__packed__)) em_80211_btm_req_reqmode_t;

typedef struct {
unsigned char elem_id;//52
unsigned char length;
bssid_t bssid;
unsigned int bssid_info;
unsigned char op_class;
unsigned char channel_num;
unsigned char phy_type;
//optional elements
unsigned char var[0];
}__attribute__((__packed__)) em_80211_neighbor_report_t;

typedef struct {
//todo: bss_termination_duration;
//session_info_url;
em_80211_neighbor_report_t bss_transition_cand_list[0];
}__attribute__((__packed__)) em_80211_btm_req_var_t;

typedef struct {
em_steering_req_t agile_multiband;
unsigned char reason_code;
Expand Down Expand Up @@ -1716,6 +1742,7 @@ typedef enum {
em_state_agent_client_cap_report,
em_state_agent_channel_pref_query,
em_state_agent_sta_link_metrics,
em_state_agent_steer_btm_res_pending,

em_state_ctrl_unconfigured = 0x100,
em_state_ctrl_wsc_m1_pending,
Expand All @@ -1736,6 +1763,7 @@ typedef enum {
em_state_ctrl_sta_cap_confirmed,
em_state_ctrl_sta_link_metrics_pending,
em_state_ctrl_sta_steer_pending,
em_state_ctrl_steer_btm_req_ack_rcvd,
em_state_ctrl_sta_disassoc_pending,
em_state_ctrl_set_policy_pending,
em_state_ctrl_ap_mld_config_pending,
Expand Down Expand Up @@ -1778,6 +1806,7 @@ typedef enum {
em_cmd_type_sta_link_metrics,
em_cmd_type_op_channel_report,
em_cmd_type_sta_steer,
em_cmd_type_btm_report,
em_cmd_type_sta_disassoc,
em_cmd_type_get_policy,
em_cmd_type_set_policy,
Expand Down Expand Up @@ -2370,7 +2399,9 @@ typedef enum {
em_bus_event_type_channel_pref_query,
em_bus_event_type_channel_sel_req,
em_bus_event_type_sta_link_metrics,
em_bus_event_type_set_radio
em_bus_event_type_set_radio,
em_bus_event_type_bss_tm_req,
em_bus_event_type_btm_response
} em_bus_event_type_t;

typedef struct {
Expand Down Expand Up @@ -2449,6 +2480,7 @@ typedef enum {
dm_orch_type_sta_link_metrics,
dm_orch_type_op_channel_report,
dm_orch_type_sta_steer,
dm_orch_type_sta_steer_btm_report,
dm_orch_type_sta_disassoc,
dm_orch_type_policy_cfg,
} dm_orch_type_t;
Expand Down Expand Up @@ -2553,15 +2585,23 @@ typedef struct {
mac_address_t sta_mac;
bssid_t source;
bssid_t target;
em_steer_req_mode_t request_mode;
unsigned int request_mode;
bool disassoc_imminent;
bool btm_abridged;
bool link_removal_imminent;
unsigned int steer_opportunity_win;
unsigned int btm_disassociation_timer;
unsigned int target_op_class;
unsigned int target_channel;
} em_cmd_steer_params_t;

typedef struct {
bssid_t source;
mac_address_t sta_mac;
unsigned char status_code;
bssid_t target;
} em_cmd_btm_report_params_t;

typedef struct {
mac_address_t sta_mac;
bssid_t bssid;
Expand All @@ -2579,6 +2619,7 @@ typedef struct {
union {
em_cmd_args_t args;
em_cmd_steer_params_t steer_params;
em_cmd_btm_report_params_t btm_report_params;
em_cmd_disassoc_params_t disassoc_params;
} u;
} em_cmd_params_t;
Expand Down
2 changes: 1 addition & 1 deletion inc/em_capability.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class em_capability_t {

public:
void process_msg(unsigned char *data, unsigned int len);
void process_state();
void process_agent_state();

int get_cap_query_tx_count() { return m_cap_query_tx_cnt; }
void set_cap_query_tx_count(unsigned int cnt) { m_cap_query_tx_cnt = cnt; }
Expand Down
30 changes: 30 additions & 0 deletions inc/em_cmd_btm_report.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright 2023 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef EM_CMD_STA_STEER_H
#define EM_CMD_STA_STEER_H

#include "em_cmd.h"

class em_cmd_btm_report_t : public em_cmd_t {

public:
em_cmd_btm_report_t(em_cmd_btm_report_params_t params);
};

#endif
10 changes: 9 additions & 1 deletion inc/em_steering.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ class em_steering_t {
int send_client_steering_req_msg();
int send_client_assoc_ctrl_req_msg();
int send_client_assoc_ctrl_req_msg(em_client_assoc_ctrl_req_t *assoc_ctrl);
int send_btm_report_msg(mac_address_t sta, bssid_t bss);
int send_1905_ack_message(mac_addr_t sta_mac);
int handle_client_steering_req(unsigned char *buff, unsigned int len);
int handle_client_steering_report(unsigned char *buff, unsigned int len);
int handle_ack_msg(unsigned char *buff, unsigned int len);
short create_error_code_tlv(unsigned char *buff, int val, mac_addr_t sta_mac);
short create_btm_report_tlv(unsigned char *buff);
short create_btm_request_tlv(unsigned char *buff);

public:
virtual int send_frame(unsigned char *buff, unsigned int len, bool multicast = false) = 0;
Expand All @@ -46,7 +54,7 @@ class em_steering_t {
void set_client_assoc_ctrl_req_tx_count(unsigned int cnt) { m_client_assoc_ctrl_req_tx_cnt = cnt; }

void process_msg(unsigned char *data, unsigned int len);
void process_state();
void process_agent_state();
void process_ctrl_state();

em_steering_t();
Expand Down
15 changes: 15 additions & 0 deletions inc/ieee80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -1537,6 +1537,21 @@ typedef uint8_t le16[2];
#define WLAN_PA_FTM 33
#define WLAN_PA_FILS_DISCOVERY 34

/* WNM action codes (IEEE Std 802.11-2016, 9.6.14.1, Table 9-354) */
#define WLAN_WNM_BTM_QUERY 6
#define WLAN_WNM_BTM_REQUEST 7
#define WLAN_WNM_BTM_RESPONSE 8

struct ieee80211_hdr {
le16 frame_control;
le16 duration;
uint8_t da[6];
uint8_t sa[6];
uint8_t bssid[6];
le16 seq_ctrl;
/* followed by 'u8 addr4[6];' if ToDS and FromDS is set in data frame
*/
} __attribute__ ((packed));

struct ieee80211_mgmt {
le16 frame_control;
Expand Down
104 changes: 102 additions & 2 deletions src/agent/dm_easy_mesh_agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@
#include "em_cmd_dev_init.h"
#include "dm_easy_mesh_agent.h"
#include <cjson/cJSON.h>
#include "ieee80211.h"
#include "em_cmd_sta_list.h"
#include "em_cmd_onewifi_cb.h"
#include "em_cmd_cfg_renew.h"
#include "em_cmd_channel_pref_query.h"
#include "em_cmd_op_channel_report.h"
#include "em_cmd_btm_report.h"

int dm_easy_mesh_agent_t::analyze_dev_init(em_bus_event_t *evt, em_cmd_t *pcmd[])
{
Expand Down Expand Up @@ -372,7 +374,6 @@ int dm_easy_mesh_agent_t::analyze_onewifi_radio_cb(em_bus_event_t *evt, em_cmd_t

return num;
}


void dm_easy_mesh_agent_t::translate_onewifi_sta_data(char *str)
{
Expand Down Expand Up @@ -595,14 +596,113 @@ int dm_easy_mesh_agent_t::analyze_sta_link_metrics(em_bus_event_t *evt, em_cmd_t
}

if ((webconfig_easymesh_decode(&config, (char *)evt->u.raw_buff, &extdata, &type)) == webconfig_error_none) {
printf("%s:%d assoc sta Link metrics decode success:\n%s\n",__func__, __LINE__, evt->u.raw_buff);
printf("%s:%d assoc sta Link metrics decode success\n",__func__, __LINE__);
} else {
printf("%s:%d assoc sta link metrics decode fail\n",__func__, __LINE__);
}

return 1;
}

int dm_easy_mesh_agent_t::analyze_btm_request_action_frame(em_bus_event_t *evt, wifi_bus_desc_t *desc, bus_handle_t *bus_hdl)
{
struct ieee80211_mgmt *ieeeframe;
action_frame_params_t *aframe;
raw_data_t l_bus_data;
int len = 0;
mac_addr_str_t mac_str;
em_steering_req_t *steer_req = (em_steering_req_t *)&evt->u.raw_buff;

len = sizeof(ieeeframe->u.action.category) + sizeof(ieeeframe->u.action.u.bss_tm_req) \
+ sizeof(em_80211_neighbor_report_t);
aframe = (action_frame_params_t *)malloc(sizeof(action_frame_params_t) + len);
// Point ieeeframe to aframe->frame_data
ieeeframe = (struct ieee80211_mgmt *)aframe->frame_data;

//convert steering req to 802.11 bss tm req
ieeeframe->u.action.category = WLAN_ACTION_WNM;
ieeeframe->u.action.u.bss_tm_req.action = WLAN_ACTION_HT;
ieeeframe->u.action.u.bss_tm_req.dialog_token = 1;

em_80211_btm_req_reqmode_t req_mode;
req_mode.pref_candidate_list_inc = 0;
req_mode.btm_abridged = steer_req->btm_abridged;
req_mode.btm_disassoc_imminent = steer_req->btm_dissoc_imminent;
//todo: check what is this
req_mode.bss_termination_inc = steer_req->btm_dissoc_timer;
//todo: check what is this
req_mode.ess_disassoc_imminent = steer_req->btm_dissoc_imminent;

ieeeframe->u.action.u.bss_tm_req.req_mode = *(uint8_t *)&req_mode;
memcpy(&ieeeframe->u.action.u.bss_tm_req.disassoc_timer, &steer_req->btm_dissoc_timer, sizeof(steer_req->btm_dissoc_timer));
//todo: check this
ieeeframe->u.action.u.bss_tm_req.validity_interval = 0;

// Copy the variable part
em_80211_btm_req_var_t *bss_list = (em_80211_btm_req_var_t *)&ieeeframe->u.action.u.bss_tm_req.variable;
bss_list->bss_transition_cand_list[0].elem_id = 52;
bss_list->bss_transition_cand_list[0].length = 13;
memcpy(bss_list->bss_transition_cand_list[0].bssid, steer_req->target_bssids, sizeof(bssid_t));
//todo: capabilities mapping tbd
bss_list->bss_transition_cand_list[0].bssid_info = 0;
bss_list->bss_transition_cand_list[0].op_class = steer_req->target_bss_op_class;
bss_list->bss_transition_cand_list[0].channel_num = steer_req->target_bss_channel_num;
//todo: check how to get this
bss_list->bss_transition_cand_list[0].phy_type = 0;

dm_easy_mesh_t::macbytes_to_string(steer_req->sta_mac_addr, mac_str);
printf("%s:%d STA MAC for BTM request %s\n", __func__, __LINE__, mac_str);
memcpy(aframe->dest_addr, steer_req->sta_mac_addr, sizeof(mac_addr_t));
aframe->frequency = 2412;
aframe->ap_index = 0;
//here sendng only the btm_req union to onewifi as header is dealt internally
aframe->frame_len = len;
memcpy(aframe->frame_data, &ieeeframe->u.action, len);

l_bus_data.data_type = bus_data_type_bytes;
l_bus_data.raw_data.bytes = (void *)aframe;
l_bus_data.raw_data_len = len + sizeof(action_frame_params_t);

if (desc->bus_set_fn(bus_hdl, "Device.WiFi.AccessPoint.1.RawFrame.Mgmt.Action.Tx", &l_bus_data)== 0) {
printf("%s:%d Frame subdoc send successfull\n",__func__, __LINE__);
}
else {
printf("%s:%d Frame subdoc send fail\n",__func__, __LINE__);
return -1;
}

return 1;
}

int dm_easy_mesh_agent_t::analyze_btm_response_action_frame(em_bus_event_t *evt, em_cmd_t *pcmd[])
{
//TODO: if callback would give for multiple entries or one by one
dm_easy_mesh_agent_t dm;
em_cmd_t *tmp;
em_cmd_params_t *evt_param;
int num = 0;
em_steering_btm_rprt_t btm;
mac_addr_str_t mac_str;
struct ieee80211_mgmt *btm_frame = (struct ieee80211_mgmt *)&evt->u.raw_buff;

em_cmd_btm_report_params_t btm_report_param;
memcpy(btm_report_param.source, btm_frame->bssid, sizeof(mac_addr_t));
memcpy(btm_report_param.sta_mac, btm_frame->sa, sizeof(mac_addr_t));
btm_report_param.status_code = btm_frame->u.action.u.bss_tm_resp.status_code;
memcpy(btm_report_param.target, &btm_frame->u.action.u.bss_tm_resp.variable, sizeof(mac_addr_t));

pcmd[num] = new em_cmd_btm_report_t(btm_report_param);
tmp = pcmd[num];
num++;

while ((pcmd[num] = tmp->clone_for_next()) != NULL) {
tmp = pcmd[num];
num++;
}

return num;
}

webconfig_error_t dm_easy_mesh_agent_t::webconfig_dummy_apply(webconfig_subdoc_t *doc, webconfig_subdoc_data_t *data)
{
return webconfig_error_none;
Expand Down
Loading

0 comments on commit eb894ed

Please sign in to comment.