From 30c3b0642d1a1745ebb8feb392acff1da71b9acd Mon Sep 17 00:00:00 2001 From: Soumya Munshi <167132989+soumyasmunshi@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:41:57 -0800 Subject: [PATCH 1/2] Neighbor Scans --- inc/dm_easy_mesh.h | 1 + inc/dm_easy_mesh_ctrl.h | 11 ++- inc/dm_easy_mesh_list.h | 6 ++ inc/dm_scan_result_list.h | 9 ++- inc/em_base.h | 9 ++- src/cli/em_cmd_cli.cpp | 41 ++++++----- src/cli/main.go | 75 ++++++++++--------- src/ctrl/dm_easy_mesh_ctrl.cpp | 4 ++ src/dm/dm_easy_mesh_list.cpp | 25 +++++++ src/dm/dm_scan_result.cpp | 128 ++++++++++++++++++++++++++++++++- src/dm/dm_scan_result_list.cpp | 87 +++++++++++++--------- 11 files changed, 300 insertions(+), 96 deletions(-) diff --git a/inc/dm_easy_mesh.h b/inc/dm_easy_mesh.h index ede3215c..6be4086f 100644 --- a/inc/dm_easy_mesh.h +++ b/inc/dm_easy_mesh.h @@ -31,6 +31,7 @@ #include "dm_dpp.h" #include "dm_op_class.h" #include "dm_policy.h" +#include "dm_scan_result.h" #include "dm_radio_cap.h" #include "dm_cac_comp.h" #include "dm_ap_mld.h" diff --git a/inc/dm_easy_mesh_ctrl.h b/inc/dm_easy_mesh_ctrl.h index 9d57d60a..2cf5eb2e 100644 --- a/inc/dm_easy_mesh_ctrl.h +++ b/inc/dm_easy_mesh_ctrl.h @@ -30,6 +30,7 @@ #include "dm_bss_list.h" #include "dm_sta_list.h" #include "dm_policy_list.h" +#include "dm_scan_result_list.h" #include "dm_dpp.h" #include "db_client.h" #include "dm_easy_mesh_list.h" @@ -39,11 +40,11 @@ class dm_easy_mesh_t; class em_mgr_t; class dm_easy_mesh_ctrl_t : - public dm_network_list_t, public dm_device_list_t, public dm_network_ssid_list_t, public dm_ieee_1905_security_list_t, public dm_radio_list_t, public dm_radio_cap_list_t, - public dm_op_class_list_t, public dm_bss_list_t, public dm_sta_list_t, public dm_policy_list_t { + public dm_op_class_list_t, public dm_bss_list_t, public dm_sta_list_t, public dm_policy_list_t, + public dm_scan_result_list_t { db_client_t m_db_client; bool m_initialized; @@ -157,6 +158,12 @@ class dm_easy_mesh_ctrl_t : void remove_policy(const char *key) { m_data_model_list.remove_policy(key); } void put_policy(const char *key, const dm_policy_t *policy) { m_data_model_list.put_policy(key, policy); } + dm_scan_result_t *get_first_scan_result() { return m_data_model_list.get_first_scan_result(); } + dm_scan_result_t *get_next_scan_result(dm_scan_result_t *scan_result) { return m_data_model_list.get_next_scan_result(scan_result); } + dm_scan_result_t *get_scan_result(const char *key) { return m_data_model_list.get_scan_result(key); } + void remove_scan_result(const char *key) { m_data_model_list.remove_scan_result(key); } + void put_scan_result(const char *key, const dm_scan_result_t *scan_result) { m_data_model_list.put_scan_result(key, scan_result); } + void handle_dirty_dm(); void init_tables(); int load_tables(); diff --git a/inc/dm_easy_mesh_list.h b/inc/dm_easy_mesh_list.h index 6db6860b..d8356344 100644 --- a/inc/dm_easy_mesh_list.h +++ b/inc/dm_easy_mesh_list.h @@ -97,6 +97,12 @@ class dm_easy_mesh_list_t { void remove_policy(const char *key); void put_policy(const char *key, const dm_policy_t *policy); + dm_scan_result_t *get_first_scan_result(); + dm_scan_result_t *get_next_scan_result(dm_scan_result_t *scan_result); + dm_scan_result_t *get_scan_result(const char *key); + void remove_scan_result(const char *key); + void put_scan_result(const char *key, const dm_scan_result_t *scan_result); + dm_easy_mesh_list_t(); ~dm_easy_mesh_list_t(); }; diff --git a/inc/dm_scan_result_list.h b/inc/dm_scan_result_list.h index 01220825..5ab0834a 100644 --- a/inc/dm_scan_result_list.h +++ b/inc/dm_scan_result_list.h @@ -23,14 +23,19 @@ #include "dm_scan_result.h" #include "db_easy_mesh.h" +typedef struct { + em_scan_result_t *result; + unsigned int index; +} db_update_scan_result_t; + class dm_easy_mesh_t; class dm_scan_result_list_t : public dm_scan_result_t, public db_easy_mesh_t { public: int init(); - dm_orch_type_t get_dm_orch_type(db_client_t& db_client, const dm_scan_result_t& scan_result); - void update_list(const dm_scan_result_t& scan_result, dm_orch_type_t op); + dm_orch_type_t get_dm_orch_type(db_client_t& db_client, const dm_scan_result_t& scan_result, unsigned int index); + void update_list(const dm_scan_result_t& scan_result, unsigned int index, dm_orch_type_t op); void delete_list(); void init_table(); diff --git a/inc/em_base.h b/inc/em_base.h index f4ff229b..ae07af3a 100644 --- a/inc/em_base.h +++ b/inc/em_base.h @@ -76,6 +76,7 @@ extern "C" #define EM_MAX_STA_PER_BSS 128 #define EM_MAX_STA_PER_STEER_POLICY 16 #define EM_MAX_STA_PER_AGENT (EM_MAX_RADIO_PER_AGENT * EM_MAX_STA_PER_BSS) +#define EM_MAX_NEIGHORS 32 #define EM_MAX_EVENT_DATA_LEN 4096*100 #define EM_MAX_CHANNELS_IN_LIST 9 @@ -647,7 +648,6 @@ typedef struct { em_radio_id_t ruid; unsigned char op_class; unsigned char channel; - bssid_t bssid; } em_scan_result_id_t; typedef struct { @@ -668,7 +668,8 @@ typedef struct { em_long_string_t timestamp; unsigned char util; unsigned char noise; - em_neighbor_t neighbor; + unsigned int num_neighbors; + em_neighbor_t neighbor[EM_MAX_NEIGHORS]; } em_scan_result_t; typedef struct { @@ -2538,9 +2539,11 @@ typedef enum { db_cfg_type_radio_cap_list_delete = (1 << 15), db_cfg_type_1905_security_list_update = (1 << 16), db_cfg_type_1905_security_list_delete = (1 << 17), - db_cfg_type_sta_metrics_update = (1 << 18), + db_cfg_type_sta_metrics_update = (1 << 18), db_cfg_type_policy_list_update = (1 << 19), db_cfg_type_policy_list_delete = (1 << 20), + db_cfg_type_scan_result_list_update = (1 << 21), + db_cfg_type_scan_result_list_delete = (1 << 22), } db_cfg_type_t; typedef struct{ diff --git a/src/cli/em_cmd_cli.cpp b/src/cli/em_cmd_cli.cpp index c6d10ba2..f9f4b132 100644 --- a/src/cli/em_cmd_cli.cpp +++ b/src/cli/em_cmd_cli.cpp @@ -110,6 +110,7 @@ int em_cmd_cli_t::get_edited_node(em_network_node_t *node, const char *header, c em_network_node_t *child; bool found_result = false; unsigned int i; + em_long_string_t key; char *net_id = m_cmd.m_param.u.args.args[1], *formatted, *node_str; for (i = 0; i < node->num_children; i++) { @@ -121,31 +122,35 @@ int em_cmd_cli_t::get_edited_node(em_network_node_t *node, const char *header, c } if (found_result == false) { - new_node = em_net_node_t::clone_network_tree(node);; - } else { + child = em_net_node_t::clone_network_tree(node);; + } - snprintf(child->key, sizeof(em_long_string_t), "wfa-dataelements:%s", header); - + + snprintf(key, sizeof(em_long_string_t), "wfa-dataelements:%s", header); + + if (child->num_children && strncmp(child->child[0]->key, key, strlen(key)) != 0) { + strncpy(child->key, key, strlen(key) + 1); tmp = (em_network_node_t *)malloc(sizeof(em_network_node_t)); - memset(tmp, 0, sizeof(em_network_node_t)); - strncpy(tmp->key, "ID", strlen("ID") + 1); - tmp->type = em_network_node_data_type_string; - strncpy(tmp->value_str, net_id, strlen(net_id) + 1); + memset(tmp, 0, sizeof(em_network_node_t)); + strncpy(tmp->key, "ID", strlen("ID") + 1); + tmp->type = em_network_node_data_type_string; + strncpy(tmp->value_str, net_id, strlen(net_id) + 1); - child->child[child->num_children] = tmp; - child->num_children++; + child->child[child->num_children] = tmp; + child->num_children++; new_node = (em_network_node_t *)malloc(sizeof(em_network_node_t)); - memset(new_node, 0, sizeof(em_network_node_t)); - new_node->type = node->type; - new_node->child[new_node->num_children] = child; - new_node->num_children++; + memset(new_node, 0, sizeof(em_network_node_t)); + new_node->type = node->type; + new_node->child[new_node->num_children] = child; + new_node->num_children++; + } else { + new_node = child; } - - //node_str = em_net_node_t::get_network_tree_string(new_node); - //m_cli.dump_lib_dbg(node_str); - //em_net_node_t::free_network_tree_string(node_str); + node_str = em_net_node_t::get_network_tree_string(new_node); + m_cli.dump_lib_dbg(node_str); + em_net_node_t::free_network_tree_string(node_str); obj = (cJSON *)em_net_node_t::network_tree_to_json(new_node); formatted = cJSON_Print(obj); strncpy(buff, formatted, strlen(formatted) + 1); diff --git a/src/cli/main.go b/src/cli/main.go index f078a932..5c846a78 100644 --- a/src/cli/main.go +++ b/src/cli/main.go @@ -118,22 +118,6 @@ type EasyMeshCmd struct { Help string } -var easyMeshCommands = map[string]EasyMeshCmd { - NetworkTopologyCmd: {NetworkTopologyCmd, 0, "get_bss OneWifiMesh", "", "", ""}, - NetworkPolicyCmd: {NetworkPolicyCmd, 1, "get_policy OneWifiMesh", "get_policy OneWifiMesh", "set_policy OneWifiMesh", ""}, - NetworkSSIDListCmd: {NetworkSSIDListCmd, 2, "get_ssid OneWifiMesh", "get_ssid OneWifiMesh", "set_ssid OneWifiMesh", ""}, - RadioListCmd: {RadioListCmd, 3, "get_radio OneWifiMesh", "", "", ""}, - ChannelsListCmd: {ChannelsListCmd, 4, "get_channel OneWifiMesh", "get_channel OneWifiMesh 1", "set_channel OneWifiMesh", ""}, - NeighborsListCmd: {NeighborsListCmd, 5, "get_channel OneWifiMesh", "get_channel OneWifiMesh 2", "scan_channel OneWifiMesh", ""}, - ClientDevicesCmd: {ClientDevicesCmd, 6, "get_sta OneWifiMesh", "", "", ""}, - SteerDevicesCmd: {SteerDevicesCmd, 7, "get_sta OneWifiMesh", "get_sta OneWifiMesh 1", "steer_sta OneWifiMesh", ""}, - NetworkMetricsCmd: {NetworkMetricsCmd, 8, "", "", "", ""}, - DeviceOnboardingCmd: {DeviceOnboardingCmd, 9, "", "", "", ""}, - WiFiEventsCmd: {WiFiEventsCmd, 10, "", "", "", ""}, - WiFiResetCmd: {WiFiResetCmd, 11, "get_network OneWifiMesh", "", "reset OneWifiMesh", ""}, - DebugCmd: {DebugCmd, 12, "dev_test OneWifiMesh", "", "", ""}, -} - type model struct { platform string list list.Model @@ -157,17 +141,35 @@ type model struct { quit chan bool ticker *time.Ticker timer *time.Timer + easyMeshCommands map[string]EasyMeshCmd + contentUpdated bool dump *os.File } func newModel(platform string) model { + easyMeshCommands := map[string]EasyMeshCmd { + NetworkTopologyCmd: {NetworkTopologyCmd, 0, "get_bss OneWifiMesh", "", "", ""}, + NetworkPolicyCmd: {NetworkPolicyCmd, 1, "get_policy OneWifiMesh", "get_policy OneWifiMesh", "set_policy OneWifiMesh", ""}, + NetworkSSIDListCmd: {NetworkSSIDListCmd, 2, "get_ssid OneWifiMesh", "get_ssid OneWifiMesh", "set_ssid OneWifiMesh", ""}, + RadioListCmd: {RadioListCmd, 3, "get_radio OneWifiMesh", "", "", ""}, + ChannelsListCmd: {ChannelsListCmd, 4, "get_channel OneWifiMesh", "get_channel OneWifiMesh 1", "set_channel OneWifiMesh", ""}, + NeighborsListCmd: {NeighborsListCmd, 5, "get_channel OneWifiMesh", "get_channel OneWifiMesh 2", "scan_channel OneWifiMesh", ""}, + ClientDevicesCmd: {ClientDevicesCmd, 6, "get_sta OneWifiMesh", "", "", ""}, + SteerDevicesCmd: {SteerDevicesCmd, 7, "get_sta OneWifiMesh", "get_sta OneWifiMesh 1", "steer_sta OneWifiMesh", ""}, + NetworkMetricsCmd: {NetworkMetricsCmd, 8, "", "", "", ""}, + DeviceOnboardingCmd: {DeviceOnboardingCmd, 9, "", "", "", ""}, + WiFiEventsCmd: {WiFiEventsCmd, 10, "", "", "", ""}, + WiFiResetCmd: {WiFiResetCmd, 11, "get_network OneWifiMesh", "", "reset OneWifiMesh", ""}, + DebugCmd: {DebugCmd, 12, "dev_test OneWifiMesh", "", "", ""}, + } + var items []list.Item - + for i := 0; i < len(easyMeshCommands); i++ { for _, value := range easyMeshCommands { if i == value.LoadOrder { - items = append(items, item{title: value.Title}) + items = append(items, item{title: value.Title}) break } } @@ -210,6 +212,8 @@ func newModel(platform string) model { activeButton: BTN_CANCEL, tree: etree.New(nodes, false, w, h, dump), dump: dump, + easyMeshCommands: easyMeshCommands, + contentUpdated: false, } } @@ -219,17 +223,14 @@ func splitIntoLines(content string) []string { func (m model) Init() tea.Cmd { var params *C.em_cli_params_t - params = (*C.em_cli_params_t)(C.malloc(C.sizeof_em_cli_params_t)) - params.user_data = unsafe.Pointer(&m) params.cb_func = nil params.cli_type = C.em_cli_type_go + C.init(params) m.currentOperatingInstructions = "\n\n\t Press 'w' to scroll up, 's' to scroll down" - C.init(params) - m.timer = time.NewTimer(1 * time.Second) m.ticker = time.NewTicker(5 * time.Second) m.quit = make(chan bool) @@ -251,7 +252,6 @@ func (m *model) timerHandler() { case <- m.ticker.C: - //spew.Fdump(m.dump, "5 second ticker fired") case <- m.quit: m.ticker.Stop() @@ -345,7 +345,7 @@ func (m model) nodesToTree(netNode *C.em_network_node_t, treeNode *etree.Node) { } func (m *model) execSelectedCommand(cmdStr string, cmdType int) { - for _, value := range easyMeshCommands { + for _, value := range m.easyMeshCommands { if cmdStr == value.Title { switch cmdType { case GET: @@ -354,7 +354,6 @@ func (m *model) execSelectedCommand(cmdStr string, cmdType int) { } m.currentNetNode = C.exec(C.CString(value.GetCommand), C.strlen(C.CString(value.GetCommand)), nil) if m.currentNetNode == nil { - spew.Fprintf(m.dump, "%s returned nil\n", value.GetCommand); return } treeNode := make([]etree.Node, 1) @@ -404,10 +403,6 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.WindowSizeMsg: - w, h:= appStyle.GetFrameSize() - spew.Fprintf(m.dump, "Frame Width: %d Frame Height: %d Msg Width: %d Msg Height: %d\n", - w, h, msg.Width, msg.Height) - m.menuHeight = msg.Height - m.bottomSpace - m.menuInstructionsHeight m.canvasWidth = msg.Width - m.menuWidth - m.rightSpace m.canvasHeight = msg.Height - m.bottomSpace @@ -415,7 +410,15 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case tea.KeyMsg: switch msg.String() { case "tab": - m.activeButton = (m.activeButton + 1) % BTN_MAX + if m.contentUpdated == true { + m.activeButton = (m.activeButton + 1) % BTN_MAX + } else { + if m.activeButton == BTN_UPDATE { + m.activeButton = BTN_CANCEL + } else { + m.activeButton = BTN_UPDATE + } + } case "j", "k": m.currentOperatingInstructions = "\n\n\t Press 'w' to scroll up, 's' to scroll down" @@ -434,24 +437,26 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if selectedItem, ok := m.list.SelectedItem().(item); ok { m.execSelectedCommand(selectedItem.title, GET) } + + m.contentUpdated = false + } case "down": if m.scrollIndex < m.tree.Cursor() { m.scrollIndex++ } - spew.Fprintf(m.dump, "down: %d\n", m.scrollIndex); case "up": if m.scrollIndex > 0 { m.scrollIndex-- } - spew.Fprintf(m.dump, "up: %d\n", m.scrollIndex); case "enter": if m.activeButton == BTN_UPDATE { m.currentOperatingInstructions = "\n\n\t Editor Mode: Press 'Apply' to apply settings, 'Cancel' to leave" if selectedItem, ok := m.list.SelectedItem().(item); ok { + m.contentUpdated = true m.execSelectedCommand(selectedItem.title, GETX) } m.tree.SetEditable(true) @@ -562,7 +567,7 @@ func (m model) View() string { statusView = styledContent + m.currentOperatingInstructions updateButton := buttonStyle.Render("Update") - okButton := buttonStyle.Render("Apply") + applyButton := buttonStyle.Render("Apply") cancelButton := buttonStyle.Render("Cancel") switch m.activeButton { @@ -570,13 +575,13 @@ func (m model) View() string { updateButton = activeButtonStyle.Render("Update") case BTN_APPLY: - okButton = activeButtonStyle.Render("Apply") + applyButton = activeButtonStyle.Render("Apply") case BTN_CANCEL: cancelButton = activeButtonStyle.Render("Cancel") } - buttons := lipgloss.JoinHorizontal(lipgloss.Center, updateButton, okButton, cancelButton) + buttons := lipgloss.JoinHorizontal(lipgloss.Center, updateButton, applyButton, cancelButton) centeredButtons := lipgloss.NewStyle().Width(100).Align(lipgloss.Center).Render(buttons) statusView = statusView + "\n\n" + centeredButtons diff --git a/src/ctrl/dm_easy_mesh_ctrl.cpp b/src/ctrl/dm_easy_mesh_ctrl.cpp index 815c4882..d863ee10 100644 --- a/src/ctrl/dm_easy_mesh_ctrl.cpp +++ b/src/ctrl/dm_easy_mesh_ctrl.cpp @@ -1052,6 +1052,7 @@ int dm_easy_mesh_ctrl_t::reset_config() dm_bss_list_t::load_table(m_db_client); dm_sta_list_t::load_table(m_db_client); dm_policy_list_t::load_table(m_db_client); + dm_scan_result_list_t::load_table(m_db_client); return 0; } @@ -1392,6 +1393,7 @@ void dm_easy_mesh_ctrl_t::init_tables() dm_bss_list_t::init(); dm_sta_list_t::init(); dm_policy_list_t::init(); + dm_scan_result_list_t::init(); } int dm_easy_mesh_ctrl_t::load_net_ssid_table() @@ -1419,6 +1421,8 @@ int dm_easy_mesh_ctrl_t::load_tables() type = db_cfg_type_sta_list_update; } else if (dm_policy_list_t::load_table(m_db_client) != 0) { type = db_cfg_type_policy_list_update; + } else if (dm_scan_result_list_t::load_table(m_db_client) != 0) { + type = db_cfg_type_scan_result_list_update; } if (type == dm_orch_type_none) { diff --git a/src/dm/dm_easy_mesh_list.cpp b/src/dm/dm_easy_mesh_list.cpp index 7d8d5b43..6b5c0f5e 100644 --- a/src/dm/dm_easy_mesh_list.cpp +++ b/src/dm/dm_easy_mesh_list.cpp @@ -1172,6 +1172,31 @@ void dm_easy_mesh_list_t::put_policy(const char *key, const dm_policy_t *policy) dm->set_policy(*policy); } +dm_scan_result_t *dm_easy_mesh_list_t::get_first_scan_result() +{ + return NULL; +} + +dm_scan_result_t *dm_easy_mesh_list_t::get_next_scan_result(dm_scan_result_t *scan_result) +{ + return NULL; +} + +dm_scan_result_t *dm_easy_mesh_list_t::get_scan_result(const char *key) +{ + return NULL; +} + +void dm_easy_mesh_list_t::remove_scan_result(const char *key) +{ + +} + +void dm_easy_mesh_list_t::put_scan_result(const char *key, const dm_scan_result_t *scan_result) +{ + +} + void dm_easy_mesh_list_t::delete_all_data_models() { dm_easy_mesh_t *dm = NULL, *tmp; diff --git a/src/dm/dm_scan_result.cpp b/src/dm/dm_scan_result.cpp index 95950491..b427378f 100644 --- a/src/dm/dm_scan_result.cpp +++ b/src/dm/dm_scan_result.cpp @@ -41,13 +41,107 @@ int dm_scan_result_t::decode(const cJSON *obj, void *parent_id) { - return 0; + cJSON *tmp, *arr_item; + char *str; + unsigned int i; + + memset(&m_scan_result, 0, sizeof(em_scan_result_t)); + + if ((tmp = cJSON_GetObjectItem(obj, "ScanStatus")) != NULL) { + m_scan_result.scan_status = cJSON_GetNumberValue(tmp); + } + + if ((tmp = cJSON_GetObjectItem(obj, "TimeStamp")) != NULL) { + str = cJSON_GetStringValue(tmp); + strncpy(m_scan_result.timestamp, str, strlen(str) + 1); + } + + if ((tmp = cJSON_GetObjectItem(obj, "Utilization")) != NULL) { + m_scan_result.util = cJSON_GetNumberValue(tmp); + } + + if ((tmp = cJSON_GetObjectItem(obj, "Noise")) != NULL) { + m_scan_result.noise = cJSON_GetNumberValue(tmp); + } + + if ((tmp = cJSON_GetObjectItem(obj, "Neighbors")) == NULL) { + return 0; + } + + for (i = 0; i < cJSON_GetArraySize(tmp); i++) { + arr_item = cJSON_GetArrayItem(tmp, i); + + if ((tmp = cJSON_GetObjectItem(arr_item, "BSSID")) != NULL) { + str = cJSON_GetStringValue(tmp); + dm_easy_mesh_t::string_to_macbytes(str, m_scan_result.neighbor[m_scan_result.num_neighbors].bssid); + } + + if ((tmp = cJSON_GetObjectItem(arr_item, "SSID")) != NULL) { + str = cJSON_GetStringValue(tmp); + strncpy(m_scan_result.neighbor[m_scan_result.num_neighbors].ssid, str, strlen(str) + 1); + } + + if ((tmp = cJSON_GetObjectItem(arr_item, "SignalStrength")) != NULL) { + m_scan_result.neighbor[m_scan_result.num_neighbors].signal_strength = cJSON_GetNumberValue(tmp); + } + + if ((tmp = cJSON_GetObjectItem(arr_item, "Bandwidth")) != NULL) { + m_scan_result.neighbor[m_scan_result.num_neighbors].bandwidth = (wifi_channelBandwidth_t)cJSON_GetNumberValue(tmp); + } + + if ((tmp = cJSON_GetObjectItem(arr_item, "BSSColor")) != NULL) { + m_scan_result.neighbor[m_scan_result.num_neighbors].bss_color = cJSON_GetNumberValue(tmp); + } + if ((tmp = cJSON_GetObjectItem(arr_item, "ChannelUtil")) != NULL) { + m_scan_result.neighbor[m_scan_result.num_neighbors].channel_util = cJSON_GetNumberValue(tmp); + } + + if ((tmp = cJSON_GetObjectItem(arr_item, "STACount")) != NULL) { + m_scan_result.neighbor[m_scan_result.num_neighbors].sta_count = cJSON_GetNumberValue(tmp); + } + + if ((tmp = cJSON_GetObjectItem(arr_item, "ScanDuration")) != NULL) { + m_scan_result.neighbor[m_scan_result.num_neighbors].aggr_scan_duration = cJSON_GetNumberValue(tmp); + } + + if ((tmp = cJSON_GetObjectItem(arr_item, "ScanType")) != NULL) { + m_scan_result.neighbor[m_scan_result.num_neighbors].scan_type = cJSON_GetNumberValue(tmp); + } + + } + + return 0; } void dm_scan_result_t::encode(cJSON *obj, em_scan_result_id_t id) { + cJSON *arr_obj, *tmp; + unsigned int i; + mac_addr_str_t bssid_str; + + cJSON_AddNumberToObject(obj, "ScanStatus", m_scan_result.scan_status); + cJSON_AddStringToObject(obj, "TimeStamp", m_scan_result.timestamp); + cJSON_AddNumberToObject(obj, "Utilization", m_scan_result.util); + cJSON_AddNumberToObject(obj, "Noise", m_scan_result.noise); + + arr_obj = cJSON_AddArrayToObject(obj, "Neighbors"); + for (i = 0; i < m_scan_result.num_neighbors; i++) { + tmp = cJSON_CreateObject(); + dm_easy_mesh_t::macbytes_to_string(m_scan_result.neighbor[i].bssid, bssid_str); + cJSON_AddStringToObject(tmp, "BSSID", bssid_str); + cJSON_AddStringToObject(tmp, "SSID", m_scan_result.neighbor[i].ssid); + cJSON_AddNumberToObject(tmp, "SignalStrength", m_scan_result.neighbor[i].signal_strength); + cJSON_AddNumberToObject(tmp, "Bandwidth", m_scan_result.neighbor[i].bandwidth); + cJSON_AddNumberToObject(tmp, "BSSColor", m_scan_result.neighbor[i].bss_color); + cJSON_AddNumberToObject(tmp, "ChannelUtil", m_scan_result.neighbor[i].channel_util); + cJSON_AddNumberToObject(tmp, "STACount", m_scan_result.neighbor[i].sta_count); + cJSON_AddNumberToObject(tmp, "ScanDuration", m_scan_result.neighbor[i].aggr_scan_duration); + cJSON_AddNumberToObject(tmp, "ScanType", m_scan_result.neighbor[i].scan_type); + + cJSON_AddItemToArray(arr_obj, tmp); + } } bool dm_scan_result_t::operator == (const dm_scan_result_t& obj) @@ -64,6 +158,38 @@ void dm_scan_result_t::operator = (const dm_scan_result_t& obj) int dm_scan_result_t::parse_scan_result_id_from_key(const char *key, em_scan_result_id_t *id) { + em_long_string_t str; + char *tmp, *remain; + unsigned int i = 0; + + strncpy(str, key, strlen(key) + 1); + remain = str; + while ((tmp = strchr(remain, '@')) != NULL) { + if (i == 0) { + *tmp = 0; + strncpy(id->net_id, remain, strlen(remain) + 1); + tmp++; + remain = tmp; + } else if (i == 1) { + *tmp = 0; + dm_easy_mesh_t::string_to_macbytes(remain, id->dev_mac); + tmp++; + remain = tmp; + } else if (i == 2) { + *tmp = 0; + dm_easy_mesh_t::string_to_macbytes(remain, id->radio_mac); + tmp++; + remain = tmp; + } else if (i == 3) { + *tmp = 0; + id->op_class = atoi(tmp); + tmp++; + id->channel = atoi(tmp); + } + i++; + } + + return 0; } diff --git a/src/dm/dm_scan_result_list.cpp b/src/dm/dm_scan_result_list.cpp index 78bf55ca..75cc705e 100644 --- a/src/dm/dm_scan_result_list.cpp +++ b/src/dm/dm_scan_result_list.cpp @@ -51,14 +51,19 @@ int dm_scan_result_list_t::set_config(db_client_t& db_client, const cJSON *obj_a dm_scan_result_t scan_result; dm_orch_type_t op; unsigned int i, size; + db_update_scan_result_t res; size = cJSON_GetArraySize(obj_arr); for (i = 0; i < size; i++) { obj = cJSON_GetArrayItem(obj_arr, i); scan_result.decode(obj, parent_id); - update_db(db_client, (op = get_dm_orch_type(db_client, scan_result)), scan_result.get_scan_result()); - update_list(scan_result, op); + for (i = 0; i < scan_result.m_scan_result.num_neighbors; i++) { + res.result = scan_result.get_scan_result(); + res.index = i; + update_db(db_client, (op = get_dm_orch_type(db_client, scan_result, i)), &res); + update_list(scan_result, i, op); + } } return 0; @@ -68,14 +73,20 @@ int dm_scan_result_list_t::set_config(db_client_t& db_client, dm_scan_result_t& { dm_orch_type_t op; char *tmp = (char *)parent_id; - - update_db(db_client, (op = get_dm_orch_type(db_client, scan_result)), scan_result.get_scan_result()); - update_list(scan_result, op); + unsigned int i; + db_update_scan_result_t res; + + for (i = 0; i < scan_result.m_scan_result.num_neighbors; i++) { + res.result = scan_result.get_scan_result(); + res.index = i; + update_db(db_client, (op = get_dm_orch_type(db_client, scan_result, i)), &res); + update_list(scan_result, i, op); + } return 0; } -dm_orch_type_t dm_scan_result_list_t::get_dm_orch_type(db_client_t& db_client, const dm_scan_result_t& scan_result) +dm_orch_type_t dm_scan_result_list_t::get_dm_orch_type(db_client_t& db_client, const dm_scan_result_t& scan_result, unsigned int index) { dm_scan_result_t *pscan_result; mac_addr_str_t dev_mac_str, radio_mac_str, bssid_str; @@ -83,7 +94,7 @@ dm_orch_type_t dm_scan_result_list_t::get_dm_orch_type(db_client_t& db_client, c dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result.m_scan_result.id.dev_mac, dev_mac_str); dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result.m_scan_result.id.ruid, radio_mac_str); - dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result.m_scan_result.id.bssid, bssid_str); + dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result.m_scan_result.neighbor[index].bssid, bssid_str); snprintf(key, sizeof(em_long_string_t), "%s@%s@%s@%d@%d@%s", scan_result.m_scan_result.id.net_id, dev_mac_str, radio_mac_str, scan_result.m_scan_result.id.op_class, scan_result.m_scan_result.id.channel, bssid_str); @@ -105,7 +116,7 @@ dm_orch_type_t dm_scan_result_list_t::get_dm_orch_type(db_client_t& db_client, c return dm_orch_type_db_insert; } -void dm_scan_result_list_t::update_list(const dm_scan_result_t& scan_result, dm_orch_type_t op) +void dm_scan_result_list_t::update_list(const dm_scan_result_t& scan_result, unsigned int index, dm_orch_type_t op) { dm_scan_result_t *pscan_result; mac_addr_str_t dev_mac_str, radio_mac_str, bssid_str; @@ -113,7 +124,7 @@ void dm_scan_result_list_t::update_list(const dm_scan_result_t& scan_result, dm_ dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result.m_scan_result.id.dev_mac, dev_mac_str); dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result.m_scan_result.id.ruid, radio_mac_str); - dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result.m_scan_result.id.bssid, bssid_str); + dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result.m_scan_result.neighbor[index].bssid, bssid_str); snprintf(key, sizeof(em_long_string_t), "%s@%s@%s@%d@%d@%s", scan_result.m_scan_result.id.net_id, dev_mac_str, radio_mac_str, scan_result.m_scan_result.id.op_class, scan_result.m_scan_result.id.channel, bssid_str); @@ -141,20 +152,23 @@ void dm_scan_result_list_t::delete_list() dm_scan_result_t *scan_result, *tmp; mac_addr_str_t dev_mac_str, radio_mac_str, bssid_str; em_long_string_t key; + unsigned int i; scan_result = get_first_scan_result(); while (scan_result != NULL) { tmp = scan_result; scan_result = get_next_scan_result(scan_result); - dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result->m_scan_result.id.dev_mac, dev_mac_str); - dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result->m_scan_result.id.ruid, radio_mac_str); - dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result->m_scan_result.id.bssid, bssid_str); - snprintf(key, sizeof(em_long_string_t), "%s@%s@%s@%d@%d@%s", + for (i = 0; i < scan_result->m_scan_result.num_neighbors; i++) { + dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result->m_scan_result.id.dev_mac, dev_mac_str); + dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result->m_scan_result.id.ruid, radio_mac_str); + dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result->m_scan_result.neighbor[i].bssid, bssid_str); + snprintf(key, sizeof(em_long_string_t), "%s@%s@%s@%d@%d@%s", scan_result->m_scan_result.id.net_id, dev_mac_str, radio_mac_str, scan_result->m_scan_result.id.op_class, scan_result->m_scan_result.id.channel, bssid_str); - remove_scan_result(key); + remove_scan_result(key); + } } } @@ -167,29 +181,32 @@ int dm_scan_result_list_t::update_db(db_client_t& db_client, dm_orch_type_t op, { mac_addr_str_t dev_mac_str, radio_mac_str, bssid_str; em_long_string_t key; - em_scan_result_t *scan_result = (em_scan_result_t *)data; + db_update_scan_result_t *res = (db_update_scan_result_t *)data; + em_scan_result_t *scan_result = res->result; + unsigned int index = res->index; int ret = 0; dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result->id.dev_mac, dev_mac_str); dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result->id.ruid, radio_mac_str); - dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result->id.bssid, bssid_str); + dm_easy_mesh_t::macbytes_to_string((unsigned char *)scan_result->neighbor[index].bssid, bssid_str); snprintf(key, sizeof(em_long_string_t), "%s@%s@%s@%d@%d@%s", scan_result->id.net_id, dev_mac_str, radio_mac_str, scan_result->id.op_class, scan_result->id.channel, bssid_str); switch (op) { case dm_orch_type_db_insert: - ret = insert_row(db_client, key, scan_result->scan_status, scan_result->timestamp, scan_result->util, scan_result->noise, - bssid_str, scan_result->neighbor.ssid, scan_result->neighbor.signal_strength, scan_result->neighbor.bandwidth, - scan_result->neighbor.bss_color, scan_result->neighbor.channel_util, scan_result->neighbor.sta_count, - scan_result->neighbor.aggr_scan_duration, scan_result->neighbor.scan_type); + ret = insert_row(db_client, key, scan_result->scan_status, scan_result->timestamp, scan_result->util, + scan_result->noise, bssid_str, scan_result->neighbor[index].ssid, + scan_result->neighbor[index].signal_strength, scan_result->neighbor[index].bandwidth, + scan_result->neighbor[index].bss_color, scan_result->neighbor[index].channel_util, scan_result->neighbor[index].sta_count, + scan_result->neighbor[index].aggr_scan_duration, scan_result->neighbor[index].scan_type); break; case dm_orch_type_db_update: ret = update_row(db_client, scan_result->scan_status, scan_result->timestamp, scan_result->util, scan_result->noise, - bssid_str, scan_result->neighbor.ssid, scan_result->neighbor.signal_strength, scan_result->neighbor.bandwidth, - scan_result->neighbor.bss_color, scan_result->neighbor.channel_util, scan_result->neighbor.sta_count, - scan_result->neighbor.aggr_scan_duration, scan_result->neighbor.scan_type, key); + bssid_str, scan_result->neighbor[index].ssid, scan_result->neighbor[index].signal_strength, scan_result->neighbor[index].bandwidth, + scan_result->neighbor[index].bss_color, scan_result->neighbor[index].channel_util, scan_result->neighbor[index].sta_count, + scan_result->neighbor[index].aggr_scan_duration, scan_result->neighbor[index].scan_type, key); break; case dm_orch_type_db_delete: @@ -236,7 +253,6 @@ int dm_scan_result_list_t::sync_db(db_client_t& db_client, void *ctx) memcpy(scan_result.id.ruid, id.ruid, sizeof(mac_address_t)); scan_result.id.op_class = id.op_class; scan_result.id.channel = id.channel; - memcpy(scan_result.id.bssid, id.bssid, sizeof(mac_address_t)); scan_result.scan_status = db_client.get_number(ctx, 2); @@ -247,20 +263,21 @@ int dm_scan_result_list_t::sync_db(db_client_t& db_client, void *ctx) scan_result.noise = db_client.get_number(ctx, 5); db_client.get_string(ctx, str, 6); - dm_easy_mesh_t::string_to_macbytes(str, scan_result.neighbor.bssid); + dm_easy_mesh_t::string_to_macbytes(str, scan_result.neighbor[scan_result.num_neighbors].bssid); db_client.get_string(ctx, str, 7); - strncpy(scan_result.neighbor.ssid, str, strlen(str) + 1); - - scan_result.neighbor.signal_strength = db_client.get_number(ctx, 8); - scan_result.neighbor.bandwidth = (wifi_channelBandwidth_t)db_client.get_number(ctx, 9); - scan_result.neighbor.bss_color = db_client.get_number(ctx, 10); - scan_result.neighbor.channel_util = db_client.get_number(ctx, 11); - scan_result.neighbor.sta_count = db_client.get_number(ctx, 12); - scan_result.neighbor.aggr_scan_duration = db_client.get_number(ctx, 13); - scan_result.neighbor.scan_type = db_client.get_number(ctx, 14); + strncpy(scan_result.neighbor[scan_result.num_neighbors].ssid, str, strlen(str) + 1); + + scan_result.neighbor[scan_result.num_neighbors].signal_strength = db_client.get_number(ctx, 8); + scan_result.neighbor[scan_result.num_neighbors].bandwidth = (wifi_channelBandwidth_t)db_client.get_number(ctx, 9); + scan_result.neighbor[scan_result.num_neighbors].bss_color = db_client.get_number(ctx, 10); + scan_result.neighbor[scan_result.num_neighbors].channel_util = db_client.get_number(ctx, 11); + scan_result.neighbor[scan_result.num_neighbors].sta_count = db_client.get_number(ctx, 12); + scan_result.neighbor[scan_result.num_neighbors].aggr_scan_duration = db_client.get_number(ctx, 13); + scan_result.neighbor[scan_result.num_neighbors].scan_type = db_client.get_number(ctx, 14); - update_list(dm_scan_result_t(&scan_result), dm_orch_type_db_insert); + update_list(dm_scan_result_t(&scan_result), scan_result.num_neighbors, dm_orch_type_db_insert); + scan_result.num_neighbors++; } return rc; From 2ae4ad98a1523ccd12afa0bd097157c4c87a1d99 Mon Sep 17 00:00:00 2001 From: rshah-1 <167130396+rshah-1@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:52:25 -0800 Subject: [PATCH 2/2] Update dm_scan_result.cpp --- src/dm/dm_scan_result.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dm/dm_scan_result.cpp b/src/dm/dm_scan_result.cpp index b427378f..7c2cdee6 100644 --- a/src/dm/dm_scan_result.cpp +++ b/src/dm/dm_scan_result.cpp @@ -177,7 +177,7 @@ int dm_scan_result_t::parse_scan_result_id_from_key(const char *key, em_scan_res remain = tmp; } else if (i == 2) { *tmp = 0; - dm_easy_mesh_t::string_to_macbytes(remain, id->radio_mac); + dm_easy_mesh_t::string_to_macbytes(remain, id->ruid); tmp++; remain = tmp; } else if (i == 3) {