NCR00313570][rdkb][MT7990][hal]update new wifi hal API
[Description]
update the following APIs:
wifi_getRadioDCSEnable
wifi_setRadioDCSEnable
wifi_getRadioDCSChannelPool
wifi_setRadioDCSChannelPool
wifi_getRadioAutoChannelRefreshPeriodSupported
wifi_getRadioAutoChannelRefreshPeriod
wifi_setRadioAutoChannelRefreshPeriod
wifi_getRadioDCSSupported
[Release-log]
N/A
diff --git a/src/logan_wifi/wifi_hal.c b/src/logan_wifi/wifi_hal.c
index 1e5837b..31c8ee9 100644
--- a/src/logan_wifi/wifi_hal.c
+++ b/src/logan_wifi/wifi_hal.c
@@ -3678,21 +3678,37 @@
{
if (NULL == output_bool)
return RETURN_ERR;
- *output_bool=FALSE;
+ *output_bool=TRUE;
return RETURN_OK;
}
INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool) //RDKB
{
+ unsigned long period = 0;
+
if (NULL == output_bool)
return RETURN_ERR;
- *output_bool=FALSE;
+
+ if (wifi_getRadioAutoChannelRefreshPeriod(radioIndex, &period) != RETURN_OK)
+ return RETURN_ERR;
+
+ *output_bool = (period > 0) ? TRUE : FALSE;
+
return RETURN_OK;
}
-INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB
+INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB
{
- //Set to wifi config only. Wait for wifi reset to apply.
+ ULONG period = 1800;
+
+ if (enable == TRUE) {
+ if (wifi_setRadioAutoChannelRefreshPeriod(radioIndex, period) != RETURN_OK)
+ return RETURN_ERR;
+ }
+ else {
+ if (wifi_setRadioAutoChannelRefreshPeriod(radioIndex, 0) != RETURN_OK)
+ return RETURN_ERR;
+ }
return RETURN_OK;
}
@@ -3914,24 +3930,85 @@
//The value of this parameter is a comma seperated list of channel number
INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool) //RDKB
{
- int res;
+
+ #define CHANNEL_AVAILABLE 0
+ #define CHANNEL_INVALID 1
+ #define CHANNEL_LIST_MAX_LENGTH 256
+ #define MAX_CHANNEL_NUMBER 255
+
+ char config_file[MAX_BUF_SIZE] = {0};
+ char possible_channels[CHANNEL_LIST_MAX_LENGTH] = {0};
+ char skip_list[CHANNEL_LIST_MAX_LENGTH] = {0};
+ int skip_table[MAX_CHANNEL_NUMBER +1] = {0};
+ wifi_band band = band_invalid;
+ char *token_channel = NULL, *token_skip = NULL;
if (NULL == output_pool)
return RETURN_ERR;
- if (radioIndex==1)
- return RETURN_OK;//TODO need to handle for 5GHz band, i think
- res = snprintf(output_pool, 256, "1,2,3,4,5,6,7,8,9,10,11");
- if (os_snprintf_error(256, res)) {
- wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
- return RETURN_ERR;
+ // get skiplist, possible_channels list
+ wifi_getRadioPossibleChannels(radioIndex, possible_channels);
+ band = wifi_index_to_band(radioIndex);
+ snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
+ wifi_datfileRead(config_file, "AutoChannelSkipList", skip_list, sizeof(skip_list));
+
+ if (skip_list[0] != '\0') {
+ int len = strlen(skip_list);
+ for (int i = 0; i < len; i++) {
+ if (skip_list[i] == ';') {
+ skip_list[i] = ',';
+ }
+ }
+ // skip list
+ token_skip = strtok(skip_list, ",");
+ while (token_skip != NULL) {
+ int channel = atoi(token_skip);
+ if (channel <= MAX_CHANNEL_NUMBER && strstr(possible_channels, token_skip) != NULL)
+ skip_table[atoi(token_skip)] = CHANNEL_INVALID;
+ token_skip = strtok(NULL, ",");
+ }
}
+ int count = 0;
+ token_channel = strtok(possible_channels, ",");
+ while (token_channel != NULL) {
+ int channel = atoi(token_channel);
+ if (channel <= MAX_CHANNEL_NUMBER && skip_table[channel] == CHANNEL_AVAILABLE) {
+ count += snprintf(&output_pool[count], CHANNEL_LIST_MAX_LENGTH-count, "%d,", channel);
+ if (count >= CHANNEL_LIST_MAX_LENGTH-1)
+ break;
+ }
+ token_channel = strtok(NULL, ",");
+ }
+ //delete the last one ','
+ if (count >0 && output_pool[count-1] == ',')
+ output_pool[count-1] = '\0';
return RETURN_OK;
}
INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool) //RDKB
{
- //Set to wifi config. And apply instantly.
+ char config_file_dat[128] = {0};
+ struct params dat = {0};
+ wifi_band band = band_invalid;
+ char new_pool[128] = {0};
+
+ if (NULL == pool)
+ return RETURN_ERR;
+
+ strncpy(new_pool, pool, strlen(pool));
+ for (int i = 0; new_pool[i] != '\0'; i++) {
+ if (new_pool[i] == ',')
+ new_pool[i] = ';';
+ }
+
+ dat.name = "AutoChannelSkipList";
+ dat.value = new_pool;
+ band = wifi_index_to_band(radioIndex);
+ snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
+ if (wifi_datfileWrite(config_file_dat, &dat, 1) != 0)
+ return RETURN_ERR;
+ wifi_reloadAp(radioIndex);
+
return RETURN_OK;
}
@@ -3939,8 +4016,10 @@
{
if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds)
return RETURN_ERR;
- *output_interval_seconds=1800;
- *output_dwell_milliseconds=40;
+ //Should refresh period time be filled in here? output_interval_seconds is INT type
+ //wifi_getRadioAutoChannelRefreshPeriod is Ulong type
+ *output_interval_seconds = 1800;
+ *output_dwell_milliseconds = 200;
return RETURN_OK;
}
@@ -4030,24 +4109,157 @@
{
if (NULL == output_bool)
return RETURN_ERR;
- *output_bool=FALSE; //not support
+ *output_bool = TRUE;
return RETURN_OK;
}
+
+int get_ACS_RefreshPeriod_callback(struct nl_msg *msg, void *arg)
+{
+ ULONG *data = (ULONG *)arg;
+ struct nlattr *tb[NL80211_ATTR_MAX + 1];
+ struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
+ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+ int err = 0;
+
+ err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+ genlmsg_attrlen(gnlh, 0), NULL);
+ if (err < 0)
+ return NL_SKIP;
+
+ if (tb[NL80211_ATTR_VENDOR_DATA]) {
+ err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
+ tb[NL80211_ATTR_VENDOR_DATA], NULL);
+ if (err < 0)
+ return NL_SKIP;
+
+ if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD]) {
+ *data = nla_get_u32(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD]);
+ }
+ }
+
+ return NL_OK;
+}
+
//Get the ACS refresh period in seconds
INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181
{
+ char interface_name[IF_NAME_SIZE] = {0};
+ int ret = -1;
+ unsigned int if_idx = 0;
+ struct unl unl_ins;
+ struct nl_msg *msg = NULL;
+ struct nlattr * msg_data = NULL;
+ struct mtk_nl80211_param param;
+ unsigned long checktime = 0;
+
+ WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
if (NULL == output_ulong)
return RETURN_ERR;
+
+ if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
+ return RETURN_ERR;
+
+ if_idx = if_nametoindex(interface_name);
+ if (!if_idx) {
+ wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
+ return RETURN_ERR;
- *output_ulong=300;
+ }
+ /*init mtk nl80211 vendor cmd*/
+ param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
+ param.if_type = NL80211_ATTR_IFINDEX;
+ param.if_idx = if_idx;
+ ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m);
+ if (ret) {
+ wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
+ return RETURN_ERR;
+ }
+
+ /*add mtk vendor cmd data*/
+ if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD, 0)) {
+ wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD attribute error\n");
+ nlmsg_free(msg);
+ goto err;
+ }
+
+ /*send mtk nl80211 vendor msg*/
+ ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_ACS_RefreshPeriod_callback, &checktime);
+
+ if (ret) {
+ wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
+ goto err;
+ }
+ /*deinit mtk nl80211 vendor msg*/
+ mtk_nl80211_deint(&unl_ins);
+ *output_ulong = checktime;
+ wifi_debug(DEBUG_NOTICE,"send cmd success\n");
+
+ WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
return RETURN_OK;
+err:
+ mtk_nl80211_deint(&unl_ins);
+ wifi_debug(DEBUG_ERROR,"send cmd fails\n");
+ return RETURN_ERR;
+
}
//Set the ACS refresh period in seconds
INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181
{
+ char interface_name[IF_NAME_SIZE] = {0};
+ int ret = -1;
+ unsigned int if_idx = 0;
+ struct unl unl_ins;
+ struct nl_msg *msg = NULL;
+ struct nlattr * msg_data = NULL;
+ struct mtk_nl80211_param param;
+
+ WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
+
+ if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
+ return RETURN_ERR;
+
+ if_idx = if_nametoindex(interface_name);
+ if (!if_idx) {
+ wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
+ return RETURN_ERR;
+ }
+ /*init mtk nl80211 vendor cmd*/
+ param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AUTO_CH_SEL;
+ param.if_type = NL80211_ATTR_IFINDEX;
+ param.if_idx = if_idx;
+
+ ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m);
+ if (ret) {
+ wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
+ return RETURN_ERR;
+ }
+
+ /*add mtk vendor cmd data*/
+ if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_AUTO_CH_CHECK_TIME, seconds)) {
+ wifi_debug(DEBUG_ERROR, "Nla put MTK_NL80211_VENDOR_ATTR_AUTO_CH_CHECK_TIME attribute error\n");
+ nlmsg_free(msg);
+ goto err;
+ }
+
+ /*send mtk nl80211 vendor msg*/
+ ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
+
+ if (ret) {
+ wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
+ goto err;
+ }
+ /*deinit mtk nl80211 vendor msg*/
+ mtk_nl80211_deint(&unl_ins);
+ wifi_debug(DEBUG_NOTICE,"send cmd success\n");
+
+ WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
+ return RETURN_OK;
+err:
+ mtk_nl80211_deint(&unl_ins);
+ wifi_debug(DEBUG_ERROR,"send cmd fails\n");
return RETURN_ERR;
}
@@ -14774,7 +14986,48 @@
wifi_debug(DEBUG_NOTICE, "Ap set IGMP Snooping Enable: %d\n", enable);
return 0;
}
+ if (strncmp(argv[1], "wifi_setRadioDCSEnable(", strlen(argv[1])) == 0) {
+ int enable = 0;
+ if(argc <= 3 )
+ {
+ wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+ exit(-1);
+ }
+ enable = (BOOL)atoi(argv[3]);
+ wifi_setRadioDCSEnable(index, enable);
+ wifi_debug(DEBUG_NOTICE, "Ap set DCS Enable: %d\n", enable);
+ return 0;
+ }
+ if (strncmp(argv[1], "wifi_getRadioAutoChannelRefreshPeriod(", strlen(argv[1])) == 0) {
+ ULONG period = 0;
+ wifi_getRadioAutoChannelRefreshPeriod(index, &period);
+ wifi_debug(DEBUG_NOTICE, "Get RefreshPeriod: %ld\n", period);
+ return 0;
+ }
+ if (strncmp(argv[1], "wifi_setRadioDfsRefreshPeriod(", strlen(argv[1])) == 0) {
+ ULONG period = 0;
+
+ period = (ULONG)atoi(argv[3]);
+ wifi_setRadioDfsRefreshPeriod(index, period);
+ wifi_debug(DEBUG_NOTICE, "Set RefreshPeriod: %ld\n", period);
+ return 0;
+ }
+ if (strncmp(argv[1], "wifi_setRadioDCSChannelPool(", strlen(argv[1])) == 0) {
+ char pool[256] = {'\0'};
+
+ strcpy(pool, argv[3]);
+ wifi_setRadioDCSChannelPool(index, pool);
+ wifi_debug(DEBUG_NOTICE, "Set DCSChannelPool: %s\n", pool);
+ return 0;
+ }
+ if (strncmp(argv[1], "wifi_getRadioDCSChannelPool(", strlen(argv[1])) == 0) {
+ char pool[256] = {'\0'};
+
+ wifi_getRadioDCSChannelPool(index, pool);
+ wifi_debug(DEBUG_NOTICE, "Get DCSChannelPool: %s\n", pool);
+ return 0;
+ }
if (strncmp(argv[1], "wifi_getRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
BOOL out_status = 0;
wifi_getRadioIGMPSnoopingEnable(index, &out_status);