From e4f1fd86536db003db0b0b1c7dcc8a899574525c Mon Sep 17 00:00:00 2001
From: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
Date: Mon, 22 Jun 2020 16:43:17 +0100
Subject: [PATCH] WiFi: fix get/set value of SupportedFrequencyBands and
 OperatingFrequencyBand parameters

---
 dmtree/tr181/os.h             |  1 +
 dmtree/tr181/wifi-iopsyswrt.c | 13 +++++++++++++
 dmtree/tr181/wifi-openwrt.c   |  5 +++++
 dmtree/tr181/wifi.c           | 16 ++++++++++++----
 json/tr181.json               | 13 ++++++++++++-
 libbbf_api/dmcommon.c         |  1 +
 libbbf_api/dmcommon.h         |  1 +
 7 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/dmtree/tr181/os.h b/dmtree/tr181/os.h
index e0998c8b3..2099bdae6 100644
--- a/dmtree/tr181/os.h
+++ b/dmtree/tr181/os.h
@@ -106,6 +106,7 @@ int os__get_access_point_associative_device_statistics_retry_count(char *refpara
 int os__get_access_point_associative_device_statistics_multiple_retry_count(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
 int os__get_radio_max_bit_rate (char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
 int os__get_radio_frequency(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
+int os__get_radio_supported_frequency_bands(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
 int os__get_radio_channel(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
 int os__get_neighboring_wifi_diagnostics_diagnostics_state(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
 int os__get_neighboring_wifi_diagnostics_result_ssid(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);
diff --git a/dmtree/tr181/wifi-iopsyswrt.c b/dmtree/tr181/wifi-iopsyswrt.c
index da476429f..c4cdc4d22 100644
--- a/dmtree/tr181/wifi-iopsyswrt.c
+++ b/dmtree/tr181/wifi-iopsyswrt.c
@@ -311,6 +311,19 @@ int os__get_radio_frequency(char *refparam, struct dmctx *ctx, void *data, char
 	return 0;
 }
 
+/*#Device.WiFi.Radio.{i}.SupportedFrequencyBands!UBUS:wifi.radio.@Name/status//supp_bands*/
+int os__get_radio_supported_frequency_bands(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+	json_object *res = NULL;
+	char object[32];
+
+	snprintf(object, sizeof(object), "wifi.radio.%s", section_name(((struct wifi_radio_args *)data)->wifi_radio_sec));
+	dmubus_call(object, "status", UBUS_ARGS{}, 0, &res);
+	DM_ASSERT(res, *value = "");
+	*value = dmjson_get_value_array_all(res, DELIMITOR, 1, "supp_bands");
+	return 0;
+}
+
 /*#Device.WiFi.Radio.{i}.ChannelsInUse!UCI:wireless/wifi-device,@i-1/channel*/
 int os__get_radio_channel(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
diff --git a/dmtree/tr181/wifi-openwrt.c b/dmtree/tr181/wifi-openwrt.c
index e96141da1..501f52329 100644
--- a/dmtree/tr181/wifi-openwrt.c
+++ b/dmtree/tr181/wifi-openwrt.c
@@ -221,6 +221,11 @@ int os__get_radio_frequency(char *refparam, struct dmctx *ctx, void *data, char
 	return not_implemented(value);
 }
 
+int os__get_radio_supported_frequency_bands(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+{
+	return not_implemented(value);
+}
+
 int os__get_radio_channel(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
 {
 	return not_implemented(value);
diff --git a/dmtree/tr181/wifi.c b/dmtree/tr181/wifi.c
index 75056aa08..9320db0f7 100644
--- a/dmtree/tr181/wifi.c
+++ b/dmtree/tr181/wifi.c
@@ -1341,9 +1341,17 @@ static int set_WiFiAccessPointAccounting_Secret(char *refparam, struct dmctx *ct
 	return 0;
 }
 
-static int get_radio_supported_frequency_bands(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
+static int set_radio_frequency(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
 {
-	*value = "2.4GHz,5GHz";
+	switch (action)	{
+		case VALUECHECK:
+			if (dm_validate_string(value, -1, -1, SupportedFrequencyBands, 2, NULL, 0))
+				return FAULT_9007;
+			break;
+		case VALUESET:
+			dmuci_set_value_by_section(((struct wifi_radio_args *)data)->wifi_radio_sec, "hwmode", (!strcmp(value, "5GHz") ? "11a" :"11g"));
+			break;
+	}
 	return 0;
 }
 
@@ -2275,8 +2283,8 @@ DMLEAF tWiFiRadioParams[] = {
 {"LowerLayers", &DMWRITE, DMT_STRING, get_WiFiRadio_LowerLayers, set_WiFiRadio_LowerLayers, NULL, NULL, BBFDM_BOTH},
 {"Name", &DMREAD, DMT_STRING, get_WiFiRadio_Name, NULL, NULL, NULL, BBFDM_BOTH},
 {"MaxBitRate", &DMREAD, DMT_UNINT, os__get_radio_max_bit_rate, NULL, NULL, NULL, BBFDM_BOTH},
-{"OperatingFrequencyBand", &DMREAD, DMT_STRING, os__get_radio_frequency, NULL, NULL, NULL, BBFDM_BOTH},
-{"SupportedFrequencyBands", &DMREAD, DMT_STRING, get_radio_supported_frequency_bands, NULL, NULL, NULL, BBFDM_BOTH},
+{"OperatingFrequencyBand", &DMWRITE, DMT_STRING, os__get_radio_frequency, set_radio_frequency, NULL, NULL, BBFDM_BOTH},
+{"SupportedFrequencyBands", &DMREAD, DMT_STRING, os__get_radio_supported_frequency_bands, NULL, NULL, NULL, BBFDM_BOTH},
 {"SupportedStandards", &DMREAD, DMT_STRING, os__get_radio_supported_standard, NULL, NULL, NULL, BBFDM_BOTH},
 {"OperatingStandards", &DMWRITE, DMT_STRING, os_get_radio_operating_standard, set_radio_operating_standard, NULL, NULL, BBFDM_BOTH},
 {"ChannelsInUse", &DMREAD, DMT_STRING, os__get_radio_channel, NULL, NULL, NULL, BBFDM_BOTH},
diff --git a/json/tr181.json b/json/tr181.json
index 9df56279a..783d75bc1 100644
--- a/json/tr181.json
+++ b/json/tr181.json
@@ -29232,7 +29232,18 @@
 							"2.4GHz", 
 							"5GHz"
 						]
-					}
+					},
+					"mapping": [
+						{
+							"type": "ubus", 
+							"ubus": {
+								"object": "wifi.radio.@Name", 
+								"method": "status", 
+								"args": {}, 
+								"key": "supp_bands"
+							}
+						}
+					]
 				}, 
 				"OperatingFrequencyBand": {
 					"type": "string", 
diff --git a/libbbf_api/dmcommon.c b/libbbf_api/dmcommon.c
index 110b15e37..fa1d1f802 100644
--- a/libbbf_api/dmcommon.c
+++ b/libbbf_api/dmcommon.c
@@ -57,6 +57,7 @@ char *DTMFMethod[] = {"InBand", "RFC2833", "SIPInfo"};
 char *ProfileEnable[] = {"Disabled", "Quiescent", "Enabled"};
 char *SupportedOperatingChannelBandwidth[] = {"20MHz", "40MHz", "80MHz", "160MHZ", "80+80MHz", "Auto"};
 char *SupportedStandards[] = {"a", "b", "g", "n", "ac", "ax"};
+char *SupportedFrequencyBands[] = {"2.4GHz", "5GHz"};
 
 char *PIN[] = {"^\\d{4}|\\d{8}$"};
 char *DestinationAddress[] = {"^\\d+/\\d+$"};
diff --git a/libbbf_api/dmcommon.h b/libbbf_api/dmcommon.h
index 7633add23..2bb394325 100644
--- a/libbbf_api/dmcommon.h
+++ b/libbbf_api/dmcommon.h
@@ -103,6 +103,7 @@ extern char *IPv4Prefix[];
 extern char *IPv6Prefix[];
 extern char *SupportedOperatingChannelBandwidth[];
 extern char *SupportedStandards[];
+extern char *SupportedFrequencyBands[];
 
 #define UPTIME "/proc/uptime"
 #define DEFAULT_CONFIG_DIR "/etc/config/"
-- 
GitLab