From 60940a57d8af7ee5118a1903fb9955e84bb3fb42 Mon Sep 17 00:00:00 2001 From: Pavithra Sundaravadivel Date: Wed, 4 Dec 2024 09:08:00 +0000 Subject: [PATCH 01/22] RDKB-58044 Needed some correction on WHiX markers Impacted Platforms: All RDKB Platforms Reason for change: Potential bugs in markers Test Procedure: Check WIFI_MAC_%d_TOTAL_COUNT and WIFI_INFO_PMF_CONFIG markers Risks: None Priority: P1 Signed-off-by:Pavithra_Sundaravadivel@comcast.com Change-Id: Iedaa96bc172251e55a3dd93e2613ba54bdf358b7 --- source/apps/whix/wifi_whix.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/source/apps/whix/wifi_whix.c b/source/apps/whix/wifi_whix.c index 002be27f..0864a81f 100644 --- a/source/apps/whix/wifi_whix.c +++ b/source/apps/whix/wifi_whix.c @@ -357,14 +357,14 @@ int whix_upload_ap_telemetry_pmf() break; } get_formatted_time(tmp); - rc = sprintf_s(log_buf, sizeof(log_buf), "%s WIFI_INFO_PMF_CONFIG_%d:%s\n", tmp, i+1, telemetry_buf); - if(rc < EOK) - { + rc = sprintf_s(log_buf, sizeof(log_buf), "%s WIFI_INFO_PMF_CONFIG_%d:%s\n", tmp, + vap_index + 1, telemetry_buf); + if (rc < EOK) { ERR_CHK(rc); } write_to_file(wifi_health_log, log_buf); wifi_util_dbg_print(WIFI_APPS, "%s", log_buf); - rc = sprintf_s(tmp, sizeof(tmp), "WIFI_INFO_PMF_CONFIG_%d", i+1); + rc = sprintf_s(tmp, sizeof(tmp), "WIFI_INFO_PMF_CONFIG_%d", vap_index + 1); if(rc < EOK) { ERR_CHK(rc); @@ -1095,6 +1095,7 @@ int upload_client_telemetry_data(wifi_app_t *app, unsigned int num_devs, unsigne wifi_vap_info_t *vap_info = NULL; bool is_managed_wifi = false; unsigned int vap_array_index; + unsigned int active_num_dev = 0; unsigned int radioIndex = getRadioIndexFromAp(vap_index); wifi_mgr_t *wifi_mgr = (wifi_mgr_t *) get_wifimgr_obj(); @@ -1189,13 +1190,14 @@ int upload_client_telemetry_data(wifi_app_t *app, unsigned int num_devs, unsigne snprintf(tmp, 32, "%s,", to_sta_key(sta[i].sta_mac, sta_key)); strncat(buff, tmp, MAX_BUFF_SIZE - strlen(buff) - 1); strncat(telemetryBuff, tmp, MAX_BUFF_SIZE - strlen(buff) - 1); + active_num_dev++; } } strncat(buff, "\n", 2); - if (0 != num_devs) { + if (0 != active_num_dev) { write_to_file(wifi_health_log, buff); } - print_sta_client_telemetry_data(num_devs, vap_index, sta); + print_sta_client_telemetry_data(active_num_dev, vap_index, sta); /* "header": "2GclientMac_split", "content": "WIFI_MAC_1:", "type": "wifihealth.txt", "header": "5GclientMac_split", "content": "WIFI_MAC_2:", "type": "wifihealth.txt", @@ -1224,7 +1226,7 @@ int upload_client_telemetry_data(wifi_app_t *app, unsigned int num_devs, unsigne get_formatted_time(tmp); memset(buff, 0, MAX_BUFF_SIZE); snprintf(buff, MAX_BUFF_SIZE - 1, "%s WIFI_MAC_%d_TOTAL_COUNT:%d\n", tmp, vap_index + 1, - num_devs); + active_num_dev); write_to_file(wifi_health_log, buff); // "header": "Total_2G_clients_split", "content": "WIFI_MAC_1_TOTAL_COUNT:", "type": // "wifihealth.txt", "header": "Total_5G_clients_split", "content": @@ -1233,29 +1235,29 @@ int upload_client_telemetry_data(wifi_app_t *app, unsigned int num_devs, unsigne // "header": "xh_cnt_2_split","content": "WIFI_MAC_4_TOTAL_COUNT:","type": // "wifihealth.txt", if (isVapPrivate(vap_index)) { - if (0 == num_devs) { + if (0 == active_num_dev) { snprintf(eventName, sizeof(eventName), "WIFI_INFO_Zero_%s_Clients", t_string); get_stubs_descriptor()->t2_event_d_fn(eventName, 1); } else { snprintf(eventName, sizeof(eventName), "Total_%s_clients_split", t_string); - get_stubs_descriptor()->t2_event_d_fn(eventName, num_devs); + get_stubs_descriptor()->t2_event_d_fn(eventName, active_num_dev); } } else if (isVapXhs(vap_index)) { snprintf(eventName, sizeof(eventName), "xh_cnt_%d_split", radioIndex + 1); - get_stubs_descriptor()->t2_event_d_fn(eventName, num_devs); + get_stubs_descriptor()->t2_event_d_fn(eventName, active_num_dev); } else if (isVapMesh(vap_index)) { snprintf(eventName, sizeof(eventName), "Total_%s_PodClients_split", t_string); - get_stubs_descriptor()->t2_event_d_fn(eventName, num_devs); + get_stubs_descriptor()->t2_event_d_fn(eventName, active_num_dev); } else if (isVapLnfPsk(vap_index) && is_managed_wifi) { snprintf(eventName, sizeof(eventName), "MG_cnt_%s_split", t_string); - get_stubs_descriptor()->t2_event_d_fn(eventName, num_devs); + get_stubs_descriptor()->t2_event_d_fn(eventName, active_num_dev); } } else { wifi_util_error_print(WIFI_APPS, "%s-%d Failed to get band for radio Index %d\n", __func__, __LINE__, radioIndex); } /* If number of device connected is 0, then dont print the markers */ - if (0 == num_devs) { + if (0 == active_num_dev) { return RETURN_OK; } wifi_util_dbg_print(WIFI_APPS, "%s", buff); From 7e195d946a332442097ddac6c59d06ca7d3f4f24 Mon Sep 17 00:00:00 2001 From: Viviane Cordeiro Date: Fri, 6 Dec 2024 17:20:23 +0000 Subject: [PATCH 02/22] RDKB-56356: wifiWebConfig.txt file size is increasing drastically after multiple blast triggers Reason for change: blaster webconfig state flag was not clear for device in gw mode. Test Procedure: trigger blaster and check for overflow in the logs Risks: Low Change-Id: Ibde1adcda7743a71f335256f241be7ff08597c66 Signed-off-by: Viviane Cordeiro --- source/apps/analytics/wifi_analytics.c | 22 +++++++++++++++++----- source/apps/blaster/wifi_blaster.c | 3 +-- source/core/wifi_ctrl_webconfig.c | 4 +++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/source/apps/analytics/wifi_analytics.c b/source/apps/analytics/wifi_analytics.c index a42406ee..62d3c743 100644 --- a/source/apps/analytics/wifi_analytics.c +++ b/source/apps/analytics/wifi_analytics.c @@ -35,7 +35,9 @@ const char *subdoc_type_to_string(webconfig_subdoc_type_t type) { -#define DOC2S(x) case x: return #x; +#define DOC2S(x) \ + case x: \ + return #x; switch (type) { DOC2S(webconfig_subdoc_type_private) DOC2S(webconfig_subdoc_type_null) @@ -45,7 +47,6 @@ const char *subdoc_type_to_string(webconfig_subdoc_type_t type) DOC2S(webconfig_subdoc_type_mesh) DOC2S(webconfig_subdoc_type_mesh_backhaul) DOC2S(webconfig_subdoc_type_mesh_sta) - DOC2S(webconfig_subdoc_type_mesh_backhaul_sta) DOC2S(webconfig_subdoc_type_lnf) DOC2S(webconfig_subdoc_type_dml) DOC2S(webconfig_subdoc_type_associated_clients) @@ -56,11 +57,22 @@ const char *subdoc_type_to_string(webconfig_subdoc_type_t type) DOC2S(webconfig_subdoc_type_harvester) DOC2S(webconfig_subdoc_type_wifi_config) DOC2S(webconfig_subdoc_type_csi) + DOC2S(webconfig_subdoc_type_stats_config) + DOC2S(webconfig_subdoc_type_steering_config) + DOC2S(webconfig_subdoc_type_steering_clients) + DOC2S(webconfig_subdoc_type_vif_neighbors) + DOC2S(webconfig_subdoc_type_mesh_backhaul_sta) DOC2S(webconfig_subdoc_type_levl) DOC2S(webconfig_subdoc_type_cac) - default: - wifi_util_error_print(WIFI_APPS,"%s:%d: event not handle[%d]\r\n",__func__, __LINE__, type); - break; + DOC2S(webconfig_subdoc_type_radio_stats) + DOC2S(webconfig_subdoc_type_neighbor_stats) + DOC2S(webconfig_subdoc_type_assocdev_stats) + DOC2S(webconfig_subdoc_type_radiodiag_stats) + DOC2S(webconfig_subdoc_type_radio_temperature) + default: + wifi_util_error_print(WIFI_APPS, "%s:%d: event not handle[%d]\r\n", __func__, __LINE__, + type); + break; } return "unknown subdoc"; diff --git a/source/apps/blaster/wifi_blaster.c b/source/apps/blaster/wifi_blaster.c index 61e8421c..989b43c9 100644 --- a/source/apps/blaster/wifi_blaster.c +++ b/source/apps/blaster/wifi_blaster.c @@ -1625,10 +1625,9 @@ static void process_request(active_msmt_t *cfg) if (ctrl->network_mode == rdk_dev_mode_type_ext) { active_msmt_report_all_steps(cfg, msg, status); + mgr->ctrl.webconfig_state |= ctrl_webconfig_state_blaster_cfg_complete_rsp_pending; } - active_msmt_log_message(BLASTER_DEBUG_LOG, "%s:%d %s\n" ,__FUNCTION__, __LINE__, msg); - mgr->ctrl.webconfig_state |= ctrl_webconfig_state_blaster_cfg_complete_rsp_pending; pthread_mutex_unlock(&g_active_msmt->lock); return; diff --git a/source/core/wifi_ctrl_webconfig.c b/source/core/wifi_ctrl_webconfig.c index a68dcb0d..db3b1591 100644 --- a/source/core/wifi_ctrl_webconfig.c +++ b/source/core/wifi_ctrl_webconfig.c @@ -456,10 +456,12 @@ int webconfig_analyze_pending_states(wifi_ctrl_t *ctrl) case ctrl_webconfig_state_blaster_cfg_complete_rsp_pending: /* Once the blaster triggered successfully, update the status as completed and pass it to OVSM */ + type = webconfig_subdoc_type_blaster; mgr->blaster_config_global.Status = blaster_state_completed; webconfig_send_blaster_status(ctrl); break; case ctrl_webconfig_state_steering_clients_rsp_pending: + type = webconfig_subdoc_type_steering_clients; webconfig_send_steering_clients_status(ctrl); break; case ctrl_webconfig_state_trigger_dml_thread_data_update_pending: @@ -1696,7 +1698,6 @@ int webconfig_hal_radio_apply(wifi_ctrl_t *ctrl, webconfig_subdoc_decoded_data_t ctrl->webconfig_state |= ctrl_webconfig_state_radio_cfg_rsp_pending; return RETURN_ERR; } - wifi_util_dbg_print(WIFI_MGR, "%s:%d: config applied.\n", __func__, __LINE__); start_wifi_sched_timer(mgr_radio_data->vaps.radio_index, ctrl, wifi_radio_sched); @@ -2012,6 +2013,7 @@ webconfig_error_t webconfig_ctrl_apply(webconfig_subdoc_t *doc, webconfig_subdoc } } else if (ctrl->network_mode == rdk_dev_mode_type_gw) { + ctrl->webconfig_state &= ~(ctrl_webconfig_state_blaster_cfg_init_rsp_pending | ctrl_webconfig_state_blaster_cfg_complete_rsp_pending); wifi_util_error_print(WIFI_CTRL, "%s:%d: Device is in GW Mode. No need to send blaster status\n", __func__, __LINE__); } } else { From a2c3cd07670dc7017faf83ab7f6cf3b8716551ee Mon Sep 17 00:00:00 2001 From: mmalla642 Date: Thu, 7 Nov 2024 06:04:17 +0000 Subject: [PATCH 03/22] BCOMB-2685: To provide utility for wifi_getApAssociatedDeviceDiagnosticResult3 Reason for change: To provide rbus utility to call the NL functions for client diagresults Test Procedure: Use rbuscli to execute the utility 1. rbuscli -i 2. subscribe Device.WiFi.WiFiAPI.result 3. setvalues Device.WiFi.WiFiAPI.command string "wifi_getApAssociatedDeviceDiagnosticResult3 1" Priority: P1 Risks: Low Signed-off-by: mothishree_mallaiyanjothimani@comcast.com Change-Id: I5fb6c5120fc89d0b477fd7d763fabec1fbb0a0a2 --- source/core/wifi_ctrl_wifiapi_handlers.c | 68 +++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/source/core/wifi_ctrl_wifiapi_handlers.c b/source/core/wifi_ctrl_wifiapi_handlers.c index 0dd507ab..89a2ed75 100644 --- a/source/core/wifi_ctrl_wifiapi_handlers.c +++ b/source/core/wifi_ctrl_wifiapi_handlers.c @@ -52,6 +52,7 @@ struct hal_api_info { {"wifi_configNeighborReports", 3, " " }, {"wifi_hal_getRadioTemperature", 1, "" }, {"wifi_getRadioChannelStats", 1, ""}, + {"wifi_getApAssociatedDeviceDiagnosticResult3", 1, ""}, }; @@ -604,6 +605,68 @@ static void wifiapi_handle_get_radio_channel_stats(char **args, unsigned int num } } +static void wifiapi_handle_get_ApAssocDeviceDiagnosticResult(char **args, unsigned int num_args, + char *result_buf, int result_buf_size) +{ + sta_key_t sta_key; + sta_key_t mld_sta_key; + int vap_index; + vap_index = atoi(args[1]); + wifi_associated_dev3_t *dev_array = NULL; + unsigned int num_devs = 0; + if (wifi_getApAssociatedDeviceDiagnosticResult3(vap_index, &dev_array, &num_devs) != RETURN_OK) { + snprintf(result_buf, result_buf_size, "Failed to get AP Associated Device Diagnostic Result\n"); + if (dev_array != NULL) { + free(dev_array); + dev_array = NULL; + } + return; + } + char* to_sta_key(uint8_t *mac_address, sta_key_t sta_key) { + snprintf(sta_key, STA_KEY_LEN, "%02x:%02x:%02x:%02x:%02x:%02x", + mac_address[0], mac_address[1], mac_address[2], + mac_address[3], mac_address[4], mac_address[5]); + return sta_key; +} + snprintf(result_buf, result_buf_size, "diag result: number of devs: %d\n", num_devs); + for (unsigned int i = 0; i < num_devs; i++) { + snprintf(result_buf, result_buf_size, + "\ncli_MACAddress: %s cli_MLDAddr: %s cli_MLDEnable: %d cli_AuthenticationState: %d" + " cli_LastDataDownlinkRate: %d cli_LastDataUplinkRate: %d cli_SignalStrength: %d" + " cli_Retransmissions: %d cli_Active: %d cli_OperatingStandard: %s" + " cli_OperatingChannelBandwidth: %s cli_SNR: %d cli_InterferenceSources: %s" + " cli_DataFramesSentAck: %lu cli_DataFramesSentNoAck: %lu cli_BytesSent: %lu" + " cli_BytesReceived: %lu cli_RSSI: %d cli_MinRSSI: %d cli_MaxRSSI: %d" + " cli_Disassociations: %d cli_AuthenticationFailures: %d cli_Associations: %llu" + " cli_PacketsSent: %lu cli_PacketsReceived: %lu cli_ErrorsSent: %lu" + " cli_RetransCount: %lu cli_FailedRetransCount: %lu cli_RetryCount: %lu" + " cli_MultipleRetryCount: %lu cli_MaxDownlinkRate: %d cli_MaxUplinkRate: %d" + " cli_activeNumSpatialStreams: %d cli_TxFrames: %llu cli_RxRetries: %llu" + " cli_RxErrors: %llu\n", + to_sta_key(dev_array[i].cli_MACAddress, sta_key), + to_sta_key(dev_array[i].cli_MLDAddr, mld_sta_key), dev_array[i].cli_MLDEnable, + dev_array[i].cli_AuthenticationState, dev_array[i].cli_LastDataDownlinkRate, + dev_array[i].cli_LastDataUplinkRate, dev_array[i].cli_SignalStrength, + dev_array[i].cli_Retransmissions, dev_array[i].cli_Active, + dev_array[i].cli_OperatingStandard, dev_array[i].cli_OperatingChannelBandwidth, + dev_array[i].cli_SNR, dev_array[i].cli_InterferenceSources, + dev_array[i].cli_DataFramesSentAck, dev_array[i].cli_DataFramesSentNoAck, + dev_array[i].cli_BytesSent, dev_array[i].cli_BytesReceived, dev_array[i].cli_RSSI, + dev_array[i].cli_MinRSSI, dev_array[i].cli_MaxRSSI, dev_array[i].cli_Disassociations, + dev_array[i].cli_AuthenticationFailures, dev_array[i].cli_Associations, + dev_array[i].cli_PacketsSent, dev_array[i].cli_PacketsReceived, + dev_array[i].cli_ErrorsSent, dev_array[i].cli_RetransCount, + dev_array[i].cli_FailedRetransCount, dev_array[i].cli_RetryCount, + dev_array[i].cli_MultipleRetryCount, dev_array[i].cli_MaxDownlinkRate, + dev_array[i].cli_MaxUplinkRate, dev_array[i].cli_activeNumSpatialStreams, + dev_array[i].cli_TxFrames, dev_array[i].cli_RxRetries, dev_array[i].cli_RxErrors); + if (dev_array != NULL) { + free(dev_array); + dev_array = NULL; + } + } +} + void process_wifiapi_command(char *command, unsigned int len) { char input[1024]; @@ -913,7 +976,10 @@ void process_wifiapi_command(char *command, unsigned int len) wifiapi_handle_hal_get_radio_temperature(args, num_args, buff, sizeof(buff)); } else if (strcmp(args[0], "wifi_getRadioChannelStats") == 0) { wifiapi_handle_get_radio_channel_stats(args, num_args, buff, sizeof(buff)); - } else { + } else if (strcmp(args[0], "wifi_getApAssociatedDeviceDiagnosticResult3") == 0) { + wifiapi_handle_get_ApAssocDeviceDiagnosticResult(args, num_args, buff, sizeof(buff)); + } + else { unsigned int idx = 0; idx += snprintf(&buff[idx], sizeof(buff)-idx, "wifi_api2: Invalid API '%s'\nSupported APIs:\n", args[0]); if (idx >= sizeof(buff)) goto publish; From 4623f907e3a38efc2682ee6133d2de96f2519921 Mon Sep 17 00:00:00 2001 From: "Pulluru, Harshavardhan" Date: Mon, 2 Dec 2024 04:24:38 +0000 Subject: [PATCH 04/22] RDKB-58072:Xfinity subdoc schema for Preassoc TCM Impacted Platforms: OneWifi platforms Reason for change: Implement Xfinity subdoc schema for Preassoc Tcm as part of Epic Test Procedure: Load the build and test the changes as per ACs Risks: Low Change-Id: Ic5eec8d8c28c87ada0a3e4702671343d1f427694 Signed-off-by:Harshavardhan_Pulluru@comcast.com --- config/TR181-WiFi-USGv2.XML | 4 +- .../subdoc_schemas_1_4/xfinity_subdoc_schema | 48 ++++++++++++------- source/core/wifi_ctrl_webconfig.c | 17 ++++++- source/core/wifi_multidoc_webconfig.c | 10 ++-- source/dml/tr_181/ml/cosa_wifi_dml.c | 8 ++-- source/webconfig/wifi_decoder.c | 29 ++++++++--- source/webconfig/wifi_encoder.c | 23 +++++++-- 7 files changed, 99 insertions(+), 40 deletions(-) diff --git a/config/TR181-WiFi-USGv2.XML b/config/TR181-WiFi-USGv2.XML index 8b5e4c23..4b6c5d74 100644 --- a/config/TR181-WiFi-USGv2.XML +++ b/config/TR181-WiFi-USGv2.XML @@ -2871,13 +2871,13 @@ INSTMSMT_PH2 --> true - TimeInMs + TcmWaitTime int int true - MinMgmtFrames + TcmMinMgmtFrames int int true diff --git a/config/subdoc_schemas_1_4/xfinity_subdoc_schema b/config/subdoc_schemas_1_4/xfinity_subdoc_schema index cbca476b..0a44cf31 100644 --- a/config/subdoc_schemas_1_4/xfinity_subdoc_schema +++ b/config/subdoc_schemas_1_4/xfinity_subdoc_schema @@ -47,9 +47,11 @@ "BasicDataTransmitRates": "12", "OperationalDataTransmitRates": "12,24,36,48,54", "SupportedDataTransmitRates": "12,24,36,48,54", - "MinimumAdvertisedMCS": "3", - "TimeInMs": 150, - "MinMgmtFrames": 3, + "MinimumAdvertisedMCS": "3" + }, + "TcmPreAssociationDeny": { + "TcmWaitTime": 150, + "TcmMinMgmtFrames": 3, "TcmExpWeightage": "0.6", "TcmGradientThreshold": "0.18" }, @@ -148,9 +150,11 @@ "BasicDataTransmitRates": "12", "OperationalDataTransmitRates": "12,24,36,48,54", "SupportedDataTransmitRates": "12,24,36,48,54", - "MinimumAdvertisedMCS": "3", - "TimeInMs": 150, - "MinMgmtFrames": 3, + "MinimumAdvertisedMCS": "3" + }, + "TcmPreAssociationDeny": { + "TcmWaitTime": 150, + "TcmMinMgmtFrames": 3, "TcmExpWeightage": "0.6", "TcmGradientThreshold": "0.18" }, @@ -247,9 +251,11 @@ "BasicDataTransmitRates": "12", "OperationalDataTransmitRates": "12,24,36,48,54", "SupportedDataTransmitRates": "12,24,36,48,54", - "MinimumAdvertisedMCS": "3", - "TimeInMs": 150, - "MinMgmtFrames": 3, + "MinimumAdvertisedMCS": "3" + }, + "TcmPreAssociationDeny": { + "TcmWaitTime": 150, + "TcmMinMgmtFrames": 3, "TcmExpWeightage": "0.6", "TcmGradientThreshold": "0.18" }, @@ -348,9 +354,11 @@ "BasicDataTransmitRates": "12", "OperationalDataTransmitRates": "12,24,36,48,54", "SupportedDataTransmitRates": "12,24,36,48,54", - "MinimumAdvertisedMCS": "3", - "TimeInMs": 150, - "MinMgmtFrames": 3, + "MinimumAdvertisedMCS": "3" + }, + "TcmPreAssociationDeny": { + "TcmWaitTime": 150, + "TcmMinMgmtFrames": 3, "TcmExpWeightage": "0.6", "TcmGradientThreshold": "0.18" }, @@ -450,9 +458,11 @@ "OperationalDataTransmitRates": "12,24,36,48,54", "SupportedDataTransmitRates": "12,24,36,48,54", "MinimumAdvertisedMCS": "3", - "6GOpInfoMinRate": "", - "TimeInMs": 150, - "MinMgmtFrames": 3, + "6GOpInfoMinRate": "" + }, + "TcmPreAssociationDeny": { + "TcmWaitTime": 150, + "TcmMinMgmtFrames": 3, "TcmExpWeightage": "0.6", "TcmGradientThreshold": "0.18" }, @@ -552,9 +562,11 @@ "OperationalDataTransmitRates": "12,24,36,48,54", "SupportedDataTransmitRates": "12,24,36,48,54", "MinimumAdvertisedMCS": "3", - "6GOpInfoMinRate": "", - "TimeInMs": 150, - "MinMgmtFrames": 3, + "6GOpInfoMinRate": "" + }, + "TcmPreAssociationDeny": { + "TcmWaitTime": 150, + "TcmMinMgmtFrames": 3, "TcmExpWeightage": "0.6", "TcmGradientThreshold": "0.18" }, diff --git a/source/core/wifi_ctrl_webconfig.c b/source/core/wifi_ctrl_webconfig.c index a68dcb0d..1cdbd0bf 100644 --- a/source/core/wifi_ctrl_webconfig.c +++ b/source/core/wifi_ctrl_webconfig.c @@ -494,6 +494,18 @@ static bool is_preassoc_cac_config_changed(wifi_vap_info_t *old, wifi_vap_info_t } } +static bool is_preassoc_tcm_config_changed(wifi_vap_info_t *old, wifi_vap_info_t *new) +{ + if ((IS_CHANGED(old->u.bss_info.preassoc.time_ms, new->u.bss_info.preassoc.time_ms)) + || (IS_CHANGED(old->u.bss_info.preassoc.min_num_mgmt_frames, new->u.bss_info.preassoc.min_num_mgmt_frames)) + || (IS_STR_CHANGED(old->u.bss_info.preassoc.tcm_exp_weightage, new->u.bss_info.preassoc.tcm_exp_weightage, sizeof(old->u.bss_info.preassoc.tcm_exp_weightage))) + || (IS_STR_CHANGED(old->u.bss_info.preassoc.tcm_gradient_threshold, new->u.bss_info.preassoc.tcm_gradient_threshold, sizeof(old->u.bss_info.preassoc.tcm_gradient_threshold)))) { + return true; + } else { + return false; + } +} + static bool is_postassoc_cac_config_changed(wifi_vap_info_t *old, wifi_vap_info_t *new) { if ((IS_STR_CHANGED(old->u.bss_info.postassoc.rssi_up_threshold, new->u.bss_info.postassoc.rssi_up_threshold, sizeof(old->u.bss_info.postassoc.rssi_up_threshold))) @@ -1234,9 +1246,10 @@ int webconfig_cac_apply(wifi_ctrl_t *ctrl, webconfig_subdoc_decoded_data_t *data for (vap_index = 0; vap_index < getNumberVAPsPerRadio(radio_index); vap_index++) { wifi_util_dbg_print(WIFI_CTRL,"Comparing cac config\n"); - if (is_preassoc_cac_config_changed(&l_vap_maps->vap_array[vap_index], &data->radios[radio_index].vaps.vap_map.vap_array[vap_index]) + if (is_preassoc_tcm_config_changed(&l_vap_maps->vap_array[vap_index], &data->radios[radio_index].vaps.vap_map.vap_array[vap_index]) + || is_preassoc_cac_config_changed(&l_vap_maps->vap_array[vap_index], &data->radios[radio_index].vaps.vap_map.vap_array[vap_index]) || is_postassoc_cac_config_changed(&l_vap_maps->vap_array[vap_index], &data->radios[radio_index].vaps.vap_map.vap_array[vap_index])) { - // cac data changed apply + // cac or tcm data changed apply wifi_util_info_print(WIFI_CTRL, "%s:%d: Change detected in received cac config, applying new configuration for vap: %d\n", __func__, __LINE__, vap_index); wifidb_update_wifi_cac_config(&data->radios[radio_index].vaps.vap_map); diff --git a/source/core/wifi_multidoc_webconfig.c b/source/core/wifi_multidoc_webconfig.c index 30391fe9..7c61314d 100644 --- a/source/core/wifi_multidoc_webconfig.c +++ b/source/core/wifi_multidoc_webconfig.c @@ -1085,10 +1085,12 @@ pErr wifi_vap_cfg_subdoc_handler(void *data) cJSON_AddStringToObject(PreAssocDeny, "SupportedDataTransmitRates", wifi_vap_map->vap_array[vapArrayIndex].u.bss_info.preassoc.supported_data_transmit_rates); cJSON_AddStringToObject(PreAssocDeny, "MinimumAdvertisedMCS", wifi_vap_map->vap_array[vapArrayIndex].u.bss_info.preassoc.minimum_advertised_mcs); cJSON_AddStringToObject(PreAssocDeny, "6GOpInfoMinRate", wifi_vap_map->vap_array[vapArrayIndex].u.bss_info.preassoc.sixGOpInfoMinRate); - cJSON_AddNumberToObject(PreAssocDeny, "TimeInMs", wifi_vap_map->vap_array[vapArrayIndex].u.bss_info.preassoc.time_ms); - cJSON_AddNumberToObject(PreAssocDeny, "MinMgmtFrames", wifi_vap_map->vap_array[vapArrayIndex].u.bss_info.preassoc.min_num_mgmt_frames); - cJSON_AddStringToObject(PreAssocDeny, "TcmExpWeightage", wifi_vap_map->vap_array[vapArrayIndex].u.bss_info.preassoc.tcm_exp_weightage); - cJSON_AddStringToObject(PreAssocDeny, "TcmGradientThreshold", wifi_vap_map->vap_array[vapArrayIndex].u.bss_info.preassoc.tcm_gradient_threshold); + + cJSON *TcmPreAssocDeny = cJSON_AddObjectToObject(vapConnectionControl_o,"TcmPreAssociationDeny"); + cJSON_AddNumberToObject(TcmPreAssocDeny, "TcmWaitTime", wifi_vap_map->vap_array[vapArrayIndex].u.bss_info.preassoc.time_ms); + cJSON_AddNumberToObject(TcmPreAssocDeny, "TcmMinMgmtFrames", wifi_vap_map->vap_array[vapArrayIndex].u.bss_info.preassoc.min_num_mgmt_frames); + cJSON_AddStringToObject(TcmPreAssocDeny, "TcmExpWeightage", wifi_vap_map->vap_array[vapArrayIndex].u.bss_info.preassoc.tcm_exp_weightage); + cJSON_AddStringToObject(TcmPreAssocDeny, "TcmGradientThreshold", wifi_vap_map->vap_array[vapArrayIndex].u.bss_info.preassoc.tcm_gradient_threshold); cJSON *PostAssocDeny = cJSON_AddObjectToObject(vapConnectionControl_o,"PostAssociationDeny"); cJSON_AddStringToObject(PostAssocDeny, "RssiUpThreshold", wifi_vap_map->vap_array[vapArrayIndex].u.bss_info.postassoc.rssi_up_threshold); diff --git a/source/dml/tr_181/ml/cosa_wifi_dml.c b/source/dml/tr_181/ml/cosa_wifi_dml.c index 95bbb4a9..d89ec4b2 100755 --- a/source/dml/tr_181/ml/cosa_wifi_dml.c +++ b/source/dml/tr_181/ml/cosa_wifi_dml.c @@ -9670,13 +9670,13 @@ PreAssocDeny_GetParamIntValue } /* check the parameter name and return the corresponding value */ - if( AnscEqualString(ParamName, "TimeInMs", TRUE)) + if( AnscEqualString(ParamName, "TcmWaitTime", TRUE)) { *pInt = pcfg->u.bss_info.preassoc.time_ms; return TRUE; } - if( AnscEqualString(ParamName, "MinMgmtFrames", TRUE)) + if( AnscEqualString(ParamName, "TcmMinMgmtFrames", TRUE)) { *pInt = pcfg->u.bss_info.preassoc.min_num_mgmt_frames; return TRUE; @@ -9961,7 +9961,7 @@ PreAssocDeny_SetParamIntValue return TRUE; } /* check the parameter name and return the corresponding value */ - if( AnscEqualString(ParamName, "TimeInMs", TRUE)) + if( AnscEqualString(ParamName, "TcmWaitTime", TRUE)) { if (vapInfo->u.bss_info.preassoc.time_ms == iValue) { return TRUE; @@ -9973,7 +9973,7 @@ PreAssocDeny_SetParamIntValue return TRUE; } - if( AnscEqualString(ParamName, "MinMgmtFrames", TRUE)) + if( AnscEqualString(ParamName, "TcmMinMgmtFrames", TRUE)) { if (vapInfo->u.bss_info.preassoc.min_num_mgmt_frames == iValue) { return TRUE; diff --git a/source/webconfig/wifi_decoder.c b/source/webconfig/wifi_decoder.c index 764b542f..a9638834 100644 --- a/source/webconfig/wifi_decoder.c +++ b/source/webconfig/wifi_decoder.c @@ -3410,7 +3410,6 @@ webconfig_error_t decode_preassoc_cac_object(const cJSON *preassoc, wifi_preasso { const cJSON *param; int val, ret; - float fval; // RssiUpThreshold decode_param_allow_empty_string(preassoc, "RssiUpThreshold", param); @@ -3545,11 +3544,22 @@ webconfig_error_t decode_preassoc_cac_object(const cJSON *preassoc, wifi_preasso else { strcpy((char *)preassoc_info->sixGOpInfoMinRate, "disabled"); } - - decode_param_integer(preassoc, "TimeInMs", param); + + wifi_util_dbg_print(WIFI_WEBCONFIG,"%s:%d: decoding preassoc settings passed\n", __func__, __LINE__); + + return webconfig_error_none; +} + +webconfig_error_t decode_tcm_preassoc_object(const cJSON *preassoc, wifi_preassoc_control_t *preassoc_info) +{ + const cJSON *param; + int ret; + float fval; + + decode_param_integer(preassoc, "TcmWaitTime", param); preassoc_info->time_ms = param->valuedouble; - decode_param_integer(preassoc, "MinMgmtFrames", param); + decode_param_integer(preassoc, "TcmMinMgmtFrames", param); preassoc_info->min_num_mgmt_frames = param->valuedouble; decode_param_allow_empty_string(preassoc, "TcmExpWeightage", param); @@ -3579,11 +3589,12 @@ webconfig_error_t decode_preassoc_cac_object(const cJSON *preassoc, wifi_preasso strcpy((char *)preassoc_info->tcm_gradient_threshold, param->valuestring); } - wifi_util_dbg_print(WIFI_WEBCONFIG,"%s:%d: decoding preassoc settings passed\n", __func__, __LINE__); - + wifi_util_dbg_print(WIFI_WEBCONFIG,"%s:%d: decoding tcm preassoc settings passed\n", __func__, __LINE__); + return webconfig_error_none; } + webconfig_error_t decode_postassoc_cac_object(const cJSON *postassoc, wifi_postassoc_control_t *postassoc_info) { const cJSON *param; @@ -3712,6 +3723,12 @@ webconfig_error_t decode_cac_object(wifi_vap_info_t *vap_info, cJSON *obj_array return webconfig_error_decode; } + decode_param_object(obj_array, "TcmPreAssociationDeny", preassoc); + if (decode_tcm_preassoc_object(preassoc, &vap_info->u.bss_info.preassoc) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: tcm preassoc objects validation failed for %s\n",__FUNCTION__, __LINE__, vap_info->vap_name); + return webconfig_error_decode; + } + decode_param_object(obj_array, "PostAssociationDeny", postassoc); if (decode_postassoc_cac_object(postassoc, &vap_info->u.bss_info.postassoc) != webconfig_error_none) { wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: postassoc cac objects validation failed for %s\n",__FUNCTION__, __LINE__, vap_info->vap_name); diff --git a/source/webconfig/wifi_encoder.c b/source/webconfig/wifi_encoder.c index b397fc37..f66c3b66 100644 --- a/source/webconfig/wifi_encoder.c +++ b/source/webconfig/wifi_encoder.c @@ -546,9 +546,16 @@ webconfig_error_t encode_preassoc_object(const wifi_preassoc_control_t *preassoc } else { cJSON_AddStringToObject(preassoc, "6GOpInfoMinRate", preassoc_info->sixGOpInfoMinRate); } - - cJSON_AddNumberToObject(preassoc, "TimeInMs", preassoc_info->time_ms); - cJSON_AddNumberToObject(preassoc, "MinMgmtFrames", preassoc_info->min_num_mgmt_frames); + wifi_util_dbg_print(WIFI_WEBCONFIG,"%s:%d: Encoding preassoc settings passed\n", __func__, __LINE__); + + return webconfig_error_none; +} + + +webconfig_error_t encode_tcm_preassoc_object(const wifi_preassoc_control_t *preassoc_info, cJSON *preassoc) +{ + cJSON_AddNumberToObject(preassoc, "TcmWaitTime", preassoc_info->time_ms); + cJSON_AddNumberToObject(preassoc, "TcmMinMgmtFrames", preassoc_info->min_num_mgmt_frames); if(strlen((char *)preassoc_info->tcm_exp_weightage) == 0) { cJSON_AddStringToObject(preassoc, "TcmExpWeightage", TCM_WEIGH); } else { @@ -559,11 +566,12 @@ webconfig_error_t encode_preassoc_object(const wifi_preassoc_control_t *preassoc } else { cJSON_AddStringToObject(preassoc, "TcmGradientThreshold", preassoc_info->tcm_gradient_threshold); } - wifi_util_dbg_print(WIFI_WEBCONFIG,"%s:%d: Encoding preassoc settings passed\n", __func__, __LINE__); + wifi_util_dbg_print(WIFI_WEBCONFIG,"%s:%d: Encoding tcm preassoc settings passed\n", __func__, __LINE__); return webconfig_error_none; } + webconfig_error_t encode_connection_ctrl_object(const wifi_vap_info_t *vap_info, cJSON *vap_obj) { cJSON *obj; @@ -578,6 +586,13 @@ webconfig_error_t encode_connection_ctrl_object(const wifi_vap_info_t *vap_info, return webconfig_error_encode; } + obj = cJSON_CreateObject(); + cJSON_AddItemToObject(vap_obj, "TcmPreAssociationDeny", obj); + if (encode_tcm_preassoc_object(&vap_info->u.bss_info.preassoc, obj) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d TcmPreassoc object encode failed for %s\n",__FUNCTION__, __LINE__, vap_info->vap_name); + return webconfig_error_encode; + } + obj = cJSON_CreateObject(); cJSON_AddItemToObject(vap_obj, "PostAssociationDeny", obj); if (encode_postassoc_object(&vap_info->u.bss_info.postassoc, obj) != webconfig_error_none) { From c5ddd8ade5829fb97f37ffe77e3646e911e51544 Mon Sep 17 00:00:00 2001 From: Jayanth rajan Date: Mon, 9 Dec 2024 17:54:00 +0000 Subject: [PATCH 05/22] RDKB-58005: [ECOMODE] Enable Eco Mode Support For WiFi Radios Reason for change: Enable EDPD for XER10 Platform as well. Test Procedure: Check Eco Mode is working or not Risks:Low Signed-off-by: Jayanth rajan --- source/core/wifi_ctrl_webconfig.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/source/core/wifi_ctrl_webconfig.c b/source/core/wifi_ctrl_webconfig.c index 1cdbd0bf..47bf7e30 100644 --- a/source/core/wifi_ctrl_webconfig.c +++ b/source/core/wifi_ctrl_webconfig.c @@ -20,6 +20,7 @@ #include #include #include /* strdup() */ +#include #include "const.h" #include "wifi_hal.h" #include "wifi_ctrl.h" @@ -1591,6 +1592,8 @@ static bool is_radio_param_config_changed(wifi_radio_operationParam_t *old , wif } #if defined (FEATURE_SUPPORT_ECOPOWERDOWN) +#define ECOMODE_COMPLETE_MARKER_FILE "/tmp/ecomode_operation_done" +#define MAX_RETRY_VALUE 15 void ecomode_telemetry_update_and_reboot(unsigned int index, bool active) { CHAR eventName[32] = {0}; @@ -1599,7 +1602,29 @@ void ecomode_telemetry_update_and_reboot(unsigned int index, bool active) snprintf(eventName, sizeof(eventName), "WIFI_RADIO_%d_ECOPOWERMODE", index + 1); get_stubs_descriptor()->t2_event_s_fn(eventName, active ? "Active" : "Inactive"); wifi_util_dbg_print(WIFI_WEBCONFIG,"%s: EcoPowerDown telemetry: %s %s uploaded for Radio %d\n", __FUNCTION__, eventName, active ? "Active" : "Inactive", index + 1); +#ifdef DISABLE_ECO_REBOOT + wifi_util_dbg_print(WIFI_WEBCONFIG, + "%s: EcoPowerDown telemetry: Restarting OneWiFi to apply EcoMode. \n", __FUNCTION__); + /** + * The ECOMode operation in the lower layer stack typically takes approximately 10-12 seconds to + * complete. This ensures the OneWiFi service is restarted once the EDPD operation is finished. + */ + int max_retries = MAX_RETRY_VALUE; + int attempt = 0; + + while (attempt < max_retries) { + if (access(ECOMODE_COMPLETE_MARKER_FILE, F_OK) == 0) { + /* EcoMode operation completed. */ + break; + } else { + sleep(1); + } + attempt++; + } + system("systemctl restart onewifi.service"); +#else reboot_device(ctrl); +#endif } #endif // defined (FEATURE_SUPPORT_ECOPOWERDOWN) From 01773eb113a30d80a26942dd36f38460131c03a1 Mon Sep 17 00:00:00 2001 From: Jayanth rajan Date: Mon, 9 Dec 2024 17:56:20 +0000 Subject: [PATCH 06/22] Revert "RDKB-58005: [ECOMODE] Enable Eco Mode Support For WiFi Radios" This reverts commit c5ddd8ade5829fb97f37ffe77e3646e911e51544. --- source/core/wifi_ctrl_webconfig.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/source/core/wifi_ctrl_webconfig.c b/source/core/wifi_ctrl_webconfig.c index 47bf7e30..1cdbd0bf 100644 --- a/source/core/wifi_ctrl_webconfig.c +++ b/source/core/wifi_ctrl_webconfig.c @@ -20,7 +20,6 @@ #include #include #include /* strdup() */ -#include #include "const.h" #include "wifi_hal.h" #include "wifi_ctrl.h" @@ -1592,8 +1591,6 @@ static bool is_radio_param_config_changed(wifi_radio_operationParam_t *old , wif } #if defined (FEATURE_SUPPORT_ECOPOWERDOWN) -#define ECOMODE_COMPLETE_MARKER_FILE "/tmp/ecomode_operation_done" -#define MAX_RETRY_VALUE 15 void ecomode_telemetry_update_and_reboot(unsigned int index, bool active) { CHAR eventName[32] = {0}; @@ -1602,29 +1599,7 @@ void ecomode_telemetry_update_and_reboot(unsigned int index, bool active) snprintf(eventName, sizeof(eventName), "WIFI_RADIO_%d_ECOPOWERMODE", index + 1); get_stubs_descriptor()->t2_event_s_fn(eventName, active ? "Active" : "Inactive"); wifi_util_dbg_print(WIFI_WEBCONFIG,"%s: EcoPowerDown telemetry: %s %s uploaded for Radio %d\n", __FUNCTION__, eventName, active ? "Active" : "Inactive", index + 1); -#ifdef DISABLE_ECO_REBOOT - wifi_util_dbg_print(WIFI_WEBCONFIG, - "%s: EcoPowerDown telemetry: Restarting OneWiFi to apply EcoMode. \n", __FUNCTION__); - /** - * The ECOMode operation in the lower layer stack typically takes approximately 10-12 seconds to - * complete. This ensures the OneWiFi service is restarted once the EDPD operation is finished. - */ - int max_retries = MAX_RETRY_VALUE; - int attempt = 0; - - while (attempt < max_retries) { - if (access(ECOMODE_COMPLETE_MARKER_FILE, F_OK) == 0) { - /* EcoMode operation completed. */ - break; - } else { - sleep(1); - } - attempt++; - } - system("systemctl restart onewifi.service"); -#else reboot_device(ctrl); -#endif } #endif // defined (FEATURE_SUPPORT_ECOPOWERDOWN) From 9c657d9fcaf4a783dd6ff5e0a481c898ddf36544 Mon Sep 17 00:00:00 2001 From: Jayanth rajan Date: Mon, 9 Dec 2024 17:59:42 +0000 Subject: [PATCH 07/22] RDKB-58005: [ECOMODE] Enable Eco Mode Support For WiFi Radios Reason for change: Enable EDPD for XER10 Platform as well. Test Procedure: Check Eco Mode is working or not Risks:Low Signed-off-by: Jayanth rajan --- source/core/wifi_ctrl_webconfig.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/source/core/wifi_ctrl_webconfig.c b/source/core/wifi_ctrl_webconfig.c index 1cdbd0bf..47bf7e30 100644 --- a/source/core/wifi_ctrl_webconfig.c +++ b/source/core/wifi_ctrl_webconfig.c @@ -20,6 +20,7 @@ #include #include #include /* strdup() */ +#include #include "const.h" #include "wifi_hal.h" #include "wifi_ctrl.h" @@ -1591,6 +1592,8 @@ static bool is_radio_param_config_changed(wifi_radio_operationParam_t *old , wif } #if defined (FEATURE_SUPPORT_ECOPOWERDOWN) +#define ECOMODE_COMPLETE_MARKER_FILE "/tmp/ecomode_operation_done" +#define MAX_RETRY_VALUE 15 void ecomode_telemetry_update_and_reboot(unsigned int index, bool active) { CHAR eventName[32] = {0}; @@ -1599,7 +1602,29 @@ void ecomode_telemetry_update_and_reboot(unsigned int index, bool active) snprintf(eventName, sizeof(eventName), "WIFI_RADIO_%d_ECOPOWERMODE", index + 1); get_stubs_descriptor()->t2_event_s_fn(eventName, active ? "Active" : "Inactive"); wifi_util_dbg_print(WIFI_WEBCONFIG,"%s: EcoPowerDown telemetry: %s %s uploaded for Radio %d\n", __FUNCTION__, eventName, active ? "Active" : "Inactive", index + 1); +#ifdef DISABLE_ECO_REBOOT + wifi_util_dbg_print(WIFI_WEBCONFIG, + "%s: EcoPowerDown telemetry: Restarting OneWiFi to apply EcoMode. \n", __FUNCTION__); + /** + * The ECOMode operation in the lower layer stack typically takes approximately 10-12 seconds to + * complete. This ensures the OneWiFi service is restarted once the EDPD operation is finished. + */ + int max_retries = MAX_RETRY_VALUE; + int attempt = 0; + + while (attempt < max_retries) { + if (access(ECOMODE_COMPLETE_MARKER_FILE, F_OK) == 0) { + /* EcoMode operation completed. */ + break; + } else { + sleep(1); + } + attempt++; + } + system("systemctl restart onewifi.service"); +#else reboot_device(ctrl); +#endif } #endif // defined (FEATURE_SUPPORT_ECOPOWERDOWN) From a5a9431a682b00737bd0429f0b4f031d862419f2 Mon Sep 17 00:00:00 2001 From: mmalla642 Date: Fri, 29 Nov 2024 09:58:22 +0000 Subject: [PATCH 08/22] RDKB-57850: Unable to enable LEVL after FR in Reason for change: The acs_pending flag is not being cleared. Whenever the onewifi is restarted, it remains fixed on the previous channel. Test Procedure: Checking the execution of Device.WiFi.WebConfig.Data.Init once the onewifi is restarted. Priority: P1 Risks: Low Signed-off-by: mothishree_mallaiyanjothimani@comcast.com Change-Id: I6607a50ef42aa686bd8026e8d076690d2f342dbc --- source/core/wifi_ctrl.c | 21 +++++++++++++++++++-- source/core/wifi_ctrl.h | 2 ++ source/core/wifi_ctrl_queue_handlers.c | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/source/core/wifi_ctrl.c b/source/core/wifi_ctrl.c index 3ed77651..85ef58a7 100644 --- a/source/core/wifi_ctrl.c +++ b/source/core/wifi_ctrl.c @@ -53,7 +53,7 @@ static int run_analytics_event(void* arg); static int switch_dfs_channel(void *arg); int dfs_channel; - +void start_wifi_sched_timer(unsigned int, struct wifi_ctrl *ctrl, wifi_scheduler_type_t type); void deinit_wifi_ctrl(wifi_ctrl_t *ctrl) { if(ctrl->vif_apply_pending_queue != NULL) { @@ -439,6 +439,7 @@ int start_radios(rdk_dev_mode_type_t mode) ctrl->acs_pending[index] = false; if (wifi_radio_oper_param->autoChannelEnabled == true) { ctrl->acs_pending[index] = true; + start_wifi_sched_timer(index, ctrl, wifi_acs_sched); //Starting the acs_scheduler } //In case of reboot/FR, Non DFS channel will be selected and radio will switch to DFS Channel after 1 min. @@ -1761,6 +1762,9 @@ int wifi_sched_timeout(void *arg) case wifi_vap_sched: handler_id = sched_id->wifi_vap_sched_handler_id; break; + case wifi_acs_sched: + handler_id = sched_id->wifi_acs_sched_handler_id; + break; default: free(args); wifi_util_error_print(WIFI_CTRL, "%s:%d: wifi index:%d invalid type:%d\n", __func__, __LINE__, args->index, args->type); @@ -1774,9 +1778,11 @@ int wifi_sched_timeout(void *arg) if (args->type == wifi_csa_sched) { resched_data_to_ctrl_queue(); } + if (args->type == wifi_acs_sched) { + l_ctrl->acs_pending[args->index] = false; // Clearing acs_pending flag + } free(args); - return TIMER_TASK_COMPLETE; } @@ -1802,6 +1808,10 @@ void start_wifi_sched_timer(unsigned int index, wifi_ctrl_t *l_ctrl, wifi_schedu VAP_ARRAY_INDEX(vap_array_index, mgr->hal_cap, index); handler_index = vap_array_index; break; + case wifi_acs_sched: + handler_id = sched_id->wifi_acs_sched_handler_id; + handler_index = index; + break; default: wifi_util_error_print(WIFI_CTRL, "%s:%d: wifi index:%d invalid type:%d\n", __func__, __LINE__, index, type); return; @@ -1848,6 +1858,10 @@ void stop_wifi_sched_timer(unsigned int index, wifi_ctrl_t *l_ctrl, wifi_schedul VAP_ARRAY_INDEX(vap_array_index, mgr->hal_cap, index); handler_index = vap_array_index; break; + case wifi_acs_sched: + handler_id = sched_id->wifi_acs_sched_handler_id; + handler_index = index; + break; default: wifi_util_error_print(WIFI_CTRL, "%s:%d: wifi index:%d invalid type:%d\n", __func__, __LINE__, index, type); return; @@ -1862,6 +1876,9 @@ void stop_wifi_sched_timer(unsigned int index, wifi_ctrl_t *l_ctrl, wifi_schedul if (type == wifi_csa_sched) { resched_data_to_ctrl_queue(); } + if (type == wifi_acs_sched) { + l_ctrl->acs_pending[handler_index] = false; // Clearing acs_pending flag + } } } diff --git a/source/core/wifi_ctrl.h b/source/core/wifi_ctrl.h index f8ccb5cb..f9e7a14a 100644 --- a/source/core/wifi_ctrl.h +++ b/source/core/wifi_ctrl.h @@ -180,12 +180,14 @@ typedef struct { int wifi_csa_sched_handler_id[MAX_NUM_RADIOS]; int wifi_radio_sched_handler_id[MAX_NUM_RADIOS]; int wifi_vap_sched_handler_id[MAX_NUM_RADIOS * MAX_NUM_VAP_PER_RADIO]; + int wifi_acs_sched_handler_id[MAX_NUM_RADIOS]; } wifi_scheduler_id_t; typedef enum { wifi_csa_sched, wifi_radio_sched, wifi_vap_sched, + wifi_acs_sched } wifi_scheduler_type_t; typedef struct { diff --git a/source/core/wifi_ctrl_queue_handlers.c b/source/core/wifi_ctrl_queue_handlers.c index 0e7b1028..d9c0f9e2 100644 --- a/source/core/wifi_ctrl_queue_handlers.c +++ b/source/core/wifi_ctrl_queue_handlers.c @@ -2606,6 +2606,7 @@ void process_channel_change_event(wifi_channel_change_event_t *ch_chg, bool is_n ch_chg->channel, ch_chg->event, ch_chg->sub_event, ch_chg->op_class); stop_wifi_sched_timer(ch_chg->radioIndex, ctrl, wifi_csa_sched); + stop_wifi_sched_timer(ch_chg->radioIndex, ctrl, wifi_acs_sched); if ((ch_chg->event == WIFI_EVENT_CHANNELS_CHANGED) && ((radio_params->channel == ch_chg->channel) && (radio_params->channelWidth == ch_chg->channelWidth))) { @@ -2793,7 +2794,6 @@ void process_channel_change_event(wifi_channel_change_event_t *ch_chg, bool is_n g_wifidb->ctrl.webconfig_state |= ctrl_webconfig_state_radio_cfg_rsp_pending; start_wifi_sched_timer(ch_chg->radioIndex, ctrl, wifi_radio_sched); update_wifi_radio_config(ch_chg->radioIndex, radio_params, radio_feat); - ctrl->acs_pending[ch_chg->radioIndex] = false; } #define MAX_NEIGHBOURS 250 From e4214ea3aba2856d4a46bbad69cb53aecbe148d3 Mon Sep 17 00:00:00 2001 From: "Pulluru, Harshavardhan" Date: Mon, 9 Dec 2024 11:27:31 +0000 Subject: [PATCH 09/22] RDKB-58058: Telemetry and Rbus for Transient Client Management Impacted Platforms: OneWifi platforms Reason for change: Implement Rbus functions for TCM as part of Epic Test Procedure: Load the build and test the changes as per ACs Risks: Low Change-Id: Id3b414554b23acfb3f685e7714270bcbb67adaa2 Signed-off-by:Harshavardhan_Pulluru@comcast.com --- config/TR181-WiFi-USGv2.XML | 6 +++++ include/wifi_base.h | 1 + source/core/wifi_ctrl_rbus_handlers.c | 33 +++++++++++++++++++++++++++ source/dml/tr_181/ml/cosa_wifi_dml.c | 6 +++++ 4 files changed, 46 insertions(+) diff --git a/config/TR181-WiFi-USGv2.XML b/config/TR181-WiFi-USGv2.XML index 4b6c5d74..66c8f4c1 100644 --- a/config/TR181-WiFi-USGv2.XML +++ b/config/TR181-WiFi-USGv2.XML @@ -2785,6 +2785,12 @@ INSTMSMT_PH2 --> string true + + TcmClientDenyAssociation + string + string + true + diff --git a/include/wifi_base.h b/include/wifi_base.h index 5e33e41d..49304e07 100644 --- a/include/wifi_base.h +++ b/include/wifi_base.h @@ -73,6 +73,7 @@ extern "C" { #define WIFI_COLLECT_STATS_RADIO_TEMPERATURE "Device.WiFi.CollectStats.Radio.{i}.RadioTemperatureStats" #define WIFI_COLLECT_STATS_VAP_TABLE "Device.WiFi.CollectStats.AccessPoint.{i}." #define WIFI_COLLECT_STATS_ASSOC_DEVICE_STATS "Device.WiFi.CollectStats.AccessPoint.{i}.AssociatedDeviceStats" +#define WIFI_NOTIFY_DENY_TCM_ASSOCIATION "Device.WiFi.ConnectionControl.TcmClientDenyAssociation" #define WIFI_STUCK_DETECT_FILE_NAME "/nvram/wifi_stuck_detect" #define PLAN_ID_LENGTH 38 diff --git a/source/core/wifi_ctrl_rbus_handlers.c b/source/core/wifi_ctrl_rbus_handlers.c index 9c906bb3..8b9c8f32 100644 --- a/source/core/wifi_ctrl_rbus_handlers.c +++ b/source/core/wifi_ctrl_rbus_handlers.c @@ -392,6 +392,39 @@ int notify_LM_Lite(wifi_ctrl_t *ctrl, LM_wifi_hosts_t *phosts, bool sync) return RETURN_OK; } +int tcm_notify_deny_association(wifi_ctrl_t *ctrl, int ap_index, mac_addr_str_t mac, + double threshold_val, double snr_gradient) +{ + bus_error_t rc; + char str[2048]; + wifi_vap_info_t *vap_info = NULL; + + memset(str, 0, 2048); + + if (ctrl == NULL) { + wifi_util_error_print(WIFI_CTRL, "%s:%d: NULL Pointer \n", __func__, __LINE__); + return RETURN_ERR; + } + + vap_info = getVapInfo(ap_index); + + snprintf(str, sizeof(str), "%d,%s,%lf,%lf", (ap_index + 1), mac, threshold_val, + snr_gradient); + + if (vap_info != NULL) { + strncpy(vap_info->u.bss_info.preassoc.tcm_client_deny_assoc_info, str, + sizeof(vap_info->u.bss_info.preassoc.tcm_client_deny_assoc_info)); + } + + rc = get_bus_descriptor()->bus_set_string_fn(&ctrl->handle, WIFI_NOTIFY_DENY_TCM_ASSOCIATION, str); + if (rc != bus_error_success) { + wifi_util_error_print(WIFI_CTRL, "%s:%d: bus: bus_set_string_fn Failed %d\n", __func__, + __LINE__, rc); + return RETURN_ERR; + } + return RETURN_OK; +} + int webconfig_bus_apply_for_dml_thread_update(wifi_ctrl_t *ctrl, webconfig_subdoc_encoded_data_t *data) { diff --git a/source/dml/tr_181/ml/cosa_wifi_dml.c b/source/dml/tr_181/ml/cosa_wifi_dml.c index d89ec4b2..2e80ae69 100755 --- a/source/dml/tr_181/ml/cosa_wifi_dml.c +++ b/source/dml/tr_181/ml/cosa_wifi_dml.c @@ -9287,6 +9287,12 @@ ConnectionControl_GetParamStringValue return 0; } + if( AnscEqualString(ParamName, "TcmClientDenyAssociation", TRUE)) + { + snprintf(pValue,*pUlSize,pcfg->u.bss_info.preassoc.tcm_client_deny_assoc_info); + return 0; + } + return -1; } From 936c48406b54f0713c61537dd4fdfc91c16413dd Mon Sep 17 00:00:00 2001 From: Amarnath Hullur Subramanyam Date: Wed, 11 Dec 2024 12:28:45 -0800 Subject: [PATCH 10/22] Revert "RDKB-58058: Telemetry and Rbus for Transient Client Management" --- config/TR181-WiFi-USGv2.XML | 6 ----- include/wifi_base.h | 1 - source/core/wifi_ctrl_rbus_handlers.c | 33 --------------------------- source/dml/tr_181/ml/cosa_wifi_dml.c | 6 ----- 4 files changed, 46 deletions(-) diff --git a/config/TR181-WiFi-USGv2.XML b/config/TR181-WiFi-USGv2.XML index 66c8f4c1..4b6c5d74 100644 --- a/config/TR181-WiFi-USGv2.XML +++ b/config/TR181-WiFi-USGv2.XML @@ -2785,12 +2785,6 @@ INSTMSMT_PH2 --> string true - - TcmClientDenyAssociation - string - string - true - diff --git a/include/wifi_base.h b/include/wifi_base.h index 49304e07..5e33e41d 100644 --- a/include/wifi_base.h +++ b/include/wifi_base.h @@ -73,7 +73,6 @@ extern "C" { #define WIFI_COLLECT_STATS_RADIO_TEMPERATURE "Device.WiFi.CollectStats.Radio.{i}.RadioTemperatureStats" #define WIFI_COLLECT_STATS_VAP_TABLE "Device.WiFi.CollectStats.AccessPoint.{i}." #define WIFI_COLLECT_STATS_ASSOC_DEVICE_STATS "Device.WiFi.CollectStats.AccessPoint.{i}.AssociatedDeviceStats" -#define WIFI_NOTIFY_DENY_TCM_ASSOCIATION "Device.WiFi.ConnectionControl.TcmClientDenyAssociation" #define WIFI_STUCK_DETECT_FILE_NAME "/nvram/wifi_stuck_detect" #define PLAN_ID_LENGTH 38 diff --git a/source/core/wifi_ctrl_rbus_handlers.c b/source/core/wifi_ctrl_rbus_handlers.c index 8b9c8f32..9c906bb3 100644 --- a/source/core/wifi_ctrl_rbus_handlers.c +++ b/source/core/wifi_ctrl_rbus_handlers.c @@ -392,39 +392,6 @@ int notify_LM_Lite(wifi_ctrl_t *ctrl, LM_wifi_hosts_t *phosts, bool sync) return RETURN_OK; } -int tcm_notify_deny_association(wifi_ctrl_t *ctrl, int ap_index, mac_addr_str_t mac, - double threshold_val, double snr_gradient) -{ - bus_error_t rc; - char str[2048]; - wifi_vap_info_t *vap_info = NULL; - - memset(str, 0, 2048); - - if (ctrl == NULL) { - wifi_util_error_print(WIFI_CTRL, "%s:%d: NULL Pointer \n", __func__, __LINE__); - return RETURN_ERR; - } - - vap_info = getVapInfo(ap_index); - - snprintf(str, sizeof(str), "%d,%s,%lf,%lf", (ap_index + 1), mac, threshold_val, - snr_gradient); - - if (vap_info != NULL) { - strncpy(vap_info->u.bss_info.preassoc.tcm_client_deny_assoc_info, str, - sizeof(vap_info->u.bss_info.preassoc.tcm_client_deny_assoc_info)); - } - - rc = get_bus_descriptor()->bus_set_string_fn(&ctrl->handle, WIFI_NOTIFY_DENY_TCM_ASSOCIATION, str); - if (rc != bus_error_success) { - wifi_util_error_print(WIFI_CTRL, "%s:%d: bus: bus_set_string_fn Failed %d\n", __func__, - __LINE__, rc); - return RETURN_ERR; - } - return RETURN_OK; -} - int webconfig_bus_apply_for_dml_thread_update(wifi_ctrl_t *ctrl, webconfig_subdoc_encoded_data_t *data) { diff --git a/source/dml/tr_181/ml/cosa_wifi_dml.c b/source/dml/tr_181/ml/cosa_wifi_dml.c index 2e80ae69..d89ec4b2 100755 --- a/source/dml/tr_181/ml/cosa_wifi_dml.c +++ b/source/dml/tr_181/ml/cosa_wifi_dml.c @@ -9287,12 +9287,6 @@ ConnectionControl_GetParamStringValue return 0; } - if( AnscEqualString(ParamName, "TcmClientDenyAssociation", TRUE)) - { - snprintf(pValue,*pUlSize,pcfg->u.bss_info.preassoc.tcm_client_deny_assoc_info); - return 0; - } - return -1; } From e2645e15c318365b6a9fda8ca531317aeabfe99a Mon Sep 17 00:00:00 2001 From: sjs889 Date: Thu, 12 Dec 2024 05:44:07 +0000 Subject: [PATCH 11/22] RDKB-58042:Telemetry & Logging Support TCM Impacted Platforms: OneWifi Platforms Reason for change: Implement Telemetry and RBUS support for TCM Algorithm as part of Epic Test Procedure: Load the build and test the changes as per ACs Risks: Low Change-Id: Ifcb3b2ae16649ec2872b7c3b5cdd68f582a7487c Signed-off-by:Srijeyarankesh_JS@comcast.com1 --- source/utils/wifi_util.c | 5 +++++ source/utils/wifi_util.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/source/utils/wifi_util.c b/source/utils/wifi_util.c index f2012faa..b1dcb5b6 100644 --- a/source/utils/wifi_util.c +++ b/source/utils/wifi_util.c @@ -809,6 +809,11 @@ void wifi_util_print(wifi_log_level_t level, wifi_dbg_type_t module, char *forma snprintf(module_filename, sizeof(module_filename), "wifiBus"); break; } + case WIFI_TCM:{ + snprintf(filename_dbg_enable, sizeof(filename_dbg_enable), LOG_PATH_PREFIX "wifiTCMDbg"); + snprintf(module_filename, sizeof(module_filename), "wifiTransientClientMgmtCtrl"); + break; + } default: return; } diff --git a/source/utils/wifi_util.h b/source/utils/wifi_util.h index bc72e0b7..6624d073 100644 --- a/source/utils/wifi_util.h +++ b/source/utils/wifi_util.h @@ -57,7 +57,8 @@ typedef enum { WIFI_SM, WIFI_BLASTER, WIFI_OCS, - WIFI_BUS + WIFI_BUS, + WIFI_TCM } wifi_dbg_type_t; typedef enum { From 0a0e95eb096e3d7fb17262b79552591d4e2ff8a0 Mon Sep 17 00:00:00 2001 From: Amarnath Hullur Subramanyam Date: Thu, 12 Dec 2024 11:09:59 -0800 Subject: [PATCH 12/22] Send Assoc frame data only when client associates Association frame data is needed only when the client associates, so add that in the subdoc only during that time. Change-Id: Ibe3ee428649efa6d925b9349e98052e28afd5577 Signed-off-by: Amarnath Hullur Subramanyam --- source/webconfig/wifi_encoder.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/source/webconfig/wifi_encoder.c b/source/webconfig/wifi_encoder.c index f66c3b66..9a7c069e 100644 --- a/source/webconfig/wifi_encoder.c +++ b/source/webconfig/wifi_encoder.c @@ -1577,7 +1577,7 @@ webconfig_error_t encode_frame_data(cJSON *obj_assoc_client, frame_data_t *frame webconfig_error_t encode_associated_client_object(rdk_wifi_vap_info_t *rdk_vap_info, cJSON *assoc_array, assoclist_type_t assoclist_type) { - bool print_assoc_client = false; + bool print_assoc_client = false, include_frame_data = false; if ((rdk_vap_info == NULL) || (assoc_array == NULL)) { wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d Associated Client encode failed\n",__FUNCTION__, __LINE__); return webconfig_error_encode; @@ -1611,10 +1611,12 @@ webconfig_error_t encode_associated_client_object(rdk_wifi_vap_info_t *rdk_vap_i assoc_dev_data = hash_map_get_first(devices_map); while (assoc_dev_data != NULL) { print_assoc_client = false; + include_frame_data = false; if (assoclist_type == assoclist_type_full) { print_assoc_client = true; } else if ((assoclist_type == assoclist_type_add) && (assoc_dev_data->client_state == client_state_connected)) { print_assoc_client = true; + include_frame_data = true; } else if ((assoclist_type == assoclist_type_remove) && (assoc_dev_data->client_state == client_state_disconnected)) { print_assoc_client = true; } @@ -1657,10 +1659,12 @@ webconfig_error_t encode_associated_client_object(rdk_wifi_vap_info_t *rdk_vap_i cJSON_AddNumberToObject(obj_assoc_client, "FailedRetransCount", assoc_dev_data->dev_stats.cli_FailedRetransCount); cJSON_AddNumberToObject(obj_assoc_client, "RetryCount", assoc_dev_data->dev_stats.cli_RetryCount); cJSON_AddNumberToObject(obj_assoc_client, "MultipleRetryCount", assoc_dev_data->dev_stats.cli_MultipleRetryCount); - if (encode_frame_data(obj_assoc_client, &assoc_dev_data->sta_data.msg_data) != - webconfig_error_none) { - wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d Encode frame data failed for client %s\n", - __func__, __LINE__, mac_string); + if (include_frame_data == true && + encode_frame_data(obj_assoc_client, &assoc_dev_data->sta_data.msg_data) != + webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d Encode frame data failed for client %s\n", __func__, __LINE__, + mac_string); } } assoc_dev_data = hash_map_get_next(devices_map, assoc_dev_data); From 044e9043b1eb1cc94839eae5c428febcf3e66660 Mon Sep 17 00:00:00 2001 From: Amarnath Hullur Subramanyam Date: Tue, 3 Dec 2024 18:01:54 -0800 Subject: [PATCH 13/22] OneWifi: New Subdocs to provide Vap configuration per Radio. Reason for change: No existing subdocs which provides the VAP configuration corresponding to a radio is present. This is required for easymesh usecase, thus the change. Test Procedure: Encode, decode and apply of VAP configuration per radio tested on Raspberry Pi. --- build/linux/makefile | 1 + include/wifi_webconfig.h | 11 + source/core/wifi_ctrl.c | 9 + source/core/wifi_ctrl.h | 7 +- source/core/wifi_ctrl_rbus_handlers.c | 3 + source/core/wifi_ctrl_webconfig.c | 121 +++++ source/webconfig/wifi_easymesh_translator.c | 10 + source/webconfig/wifi_webconfig.c | 37 ++ source/webconfig/wifi_webconfig_multivap.c | 495 ++++++++++++++++++++ 9 files changed, 692 insertions(+), 2 deletions(-) create mode 100644 source/webconfig/wifi_webconfig_multivap.c diff --git a/build/linux/makefile b/build/linux/makefile index ee6a320f..8317045a 100644 --- a/build/linux/makefile +++ b/build/linux/makefile @@ -328,6 +328,7 @@ WEBCONFIG_SOURCES = $(ONE_WIFI_HOME)/source/webconfig/wifi_decoder.c \ $(ONE_WIFI_HOME)/source/webconfig/wifi_webconfig_assocdevice_stats.c \ $(ONE_WIFI_HOME)/source/webconfig/wifi_webconfig_radio_temperature.c \ $(ONE_WIFI_HOME)/source/webconfig/wifi_webconfig_radiodiag_stats.c \ + $(ONE_WIFI_HOME)/source/webconfig/wifi_webconfig_multivap.c \ $(ONE_WIFI_HOME)/source/utils/wifi_util.c \ HEBUS_SOURCES = $(wildcard $(ONE_WIFI_HOME)/source/platform/linux/he_bus/src/*.c) \ diff --git a/include/wifi_webconfig.h b/include/wifi_webconfig.h index 8dd5ce7d..3be595e0 100644 --- a/include/wifi_webconfig.h +++ b/include/wifi_webconfig.h @@ -128,6 +128,9 @@ typedef enum { webconfig_subdoc_type_assocdev_stats, webconfig_subdoc_type_radiodiag_stats, webconfig_subdoc_type_radio_temperature, + webconfig_subdoc_type_vap_24G, + webconfig_subdoc_type_vap_5G, + webconfig_subdoc_type_vap_6G, webconfig_subdoc_type_max } webconfig_subdoc_type_t; @@ -578,6 +581,14 @@ webconfig_error_t decode_radio_temperature_stats_subdoc(webconfig_t *confi webconfig_error_t encode_radio_temperature_stats_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); webconfig_error_t translate_to_radio_temperature_stats_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); webconfig_error_t translate_from_radio_temperature_stats_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); + +// Vap_24G, Vap_5G and Vap_6G +webconfig_error_t init_multivap_subdoc(webconfig_subdoc_t *doc); +webconfig_error_t access_check_multivap_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); +webconfig_error_t decode_multivap_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); +webconfig_error_t encode_multivap_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); +webconfig_error_t translate_to_multivap_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); +webconfig_error_t translate_from_multivap_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); #ifdef __cplusplus } #endif diff --git a/source/core/wifi_ctrl.c b/source/core/wifi_ctrl.c index 961e0b02..f4738d37 100644 --- a/source/core/wifi_ctrl.c +++ b/source/core/wifi_ctrl.c @@ -1709,6 +1709,15 @@ bool check_wifi_vap_sched_timeout_active_status(wifi_ctrl_t *l_ctrl, BOOL (*cb)( return false; } +bool check_wifi_multivap_sched_timeout_active_status(wifi_ctrl_t *l_ctrl, int radio_index) +{ + //TBD: Check all the sched handler of the VAP associated with the radio_index + wifi_mgr_t *mgr = (wifi_mgr_t *)get_wifimgr_obj(); + + // Currently returning false + return false; +} + void resched_data_to_ctrl_queue() { wifi_ctrl_t *l_ctrl; diff --git a/source/core/wifi_ctrl.h b/source/core/wifi_ctrl.h index 820ce95b..b8310744 100644 --- a/source/core/wifi_ctrl.h +++ b/source/core/wifi_ctrl.h @@ -147,10 +147,13 @@ typedef enum { ctrl_webconfig_state_blaster_cfg_complete_rsp_pending = 0x40000, ctrl_webconfig_state_vap_mesh_backhaul_sta_cfg_rsp_pending = 0x80000, ctrl_webconfig_state_trigger_dml_thread_data_update_pending = 0x100000, - ctrl_webconfig_state_max = 0x200000 + ctrl_webconfig_state_vap_24G_cfg_rsp_pending = 0x200000, + ctrl_webconfig_state_vap_5G_cfg_rsp_pending = 0x400000, + ctrl_webconfig_state_vap_6G_cfg_rsp_pending = 0x800000, + ctrl_webconfig_state_max = 0x1000000 } wifi_ctrl_webconfig_state_t; -#define CTRL_WEBCONFIG_STATE_MASK 0x1fffff +#define CTRL_WEBCONFIG_STATE_MASK 0x1ffffff typedef struct { char mac_addr[MAC_STR_LEN]; diff --git a/source/core/wifi_ctrl_rbus_handlers.c b/source/core/wifi_ctrl_rbus_handlers.c index 739d94bf..9eeb0c83 100644 --- a/source/core/wifi_ctrl_rbus_handlers.c +++ b/source/core/wifi_ctrl_rbus_handlers.c @@ -422,6 +422,9 @@ int webconfig_bus_apply(wifi_ctrl_t *ctrl, webconfig_subdoc_encoded_data_t *data rdata.raw_data.bytes = (void *)data->raw; rdata.raw_data_len = strlen(data->raw) + 1; + wifi_util_dbg_print(WIFI_CTRL, "%s:%d:bus_event_publish_fn WIFI_WEBCONFIG_DOC_DATA_NORTH initiated %d\n", __func__, + __LINE__); + rc = get_bus_descriptor()->bus_event_publish_fn(&ctrl->handle, WIFI_WEBCONFIG_DOC_DATA_NORTH, &rdata); if (rc != bus_error_success) { diff --git a/source/core/wifi_ctrl_webconfig.c b/source/core/wifi_ctrl_webconfig.c index d1e3470a..f91d7942 100644 --- a/source/core/wifi_ctrl_webconfig.c +++ b/source/core/wifi_ctrl_webconfig.c @@ -327,6 +327,21 @@ int webconfig_send_steering_clients_status(wifi_ctrl_t *ctrl) return RETURN_OK; } +int webconfig_send_multivap_subdoc_status(wifi_ctrl_t *ctrl, webconfig_subdoc_type_t type) +{ + webconfig_subdoc_data_t data; + + webconfig_init_subdoc_data(&data); + + if (webconfig_encode(&ctrl->webconfig, &data, type) != webconfig_error_none) { + wifi_util_error_print(WIFI_CTRL, "%s:%d - Failed webconfig_encode\n", __FUNCTION__, + __LINE__); + } else { + webconfig_data_free(&data); + } + return RETURN_OK; +} + int webconfig_analyze_pending_states(wifi_ctrl_t *ctrl) { static int pending_state = ctrl_webconfig_state_max; @@ -468,6 +483,30 @@ int webconfig_analyze_pending_states(wifi_ctrl_t *ctrl) type = webconfig_subdoc_type_dml; webconfig_send_dml_subdoc_status(ctrl); break; + case ctrl_webconfig_state_vap_24G_cfg_rsp_pending: + if (check_wifi_multivap_sched_timeout_active_status(ctrl, 0) == false) { + type = webconfig_subdoc_type_vap_24G; + webconfig_send_multivap_subdoc_status(ctrl, type); + } else { + return RETURN_OK; + } + break; + case ctrl_webconfig_state_vap_5G_cfg_rsp_pending: + if (check_wifi_multivap_sched_timeout_active_status(ctrl, 1) == false) { + type = webconfig_subdoc_type_vap_5G; + webconfig_send_multivap_subdoc_status(ctrl, type); + } else { + return RETURN_OK; + } + break; + case ctrl_webconfig_state_vap_6G_cfg_rsp_pending: + if (check_wifi_multivap_sched_timeout_active_status(ctrl, 2) == false) { + type = webconfig_subdoc_type_vap_6G; + webconfig_send_multivap_subdoc_status(ctrl, type); + } else { + return RETURN_OK; + } + break; default: wifi_util_dbg_print(WIFI_CTRL, "%s:%d - default pending subdoc status:0x%x\r\n", __func__, __LINE__, (ctrl->webconfig_state & CTRL_WEBCONFIG_STATE_MASK)); break; @@ -661,6 +700,9 @@ int webconfig_hal_vap_apply_by_name(wifi_ctrl_t *ctrl, webconfig_subdoc_decoded_ } if (found_target == false) { + wifi_util_error_print(WIFI_MGR, + "%s:%d: Could not find tgt_radio_idx:%d for vap name:%s\n", __func__, __LINE__, + tgt_radio_idx, vap_names[i]); continue; } @@ -676,6 +718,9 @@ int webconfig_hal_vap_apply_by_name(wifi_ctrl_t *ctrl, webconfig_subdoc_decoded_ } if (found_target == false) { + wifi_util_error_print(WIFI_MGR, + "%s:%d: Could not find tgt_vap_index:%d for vap name:%s\n", __func__, __LINE__, + tgt_vap_index, vap_names[i]); continue; } @@ -1380,6 +1425,51 @@ int webconfig_hal_mesh_backhaul_vap_apply(wifi_ctrl_t *ctrl, webconfig_subdoc_de return webconfig_hal_vap_apply_by_name(ctrl, data, vap_names, num_vaps); } +int webconfig_hal_multivap_apply(wifi_ctrl_t *ctrl, webconfig_subdoc_decoded_data_t *data, + webconfig_subdoc_type_t doc_type) +{ + unsigned int num_vaps = 0; + unsigned int ap_index; + char *vap_name; + char *vap_names[MAX_NUM_VAP_PER_RADIO]; + wifi_mgr_t *mgr = get_wifimgr_obj(); + rdk_wifi_vap_map_t *mgr_vap_map = NULL; + int radio_index = -1; + + switch (doc_type) { + case webconfig_subdoc_type_vap_24G: + radio_index = 0; + break; + case webconfig_subdoc_type_vap_5G: + radio_index = 1; + break; + case webconfig_subdoc_type_vap_6G: + radio_index = 2; + break; + default: + // Invalid doc_type return err + wifi_util_error_print(WIFI_MGR, "%s:%d Invalid doc_type:%d\n", __func__, __LINE__, + doc_type); + return RETURN_ERR; + } + + wifi_util_dbg_print(WIFI_MGR, "%s:%d Selected Radio Index:%d for doc_type:%d\n", __func__, + __LINE__, radio_index, doc_type); + mgr_vap_map = &mgr->radio_config[radio_index].vaps; + if (mgr_vap_map == NULL) { + wifi_util_error_print(WIFI_MGR, "%s:%d Error vap_map is NULL for Radio Index:%d\n", + __func__, __LINE__, radio_index); + return RETURN_ERR; + } + + // Consider all the Vap associated with the radio_index + for (UINT index = 0; index < mgr_vap_map->num_vaps; index++) { + vap_names[num_vaps] = mgr_vap_map->rdk_vap_array[index].vap_name; + num_vaps++; + } + return webconfig_hal_vap_apply_by_name(ctrl, data, vap_names, num_vaps); +} + int webconfig_hal_mac_filter_apply(wifi_ctrl_t *ctrl, webconfig_subdoc_decoded_data_t *data, webconfig_subdoc_type_t subdoc_type) { unsigned int radio_index, vap_index; @@ -2160,6 +2250,37 @@ webconfig_error_t webconfig_ctrl_apply(webconfig_subdoc_t *doc, webconfig_subdoc #endif break; + case webconfig_subdoc_type_vap_24G: + case webconfig_subdoc_type_vap_5G: + case webconfig_subdoc_type_vap_6G: + wifi_ctrl_webconfig_state_t conf_state_pending; + if (doc->type == webconfig_subdoc_type_vap_24G) { + conf_state_pending = ctrl_webconfig_state_vap_24G_cfg_rsp_pending; + } else if (doc->type == webconfig_subdoc_type_vap_5G) { + conf_state_pending = ctrl_webconfig_state_vap_5G_cfg_rsp_pending; + } else { + conf_state_pending = ctrl_webconfig_state_vap_6G_cfg_rsp_pending; + } + if (data->descriptor & webconfig_data_descriptor_encoded) { + if (ctrl->webconfig_state & conf_state_pending) { + ctrl->webconfig_state &= ~conf_state_pending; + ret = webconfig_bus_apply(ctrl, &data->u.encoded); + } + } else { + if (check_wifi_csa_sched_timeout_active_status(ctrl) == true) { + if (push_data_to_apply_pending_queue(data) != RETURN_OK) { + return webconfig_error_apply; + } + } else { + ctrl->webconfig_state |= conf_state_pending; + webconfig_analytic_event_data_to_hal_apply(data); + ret = webconfig_hal_multivap_apply(ctrl, &data->u.decoded, doc->type); + } + } + // This is for captive_portal_check for private SSID when defaults modified + captive_portal_check(); + break; + default: break; } diff --git a/source/webconfig/wifi_easymesh_translator.c b/source/webconfig/wifi_easymesh_translator.c index 7b8c102b..a88ed8d5 100644 --- a/source/webconfig/wifi_easymesh_translator.c +++ b/source/webconfig/wifi_easymesh_translator.c @@ -1860,6 +1860,11 @@ webconfig_error_t translate_to_easymesh_tables(webconfig_subdoc_type_t type, we } break; */ + case webconfig_subdoc_type_vap_24G: + case webconfig_subdoc_type_vap_5G: + case webconfig_subdoc_type_vap_6G: + //TBD: Update the necessary datastructures of easymesh + default: break; } @@ -1935,6 +1940,11 @@ webconfig_error_t translate_from_easymesh_tables(webconfig_subdoc_type_t type, } break; + case webconfig_subdoc_type_vap_24G: + case webconfig_subdoc_type_vap_5G: + case webconfig_subdoc_type_vap_6G: + //TBD: Update the necessary datastructures from easymesh to OneWifi. + default: break; } diff --git a/source/webconfig/wifi_webconfig.c b/source/webconfig/wifi_webconfig.c index f3650901..8b1af043 100644 --- a/source/webconfig/wifi_webconfig.c +++ b/source/webconfig/wifi_webconfig.c @@ -621,6 +621,43 @@ webconfig_error_t webconfig_init(webconfig_t *config) config->subdocs[webconfig_subdoc_type_radio_temperature].decode_subdoc = decode_radio_temperature_stats_subdoc; config->subdocs[webconfig_subdoc_type_radio_temperature].translate_to_subdoc = translate_to_radio_temperature_stats_subdoc; config->subdocs[webconfig_subdoc_type_radio_temperature].translate_from_subdoc = translate_from_radio_temperature_stats_subdoc; + + config->subdocs[webconfig_subdoc_type_vap_24G].type = webconfig_subdoc_type_vap_24G; + strcpy(config->subdocs[webconfig_subdoc_type_vap_24G].name, "Vap_2.4G"); + config->subdocs[webconfig_subdoc_type_vap_24G].major = 1; + config->subdocs[webconfig_subdoc_type_vap_24G].minor = 1; + config->subdocs[webconfig_subdoc_type_vap_24G].init_subdoc = init_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_24G].init_subdoc(&config->subdocs[webconfig_subdoc_type_vap_24G]); + config->subdocs[webconfig_subdoc_type_vap_24G].access_check_subdoc = access_check_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_24G].encode_subdoc = encode_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_24G].decode_subdoc = decode_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_24G].translate_to_subdoc = translate_to_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_24G].translate_from_subdoc = translate_from_multivap_subdoc; + + config->subdocs[webconfig_subdoc_type_vap_5G].type = webconfig_subdoc_type_vap_5G; + strcpy(config->subdocs[webconfig_subdoc_type_vap_5G].name, "Vap_5G"); + config->subdocs[webconfig_subdoc_type_vap_5G].major = 1; + config->subdocs[webconfig_subdoc_type_vap_5G].minor = 1; + config->subdocs[webconfig_subdoc_type_vap_5G].init_subdoc = init_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_5G].init_subdoc(&config->subdocs[webconfig_subdoc_type_vap_5G]); + config->subdocs[webconfig_subdoc_type_vap_5G].access_check_subdoc = access_check_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_5G].encode_subdoc = encode_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_5G].decode_subdoc = decode_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_5G].translate_to_subdoc = translate_to_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_5G].translate_from_subdoc = translate_from_multivap_subdoc; + + config->subdocs[webconfig_subdoc_type_vap_6G].type = webconfig_subdoc_type_vap_6G; + strcpy(config->subdocs[webconfig_subdoc_type_vap_6G].name, "Vap_6G"); + config->subdocs[webconfig_subdoc_type_vap_6G].major = 1; + config->subdocs[webconfig_subdoc_type_vap_6G].minor = 1; + config->subdocs[webconfig_subdoc_type_vap_6G].init_subdoc = init_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_6G].init_subdoc(&config->subdocs[webconfig_subdoc_type_vap_6G]); + config->subdocs[webconfig_subdoc_type_vap_6G].access_check_subdoc = access_check_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_6G].encode_subdoc = encode_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_6G].decode_subdoc = decode_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_6G].translate_to_subdoc = translate_to_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_vap_6G].translate_from_subdoc = translate_from_multivap_subdoc; + config->proto_desc.translate_to = translate_to_proto; config->proto_desc.translate_from = translate_from_proto; diff --git a/source/webconfig/wifi_webconfig_multivap.c b/source/webconfig/wifi_webconfig_multivap.c new file mode 100644 index 00000000..f96f49db --- /dev/null +++ b/source/webconfig/wifi_webconfig_multivap.c @@ -0,0 +1,495 @@ +/************************************************************************************ + If not stated otherwise in this file or this component's LICENSE file the + following copyright and licenses apply: + + Copyright 2024 RDK Management + + 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. +**************************************************************************/ +#include "collection.h" +#include "wifi_ctrl.h" +#include "wifi_monitor.h" +#include "wifi_util.h" +#include "wifi_webconfig.h" +#include +#include +#include +#include +#include +#include + +extern webconfig_error_t encode_private_vap_object(const wifi_vap_info_t *vap_info, + const rdk_wifi_vap_info_t *rdk_vap_info, cJSON *vap_obj); +extern webconfig_error_t encode_hotspot_open_vap_object(const wifi_vap_info_t *vap_info, + const rdk_wifi_vap_info_t *rdk_vap_info, cJSON *vap_obj); +extern webconfig_error_t encode_hotspot_secure_vap_object(const wifi_vap_info_t *vap_info, + const rdk_wifi_vap_info_t *rdk_vap_info, cJSON *vap_obj); +extern webconfig_error_t encode_lnf_psk_vap_object(const wifi_vap_info_t *vap_info, + const rdk_wifi_vap_info_t *rdk_vap_info, cJSON *vap_obj); +extern webconfig_error_t encode_lnf_radius_vap_object(const wifi_vap_info_t *vap_info, + const rdk_wifi_vap_info_t *rdk_vap_info, cJSON *vap_obj); +extern webconfig_error_t encode_mesh_backhaul_vap_object(const wifi_vap_info_t *vap_info, + const rdk_wifi_vap_info_t *rdk_vap_info, cJSON *vap_obj); +extern webconfig_error_t encode_iot_vap_object(const wifi_vap_info_t *vap_info, + const rdk_wifi_vap_info_t *rdk_vap_info, cJSON *vap_obj); +extern webconfig_error_t encode_mesh_sta_object(const wifi_vap_info_t *vap_info, + const rdk_wifi_vap_info_t *rdk_vap_info, cJSON *vap_obj); + +extern webconfig_error_t decode_private_vap_object(const cJSON *vap, wifi_vap_info_t *vap_info, + rdk_wifi_vap_info_t *rdk_vap_info, wifi_platform_property_t *wifi_prop); +extern webconfig_error_t decode_hotspot_open_vap_object(const cJSON *vap, wifi_vap_info_t *vap_info, + rdk_wifi_vap_info_t *rdk_vap_info, wifi_platform_property_t *wifi_prop); +extern webconfig_error_t decode_hotspot_secure_vap_object(const cJSON *vap, + wifi_vap_info_t *vap_info, rdk_wifi_vap_info_t *rdk_vap_info, + wifi_platform_property_t *wifi_prop); +extern webconfig_error_t decode_lnf_psk_vap_object(const cJSON *vap, wifi_vap_info_t *vap_info, + rdk_wifi_vap_info_t *rdk_vap_info, wifi_platform_property_t *wifi_prop); +extern webconfig_error_t decode_lnf_radius_vap_object(const cJSON *vap, wifi_vap_info_t *vap_info, + rdk_wifi_vap_info_t *rdk_vap_info, wifi_platform_property_t *wifi_prop); +extern webconfig_error_t decode_iot_vap_object(const cJSON *vap, wifi_vap_info_t *vap_info, + rdk_wifi_vap_info_t *rdk_vap_info, wifi_platform_property_t *wifi_prop); +extern webconfig_error_t decode_mesh_backhaul_vap_object(const cJSON *vap, + wifi_vap_info_t *vap_info, rdk_wifi_vap_info_t *rdk_vap_info, + wifi_platform_property_t *wifi_prop); +extern webconfig_error_t decode_mesh_sta_object(const cJSON *vap, wifi_vap_info_t *vap_info, + rdk_wifi_vap_info_t *rdk_vap_info, wifi_platform_property_t *wifi_prop); + +webconfig_subdoc_object_t multivap_objects[3] = { + { webconfig_subdoc_object_type_version, "Version" }, + { webconfig_subdoc_object_type_subdoc, "SubDocName" }, + { webconfig_subdoc_object_type_vaps, "WifiVapConfig" }, +}; + +webconfig_error_t init_multivap_subdoc(webconfig_subdoc_t *doc) +{ + doc->num_objects = sizeof(multivap_objects) / sizeof(webconfig_subdoc_object_t); + memcpy((unsigned char *)doc->objects, (unsigned char *)&multivap_objects, + sizeof(multivap_objects)); + + return webconfig_error_none; +} + +webconfig_error_t access_check_multivap_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data) +{ + return webconfig_error_none; +} + +webconfig_error_t translate_from_multivap_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data) +{ + if (((data->descriptor & webconfig_data_descriptor_translate_to_ovsdb) == + webconfig_data_descriptor_translate_to_ovsdb) || + ((data->descriptor & webconfig_data_descriptor_translate_to_easymesh) == + webconfig_data_descriptor_translate_to_easymesh)) { + if (config->proto_desc.translate_to(data->type, data) != webconfig_error_none) { + if ((data->descriptor & webconfig_data_descriptor_translate_to_ovsdb) == + webconfig_data_descriptor_translate_to_ovsdb) { + return webconfig_error_translate_to_ovsdb; + } else { + return webconfig_error_translate_to_easymesh; + } + } + } else if ((data->descriptor & webconfig_data_descriptor_translate_to_tr181) == + webconfig_data_descriptor_translate_to_tr181) { + } else { + // no translation required + } + return webconfig_error_none; +} + +webconfig_error_t translate_to_multivap_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data) +{ + if (((data->descriptor & webconfig_data_descriptor_translate_from_ovsdb) == + webconfig_data_descriptor_translate_from_ovsdb) || + ((data->descriptor & webconfig_data_descriptor_translate_from_easymesh) == + webconfig_data_descriptor_translate_from_easymesh)) { + if (config->proto_desc.translate_from(data->type, data) != webconfig_error_none) { + if ((data->descriptor & webconfig_data_descriptor_translate_from_ovsdb) == + webconfig_data_descriptor_translate_from_ovsdb) { + return webconfig_error_translate_from_ovsdb; + } else { + return webconfig_error_translate_from_easymesh; + } + } + } else if ((data->descriptor & webconfig_data_descriptor_translate_from_tr181) == + webconfig_data_descriptor_translate_from_tr181) { + } else { + // no translation required + } + return webconfig_error_none; +} + +webconfig_error_t encode_multivap_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data) +{ + cJSON *json; + cJSON *obj, *obj_array; + wifi_vap_info_map_t *map; + rdk_wifi_radio_t *radio; + wifi_vap_info_t *vap; + rdk_wifi_vap_info_t *rdk_vap; + webconfig_subdoc_decoded_data_t *params; + int radio_index = -1; + char *str; + char mac_string[18] = { 0 }; + int primary_macaddr_added = 0; + + wifi_util_dbg_print(WIFI_WEBCONFIG, "%s: Enter subdoc_type:%d\n", __FUNCTION__, data->type); + + params = &data->u.decoded; + json = cJSON_CreateObject(); + data->u.encoded.json = json; + + cJSON_AddStringToObject(json, "Version", "1.0"); + + switch (data->type) { + case webconfig_subdoc_type_vap_24G: + cJSON_AddStringToObject(json, "SubDocName", "Vap_2.4G"); + radio_index = 0; + break; + case webconfig_subdoc_type_vap_5G: + cJSON_AddStringToObject(json, "SubDocName", "Vap_5G"); + radio_index = 1; + break; + case webconfig_subdoc_type_vap_6G: + cJSON_AddStringToObject(json, "SubDocName", "Vap_6G"); + radio_index = 2; + break; + default: + // Invalid type, set Radio index to -1 + radio_index = -1; + break; + } + + if (radio_index < 0 || radio_index >= params->num_radios) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d radio index:%d not correct for num_radios:%d.\n", __func__, __LINE__, + radio_index, params->num_radios); + cJSON_Delete(json); + return webconfig_error_encode; + } + + wifi_util_dbg_print(WIFI_WEBCONFIG, "%s:%d Radio Index:%d\n", __func__, __LINE__, radio_index); + // Based on the data->type determine the radio pointer. + radio = ¶ms->radios[radio_index]; + map = &radio->vaps.vap_map; + + // Add the mac address of the primary vapname + for (unsigned int j = 0; j < map->num_vaps; j++) { + vap = &map->vap_array[j]; + rdk_vap = &radio->vaps.rdk_vap_array[j]; + if (is_vap_private(¶ms->hal_cap.wifi_prop, vap->vap_index) && + (strlen(vap->vap_name) != 0)) { + // Obtain the mac and add + uint8_mac_to_string_mac((uint8_t *)vap->u.bss_info.bssid, mac_string); + cJSON_AddStringToObject(json, "Primary MacAddress", mac_string); + primary_macaddr_added = 1; + break; + } + } + wifi_util_dbg_print(WIFI_WEBCONFIG, "%s:%d Primary Macaddress %s\n", __func__, __LINE__, + ((primary_macaddr_added == 0) ? "not added" : "added")); + + // encode multivap objects associated with the radio_index + obj_array = cJSON_CreateArray(); + cJSON_AddItemToObject(json, "WifiVapConfig", obj_array); + + for (unsigned int j = 0; j < map->num_vaps; j++) { + vap = &map->vap_array[j]; + rdk_vap = &radio->vaps.rdk_vap_array[j]; + if (is_vap_private(¶ms->hal_cap.wifi_prop, vap->vap_index) && + (strlen(vap->vap_name) != 0)) { + obj = cJSON_CreateObject(); + cJSON_AddItemToArray(obj_array, obj); + if (encode_private_vap_object(vap, rdk_vap, obj) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: Failed to encode private vap object for Radio index:%d\n", __func__, + __LINE__, radio_index); + cJSON_Delete(json); + return webconfig_error_encode; + } + } else if (is_vap_hotspot_open(¶ms->hal_cap.wifi_prop, vap->vap_index) && + (strlen(vap->vap_name) != 0)) { + obj = cJSON_CreateObject(); + cJSON_AddItemToArray(obj_array, obj); + if (encode_hotspot_open_vap_object(vap, rdk_vap, obj) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: Failed to encode hotspot open vap object for Radio index:%d\n", + __func__, __LINE__, radio_index); + cJSON_Delete(json); + return webconfig_error_encode; + } + } else if (is_vap_hotspot_secure(¶ms->hal_cap.wifi_prop, vap->vap_index) && + (strlen(vap->vap_name) != 0)) { + obj = cJSON_CreateObject(); + cJSON_AddItemToArray(obj_array, obj); + if (encode_hotspot_secure_vap_object(vap, rdk_vap, obj) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: Failed to encode hotspot secure vap object for Radio index:%d\n", + __func__, __LINE__, radio_index); + cJSON_Delete(json); + return webconfig_error_encode; + } + } else if (is_vap_lnf_psk(¶ms->hal_cap.wifi_prop, vap->vap_index) && + (strlen(vap->vap_name) != 0)) { + obj = cJSON_CreateObject(); + cJSON_AddItemToArray(obj_array, obj); + if (encode_lnf_psk_vap_object(vap, rdk_vap, obj) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: Failed to encode lnf_psk psk vap object for Radio index:%d\n", __func__, + __LINE__, radio_index); + cJSON_Delete(json); + return webconfig_error_encode; + } + } else if (is_vap_lnf_radius(¶ms->hal_cap.wifi_prop, vap->vap_index) && + (strlen(vap->vap_name) != 0)) { + obj = cJSON_CreateObject(); + cJSON_AddItemToArray(obj_array, obj); + if (encode_lnf_radius_vap_object(vap, rdk_vap, obj) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: Failed to encode lnf_radius vap object for Radio index:%d\n", __func__, + __LINE__, radio_index); + cJSON_Delete(json); + return webconfig_error_encode; + } + } else if (is_vap_mesh_backhaul(¶ms->hal_cap.wifi_prop, vap->vap_index) && + (strlen(vap->vap_name) != 0)) { + obj = cJSON_CreateObject(); + cJSON_AddItemToArray(obj_array, obj); + if (encode_mesh_backhaul_vap_object(vap, rdk_vap, obj) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: Failed to encode mesh backhaul vap object for Radio index:%d\n", + __func__, __LINE__, radio_index); + cJSON_Delete(json); + return webconfig_error_encode; + } + } else if (is_vap_mesh_sta(¶ms->hal_cap.wifi_prop, vap->vap_index) && + (strlen(vap->vap_name) != 0)) { + obj = cJSON_CreateObject(); + cJSON_AddItemToArray(obj_array, obj); + if (encode_mesh_sta_object(vap, rdk_vap, obj) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: Failed to encode mesh sta object for Radio index:%d\n", __func__, + __LINE__, radio_index); + cJSON_Delete(json); + return webconfig_error_encode; + } + } else if (is_vap_xhs(¶ms->hal_cap.wifi_prop, vap->vap_index) && + (strlen(vap->vap_name) != 0)) { + obj = cJSON_CreateObject(); + cJSON_AddItemToArray(obj_array, obj); + if (encode_iot_vap_object(vap, rdk_vap, obj) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: Failed to encode iot vap object for Radio index: %d\n", __func__, + __LINE__, radio_index); + cJSON_Delete(json); + return webconfig_error_encode; + } + } else { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: Unknown vap:%s unable to encode for Radio index: %d\n", __func__, __LINE__, + vap->vap_name, radio_index); + cJSON_Delete(json); + return webconfig_error_encode; + } + } + + str = cJSON_Print(json); + + data->u.encoded.raw = (webconfig_subdoc_encoded_raw_t)calloc(strlen(str) + 1, sizeof(char)); + if (data->u.encoded.raw == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d Failed to allocate memory.\n", __func__, + __LINE__); + cJSON_free(str); + cJSON_Delete(json); + return webconfig_error_encode; + } + + memcpy(data->u.encoded.raw, str, strlen(str)); + + json_param_obscure(str, "Passphrase"); + json_param_obscure(str, "RadiusSecret"); + json_param_obscure(str, "SecondaryRadiusSecret"); + json_param_obscure(str, "DasSecret"); + wifi_util_dbg_print(WIFI_WEBCONFIG, "%s:%d: Encoded JSON:\n%s\n", __func__, __LINE__, str); + cJSON_free(str); + cJSON_Delete(json); + wifi_util_info_print(WIFI_WEBCONFIG, "%s:%d: encode success\n", __func__, __LINE__); + return webconfig_error_none; +} + +webconfig_error_t decode_multivap_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data) +{ + webconfig_subdoc_t *doc; + cJSON *obj_vaps; + cJSON *obj, *obj_vap; + unsigned int size, radio_index, vap_array_index; + unsigned int presence_count = 0; + char *name; + unsigned int num_lnf_ssid; + wifi_vap_name_t vap_names[MAX_NUM_VAP_PER_RADIO]; + wifi_vap_info_t *vap_info; + rdk_wifi_vap_info_t *rdk_vap_info; + cJSON *json = data->u.encoded.json; + webconfig_subdoc_decoded_data_t *params; + unsigned int i = 0, j = 0; + char *str; + + wifi_util_dbg_print(WIFI_WEBCONFIG, "%s: Enter subdoc_type:%d\n", __FUNCTION__, data->type); + + str = cJSON_Print(json); + json_param_obscure(str, "Passphrase"); + json_param_obscure(str, "RadiusSecret"); + json_param_obscure(str, "SecondaryRadiusSecret"); + json_param_obscure(str, "DasSecret"); + wifi_util_dbg_print(WIFI_WEBCONFIG, "%s:%d: decoded JSON:\n%s\n", __func__, __LINE__, str); + cJSON_free(str); + + params = &data->u.decoded; + doc = &config->subdocs[data->type]; + + // decode VAP objects + obj_vaps = cJSON_GetObjectItem(json, "WifiVapConfig"); + if (cJSON_IsArray(obj_vaps) == false) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: vap object not present\n", __func__, + __LINE__); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_invalid_subdoc; + } + + size = cJSON_GetArraySize(obj_vaps); + if (size > MAX_NUM_VAP_PER_RADIO) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: vap objects size: %d exceeding MAX_NUM_VAP_PER_RADIO:%d\n", __func__, __LINE__, + size, MAX_NUM_VAP_PER_RADIO); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_invalid_subdoc; + } + + for (i = 0; i < size; i++) { + obj_vap = cJSON_GetArrayItem(obj_vaps, i); + // check presence of all vap names + if ((obj = cJSON_GetObjectItem(obj_vap, "VapName")) == NULL) { + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "VapName not present.\n%s\n", + (char *)data->u.encoded.raw); + return webconfig_error_invalid_subdoc; + } + } + + for (i = 0; i < params->hal_cap.wifi_prop.numRadios; i++) { + params->radios[i].vaps.vap_map.num_vaps = + params->hal_cap.wifi_prop.radiocap[i].maxNumberVAPs; + params->radios[i].vaps.num_vaps = params->hal_cap.wifi_prop.radiocap[i].maxNumberVAPs; + } + + for (i = 0; i < size; i++) { + obj_vap = cJSON_GetArrayItem(obj_vaps, i); + name = cJSON_GetStringValue(cJSON_GetObjectItem(obj_vap, "VapName")); + radio_index = convert_vap_name_to_radio_array_index(¶ms->hal_cap.wifi_prop, name); + vap_array_index = convert_vap_name_to_array_index(¶ms->hal_cap.wifi_prop, name); + if (((int)radio_index < 0) || ((int)vap_array_index < 0)) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: Invalid radio_index:%d or vap_array_index:%d\n", __func__, __LINE__, + radio_index, vap_array_index); + continue; + } + wifi_util_dbg_print(WIFI_WEBCONFIG, "%s:%d: radio index: %d , vap name: %s\n%s\n", __func__, + __LINE__, radio_index, name, cJSON_Print(obj_vap)); + vap_info = ¶ms->radios[radio_index].vaps.vap_map.vap_array[vap_array_index]; + rdk_vap_info = ¶ms->radios[radio_index].vaps.rdk_vap_array[vap_array_index]; + memset(vap_info, 0, sizeof(wifi_vap_info_t)); + if (strncmp(name, "private_ssid", strlen("private_ssid")) == 0) { + if (decode_private_vap_object(obj_vap, vap_info, rdk_vap_info, + ¶ms->hal_cap.wifi_prop) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: VAP object validation failed\n", + __func__, __LINE__); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_decode; + } + } else if (strncmp(name, "hotspot_open", strlen("hotspot_open")) == 0) { + if (decode_hotspot_open_vap_object(obj_vap, vap_info, rdk_vap_info, + ¶ms->hal_cap.wifi_prop) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: VAP object validation failed\n", + __func__, __LINE__); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_decode; + } + } else if (strncmp(name, "hotspot_secure", strlen("hotspot_secure")) == 0) { + if (decode_hotspot_secure_vap_object(obj_vap, vap_info, rdk_vap_info, + ¶ms->hal_cap.wifi_prop) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: VAP object validation failed\n", + __func__, __LINE__); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_decode; + } + } else if (strncmp(name, "lnf_psk", strlen("lnf_psk")) == 0) { + if (decode_lnf_psk_vap_object(obj_vap, vap_info, rdk_vap_info, + ¶ms->hal_cap.wifi_prop) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: VAP object validation failed\n", + __func__, __LINE__); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_decode; + } + } else if (strncmp(name, "lnf_radius", strlen("lnf_radius")) == 0) { + if (decode_lnf_radius_vap_object(obj_vap, vap_info, rdk_vap_info, + ¶ms->hal_cap.wifi_prop) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: VAP object validation failed\n", + __func__, __LINE__); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_decode; + } + } else if (strncmp(name, "iot_ssid", strlen("iot_ssid")) == 0) { + if (decode_iot_vap_object(obj_vap, vap_info, rdk_vap_info, + ¶ms->hal_cap.wifi_prop) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: VAP object validation failed\n", + __func__, __LINE__); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_decode; + } + } else if (strncmp(name, "mesh_backhaul", strlen("mesh_backhaul")) == 0) { + if (decode_mesh_backhaul_vap_object(obj_vap, vap_info, rdk_vap_info, + ¶ms->hal_cap.wifi_prop) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: VAP object validation failed\n", + __func__, __LINE__); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_decode; + } + } else if (strncmp(name, "mesh_sta", strlen("mesh_sta")) == 0) { + if (decode_mesh_sta_object(obj_vap, vap_info, rdk_vap_info, + ¶ms->hal_cap.wifi_prop) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: VAP object validation failed\n", + __func__, __LINE__); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_decode; + } + } else { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: Unknown Vap:%s unable to decode\n", + __func__, __LINE__, name); + cJSON_Delete(json); + return webconfig_error_decode; + } + } + + wifi_util_info_print(WIFI_WEBCONFIG, "%s:%d: decode success\n", __func__, __LINE__); + cJSON_Delete(json); + return webconfig_error_none; +} From 53e615029858f6d848ae5261392d1e0d211b9ddc Mon Sep 17 00:00:00 2001 From: Amarnath Hullur Subramanyam Date: Mon, 9 Dec 2024 23:03:43 -0800 Subject: [PATCH 14/22] OneWifi: New Subdocs to provide Single Radio configuration Reason for change: Easymesh agent needs single radio subdoc to apply configuration on single radio basis. This commit adds new subdocs which addresses the ask. Test Procedure: Tested encode, decode and apply of single radio config changes. --- include/wifi_webconfig.h | 11 ++ source/core/wifi_ctrl.c | 31 ++++ source/core/wifi_ctrl.h | 7 +- source/core/wifi_ctrl_webconfig.c | 229 ++++++++++++++++++++++++ source/webconfig/wifi_webconfig.c | 36 ++++ source/webconfig/wifi_webconfig_radio.c | 225 +++++++++++++++++++++++ 6 files changed, 537 insertions(+), 2 deletions(-) diff --git a/include/wifi_webconfig.h b/include/wifi_webconfig.h index 3be595e0..0109593b 100644 --- a/include/wifi_webconfig.h +++ b/include/wifi_webconfig.h @@ -131,6 +131,9 @@ typedef enum { webconfig_subdoc_type_vap_24G, webconfig_subdoc_type_vap_5G, webconfig_subdoc_type_vap_6G, + webconfig_subdoc_type_radio_24G, + webconfig_subdoc_type_radio_5G, + webconfig_subdoc_type_radio_6G, webconfig_subdoc_type_max } webconfig_subdoc_type_t; @@ -589,6 +592,14 @@ webconfig_error_t decode_multivap_subdoc(webconfig_t *config, webconfig_su webconfig_error_t encode_multivap_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); webconfig_error_t translate_to_multivap_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); webconfig_error_t translate_from_multivap_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); + +// Per Radio Config for 2.4G, 5G and 6G +webconfig_error_t init_single_radio_subdoc(webconfig_subdoc_t *doc); +webconfig_error_t access_check_single_radio_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); +webconfig_error_t decode_single_radio_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); +webconfig_error_t encode_single_radio_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); +webconfig_error_t translate_to_single_radio_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); +webconfig_error_t translate_from_single_radio_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data); #ifdef __cplusplus } #endif diff --git a/source/core/wifi_ctrl.c b/source/core/wifi_ctrl.c index f4738d37..517660e6 100644 --- a/source/core/wifi_ctrl.c +++ b/source/core/wifi_ctrl.c @@ -1695,6 +1695,37 @@ bool check_wifi_radio_sched_timeout_active_status(wifi_ctrl_t *l_ctrl) return false; } +bool check_wifi_csa_sched_timeout_active_status_of_radio_index(wifi_ctrl_t *l_ctrl, int radio_index) +{ + wifi_scheduler_id_t *sched_id = &l_ctrl->wifi_sched_id; + + if (radio_index < 0 || radio_index >= getNumberRadios()) { + // Invalid index + return false; + } + + if (sched_id->wifi_csa_sched_handler_id[radio_index] != 0) { + return true; + } + return false; +} + +bool check_wifi_radio_sched_timeout_active_status_of_radio_index(wifi_ctrl_t *l_ctrl, + int radio_index) +{ + wifi_scheduler_id_t *sched_id = &l_ctrl->wifi_sched_id; + + if (radio_index < 0 || radio_index >= getNumberRadios()) { + // Invalid index + return false; + } + + if (sched_id->wifi_radio_sched_handler_id[radio_index] != 0) { + return true; + } + return false; +} + bool check_wifi_vap_sched_timeout_active_status(wifi_ctrl_t *l_ctrl, BOOL (*cb)(UINT apIndex)) { unsigned int index = 0; diff --git a/source/core/wifi_ctrl.h b/source/core/wifi_ctrl.h index b8310744..3b958abd 100644 --- a/source/core/wifi_ctrl.h +++ b/source/core/wifi_ctrl.h @@ -150,10 +150,13 @@ typedef enum { ctrl_webconfig_state_vap_24G_cfg_rsp_pending = 0x200000, ctrl_webconfig_state_vap_5G_cfg_rsp_pending = 0x400000, ctrl_webconfig_state_vap_6G_cfg_rsp_pending = 0x800000, - ctrl_webconfig_state_max = 0x1000000 + ctrl_webconfig_state_radio_24G_rsp_pending = 0x1000000, + ctrl_webconfig_state_radio_5G_rsp_pending = 0x2000000, + ctrl_webconfig_state_radio_6G_rsp_pending = 0x4000000, + ctrl_webconfig_state_max = 0x8000000 } wifi_ctrl_webconfig_state_t; -#define CTRL_WEBCONFIG_STATE_MASK 0x1ffffff +#define CTRL_WEBCONFIG_STATE_MASK 0xfffffff typedef struct { char mac_addr[MAC_STR_LEN]; diff --git a/source/core/wifi_ctrl_webconfig.c b/source/core/wifi_ctrl_webconfig.c index f91d7942..c3e6442a 100644 --- a/source/core/wifi_ctrl_webconfig.c +++ b/source/core/wifi_ctrl_webconfig.c @@ -507,6 +507,31 @@ int webconfig_analyze_pending_states(wifi_ctrl_t *ctrl) return RETURN_OK; } break; + case ctrl_webconfig_state_radio_24G_rsp_pending: + case ctrl_webconfig_state_radio_5G_rsp_pending: + case ctrl_webconfig_state_radio_6G_rsp_pending: + int radio_index = -1; + int state = (ctrl->webconfig_state & pending_state); + if (state == ctrl_webconfig_state_radio_24G_rsp_pending) { + radio_index = 0; + type = webconfig_subdoc_type_radio_24G; + } else if (state == ctrl_webconfig_state_radio_5G_rsp_pending) { + radio_index = 1; + type = webconfig_subdoc_type_radio_5G; + } else { + radio_index = 2; + type = webconfig_subdoc_type_radio_6G; + } + if (check_wifi_radio_sched_timeout_active_status_of_radio_index(ctrl, radio_index) == + false && + check_wifi_csa_sched_timeout_active_status_of_radio_index(ctrl, radio_index) == + false) { + webconfig_send_radio_subdoc_status(ctrl, type); + } else { + return RETURN_OK; + } + break; + default: wifi_util_dbg_print(WIFI_CTRL, "%s:%d - default pending subdoc status:0x%x\r\n", __func__, __LINE__, (ctrl->webconfig_state & CTRL_WEBCONFIG_STATE_MASK)); break; @@ -1823,6 +1848,180 @@ int webconfig_hal_radio_apply(wifi_ctrl_t *ctrl, webconfig_subdoc_decoded_data_t return RETURN_OK; } +int webconfig_hal_single_radio_apply(wifi_ctrl_t *ctrl, webconfig_subdoc_decoded_data_t *data, + webconfig_subdoc_type_t doc_type) +{ + unsigned int j; + rdk_wifi_radio_t *radio_data, *mgr_radio_data; + wifi_mgr_t *mgr = get_wifimgr_obj(); + bool found_radio_index = false; + int ret; + int is_changed = 0; + bool is_radio_6g_modified = false; + vap_svc_t *pub_svc = NULL; +#if defined(FEATURE_SUPPORT_ECOPOWERDOWN) + bool old_ecomode = false; + bool new_ecomode = false; +#endif + int radio_index = -1; + + switch (doc_type) { + case webconfig_subdoc_type_radio_24G: + radio_index = 0; + break; + case webconfig_subdoc_type_radio_5G: + radio_index = 1; + break; + case webconfig_subdoc_type_radio_6G: + radio_index = 2; + break; + default: + // Invalid doc_type return err + wifi_util_error_print(WIFI_MGR, "%s:%d Invalid doc_type:%d\n", __func__, __LINE__, + doc_type); + return RETURN_ERR; + } + + wifi_util_dbg_print(WIFI_MGR, "%s:%d Selected Radio Index:%d for doc_type:%d\n", __func__, + __LINE__, radio_index, doc_type); + + // apply the radio and vap data + radio_data = &data->radios[radio_index]; + + for (j = 0; j < getNumberRadios(); j++) { + mgr_radio_data = &mgr->radio_config[j]; + if (mgr_radio_data->vaps.radio_index == radio_data->vaps.radio_index) { + found_radio_index = true; + break; + } + } + + if (found_radio_index == false) { + wifi_util_error_print(WIFI_MGR, "%s:%d Radio with index:%d for doc_type:%d not found\n", + __func__, __LINE__, radio_index, doc_type); + return RETURN_ERR; + } + + if (is_radio_band_5G(radio_data->oper.band) && + is_radio_feat_config_changed(mgr_radio_data, radio_data)) { + // Not required currently for 2.4GHz, can be added later for 5GH and 6G after support is + // added + is_changed = 1; + wifi_util_dbg_print(WIFI_MGR, "%s:%d Tscan:%lu, Nscan:%lu, Tidle:%lu \n", __func__, + __LINE__, radio_data->feature.OffChanTscanInMsec, radio_data->feature.OffChanNscanInSec, + radio_data->feature.OffChanTidleInSec); + } + + if ((is_radio_param_config_changed(&mgr_radio_data->oper, &radio_data->oper) == true)) { + // radio data changed apply + is_changed = 1; + if (IS_CHANGED(mgr_radio_data->oper.enable, radio_data->oper.enable) && + is_6g_supported_device(&mgr->hal_cap.wifi_prop)) { + wifi_util_info_print(WIFI_MGR, + "Radio enable field is modified from mgr_radio_data->oper->enable=%d and " + "radio_data->oper->enable=%d\n", + mgr_radio_data->oper.enable, radio_data->oper.enable); + is_radio_6g_modified = true; + } + wifi_util_info_print(WIFI_MGR, + "%s:%d: Change detected in received radio config, applying new configuration for " + "radio: %s\n", + __func__, __LINE__, radio_data->name); + radio_param_config_changed_event_logging(&mgr_radio_data->oper, &radio_data->oper, + radio_data->name); + print_wifi_hal_radio_data(WIFI_WEBCONFIG, "old", radio_index, &mgr_radio_data->oper); + print_wifi_hal_radio_data(WIFI_WEBCONFIG, "New", radio_index, &radio_data->oper); + + // Optimizer will try to change, channel on current STA along with parent change, So it + // shouldn't skip for pods. + if (ctrl->network_mode == rdk_dev_mode_type_ext) { + vap_svc_t *ext_svc; + ext_svc = get_svc_by_type(ctrl, vap_svc_type_mesh_ext); + if (ext_svc != NULL) { + vap_svc_ext_t *ext; + ext = &ext_svc->u.ext; + unsigned int connected_radio_index = 0; + connected_radio_index = get_radio_index_for_vap_index(ext_svc->prop, + ext->connected_vap_index); + if ((ext->conn_state == connection_state_connected) && + (connected_radio_index == mgr_radio_data->vaps.radio_index) && + (mgr_radio_data->oper.channel != radio_data->oper.channel)) { + start_wifi_sched_timer(mgr_radio_data->vaps.radio_index, ctrl, wifi_csa_sched); + ext_svc->event_fn(ext_svc, wifi_event_type_webconfig, + wifi_event_webconfig_set_data, vap_svc_event_none, &radio_data->oper); + // driver does not change channel in STA connected state therefore skip + // wifi_hal_setRadioOperatingParameters and update channel on disconnection/CSA + return RETURN_OK; + } + } + } +#if defined(FEATURE_SUPPORT_ECOPOWERDOWN) + // Save the ECO mode state before update to the DB + old_ecomode = mgr_radio_data->oper.EcoPowerDown; + new_ecomode = radio_data->oper.EcoPowerDown; + if (old_ecomode != new_ecomode) { + radio_data->oper.enable = ((new_ecomode) ? false : true); + wifi_util_info_print(WIFI_MGR, + "%s:%d:Changing radio enable status:radio_data->oper.enable= %d\n", __func__, + __LINE__, radio_data->oper.enable); + } +#endif // defined (FEATURE_SUPPORT_ECOPOWERDOWN) + wifi_util_dbg_print(WIFI_WEBCONFIG, "[%s]:WIFI RFC OW CORE THREAD DISABLED \r\n", + __FUNCTION__); + + if (wifi_radio_operationParam_validation(&mgr->hal_cap, &radio_data->oper) != RETURN_OK) { + wifi_util_error_print(WIFI_MGR, "%s:%d: failed to validate %s parameters\n", __func__, + __LINE__, radio_data->name); + return RETURN_ERR; + } + + ret = wifi_hal_setRadioOperatingParameters(mgr_radio_data->vaps.radio_index, + &radio_data->oper); + + if (ret != RETURN_OK) { + wifi_util_error_print(WIFI_MGR, "%s:%d: failed to apply\n", __func__, __LINE__); + return RETURN_ERR; + } + wifi_util_dbg_print(WIFI_MGR, "%s:%d: config applied.\n", __func__, __LINE__); + + start_wifi_sched_timer(mgr_radio_data->vaps.radio_index, ctrl, wifi_radio_sched); + + if (is_csa_sched_timer_trigger(mgr_radio_data->oper, radio_data->oper) == true) { + start_wifi_sched_timer(mgr_radio_data->vaps.radio_index, ctrl, wifi_csa_sched); + } + } + + if (is_changed) { + // write the value to database +#ifndef LINUX_VM_PORT + wifidb_update_wifi_radio_config(mgr_radio_data->vaps.radio_index, &radio_data->oper, + &radio_data->feature); +#endif + +#if defined(FEATURE_SUPPORT_ECOPOWERDOWN) + // Upload the telemetry marker and reboot the device + // only if there is a change in the DM Device.WiFi.Radio.{i}.X_RDK_EcoPowerDown + wifi_util_info_print(WIFI_MGR, "%s:%d: oldEco = %d newEco = %d\n", __func__, __LINE__, + old_ecomode, new_ecomode); + if (old_ecomode != new_ecomode) { + // write the value to database and reboot + ecomode_telemetry_update_and_reboot(i, new_ecomode); + } +#endif // defined (FEATURE_SUPPORT_ECOPOWERDOWN) + if (is_radio_6g_modified) { + pub_svc = get_svc_by_type(ctrl, vap_svc_type_public); + if (pub_svc->event_fn != NULL) { + pub_svc->event_fn(pub_svc, wifi_event_type_command, wifi_event_type_xfinity_rrm, + vap_svc_event_none, NULL); + } + } + } else { + wifi_util_info_print(WIFI_MGR, + "%s:%d: Received radio config for radio %u is same, not applying\n", __func__, __LINE__, + mgr_radio_data->vaps.radio_index); + } + return RETURN_OK; +} int push_data_to_apply_pending_queue(webconfig_subdoc_data_t *data) { @@ -2281,6 +2480,36 @@ webconfig_error_t webconfig_ctrl_apply(webconfig_subdoc_t *doc, webconfig_subdoc captive_portal_check(); break; + case webconfig_subdoc_type_radio_24G: + case webconfig_subdoc_type_radio_5G: + case webconfig_subdoc_type_radio_6G: + wifi_ctrl_webconfig_state_t radio_state_pending; + if (doc->type == webconfig_subdoc_type_radio_24G) { + radio_state_pending = ctrl_webconfig_state_radio_24G_rsp_pending; + } else if (doc->type == webconfig_subdoc_type_radio_5G) { + radio_state_pending = ctrl_webconfig_state_radio_5G_rsp_pending; + } else { + radio_state_pending = ctrl_webconfig_state_radio_6G_rsp_pending; + } + if (data->descriptor & webconfig_data_descriptor_encoded) { + if (ctrl->webconfig_state & radio_state_pending) { + ctrl->webconfig_state &= ~radio_state_pending; + ret = webconfig_bus_apply(ctrl, &data->u.encoded); + } + } else { + if (check_wifi_csa_sched_timeout_active_status(ctrl) == true) { + if (push_data_to_apply_pending_queue(data) != RETURN_OK) { + return webconfig_error_apply; + } + } else { + ctrl->webconfig_state |= radio_state_pending; + webconfig_analytic_event_data_to_hal_apply(data); + ret = webconfig_hal_single_radio_apply(ctrl, &data->u.decoded, doc->type); + + } + } + break; + default: break; } diff --git a/source/webconfig/wifi_webconfig.c b/source/webconfig/wifi_webconfig.c index 8b1af043..c609ca25 100644 --- a/source/webconfig/wifi_webconfig.c +++ b/source/webconfig/wifi_webconfig.c @@ -658,6 +658,42 @@ webconfig_error_t webconfig_init(webconfig_t *config) config->subdocs[webconfig_subdoc_type_vap_6G].translate_to_subdoc = translate_to_multivap_subdoc; config->subdocs[webconfig_subdoc_type_vap_6G].translate_from_subdoc = translate_from_multivap_subdoc; + config->subdocs[webconfig_subdoc_type_radio_24G].type = webconfig_subdoc_type_radio_24G; + strcpy(config->subdocs[webconfig_subdoc_type_radio_24G].name, "radio_2.4G"); + config->subdocs[webconfig_subdoc_type_radio_24G].major = 1; + config->subdocs[webconfig_subdoc_type_radio_24G].minor = 1; + config->subdocs[webconfig_subdoc_type_radio_24G].init_subdoc = init_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_24G].init_subdoc(&config->subdocs[webconfig_subdoc_type_radio_24G]); + config->subdocs[webconfig_subdoc_type_radio_24G].access_check_subdoc = access_check_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_24G].encode_subdoc = encode_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_24G].decode_subdoc = decode_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_24G].translate_to_subdoc = translate_to_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_24G].translate_from_subdoc = translate_from_single_radio_subdoc; + + config->subdocs[webconfig_subdoc_type_radio_5G].type = webconfig_subdoc_type_radio_5G; + strcpy(config->subdocs[webconfig_subdoc_type_radio_5G].name, "radio_5G"); + config->subdocs[webconfig_subdoc_type_radio_5G].major = 1; + config->subdocs[webconfig_subdoc_type_radio_5G].minor = 1; + config->subdocs[webconfig_subdoc_type_radio_5G].init_subdoc = init_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_5G].init_subdoc(&config->subdocs[webconfig_subdoc_type_radio_5G]); + config->subdocs[webconfig_subdoc_type_radio_5G].access_check_subdoc = access_check_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_5G].encode_subdoc = encode_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_5G].decode_subdoc = decode_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_5G].translate_to_subdoc = translate_to_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_5G].translate_from_subdoc = translate_from_single_radio_subdoc; + + config->subdocs[webconfig_subdoc_type_radio_6G].type = webconfig_subdoc_type_radio_6G; + strcpy(config->subdocs[webconfig_subdoc_type_radio_6G].name, "radio_5G"); + config->subdocs[webconfig_subdoc_type_radio_6G].major = 1; + config->subdocs[webconfig_subdoc_type_radio_6G].minor = 1; + config->subdocs[webconfig_subdoc_type_radio_6G].init_subdoc = init_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_6G].init_subdoc(&config->subdocs[webconfig_subdoc_type_radio_6G]); + config->subdocs[webconfig_subdoc_type_radio_6G].access_check_subdoc = access_check_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_6G].encode_subdoc = encode_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_6G].decode_subdoc = decode_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_6G].translate_to_subdoc = translate_to_single_radio_subdoc; + config->subdocs[webconfig_subdoc_type_radio_6G].translate_from_subdoc = translate_from_single_radio_subdoc; + config->proto_desc.translate_to = translate_to_proto; config->proto_desc.translate_from = translate_from_proto; diff --git a/source/webconfig/wifi_webconfig_radio.c b/source/webconfig/wifi_webconfig_radio.c index 69d04397..4ca926d8 100644 --- a/source/webconfig/wifi_webconfig_radio.c +++ b/source/webconfig/wifi_webconfig_radio.c @@ -28,6 +28,9 @@ #include "wifi_util.h" #include "wifi_ctrl.h" +extern webconfig_error_t encode_radio_object(const rdk_wifi_radio_t *radio, cJSON *radio_object); +extern webconfig_error_t decode_radio_object(const cJSON *obj_radio, rdk_wifi_radio_t *radio); + webconfig_subdoc_object_t radio_objects[3] = { { webconfig_subdoc_object_type_version, "Version" }, { webconfig_subdoc_object_type_subdoc, "SubDocName" }, @@ -225,3 +228,225 @@ webconfig_error_t decode_radio_subdoc(webconfig_t *config, webconfig_subdoc_data cJSON_Delete(json); return webconfig_error_none; } + +webconfig_error_t init_single_radio_subdoc(webconfig_subdoc_t *doc) +{ + doc->num_objects = sizeof(radio_objects) / sizeof(webconfig_subdoc_object_t); + memcpy((unsigned char *)doc->objects, (unsigned char *)&radio_objects, sizeof(radio_objects)); + return webconfig_error_none; +} + +webconfig_error_t access_check_single_radio_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data) +{ + return webconfig_error_none; +} + +webconfig_error_t translate_from_single_radio_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data) +{ + if (((data->descriptor & webconfig_data_descriptor_translate_to_ovsdb) == + webconfig_data_descriptor_translate_to_ovsdb) || + ((data->descriptor & webconfig_data_descriptor_translate_to_easymesh) == + webconfig_data_descriptor_translate_to_easymesh)) { + if (config->proto_desc.translate_to(data->type, data) != + webconfig_error_none) { + if ((data->descriptor & webconfig_data_descriptor_translate_to_ovsdb) == + webconfig_data_descriptor_translate_to_ovsdb) { + return webconfig_error_translate_to_ovsdb; + } else { + return webconfig_error_translate_to_easymesh; + } + } + } else if ((data->descriptor & webconfig_data_descriptor_translate_to_tr181) == + webconfig_data_descriptor_translate_to_tr181) { + + } else { + // no translation required + } + return webconfig_error_none; +} + +webconfig_error_t translate_to_single_radio_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data) +{ + if (((data->descriptor & webconfig_data_descriptor_translate_from_ovsdb) == + webconfig_data_descriptor_translate_from_ovsdb) || + ((data->descriptor & webconfig_data_descriptor_translate_from_easymesh) == + webconfig_data_descriptor_translate_from_easymesh)) { + if (config->proto_desc.translate_from(data->type, data) != + webconfig_error_none) { + if ((data->descriptor & webconfig_data_descriptor_translate_from_ovsdb) == + webconfig_data_descriptor_translate_from_ovsdb) { + return webconfig_error_translate_from_ovsdb; + } else { + return webconfig_error_translate_from_easymesh; + } + } + } else if ((data->descriptor & webconfig_data_descriptor_translate_from_tr181) == + webconfig_data_descriptor_translate_from_tr181) { + } else { + // no translation required + } + return webconfig_error_none; +} + +webconfig_error_t encode_single_radio_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data) +{ + cJSON *json; + cJSON *obj, *obj_array; + rdk_wifi_radio_t *radio; + webconfig_subdoc_decoded_data_t *params; + char *str; + int radio_index = -1; + + params = &data->u.decoded; + json = cJSON_CreateObject(); + data->u.encoded.json = json; + + cJSON_AddStringToObject(json, "Version", "1.0"); + + switch (data->type) { + case webconfig_subdoc_type_radio_24G: + cJSON_AddStringToObject(json, "SubDocName", "radio_2.4G"); + radio_index = 0; + break; + case webconfig_subdoc_type_radio_5G: + cJSON_AddStringToObject(json, "SubDocName", "radio_5G"); + radio_index = 1; + break; + case webconfig_subdoc_type_radio_6G: + cJSON_AddStringToObject(json, "SubDocName", "radio_6G"); + radio_index = 2; + break; + default: + // Invalid type, set Radio index to -1 + radio_index = -1; + break; + } + + if (radio_index < 0 || radio_index >= MAX_NUM_RADIOS) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d radio index:%d not correct.\n", __func__, + __LINE__, radio_index); + cJSON_Delete(json); + return webconfig_error_encode; + } + + wifi_util_dbg_print(WIFI_WEBCONFIG, "%s:%d Radio Index:%d\n", __func__, __LINE__, radio_index); + + // encode a single radio object + obj_array = cJSON_CreateArray(); + cJSON_AddItemToObject(json, "WifiRadioConfig", obj_array); + + radio = ¶ms->radios[radio_index]; + obj = cJSON_CreateObject(); + cJSON_AddItemToArray(obj_array, obj); + + if (encode_radio_object(radio, obj) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: Failed to encode radio object\n", __func__, + __LINE__); + cJSON_Delete(json); + return webconfig_error_encode; + } + + str = cJSON_Print(json); + + data->u.encoded.raw = (webconfig_subdoc_encoded_raw_t)calloc(strlen(str) + 1, sizeof(char)); + if (data->u.encoded.raw == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d Failed to allocate memory.\n", __func__, + __LINE__); + cJSON_free(str); + cJSON_Delete(json); + return webconfig_error_encode; + } + + memcpy(data->u.encoded.raw, str, strlen(str)); + cJSON_free(str); + cJSON_Delete(json); + wifi_util_info_print(WIFI_WEBCONFIG, "%s:%d: encode success\n", __func__, __LINE__); + return webconfig_error_none; +} + +webconfig_error_t decode_single_radio_subdoc(webconfig_t *config, webconfig_subdoc_data_t *data) +{ + webconfig_subdoc_t *doc; + cJSON *obj_radios; + cJSON *obj, *obj_radio; + unsigned int i, size, radio_index = 0; + cJSON *json = data->u.encoded.json; + webconfig_subdoc_decoded_data_t *params; + + params = &data->u.decoded; + doc = &config->subdocs[data->type]; + + wifi_util_dbg_print(WIFI_WEBCONFIG, "%s:%d: Encoded JSON:\n%s\n", __func__, __LINE__, + data->u.encoded.raw); + + for (i = 0; i < doc->num_objects; i++) { + if ((cJSON_GetObjectItem(json, doc->objects[i].name)) == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: object:%s not present, validation failed\n", __func__, __LINE__, + doc->objects[i].name); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_invalid_subdoc; + } + } + + // decode radio objects + obj_radios = cJSON_GetObjectItem(json, "WifiRadioConfig"); + if (cJSON_IsArray(obj_radios) == false) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: Radio object not present\n", __func__, + __LINE__); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_invalid_subdoc; + } + + size = cJSON_GetArraySize(obj_radios); + if (size != 1) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: Not correct number of radio objects: %d\n", + __func__, __LINE__, size); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_invalid_subdoc; + } + + obj_radio = cJSON_GetArrayItem(obj_radios, 0); + // check presence of the radio name + if ((obj = cJSON_GetObjectItem(obj_radio, "RadioName")) == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: Radio name not present, exiting\n", __func__, + __LINE__); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_invalid_subdoc; + } + + if (convert_radio_name_to_index(&radio_index, cJSON_GetStringValue(obj)) != 0) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: Radio index not found, exiting\n", __func__, + __LINE__); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_invalid_subdoc; + } + + if (radio_index >= MAX_NUM_RADIOS) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: Radio index:%u exceeds MAX:%u\n", __func__, + __LINE__, radio_index, MAX_NUM_RADIOS); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_invalid_subdoc; + } + + wifi_util_dbg_print(WIFI_WEBCONFIG, "%s:%d: Decoding Radio at Radio index:%u\n", __func__, __LINE__, + radio_index); + + if (decode_radio_object(obj_radio, ¶ms->radios[radio_index]) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: Radio object validation failed\n", __func__, + __LINE__); + cJSON_Delete(json); + wifi_util_error_print(WIFI_WEBCONFIG, "%s\n", (char *)data->u.encoded.raw); + return webconfig_error_decode; + } + + wifi_util_info_print(WIFI_WEBCONFIG, "%s:%d: decode success\n", __func__, __LINE__); + cJSON_Delete(json); + return webconfig_error_none; +} From c728bd5452cbeeb57713371e5d781d5d21b227c5 Mon Sep 17 00:00:00 2001 From: Sanjay Venkatesan Date: Fri, 6 Dec 2024 14:00:57 +0000 Subject: [PATCH 15/22] RDKB-58055: wifiSM log improvement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Impacted Platforms: All RDKB platforms. Reason for change: SM App Neighbor logs enhancement. Test Procedure: 1. Boot up the TCH XB8 with above mentioned build 2. Enable the Onewifi SM feature & also enable the SM debug using the following command • dmcli eRT setv Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SM_APP.Disable bool false • Touch /nvram/wifiSM 3. Check for the Neighbor logs in /tmp/wifiSM. Risks: Low Priority: P2 Change-Id: I7e40af6cf054ecb359e92167b9b7e2717bf25229 Signed-off-by:Sanjay_Venkatesan@comcast.com --- source/apps/sm/sm_neighbor_cache.c | 11 ++++++----- source/apps/sm/wifi_sm.c | 16 +++++++++++----- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/source/apps/sm/sm_neighbor_cache.c b/source/apps/sm/sm_neighbor_cache.c index cf31e836..a6bfa235 100644 --- a/source/apps/sm/sm_neighbor_cache.c +++ b/source/apps/sm/sm_neighbor_cache.c @@ -121,8 +121,8 @@ static sm_neighbor_t* neighbor_get_or_alloc(sm_neighbor_cache_t *cache, sm_neigh return neighbor; } - -static int neighbor_convert_hal_to_sample(unsigned int radio_index, wifi_neighbor_ap2_t *hal, dpp_neighbor_record_list_t *result) +static int neighbor_convert_hal_to_sample(unsigned int radio_index, wifi_neighbor_ap2_t *hal, + dpp_neighbor_record_list_t *result, survey_type_t survey_type) { CHECK_NULL(hal); CHECK_NULL(result); @@ -137,12 +137,13 @@ static int neighbor_convert_hal_to_sample(unsigned int radio_index, wifi_neighbo entry->lastseen = time(NULL); /* TODO: get the time of the scan ? */ entry->chanwidth = str_to_dpp_chan_width(hal->ap_OperatingChannelBandwidth); - wifi_util_dbg_print(WIFI_SM, "%s:%d: Fetched neighbor sample on %s channel %u SSID %s\n", __func__, __LINE__, radio_index_to_radio_type_str(radio_index), hal->ap_Channel, hal->ap_SSID); + wifi_util_dbg_print(WIFI_SM, "%s:%d: Fetched neighbor %s sample on %s channel %u SSID %s\n", + __func__, __LINE__, survey_type_to_str(survey_type), + radio_index_to_radio_type_str(radio_index), hal->ap_Channel, hal->ap_SSID); return RETURN_OK; } - static int neighbor_sample_add(sm_neighbor_cache_t *cache, survey_type_t survey_type, unsigned int radio_index, wifi_neighbor_ap2_t *stats) { @@ -178,7 +179,7 @@ static int neighbor_sample_add(sm_neighbor_cache_t *cache, survey_type_t survey_ goto exit_err; } - rc = neighbor_convert_hal_to_sample(radio_index, stats, sample); + rc = neighbor_convert_hal_to_sample(radio_index, stats, sample, survey_type); if (rc != RETURN_OK) { wifi_util_error_print(WIFI_SM, "%s:%d: failed to convert hal to sample\n", __func__, __LINE__); goto exit_err; diff --git a/source/apps/sm/wifi_sm.c b/source/apps/sm/wifi_sm.c index 02afa0d5..b55bcd14 100644 --- a/source/apps/sm/wifi_sm.c +++ b/source/apps/sm/wifi_sm.c @@ -99,11 +99,17 @@ int neighbor_response(wifi_provider_response_t *provider_response) neighbor_ap = (wifi_neighbor_ap2_t *)provider_response->stat_pointer; - wifi_util_dbg_print(WIFI_SM,"%s:%d: radio_index : %d stats_array_size : %d\r\n",__func__, __LINE__, radio_index, provider_response->stat_array_size); - - for (count = 0; count < provider_response->stat_array_size; count++) { - wifi_util_dbg_print(WIFI_SM,"%s:%d: count : %d ap_SSID : %s\r\n",__func__, __LINE__, count, neighbor_ap[count].ap_SSID); - sm_neighbor_sample_store(radio_index, survey_type, &neighbor_ap[count]); + wifi_util_dbg_print(WIFI_SM, "%s:%d: radio_index : %d stats_array_size : %d\r\n", __func__, + __LINE__, radio_index, provider_response->stat_array_size); + if (provider_response->stat_array_size == 0) { + wifi_util_dbg_print(WIFI_SM, "%s:%d: No neighbor APs found in %s on %s\r\n", __func__, + __LINE__, survey_type_to_str(survey_type), radio_index_to_radio_type_str(radio_index)); + } else { + for (count = 0; count < provider_response->stat_array_size; count++) { + wifi_util_dbg_print(WIFI_SM, "%s:%d: count : %d ap_SSID : %s\r\n", __func__, __LINE__, + count, neighbor_ap[count].ap_SSID); + sm_neighbor_sample_store(radio_index, survey_type, &neighbor_ap[count]); + } } return RETURN_OK; } From ccd899d07128f526c75071c2b6c9b868cec2370c Mon Sep 17 00:00:00 2001 From: Viviane Cordeiro Date: Tue, 10 Dec 2024 16:51:31 +0000 Subject: [PATCH 16/22] RDKB-58137: can errors console spam Reason for change: SM sends dwell time zero for onchannel survey. Change dwell time to 20ms if requested dwell time is zero. Test Procedure: Enable Onewifi SM and check for error message is not present. "wlc_scan_on_dfs_chan: WLC_SCAN ignored due to less dwell time 10sec" Risks: Low Priority: P2 Change-Id: I6ac17ce4ca9b12b620b5dafb8cb8734caf500cbc Signed-off-by: Viviane Cordeiro --- source/stats/wifi_stats_radio_channel.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/stats/wifi_stats_radio_channel.c b/source/stats/wifi_stats_radio_channel.c index 2030e28c..c7724a6f 100644 --- a/source/stats/wifi_stats_radio_channel.c +++ b/source/stats/wifi_stats_radio_channel.c @@ -878,7 +878,7 @@ int execute_radio_channel_api(wifi_mon_collector_element_t *c_elem, wifi_monitor } else { dwell_time = args->dwell_time; if (dwell_time == 0) { - dwell_time = 10; + dwell_time = 20; } if (args->scan_mode == WIFI_RADIO_SCAN_MODE_ONCHAN) { // make sure dwell time is less than 20ms if DFS channel @@ -887,9 +887,7 @@ int execute_radio_channel_api(wifi_mon_collector_element_t *c_elem, wifi_monitor radioOperation->band == WIFI_FREQUENCY_5_BAND) { if (is_5g_20M_channel_in_dfs(radioOperation->channel) || radioOperation->channelWidth == WIFI_CHANNELBANDWIDTH_160MHZ) { - if (dwell_time > 20) { - dwell_time = 20; - } + dwell_time = 20; } } } From 10e0ec8d719c9c0b4fbd3e8218ae64c03f6576ae Mon Sep 17 00:00:00 2001 From: abhijithtk17 <142573242+abhijithtk17@users.noreply.github.com> Date: Fri, 13 Dec 2024 17:59:01 +0530 Subject: [PATCH 17/22] Implement translation for configuration per Radio --- include/webconfig_external_proto_easymesh.h | 4 +- source/webconfig/wifi_easymesh_translator.c | 536 ++++++++++++++------ 2 files changed, 392 insertions(+), 148 deletions(-) diff --git a/include/webconfig_external_proto_easymesh.h b/include/webconfig_external_proto_easymesh.h index fdbdd83f..0ce3ac73 100644 --- a/include/webconfig_external_proto_easymesh.h +++ b/include/webconfig_external_proto_easymesh.h @@ -43,6 +43,7 @@ typedef em_sta_info_t * (*ext_proto_get_first_sta_info_t)(void *data_model, em_t typedef em_sta_info_t * (*ext_proto_get_next_sta_info_t)(void *data_model, em_sta_info_t *sta_info, em_target_sta_map_t target); typedef em_sta_info_t * (*ext_proto_get_sta_info_t)(void *data_model, mac_address_t sta, bssid_t bssid, mac_address_t ruid, em_target_sta_map_t target); typedef void (*ext_proto_put_sta_info_t)(void *data_model, em_sta_info_t *sta_info, em_target_sta_map_t target); +typedef em_bss_info_t * (*ext_proto_em_get_bss_info_with_mac_t)(void *data_model, mac_address_t mac); typedef struct { void *data_model; /* agent data model dm_easy_mesh_t */ @@ -65,6 +66,7 @@ typedef struct { ext_proto_get_next_sta_info_t get_next_sta_info; ext_proto_get_sta_info_t get_sta_info; ext_proto_put_sta_info_t put_sta_info; + ext_proto_em_get_bss_info_with_mac_t get_bss_info_with_mac; } webconfig_external_easymesh_t; void webconfig_proto_easymesh_init(webconfig_external_easymesh_t *proto, void *data_model, void *m2ctrl_vapconfig, @@ -75,7 +77,7 @@ void webconfig_proto_easymesh_init(webconfig_external_easymesh_t *proto, void *d ext_proto_em_get_radio_info_t get_radio, ext_proto_em_get_ieee_1905_security_info_t get_sec, ext_proto_em_get_bss_info_t get_bss, ext_proto_em_get_op_class_info_t get_op_class, ext_proto_get_first_sta_info_t get_first_sta, ext_proto_get_next_sta_info_t get_next_sta, - ext_proto_get_sta_info_t get_sta, ext_proto_put_sta_info_t put_sta); + ext_proto_get_sta_info_t get_sta, ext_proto_put_sta_info_t put_sta, ext_proto_em_get_bss_info_with_mac_t get_bss_info_with_mac); #ifdef __cplusplus } diff --git a/source/webconfig/wifi_easymesh_translator.c b/source/webconfig/wifi_easymesh_translator.c index a88ed8d5..c8cde90b 100644 --- a/source/webconfig/wifi_easymesh_translator.c +++ b/source/webconfig/wifi_easymesh_translator.c @@ -294,7 +294,7 @@ webconfig_error_t translate_radio_object_to_easymesh_for_radio(webconfig_subdoc_ { em_radio_info_t *em_radio_info; em_op_class_info_t *em_op_class_info; - unsigned int radio_index = 0, bss_count = 0; + unsigned int radio_index = 0, bss_count = 0, per_radio_subdoc = 0, freq_band = 0, radio_count = 0; rdk_wifi_radio_t *radio; wifi_vap_info_t *vap; wifi_vap_info_map_t *vap_map; @@ -302,7 +302,7 @@ webconfig_error_t translate_radio_object_to_easymesh_for_radio(webconfig_subdoc_ webconfig_external_easymesh_t *proto; wifi_radio_operationParam_t *oper_param; webconfig_subdoc_decoded_data_t *decoded_params; - unsigned int no_of_opclass = 0, i = 0, j = 0; + unsigned int no_of_opclass = 0, i = 0, j = 0, index = 0; decoded_params = &data->u.decoded; if (decoded_params == NULL) { @@ -326,13 +326,26 @@ webconfig_error_t translate_radio_object_to_easymesh_for_radio(webconfig_subdoc_ __func__, __LINE__, decoded_params->num_radios); return webconfig_error_translate_to_easymesh; } + + if (data->type == webconfig_subdoc_type_radio_24G) { + freq_band = WIFI_FREQUENCY_2_4_BAND; + per_radio_subdoc++; + } else if (data->type == webconfig_subdoc_type_radio_5G) { + freq_band = WIFI_FREQUENCY_5_BAND; + per_radio_subdoc++; + } else if (data->type == webconfig_subdoc_type_radio_6G) { + freq_band = WIFI_FREQUENCY_6_BAND; + per_radio_subdoc++; + } + wifi_platform_property_t *wifi_prop = &data->u.decoded.hal_cap.wifi_prop; - proto->set_num_radio(proto->data_model, decoded_params->num_radios); for (unsigned int index = 0; index < decoded_params->num_radios; index++) { - em_radio_info = proto->get_radio_info(proto->data_model, index); + em_radio_info = proto->get_radio_info(proto->data_model, radio_count); radio = &decoded_params->radios[index]; - em_op_class_info = proto->get_op_class_info(proto->data_model, index); oper_param = &decoded_params->radios[index].oper; + if ((per_radio_subdoc > 0) && (oper_param->band != freq_band)) { + continue; + } radio_index = convert_radio_name_to_radio_index(decoded_params->radios[index].name); em_radio_info->enabled = oper_param->enable; radio_iface_map = NULL; @@ -349,65 +362,33 @@ webconfig_error_t translate_radio_object_to_easymesh_for_radio(webconfig_subdoc_ strncpy(em_radio_info->id.name, radio->name, sizeof(em_interface_name_t)); mac_address_from_name(radio_iface_map->interface_name, em_radio_info->id.mac); no_of_opclass = proto->get_num_op_class(proto->data_model); + radio_count ++; for (i = 0; i < oper_param->numOperatingClasses; i++) { - for (j = 0; j < no_of_opclass; j++) { - em_op_class_info = proto->get_op_class_info(proto->data_model, j); - //op class already exist so updating - if ((memcmp(em_radio_info->id.mac, em_op_class_info->id.ruid, sizeof(mac_address_t)) == 0) && - (oper_param->operatingClasses[i].opClass == em_op_class_info->op_class) && - ( em_op_class_info->id.type) == em_op_class_type_capability ) { - em_op_class_info->op_class = oper_param->operatingClasses[i].opClass; - em_op_class_info->id.op_class = oper_param->operatingClasses[i].opClass; - em_op_class_info->max_tx_power = oper_param->operatingClasses[i].maxTxPower; - em_op_class_info->num_channels = oper_param->operatingClasses[i].numberOfNonOperChan; - for(int k = 0; k < oper_param->operatingClasses[i].numberOfNonOperChan; k++) { - em_op_class_info->channels[k] = oper_param->operatingClasses[i].nonOperable[k]; - } - break; - } - } - //Add new entry - if (j == no_of_opclass) { - em_op_class_info = proto->get_op_class_info(proto->data_model, j); - mac_address_from_name(radio_iface_map->interface_name,em_op_class_info->id.ruid); - em_op_class_info->id.type = em_op_class_type_capability; - em_op_class_info->id.op_class = oper_param->operatingClasses[i].opClass; - em_op_class_info->op_class = oper_param->operatingClasses[i].opClass; - em_op_class_info->max_tx_power = oper_param->operatingClasses[i].maxTxPower; - em_op_class_info->num_channels = oper_param->operatingClasses[i].numberOfNonOperChan; - for(int k = 0; k < oper_param->operatingClasses[j].numberOfNonOperChan; k++) { - em_op_class_info->channels[k] = oper_param->operatingClasses[i].nonOperable[k]; - } - no_of_opclass++; - proto->set_num_op_class(proto->data_model, no_of_opclass); - } - } - - //Update current operating class - for (j = 0; j < no_of_opclass; j++) { - em_op_class_info = proto->get_op_class_info(proto->data_model, j); - if ((memcmp(em_radio_info->id.mac, em_op_class_info->id.ruid, sizeof(mac_address_t)) == 0) && - (oper_param->operatingClass == em_op_class_info->op_class) && - (em_op_class_info->id.type == em_op_class_type_current )) { - em_op_class_info->op_class = oper_param->operatingClass; - em_op_class_info->id.op_class = oper_param->operatingClass; - em_op_class_info->channel = oper_param->channel; - break; - } - } - //New op class - if (j == no_of_opclass) { - em_op_class_info = proto->get_op_class_info(proto->data_model, j); + em_op_class_info = proto->get_op_class_info(proto->data_model, no_of_opclass); mac_address_from_name(radio_iface_map->interface_name,em_op_class_info->id.ruid); - em_op_class_info->id.type = em_op_class_type_current; - em_op_class_info->id.op_class = oper_param->operatingClass; - em_op_class_info->op_class = oper_param->operatingClass; - em_op_class_info->channel = oper_param->channel; + em_op_class_info->id.type = em_op_class_type_capability; + em_op_class_info->id.op_class = oper_param->operatingClasses[i].opClass; + em_op_class_info->op_class = oper_param->operatingClasses[i].opClass; + em_op_class_info->max_tx_power = oper_param->operatingClasses[i].maxTxPower; + em_op_class_info->num_channels = oper_param->operatingClasses[i].numberOfNonOperChan; + for(int k = 0; k < oper_param->operatingClasses[i].numberOfNonOperChan; k++) { + em_op_class_info->channels[k] = oper_param->operatingClasses[i].nonOperable[k]; + } no_of_opclass++; - proto->set_num_op_class(proto->data_model,no_of_opclass); + proto->set_num_op_class(proto->data_model, no_of_opclass); } + //Update current operating class + em_op_class_info = proto->get_op_class_info(proto->data_model, no_of_opclass); + mac_address_from_name(radio_iface_map->interface_name,em_op_class_info->id.ruid); + em_op_class_info->id.type = em_op_class_type_current; + em_op_class_info->id.op_class = oper_param->operatingClass; + em_op_class_info->op_class = oper_param->operatingClass; + em_op_class_info->channel = oper_param->channel; + no_of_opclass++; + proto->set_num_op_class(proto->data_model,no_of_opclass); } + proto->set_num_radio(proto->data_model, radio_count); return webconfig_error_none; } @@ -417,7 +398,7 @@ webconfig_error_t translate_radio_object_to_easymesh_for_dml(webconfig_subdoc_da { em_radio_info_t *em_radio_info; em_op_class_info_t *em_op_class_info; - unsigned int radio_index = 0, bss_count = 0; + unsigned int radio_index = 0, bss_count = 0, op_class_count = 0; rdk_wifi_radio_t *radio; wifi_vap_info_t *vap; wifi_vap_info_map_t *vap_map; @@ -480,8 +461,9 @@ webconfig_error_t translate_radio_object_to_easymesh_for_dml(webconfig_subdoc_da } strncpy(em_radio_info->id.name,radio_iface_map->radio_name, sizeof(em_interface_name_t)); mac_address_from_name(radio_iface_map->interface_name, em_radio_info->id.mac); + op_class_count = proto->get_num_op_class(proto->data_model); for (unsigned int j = 0; j < oper_param->numOperatingClasses; j++) { - em_op_class_info = proto->get_op_class_info(proto->data_model, j); + em_op_class_info = (em_op_class_info_t *)(proto->get_op_class_info(proto->data_model, op_class_count)); mac_address_from_name(radio_iface_map->interface_name, em_op_class_info->id.ruid); em_op_class_info->id.type = 2; em_op_class_info->id.op_class = oper_param->operatingClasses[j].opClass; @@ -491,9 +473,10 @@ webconfig_error_t translate_radio_object_to_easymesh_for_dml(webconfig_subdoc_da for(int i = 0; i < oper_param->operatingClasses[j].numberOfNonOperChan; i++) { em_op_class_info->channels[i] = oper_param->operatingClasses[j].nonOperable[i]; } + op_class_count++; } //Update current operating class - em_op_class_info = proto->get_op_class_info(proto->data_model, oper_param->numOperatingClasses); + em_op_class_info = proto->get_op_class_info(proto->data_model, op_class_count); mac_address_from_name(radio_iface_map->interface_name,em_op_class_info->id.ruid); em_op_class_info->id.type = 1; em_op_class_info->op_class = oper_param->operatingClass; @@ -501,7 +484,7 @@ webconfig_error_t translate_radio_object_to_easymesh_for_dml(webconfig_subdoc_da em_op_class_info->channel = oper_param->channel; //Incrementing the number of operating classes by one, as the dml lacks an operating class for current. - proto->set_num_op_class(proto->data_model, (oper_param->numOperatingClasses+1)); + proto->set_num_op_class(proto->data_model, (op_class_count+1)); mac_address_from_name(radio_iface_map->interface_name, em_radio_info->id.mac); //Add default params of radio_info @@ -988,22 +971,23 @@ webconfig_error_t translate_mesh_sta_info_to_em_bss_config(wifi_vap_info_t *vap, } // translate_vap_object_to_easymesh_for_dml() converts DML data elements of wifi_vap_info_t to em_bss_info_t of easymesh -webconfig_error_t translate_vap_object_to_easymesh_for_dml(webconfig_subdoc_data_t *data) +webconfig_error_t translate_vap_object_to_easymesh_for_dml(webconfig_subdoc_data_t *data) { em_radio_info_t *em_radio_info; em_bss_info_t *em_bss_info; - em_bss_info_t *em_vap_info; - em_bss_info_t *vap_info_row; + em_bss_info_t *em_vap_info; + em_bss_info_t *vap_info_row; wifi_vap_info_map_t *vap_map; - em_ssid_2_vid_map_info_t *ssid_vid_info; + em_ssid_2_vid_map_info_t *ssid_vid_map = NULL; em_ssid_2_vid_map_info_t *ssid_vid_row; webconfig_external_easymesh_t *proto; webconfig_subdoc_decoded_data_t *decoded_params; wifi_hal_capability_t *hal_cap; wifi_interface_name_idex_map_t *iface_map; + radio_interface_mapping_t *radio_iface_map; unsigned int count = 0; wifi_vap_info_t *vap; - unsigned int i = 0,j = 0, k = 0; + unsigned int i = 0,j = 0, k = 0, num_bss = 0, radio_index = 0; rdk_wifi_radio_t *radio; mac_address_t rmac; @@ -1035,9 +1019,20 @@ webconfig_error_t translate_vap_object_to_easymesh_for_dml(webconfig_subdoc_da for (i = 0; i < decoded_params->num_radios; i++) { radio = &decoded_params->radios[i]; vap_map = &radio->vaps.vap_map; - proto->set_num_bss(proto->data_model, radio->vaps.num_vaps); - count = 0; - mac_address_from_name(radio->name, rmac); + num_bss = proto->get_num_bss(proto->data_model); + radio_index = convert_radio_name_to_radio_index(decoded_params->radios[i].name); + radio_iface_map = NULL; + for (unsigned int k = 0; k < (sizeof(wifi_prop->radio_interface_map)/sizeof(radio_interface_mapping_t)); k++) { + if (wifi_prop->radio_interface_map[k].radio_index == radio_index) { + radio_iface_map = &(wifi_prop->radio_interface_map[k]); + break; + } + } + if (radio_iface_map == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Unable to find the interface map entry for \n", __func__, __LINE__); + return webconfig_error_translate_to_easymesh; + } + mac_address_from_name(radio_iface_map->interface_name, rmac); for (j = 0; j < radio->vaps.num_vaps; j++) { //Get the corresponding vap vap = &vap_map->vap_array[j]; @@ -1048,21 +1043,13 @@ webconfig_error_t translate_vap_object_to_easymesh_for_dml(webconfig_subdoc_da } // please move this code to specific vap function like ovsdb_translator - em_bss_info = (em_bss_info_t *)(proto->get_bss_info(proto->data_model, j) + count); - em_ssid_2_vid_map_info_t* ssid_vid_map = NULL; - count++; - iface_map = NULL; - for (k = 0; k < (sizeof(hal_cap->wifi_prop.interface_map)/sizeof(wifi_interface_name_idex_map_t)); k++) { - if (hal_cap->wifi_prop.interface_map[k].index == vap->vap_index) { - iface_map = &(hal_cap->wifi_prop.interface_map[k]); - break; - } - } - if (iface_map == NULL) { - wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Unable to find the interface map entry for %d\n", __func__, __LINE__, vap->vap_index); - return webconfig_error_translate_to_easymesh; + em_bss_info = (em_bss_info_t *)(proto->get_bss_info(proto->data_model, num_bss)); + if (em_bss_info == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Cannot find bss info for index %d\n", __func__, __LINE__, vap->vap_index); + continue; } - + num_bss++; + proto->set_num_bss(proto->data_model, num_bss); memcpy(&em_bss_info->ruid.mac,&rmac,sizeof(mac_address_t)); // please move this code to specific vap function like ovsdb_translator if (is_vap_private(wifi_prop, vap->vap_index) == TRUE) { @@ -1104,22 +1091,18 @@ webconfig_error_t translate_vap_object_to_easymesh_for_dml(webconfig_subdoc_da //translate_vap_object_to_easymesh_bss_info() converts data elements of wifi_vap_info_t to em_bss_info_t of easymesh webconfig_error_t translate_vap_object_to_easymesh_bss_info(webconfig_subdoc_data_t *data,char *vap_name) { - em_bss_info_t *em_vap_info; - em_bss_info_t *vap_info_row; - em_ssid_2_vid_map_info_t *ssid_vid_info; + em_bss_info_t *em_vap_info; + em_bss_info_t *vap_info_row; em_ssid_2_vid_map_info_t *ssid_vid_row; - mac_address_t rmac; wifi_vap_info_map_t *vap_map; webconfig_external_easymesh_t *proto; webconfig_subdoc_decoded_data_t *decoded_params; wifi_hal_capability_t *hal_cap; - wifi_interface_name_idex_map_t *iface_map; - unsigned int count = 0; + radio_interface_mapping_t *iface_map; wifi_vap_info_t *vap; - unsigned int i = 0,j = 0, k = 0; + unsigned int i = 0,j = 0, k = 0, count = 0, radio_index = 0; rdk_wifi_radio_t *radio; - em_radio_info_t *em_radio_info; decoded_params = &data->u.decoded; if (decoded_params == NULL) { @@ -1148,43 +1131,143 @@ webconfig_error_t translate_vap_object_to_easymesh_bss_info(webconfig_subdoc_dat //Get the number of radios for (i = 0; i < decoded_params->num_radios; i++) { radio = &decoded_params->radios[i]; - - em_radio_info = proto->get_radio_info(proto->data_model, i); - proto->set_num_bss(proto->data_model, radio->vaps.num_vaps); - - //em_vap_info = em_radio_data[i].bss_info;//Please add NULL check TBD-P - //ssid_vid_info = em_radio_data[i].ssid_vid_map;//Please add NULL check TBD-P - ssid_vid_info = NULL; vap_map = &radio->vaps.vap_map; - count = 0; - mac_address_from_name(radio->name, rmac); + radio_index = convert_radio_name_to_radio_index(decoded_params->radios[i].name); + iface_map = NULL; + for (unsigned int k = 0; k < (sizeof(wifi_prop->radio_interface_map)/sizeof(radio_interface_mapping_t)); k++) { + if (wifi_prop->radio_interface_map[k].radio_index == radio_index) { + iface_map = &(wifi_prop->radio_interface_map[k]); + break; + } + } + if (iface_map == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Unable to find the interface map entry for \n", __func__, __LINE__); + return webconfig_error_translate_to_easymesh; + } + mac_address_from_name(iface_map->interface_name, rmac); for (j = 0; j < radio->vaps.num_vaps; j++) { //Get the corresponding vap vap = &vap_map->vap_array[j]; - em_vap_info = proto->get_bss_info(proto->data_model, j);//Please add NULL check TBD-P - wifi_util_dbg_print(WIFI_WEBCONFIG,"%s:%d: vap->vap_name:%s \r\n", __func__, __LINE__, vap->vap_name); - if (is_vap_hotspot(wifi_prop,vap->vap_index) == true) { + vap_info_row = proto->get_bss_info(proto->data_model, count); + if (vap_info_row == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: Cannot find the bssid\n", __func__, __LINE__); continue; } - - vap_info_row = (em_bss_info_t *)(em_vap_info + count); - ssid_vid_row = (em_ssid_2_vid_map_info_t *)(ssid_vid_info + count); - count++; if (strstr(vap->vap_name,vap_name) == false) { continue; } - iface_map = NULL; - for (k = 0; k < (sizeof(hal_cap->wifi_prop.interface_map)/sizeof(wifi_interface_name_idex_map_t)); k++) { - if (hal_cap->wifi_prop.interface_map[k].index == vap->vap_index) { - iface_map = &(hal_cap->wifi_prop.interface_map[k]); - break; + count++; + proto->set_num_bss(proto->data_model, count); + memcpy(&vap_info_row->ruid.mac,&rmac,sizeof(mac_address_t)); + // please move this code to specific vap function like ovsdb_translator + if (is_vap_private(wifi_prop, vap->vap_index) == TRUE) { + if (translate_private_vap_info_to_em_bss_config(vap, iface_map, vap_info_row, ssid_vid_row, wifi_prop) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Translation of private vap to EM failed for %d\n", __func__, __LINE__, vap->vap_index); + return webconfig_error_translate_to_easymesh; + } + } else if (is_vap_xhs(wifi_prop, vap->vap_index) == TRUE) { + if (translate_xhs_vap_info_to_em_bss_config(vap, iface_map, vap_info_row, ssid_vid_row, wifi_prop) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Translation of iot vap to EM failed for %d\n", __func__, __LINE__, vap->vap_index); + return webconfig_error_translate_to_easymesh; + } + } else if (is_vap_lnf_psk(wifi_prop, vap->vap_index) == TRUE) { + if (translate_lnf_psk_vap_info_to_em_bss_config(vap, iface_map, vap_info_row, ssid_vid_row, wifi_prop) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Translation of lnf psk vap to EM failed for %d\n", __func__, __LINE__, vap->vap_index); + return webconfig_error_translate_to_easymesh; + } + } else if (is_vap_lnf_radius(wifi_prop, vap->vap_index) == TRUE) { + if (translate_lnf_radius_vap_info_to_em_bss_config(vap, iface_map, vap_info_row, ssid_vid_row, wifi_prop) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Translation of lnf radius vap to EM failed for %d\n", __func__, __LINE__, vap->vap_index); + return webconfig_error_translate_to_easymesh; + } + } else if (is_vap_mesh_backhaul(wifi_prop, vap->vap_index) == TRUE) { + if (translate_mesh_backhaul_vap_info_to_em_bss_config(vap, iface_map, vap_info_row, ssid_vid_row, wifi_prop) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Translation of backhaul vap to EM failed for %d\n", __func__, __LINE__, vap->vap_index); + return webconfig_error_translate_to_easymesh; + } + } else if (is_vap_mesh_sta(wifi_prop, vap->vap_index) == TRUE) { + if (translate_mesh_sta_info_to_em_bss_config(vap, iface_map, vap_info_row, ssid_vid_row, wifi_prop) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Translation of mesh_stavap to EM failed for %d\n", __func__, __LINE__, vap->vap_index); + return webconfig_error_translate_to_easymesh; } } - if (iface_map == NULL) { - wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Unable to find the interface map entry for %d\n", __func__, __LINE__, vap->vap_index); - return webconfig_error_translate_to_easymesh; - } + } + } + return webconfig_error_none; +} + +//translate_per_radio_vap_object_to_easymesh_bss_info() converts data elements of wifi_vap_info_t to em_bss_info_t of easymesh +webconfig_error_t translate_per_radio_vap_object_to_easymesh_bss_info(webconfig_subdoc_data_t *data, wifi_freq_bands_t freq_band) +{ + em_bss_info_t *em_vap_info; + em_bss_info_t *vap_info_row; + em_ssid_2_vid_map_info_t *ssid_vid_row; + wifi_vap_info_map_t *vap_map; + webconfig_external_easymesh_t *proto; + webconfig_subdoc_decoded_data_t *decoded_params; + wifi_vap_info_t *vap; + wifi_hal_capability_t *hal_cap; + radio_interface_mapping_t *iface_map; + mac_address_t rmac; + unsigned int i = 0,j = 0, k = 0, count = 0, radio_index = 0; + rdk_wifi_radio_t *radio; + wifi_radio_operationParam_t *oper_param; + decoded_params = &data->u.decoded; + if (decoded_params == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: decoded_params is NULL\n", __func__, __LINE__); + return webconfig_error_translate_to_easymesh; + } + + proto = (webconfig_external_easymesh_t *)data->u.decoded.external_protos; + hal_cap = &data->u.decoded.hal_cap; + if (proto == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: external_protos is NULL\n", __func__, __LINE__); + return webconfig_error_translate_to_easymesh; + } + + if (proto->get_radio_info(proto->data_model, 0) == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: get_radio_info is NULL\n", __func__, __LINE__); + return webconfig_error_translate_to_easymesh; + } + + if ((decoded_params->num_radios < MIN_NUM_RADIOS) || (decoded_params->num_radios > MAX_NUM_RADIOS )){ + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: Invalid number of radios : %x\n", __func__, __LINE__, decoded_params->num_radios); + return webconfig_error_invalid_subdoc; + } + + wifi_platform_property_t *wifi_prop = &data->u.decoded.hal_cap.wifi_prop; + //Get the number of radios + for (i = 0; i < decoded_params->num_radios; i++) { + radio = &decoded_params->radios[i]; + vap_map = &radio->vaps.vap_map; + oper_param = &decoded_params->radios[i].oper; + if (oper_param->band != freq_band) { + continue; + } + radio_index = convert_radio_name_to_radio_index(decoded_params->radios[i].name); + iface_map = NULL; + for (unsigned int k = 0; k < (sizeof(wifi_prop->radio_interface_map)/sizeof(radio_interface_mapping_t)); k++) { + if (wifi_prop->radio_interface_map[k].radio_index == radio_index) { + iface_map = &(wifi_prop->radio_interface_map[k]); + break; + } + } + if (iface_map == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Unable to find the interface map entry for \n", __func__, __LINE__); + return webconfig_error_translate_to_easymesh; + } + mac_address_from_name(iface_map->interface_name, rmac); + for (j = 0; j < radio->vaps.num_vaps; j++) { + //Get the corresponding vap + vap = &vap_map->vap_array[j]; + vap_info_row = proto->get_bss_info(proto->data_model, count); + if (vap_info_row == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: Cannot find the bssid\n", __func__, __LINE__); + continue; + } + count++; + proto->set_num_bss(proto->data_model, count); memcpy(&vap_info_row->ruid.mac,&rmac,sizeof(mac_address_t)); // please move this code to specific vap function like ovsdb_translator if (is_vap_private(wifi_prop, vap->vap_index) == TRUE) { @@ -1426,6 +1509,125 @@ webconfig_error_t translate_em_bss_to_mesh_sta_info(wifi_vap_info_t *vap, cons } */ +//translating easymesh bss info to onewifi for each vap in a radio +webconfig_error_t translate_from_easymesh_bssinfo_to_vap_per_radio(webconfig_subdoc_data_t *data) +{ + em_bss_info_t *em_vap_info; + em_bss_info_t *vap_info_row; + wifi_vap_info_map_t *vap_map; + webconfig_external_easymesh_t *proto; + webconfig_subdoc_decoded_data_t *decoded_params; + wifi_vap_info_t *vap; + unsigned int i = 0,j = 0, k = 0, count = 0, radio_index = 0; + rdk_wifi_radio_t *radio; + wifi_hal_capability_t *hal_cap; + decoded_params = &data->u.decoded; + wifi_interface_name_idex_map_t *radio_iface_map; + m2ctrl_vapconfig *vap_config; + mac_address_t mac; + + if (decoded_params == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: decoded_params is NULL\n", __func__, __LINE__); + return webconfig_error_translate_from_easymesh; + } + + proto = (webconfig_external_easymesh_t *)data->u.decoded.external_protos; + if (proto == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: external_protos is NULL\n", __func__, __LINE__); + return webconfig_error_translate_from_easymesh; + } + + if (proto->get_radio_info(proto->data_model, 0) == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: get_radio_info is NULL\n", __func__, __LINE__); + return webconfig_error_translate_from_easymesh; + } + + if ((decoded_params->num_radios < MIN_NUM_RADIOS) || (decoded_params->num_radios > MAX_NUM_RADIOS )){ + wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: Invalid number of radios : %x\n", __func__, __LINE__, decoded_params->num_radios); + return webconfig_error_invalid_subdoc; + } + + vap_config = proto->m2ctrl_vapconfig; + wifi_platform_property_t *wifi_prop = &data->u.decoded.hal_cap.wifi_prop; + hal_cap =&data->u.decoded.hal_cap; + + if (data->type == webconfig_subdoc_type_vap_24G) { + radio_index = 0; + } else if (data->type == webconfig_subdoc_type_vap_5G) { + radio_index = 1; + } else { + radio_index = 2; + } + + radio = &decoded_params->radios[radio_index]; + + //radio_index = convert_radio_name_to_radio_index(decoded_params->radios[0].name); + radio_iface_map = NULL; + for (unsigned int k = 0; k < (sizeof(wifi_prop->radio_interface_map)/sizeof(radio_interface_mapping_t)); k++) { + if (wifi_prop->radio_interface_map[k].radio_index == radio_index) { + radio_iface_map = &(wifi_prop->radio_interface_map[k]); + break; + } + } + if (radio_iface_map == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Unable to find the interface map entry for \n", __func__, __LINE__); + return webconfig_error_translate_to_easymesh; + } + vap_map = &radio->vaps.vap_map; + for (j = 0; j < radio->vaps.num_vaps; j++) { + //Get the corresponding vap + vap = &vap_map->vap_array[j]; + vap_info_row = proto->get_bss_info_with_mac(proto->data_model, vap->u.bss_info.bssid); + if (vap_info_row == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: em_vap_info is NULL\n", __func__, __LINE__); + continue; + } + + if (is_vap_private(wifi_prop, vap->vap_index) == TRUE) { + if (translate_em_bss_to_private_vap_info(vap, vap_info_row) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Translation from EM to private vap failed %d\n", __func__, __LINE__, vap->vap_index); + return webconfig_error_translate_from_easymesh; + } + } else if (is_vap_xhs(wifi_prop, vap->vap_index) == TRUE) { + if (translate_em_bss_to_xhs_vap_info(vap, vap_info_row) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Translation from EM to iot vap failed %d\n", __func__, __LINE__, vap->vap_index); + return webconfig_error_translate_from_easymesh; + } + } else if (is_vap_lnf_psk(wifi_prop, vap->vap_index) == TRUE) { + if (translate_em_bss_to_lnf_psk_vap_info(vap, vap_info_row) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Translation from EM to lnf psk vap failed for %d\n", __func__, __LINE__, vap->vap_index); + return webconfig_error_translate_from_easymesh; + } + } else if (is_vap_lnf_radius(wifi_prop, vap->vap_index) == TRUE) { + if (translate_em_bss_to_lnf_radius_vap_info(vap, vap_info_row) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Translation from EM to lnf radius vap failed for %d\n", __func__, __LINE__, vap->vap_index); + return webconfig_error_translate_from_easymesh; + } + } else if (is_vap_mesh_backhaul(wifi_prop, vap->vap_index) == TRUE) { + if (translate_em_bss_to_mesh_backhaul_vap_info(vap, vap_info_row) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Translation from EM to backhaul vap failed for %d\n", __func__, __LINE__, vap->vap_index); + return webconfig_error_translate_from_easymesh; + } + } else if (is_vap_mesh_sta(wifi_prop, vap->vap_index) == TRUE) { + if (translate_em_bss_to_mesh_sta_info(vap, vap_info_row) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Translation from EM to mesh_stavap failed for %d\n", __func__, __LINE__, vap->vap_index); + return webconfig_error_translate_from_easymesh; + } + } + + if ((vap_config != NULL) && (memcmp(vap_config->mac, vap_info_row->ruid.mac, sizeof(mac_address_t)) == 0)) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: ssid=%s sec_mode=%d password=%s", __func__, __LINE__, + vap_config->ssid,vap_config->authtype,vap_config->password); + vap->u.bss_info.security.mode = vap_config->authtype; + strncpy(vap->u.bss_info.ssid, vap_config->ssid, sizeof(vap->u.bss_info.ssid)-1); + strncpy(vap->u.bss_info.security.u.key.key, vap_config->password, sizeof(vap->u.bss_info.security.u.key.key)-1); + vap->u.bss_info.enabled = vap_config->enable; + } + } + + return webconfig_error_none; +} + // translate_from_easymesh_bssinfo_to_vap_object() converts data elements of wifi_vap_info_t to em_bss_info_t of easymesh webconfig_error_t translate_from_easymesh_bssinfo_to_vap_object(webconfig_subdoc_data_t *data,char *vap_name) { @@ -1434,13 +1636,12 @@ webconfig_error_t translate_from_easymesh_bssinfo_to_vap_object(webconfig_subdoc wifi_vap_info_map_t *vap_map; webconfig_external_easymesh_t *proto; webconfig_subdoc_decoded_data_t *decoded_params; - unsigned int count = 0; wifi_vap_info_t *vap; - unsigned int i = 0,j = 0, k = 0; + unsigned int i = 0,j = 0, k = 0, count = 0, radio_index = 0; rdk_wifi_radio_t *radio; wifi_hal_capability_t *hal_cap; decoded_params = &data->u.decoded; - wifi_interface_name_idex_map_t *iface_map; + wifi_interface_name_idex_map_t *radio_iface_map; m2ctrl_vapconfig *vap_config; if (decoded_params == NULL) { @@ -1470,40 +1671,37 @@ webconfig_error_t translate_from_easymesh_bssinfo_to_vap_object(webconfig_subdoc //Get the number of radios for (i = 0; i < decoded_params->num_radios; i++) { radio = &decoded_params->radios[i]; - + radio_index = convert_radio_name_to_radio_index(decoded_params->radios[i].name); + radio_iface_map = NULL; + for (unsigned int k = 0; k < (sizeof(wifi_prop->radio_interface_map)/sizeof(radio_interface_mapping_t)); k++) { + if (wifi_prop->radio_interface_map[k].radio_index == radio_index) { + radio_iface_map = &(wifi_prop->radio_interface_map[k]); + break; + } + } + if (radio_iface_map == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Unable to find the interface map entry for \n", __func__, __LINE__); + return webconfig_error_translate_to_easymesh; + } vap_map = &radio->vaps.vap_map; for (j = 0; j < radio->vaps.num_vaps; j++) { //Get the corresponding vap vap = &vap_map->vap_array[j]; - em_vap_info = proto->get_bss_info(proto->data_model, j);//Please add NULL check TBD-P - if (em_vap_info == NULL) { - wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: em_vap_info is NULL\n", __func__, __LINE__); - return webconfig_error_translate_from_easymesh; + vap_info_row = proto->get_bss_info(proto->data_model, count); + if (vap_info_row == NULL) { + wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: vap_info_row is NULL\n", __func__, __LINE__); + continue; } - count = 0; + count++; + proto->set_num_bss(proto->data_model, count); wifi_util_dbg_print(WIFI_WEBCONFIG,"%s:%d: vap->vap_name:%s \r\n", __func__, __LINE__, vap->vap_name); if (is_vap_hotspot(wifi_prop,vap->vap_index) == true) { continue; } - // please move this code to specific vap function like ovsdb_translator - vap_info_row = (em_bss_info_t *)(em_vap_info + count); - count++; if (strstr(vap->vap_name,vap_name) == false) { continue; } - iface_map = NULL; - for (k = 0; k < (sizeof(hal_cap->wifi_prop.interface_map)/sizeof(wifi_interface_name_idex_map_t)); k++) { - if (hal_cap->wifi_prop.interface_map[k].index == vap->vap_index) { - iface_map = &(hal_cap->wifi_prop.interface_map[k]); - break; - } - } - if (iface_map == NULL) { - wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Unable to find the interface map entry for %d\n", __func__, __LINE__, vap->vap_index); - return webconfig_error_translate_from_easymesh; - } - if (is_vap_private(wifi_prop, vap->vap_index) == TRUE) { if (translate_em_bss_to_private_vap_info(vap, vap_info_row) != webconfig_error_none) { wifi_util_error_print(WIFI_WEBCONFIG,"%s:%d: Translation from EM to private vap failed %d\n", __func__, __LINE__, vap->vap_index); @@ -1559,7 +1757,7 @@ webconfig_error_t translate_radio_object_from_easymesh_to_radio(webconfig_subdoc webconfig_subdoc_decoded_data_t *decoded_params; wifi_radio_operationParam_t *oper_param; webconfig_external_easymesh_t *proto; - unsigned int i,j,radio_index; + unsigned int i,j,radio_index, freq_band = 0, per_radio_subdoc = 0; rdk_wifi_radio_t *radio; em_op_class_info_t *em_op_class_info; radio_interface_mapping_t *radio_iface_map; @@ -1590,9 +1788,23 @@ webconfig_error_t translate_radio_object_from_easymesh_to_radio(webconfig_subdoc return webconfig_error_invalid_subdoc; } + if (data->type == webconfig_subdoc_type_radio_24G) { + freq_band = WIFI_FREQUENCY_2_4_BAND; + per_radio_subdoc++; + } else if (data->type == webconfig_subdoc_type_radio_5G) { + freq_band = WIFI_FREQUENCY_5_BAND; + per_radio_subdoc++; + } else if (data->type == webconfig_subdoc_type_radio_6G) { + freq_band = WIFI_FREQUENCY_6_BAND; + per_radio_subdoc++; + } + for (i = 0; i < decoded_params->num_radios; i++) { radio = &decoded_params->radios[i]; oper_param = &decoded_params->radios[i].oper; + if ((per_radio_subdoc > 0) && (oper_param->band != freq_band)) { + continue; + } num = proto->get_num_op_class(proto->data_model); radio_index = convert_radio_name_to_radio_index(decoded_params->radios[i].name); radio_iface_map = NULL; @@ -1610,8 +1822,9 @@ webconfig_error_t translate_radio_object_from_easymesh_to_radio(webconfig_subdoc for (j = 0; j < num; j++) { em_op_class_info = proto->get_op_class_info(proto->data_model, j); if ((em_op_class_info != NULL) && (em_op_class_info->id.type == 1) && - (memcmp(&ruid, em_op_class_info->id.ruid, sizeof(mac_address_t)) == 0)) { - oper_param->op_class = em_op_class_info->op_class ; + (memcmp(&ruid, &em_op_class_info->id.ruid, sizeof(mac_address_t)) == 0)) { + oper_param->op_class = em_op_class_info->op_class; + oper_param->operatingClass = em_op_class_info->op_class; oper_param->channel = em_op_class_info->channel; } } @@ -1845,6 +2058,9 @@ webconfig_error_t translate_to_easymesh_tables(webconfig_subdoc_type_t type, we break; case webconfig_subdoc_type_radio: + case webconfig_subdoc_type_radio_24G: + case webconfig_subdoc_type_radio_5G: + case webconfig_subdoc_type_radio_6G: if (translate_radio_object_to_easymesh_for_radio(data) != webconfig_error_none) { wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: webconfig_subdoc_type_dml radio_object translation to easymesh failed\n", __func__, __LINE__); @@ -1861,9 +2077,26 @@ webconfig_error_t translate_to_easymesh_tables(webconfig_subdoc_type_t type, we break; */ case webconfig_subdoc_type_vap_24G: + if (translate_per_radio_vap_object_to_easymesh_bss_info(data, WIFI_FREQUENCY_2_4_BAND) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: webconfig_subdoc_type_private vap_object translation to easymesh failed\n", __func__, __LINE__); + return webconfig_error_translate_to_easymesh; + } + break; case webconfig_subdoc_type_vap_5G: + if (translate_per_radio_vap_object_to_easymesh_bss_info(data, WIFI_FREQUENCY_5_BAND) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: webconfig_subdoc_type_private vap_object translation to easymesh failed\n", __func__, __LINE__); + return webconfig_error_translate_to_easymesh; + } + break; case webconfig_subdoc_type_vap_6G: - //TBD: Update the necessary datastructures of easymesh + if (translate_per_radio_vap_object_to_easymesh_bss_info(data, WIFI_FREQUENCY_6_BAND) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: webconfig_subdoc_type_private vap_object translation to easymesh failed\n", __func__, __LINE__); + return webconfig_error_translate_to_easymesh; + } + break; default: break; @@ -1933,6 +2166,9 @@ webconfig_error_t translate_from_easymesh_tables(webconfig_subdoc_type_t type, break; case webconfig_subdoc_type_radio: + case webconfig_subdoc_type_radio_24G: + case webconfig_subdoc_type_radio_5G: + case webconfig_subdoc_type_radio_6G: if (translate_radio_object_from_easymesh_to_radio(data) != webconfig_error_none) { wifi_util_error_print(WIFI_WEBCONFIG, "%s:%d: webconfig_subdoc_type_radio translation to easymesh failed\n", __func__, __LINE__); @@ -1943,7 +2179,12 @@ webconfig_error_t translate_from_easymesh_tables(webconfig_subdoc_type_t type, case webconfig_subdoc_type_vap_24G: case webconfig_subdoc_type_vap_5G: case webconfig_subdoc_type_vap_6G: - //TBD: Update the necessary datastructures from easymesh to OneWifi. + if (translate_from_easymesh_bssinfo_to_vap_per_radio(data) != webconfig_error_none) { + wifi_util_error_print(WIFI_WEBCONFIG, + "%s:%d: webconfig_subdoc_type_private vap_object translation to easymesh failed\n", __func__, __LINE__); + return webconfig_error_translate_from_easymesh; + } + break; default: break; @@ -1959,7 +2200,7 @@ void webconfig_proto_easymesh_init(webconfig_external_easymesh_t *proto, void *d ext_proto_em_get_radio_info_t get_radio, ext_proto_em_get_ieee_1905_security_info_t get_sec, ext_proto_em_get_bss_info_t get_bss, ext_proto_em_get_op_class_info_t get_op_class, ext_proto_get_first_sta_info_t get_first_sta, ext_proto_get_next_sta_info_t get_next_sta, - ext_proto_get_sta_info_t get_sta, ext_proto_put_sta_info_t put_sta) + ext_proto_get_sta_info_t get_sta, ext_proto_put_sta_info_t put_sta, ext_proto_em_get_bss_info_with_mac_t get_bss_with_mac) { proto->data_model = data_model; proto->m2ctrl_vapconfig = m2ctrl_vapconfig; @@ -1979,4 +2220,5 @@ void webconfig_proto_easymesh_init(webconfig_external_easymesh_t *proto, void *d proto->get_next_sta_info = get_next_sta; proto->get_sta_info = get_sta; proto->put_sta_info = put_sta; + proto->get_bss_info_with_mac = get_bss_with_mac; } From 5a67dfc9e3fe2d63c5182f6bf269b09893265e20 Mon Sep 17 00:00:00 2001 From: Amarnath Hullur Subramanyam <182549733+amarnathhullur@users.noreply.github.com> Date: Mon, 16 Dec 2024 12:22:47 -0800 Subject: [PATCH 18/22] Remove duplicate inclusion of em_base.h --- include/webconfig_external_proto_easymesh.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/webconfig_external_proto_easymesh.h b/include/webconfig_external_proto_easymesh.h index 0ce3ac73..ce9f1491 100644 --- a/include/webconfig_external_proto_easymesh.h +++ b/include/webconfig_external_proto_easymesh.h @@ -25,8 +25,6 @@ extern "C" { #endif -#include "em_base.h" - typedef unsigned int (*ext_proto_get_num_radio_t)(void *data_model); typedef void (*ext_proto_set_num_radio_t)(void *data_model, unsigned int num_radio); typedef unsigned int (*ext_proto_get_num_op_class_t)(void *data_model); From b498af02e977002a2c504da4b57f163d509b6534 Mon Sep 17 00:00:00 2001 From: Amarnath Hullur Subramanyam <182549733+amarnathhullur@users.noreply.github.com> Date: Mon, 16 Dec 2024 12:25:36 -0800 Subject: [PATCH 19/22] Add .gitignore for ignoring compiled .o, lib and bin files --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..6b2dbfe5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +install/ +*.o +*.so +.vscode/ From 8bb413a7d32be7fe65138f11679db225ee3e1349 Mon Sep 17 00:00:00 2001 From: Sanjay Venkatesan Date: Mon, 16 Dec 2024 14:04:02 +0000 Subject: [PATCH 20/22] RDKB-58139: LEVL fingerprints are not reflected on CUJO portal Impacted Platforms: All RDKB platforms. Reason for change: Invalid data type is being passed to rbus publish function. Test Procedure: 1. Load the above mentioned build. 2. Subscribe to this event like below, rbuscli -i rbuscli> sub Device.WiFi.AccessPoint.2.X_RDK_deviceConnected 3. Connect a client to any of the private vap. 4. And check for the received event data is not null and contains mac address of the connected client. 5. If the data is null, then issue is reproduced. Risks: Medium Priority: P1 Change-Id: Id4de9aade2044cd02ae8ded8e95c836293fd6d8f Signed-off-by:Sanjay_Venkatesan@comcast.com --- source/core/wifi_ctrl_rbus_handlers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/core/wifi_ctrl_rbus_handlers.c b/source/core/wifi_ctrl_rbus_handlers.c index a8b10ad1..6fe4ecc3 100644 --- a/source/core/wifi_ctrl_rbus_handlers.c +++ b/source/core/wifi_ctrl_rbus_handlers.c @@ -2554,8 +2554,8 @@ int events_bus_publish(wifi_event_t *evt) if (events_getSubscribed(eventName) == TRUE) { pthread_mutex_lock(&ctrl->events_bus_data.events_bus_lock); memset(&data, 0, sizeof(raw_data_t)); - data.data_type = bus_data_type_uint8; - data.raw_data.u8 = evt->u.mon_data->u.dev.sta_mac[0]; + data.data_type = bus_data_type_bytes; + data.raw_data.bytes = evt->u.mon_data->u.dev.sta_mac; data.raw_data_len = sizeof(evt->u.mon_data->u.dev.sta_mac); rc = get_bus_descriptor()->bus_event_publish_fn(&ctrl->handle, eventName, &data); From 4eee4020e18ed7c9c70002ded98244320a4a9a03 Mon Sep 17 00:00:00 2001 From: rakhilpe Date: Tue, 17 Dec 2024 18:42:42 +0530 Subject: [PATCH 21/22] Add support for sending and subscribing to action frames. Reason for change: Added support for sending and subscribing to action frames from easymesh agent. Test Procedure: Ensure easymesh agent can send and receive action frame packets. Risks: Medium Priority: P1 Signed-off-by: Rakhil P E --- include/wifi_base.h | 10 +++ include/wifi_events.h | 2 + source/core/wifi_ctrl.c | 6 ++ source/core/wifi_ctrl_queue_handlers.c | 29 +++++++++ source/core/wifi_ctrl_rbus_handlers.c | 87 ++++++++++++++++++++++++++ source/core/wifi_events.c | 2 + 6 files changed, 136 insertions(+) diff --git a/include/wifi_base.h b/include/wifi_base.h index 5e33e41d..6499db32 100644 --- a/include/wifi_base.h +++ b/include/wifi_base.h @@ -57,6 +57,8 @@ extern "C" { #define WIFI_ACCESSPOINT_DIAGDATA "Device.WiFi.AccessPoint.{i}.X_RDK_DiagData" #define WIFI_ACCESSPOINT_FORCE_APPLY "Device.WiFi.AccessPoint.{i}.ForceApply" #define WIFI_ACCESSPOINT_RADIUS_CONNECTED_ENDPOINT "Device.WiFi.AccessPoint.{i}.Security.ConnectedRadiusEndpoint" +#define WIFI_ACCESSPOINT_RAWFRAME_MGMT_ACTION_TX "Device.WiFi.AccessPoint.{i}.RawFrame.Mgmt.Action.Tx" +#define WIFI_ACCESSPOINT_RAWFRAME_MGMT_ACTION_RX "Device.WiFi.AccessPoint.{i}.RawFrame.Mgmt.Action.Rx" #define WIFI_CSI_TABLE "Device.WiFi.X_RDK_CSI.{i}." #define WIFI_CSI_DATA "Device.WiFi.X_RDK_CSI.{i}.data" #define WIFI_CSI_CLIENTMACLIST "Device.WiFi.X_RDK_CSI.{i}.ClientMaclist" @@ -263,6 +265,14 @@ typedef enum { whix_app_event_type_max } whix_app_event_type_t; +typedef struct { + unsigned int ap_index; + mac_addr_t dest_addr; + unsigned int frequency; + unsigned int frame_len; + uint8_t frame_data[0]; +} __attribute__((packed)) action_frame_params_t; + typedef struct { unsigned int radio_index; unsigned int vap_index; diff --git a/include/wifi_events.h b/include/wifi_events.h index debaba95..1d8fdfca 100644 --- a/include/wifi_events.h +++ b/include/wifi_events.h @@ -149,6 +149,7 @@ typedef enum { wifi_event_type_xfinity_rrm, wifi_event_type_collect_stats, wifi_event_type_tcm_rfc, + wifi_event_type_send_action_frame, wifi_event_command_max, @@ -181,6 +182,7 @@ typedef enum { wifi_event_monitor_get_radiodiag_stats, wifi_event_monitor_get_radio_temperature, wifi_event_monitor_set_subscribe, + wifi_event_monitor_action_frame, wifi_event_monitor_max, // Tunnel diff --git a/source/core/wifi_ctrl.c b/source/core/wifi_ctrl.c index 2a51e214..8e0c136f 100644 --- a/source/core/wifi_ctrl.c +++ b/source/core/wifi_ctrl.c @@ -1062,6 +1062,7 @@ int mgmt_wifi_frame_recv(int ap_index, mac_address_t sta_mac, uint8_t *frame, ui wifi_actionFrameHdr_t *paction = NULL; frame_data_t mgmt_frame; wifi_event_subtype_t evt_subtype = wifi_event_hal_unknown_frame; + wifi_monitor_data_t data; if (len == 0) { wifi_util_dbg_print(WIFI_CTRL,"%s:%d Recived zero length frame\n", __func__, __LINE__); @@ -1108,6 +1109,11 @@ int mgmt_wifi_frame_recv(int ap_index, mac_address_t sta_mac, uint8_t *frame, ui mgmt_frame.frame.len = len; evt_subtype = wifi_event_hal_reassoc_rsp_frame; } else if (type == WIFI_MGMT_FRAME_TYPE_ACTION) { + memset(&data, 0, sizeof(wifi_monitor_data_t)); + data.ap_index = ap_index; + data.u.msg.frame.len = len; + memcpy(&data.u.msg.data, frame, len); + push_event_to_monitor_queue(&data, wifi_event_monitor_action_frame, NULL); paction = (wifi_actionFrameHdr_t *)(frame + sizeof(struct ieee80211_frame)); switch (paction->cat) { case wifi_action_frame_type_public: diff --git a/source/core/wifi_ctrl_queue_handlers.c b/source/core/wifi_ctrl_queue_handlers.c index d9c0f9e2..4da5aee7 100644 --- a/source/core/wifi_ctrl_queue_handlers.c +++ b/source/core/wifi_ctrl_queue_handlers.c @@ -3011,6 +3011,32 @@ static void process_monitor_init_command(void) free(data); } +void process_send_action_frame_command(void *data, unsigned int len) +{ + action_frame_params_t *params; + + if (data == NULL) { + wifi_util_error_print(WIFI_CTRL, "%s:%d NUll data Pointer\n", __func__, __LINE__); + return; + } + + if (len < sizeof(action_frame_params_t) + 1) { + wifi_util_error_print(WIFI_CTRL, "%s:%d Invalid parameter size \r\n", __func__, __LINE__); + return; + } + + params = (action_frame_params_t *)data; + + if (wifi_sendActionFrame(params->ap_index, params->dest_addr, params->frequency, + params->frame_data, params->frame_len)) { + wifi_util_error_print(WIFI_CTRL, "%s:%d HAL sendActionFrame method failed :\r\n", __func__, + __LINE__); + return; + } + + return; +} + void handle_command_event(wifi_ctrl_t *ctrl, void *data, unsigned int len, wifi_event_subtype_t subtype) { @@ -3132,6 +3158,9 @@ void handle_command_event(wifi_ctrl_t *ctrl, void *data, unsigned int len, case wifi_event_type_notify_monitor_done: process_monitor_init_command(); break; + case wifi_event_type_send_action_frame: + process_send_action_frame_command(data, len); + break; case wifi_event_type_mgmt_frame_bus_rfc: case wifi_event_type_sta_connect_in_progress: case wifi_event_type_udhcp_ip_fail: diff --git a/source/core/wifi_ctrl_rbus_handlers.c b/source/core/wifi_ctrl_rbus_handlers.c index 6fe4ecc3..1ebdec7d 100644 --- a/source/core/wifi_ctrl_rbus_handlers.c +++ b/source/core/wifi_ctrl_rbus_handlers.c @@ -2033,6 +2033,21 @@ bus_error_t eventSubHandler(char *eventName, bus_event_sub_action_t action, data = NULL; } break; + case wifi_event_monitor_action_frame: + idx = event->idx; + wifi_util_info_print(WIFI_CTRL, "%s:%d action=%s\n eventName=%s idx %d\n", __func__, + __LINE__, action == bus_event_action_subscribe ? "subscribe" : "unsubscribe", + eventName, idx); + if (action == bus_event_action_subscribe) { + event->num_subscribers++; + event->subscribed = TRUE; + } else { + event->num_subscribers--; + if (event->num_subscribers == 0) { + event->subscribed = FALSE; + } + } + break; default: wifi_util_dbg_print(WIFI_CTRL, "%s(): Invalid event type\n", __FUNCTION__); break; @@ -2266,6 +2281,16 @@ bus_error_t ap_table_addrowhandler(char const *tableName, char const *aliasName, queue_push(ctrl->events_bus_data.events_bus_queue, event); } + event = (event_bus_element_t *)malloc(sizeof(event_bus_element_t)); + if (event != NULL) { + sprintf(event->name, "Device.WiFi.AccessPoint.%d.RawFrame.Mgmt.Action.Rx", *instNum); + event->idx = vap_index; + event->type = wifi_event_monitor_action_frame; + event->subscribed = FALSE; + event->num_subscribers = 0; + queue_push(ctrl->events_bus_data.events_bus_queue, event); + } + pthread_mutex_unlock(&ctrl->events_bus_data.events_bus_lock); wifi_util_dbg_print(WIFI_CTRL, "%s(): exit\n", __FUNCTION__); @@ -2569,6 +2594,27 @@ int events_bus_publish(wifi_event_t *evt) } } break; + case wifi_event_monitor_action_frame: + sprintf(eventName, "Device.WiFi.AccessPoint.%d.RawFrame.Mgmt.Action.Rx", + evt->u.mon_data->ap_index + 1); + if (events_getSubscribed(eventName) == TRUE) { + pthread_mutex_lock(&ctrl->events_bus_data.events_bus_lock); + memset(&data, 0, sizeof(raw_data_t)); + data.data_type = bus_data_type_bytes; + data.raw_data.bytes = (void *)&evt->u.mon_data->u.msg.data; + data.raw_data_len = evt->u.mon_data->u.msg.frame.len; + + rc = get_bus_descriptor()->bus_event_publish_fn(&ctrl->handle, eventName, &data); + pthread_mutex_unlock(&ctrl->events_bus_data.events_bus_lock); + if (rc != bus_error_success) { + wifi_util_error_print(WIFI_CTRL, "%s(): bus_event_publish_fn Event failed: %d\n", + __FUNCTION__, rc); + } else { + wifi_util_dbg_print(WIFI_CTRL, "%s(): Event - %s %s \n", __FUNCTION__, + wifi_event_subtype_to_string(evt->sub_type), eventName); + } + } + break; default: wifi_util_dbg_print(WIFI_CTRL, "%s(): Invalid event type\n", __FUNCTION__); break; @@ -2651,6 +2697,41 @@ bus_error_t get_client_assoc_request_multi(char const* methodName, raw_data_t *i return bus_error_success; } +bus_error_t send_action_frame(char *name, raw_data_t *p_data) +{ + + unsigned int len = 0; + char *pTmp = NULL; + unsigned int idx = 0; + int ret; + unsigned int num_of_radios = getNumberRadios(); + + if (!name) { + wifi_util_error_print(WIFI_CTRL, "%s:%d property name is not found\r\n", __FUNCTION__, + __LINE__); + return bus_error_element_name_missing; + } + + pTmp = (char *)p_data->raw_data.bytes; + if ((p_data->data_type != bus_data_type_bytes) || (pTmp == NULL)) { + wifi_util_error_print(WIFI_CTRL, "%s:%d wrong bus data_type:%x\n", __func__, __LINE__, + p_data->data_type); + return bus_error_invalid_input; + } + + ret = sscanf(name, "Device.WiFi.AccessPoint.%d.RawFrame.Mgmt.Action.Tx", &idx); + if (ret != 1 || idx < 0 || idx > num_of_radios * MAX_NUM_VAP_PER_RADIO) { + wifi_util_error_print(WIFI_CTRL, "%s:%d Invalid name : %s\r\n", __func__, __LINE__, name); + return bus_error_invalid_event; + } + + len = p_data->raw_data_len; + push_event_to_ctrl_queue((char *)pTmp, len, wifi_event_type_command, + wifi_event_type_send_action_frame, NULL); + + return bus_error_success; +} + bus_error_t set_force_vap_apply(char *name, raw_data_t *p_data) { unsigned int idx = 0; @@ -2820,6 +2901,12 @@ void bus_register_handlers(wifi_ctrl_t *ctrl) { WIFI_ACCESSPOINT_FORCE_APPLY, bus_element_type_method, { NULL, set_force_vap_apply, NULL, NULL, NULL, NULL}, slow_speed, ZERO_TABLE, { bus_data_type_boolean, true, 0, 0, 0, NULL } }, + { WIFI_ACCESSPOINT_RAWFRAME_MGMT_ACTION_RX, bus_element_type_event, + { NULL, NULL, NULL, NULL, eventSubHandler, NULL}, high_speed, ZERO_TABLE, + { bus_data_type_bytes, false, 0, 0, 0, NULL } }, + { WIFI_ACCESSPOINT_RAWFRAME_MGMT_ACTION_TX, bus_element_type_method, + { NULL, send_action_frame, NULL, NULL, NULL, NULL}, high_speed, ZERO_TABLE, + { bus_data_type_bytes, true, 0, 0, 0, NULL } }, { ACCESSPOINT_ASSOC_REQ_EVENT, bus_element_type_method, { NULL, NULL, NULL, NULL, NULL, NULL}, slow_speed, ZERO_TABLE, { bus_data_type_string, true, 0, 0, 0, NULL } }, diff --git a/source/core/wifi_events.c b/source/core/wifi_events.c index 500fb1d7..894239b1 100644 --- a/source/core/wifi_events.c +++ b/source/core/wifi_events.c @@ -146,6 +146,7 @@ const char *wifi_event_subtype_to_string(wifi_event_subtype_t type) DOC2S(wifi_event_type_stop_inst_msmt) DOC2S(wifi_event_type_xfinity_rrm) DOC2S(wifi_event_type_collect_stats) + DOC2S(wifi_event_type_send_action_frame) DOC2S(wifi_event_command_max) DOC2S(wifi_event_monitor_diagnostics) DOC2S(wifi_event_monitor_connect) @@ -176,6 +177,7 @@ const char *wifi_event_subtype_to_string(wifi_event_subtype_t type) DOC2S(wifi_event_monitor_get_radiodiag_stats) DOC2S(wifi_event_monitor_get_radio_temperature) DOC2S(wifi_event_monitor_set_subscribe) + DOC2S(wifi_event_monitor_action_frame) DOC2S(wifi_event_monitor_max) DOC2S(wifi_event_type_xfinity_tunnel_up) DOC2S(wifi_event_type_xfinity_tunnel_down) From 5e892f6639fb955997fa486bba587594dee0ef12 Mon Sep 17 00:00:00 2001 From: rakhilpe Date: Tue, 17 Dec 2024 20:49:31 +0530 Subject: [PATCH 22/22] updated the log to reflect the error reason --- source/core/wifi_ctrl_rbus_handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/core/wifi_ctrl_rbus_handlers.c b/source/core/wifi_ctrl_rbus_handlers.c index 1ebdec7d..869dcf0c 100644 --- a/source/core/wifi_ctrl_rbus_handlers.c +++ b/source/core/wifi_ctrl_rbus_handlers.c @@ -2721,7 +2721,7 @@ bus_error_t send_action_frame(char *name, raw_data_t *p_data) ret = sscanf(name, "Device.WiFi.AccessPoint.%d.RawFrame.Mgmt.Action.Tx", &idx); if (ret != 1 || idx < 0 || idx > num_of_radios * MAX_NUM_VAP_PER_RADIO) { - wifi_util_error_print(WIFI_CTRL, "%s:%d Invalid name : %s\r\n", __func__, __LINE__, name); + wifi_util_error_print(WIFI_CTRL, "%s:%d Invalid index : %s\r\n", __func__, __LINE__, name); return bus_error_invalid_event; }