1+ from .... import channels
12from ..schema import default_radio_driver
23from .base import OpenWrtConverter
34
@@ -20,8 +21,7 @@ def __intermediate_radio(self, radio):
2021 radio ['txpower' ] = radio .pop ('tx_power' )
2122 # rename driver to type
2223 radio ['type' ] = radio .pop ('driver' , default_radio_driver )
23- # determine hwmode option
24- radio ['hwmode' ] = self .__intermediate_hwmode (radio )
24+ self .__set_intermediate_band (radio )
2525 # check if using channel 0, that means "auto"
2626 if radio ['channel' ] == 0 :
2727 radio ['channel' ] = 'auto'
@@ -35,10 +35,78 @@ def __intermediate_radio(self, radio):
3535 radio ['country' ] = radio ['country' ].upper ()
3636 return self .sorted_dict (radio )
3737
38+ def __set_intermediate_band (self , radio ):
39+ if self .dsa :
40+ radio ['band' ] = self .__intermediate_band (radio )
41+ else :
42+ radio ['hwmode' ] = self .__intermediate_hwmode (radio )
43+
44+ def __intermediate_band (self , radio ):
45+ """
46+ Returns value for "band" option (introduced in OpenWrt 21)
47+
48+ Backward compatibility: If the configuration defines
49+ "hwmode" instead of "band", then the value for "band" is inferred
50+ from "hwmode".
51+
52+ If both "band" and "hwmode" are absent, then value for "band"
53+ is inferred from "protocal" or "channel".
54+ """
55+ hwmode = radio .pop ('hwmode' , None )
56+ band = radio .pop ('band' , None )
57+ if band :
58+ return band
59+ if hwmode :
60+ return self .__intermediate_band_from_hwmode (hwmode )
61+ channel = radio .get ('channel' )
62+ protocol = radio .get ('protocol' )
63+ # Infer radio frequency from protocol if possible
64+ if protocol == '802.11ad' :
65+ return '60g'
66+ elif protocol in ['802.11b' , '802.11g' ]:
67+ return '2g'
68+ elif protocol in ['802.11a' , '802.11ac' ]:
69+ return '5g'
70+ # Infer radio frequency from channel of the radio
71+ if channel in channels .channels_2ghz :
72+ return '2g'
73+ elif channel in channels .channels_5ghz :
74+ return '5g'
75+ elif channel in channels .channels_6ghz :
76+ return '6g'
77+
78+ def __intermediate_band_from_hwmode (self , hwmode ):
79+ # Using "hwmode" we can only predict 2GHz and 5GHz radios.
80+ # Support for 802.11ax (2/5/6 GHz) and 802.11ad (60 GHz)
81+ # was added in OpenWrt 21.
82+ if hwmode == '11a' :
83+ return '5g'
84+ elif hwmode in ['11b' , '11g' ]:
85+ return '2g'
86+
3887 def __intermediate_hwmode (self , radio ):
3988 """
40- possible return values are: 11a, 11b, 11g
89+ Returns value for "hwmode" option (OpenWrt < 21)
90+
91+ Backward compatibility: If the configuration defines
92+ "band" (introduced in OpenWrt 21) instead of "hwmode",
93+ then the value for "hwmode" is inferred from "band".
4194 """
95+ hwmode = radio .pop ('hwmode' , None )
96+ band = radio .pop ('band' , None )
97+ if hwmode :
98+ return hwmode
99+ if band :
100+ # 802.11ax and 802.11ad were not supported in OpenWrt < 21.
101+ # Hence, we ignore "6g" and "60g" values.
102+ if band == '2g' :
103+ if radio ['protocol' ] == '802.11b' :
104+ return '11b'
105+ else :
106+ return '11g'
107+ elif band == '5g' :
108+ return '11a'
109+ # Use protocol to infer "hwmode"
42110 protocol = radio ['protocol' ]
43111 if protocol in ['802.11a' , '802.11b' , '802.11g' ]:
44112 # return 11a, 11b or 11g
@@ -97,14 +165,20 @@ def __netjson_protocol(self, radio):
97165 determines NetJSON protocol radio attribute
98166 """
99167 htmode = radio .get ('htmode' )
100- hwmode = radio .get ('hwmode' , None )
101168 if htmode .startswith ('HT' ):
102169 return '802.11n'
103170 elif htmode .startswith ('VHT' ):
104171 return '802.11ac'
105172 elif htmode .startswith ('HE' ):
106173 return '802.11ax'
107- return '802.{0}' .format (hwmode )
174+ elif htmode == 'NONE' :
175+ band = radio .get ('band' )
176+ if self .dsa and band :
177+ band_map = {'2g' : '802.11g' , '5g' : '802.11a' , '60g' : '802.11ad' }
178+ return band_map [band ]
179+ else :
180+ hwmode = radio .get ('hwmode' , None )
181+ return '802.{0}' .format (hwmode )
108182
109183 def __netjson_channel (self , radio ):
110184 """
@@ -114,7 +188,7 @@ def __netjson_channel(self, radio):
114188 return 0
115189 # delete hwmode because is needed
116190 # only when channel is auto
117- del radio [ 'hwmode' ]
191+ radio . pop ( 'hwmode' , None )
118192 return int (radio ['channel' ])
119193
120194 def __netjson_channel_width (self , radio ):
0 commit comments