• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "wifi_event.h"
16 #include "wifi_error_code.h"
17 #include "wifi_device_config.h"
18 #include "wifi_hotspot_config.h"
19 #include "inet.h"
20 #include "wifi_host.h"
21 #include "dhcp.h"
22 #include "dhcps.h"
23 #include "wlan_if.h"
24 #include "wifi_config.h"
25 #include "securec.h"
26 #include "dbg.h"
27 
28 #define IP_MASK 0x00FFFFFF
29 #define DEFAULT_AP_VIF 0
30 #define DEFAULT_BAND PHY_BAND_2G4
31 #define DEFAULT_CHANNLE 7
32 #define RSSI_LEVEL_4_2_G (-65)
33 #define RSSI_LEVEL_3_2_G (-75)
34 #define RSSI_LEVEL_2_2_G (-82)
35 #define RSSI_LEVEL_1_2_G (-88)
36 #define RSSI_LEVEL_4_5_G (-65)
37 #define RSSI_LEVEL_3_5_G (-72)
38 #define RSSI_LEVEL_2_5_G (-79)
39 #define RSSI_LEVEL_1_5_G (-85)
40 
41 ChipseaWifiApData g_apData = {0};
42 
SetApVif()43 static int32_t SetApVif()
44 {
45     struct fhost_vif_tag *fhost_vif;
46     struct fhost_cntrl_link *apLink;
47     ipc_host_cntrl_start();
48 
49     apLink = fhost_cntrl_cfgrwnx_link_open();
50     if (apLink == NULL) {
51         dbg("Failed to open link with control task\n");
52         return ERROR_WIFI_UNKNOWN;
53     }
54 
55     if (fhost_set_vif_type(apLink, DEFAULT_AP_VIF, VIF_UNKNOWN, false) ||
56         fhost_set_vif_type(apLink, DEFAULT_AP_VIF, VIF_AP, false)) {
57         fhost_cntrl_cfgrwnx_link_close(apLink);
58         return ERROR_WIFI_UNKNOWN;
59     }
60 
61     fhost_cntrl_cfgrwnx_link_close(apLink);
62 
63     fhost_vif = &fhost_env.vif[DEFAULT_AP_VIF];
64     MAC_ADDR_CPY(&(vif_info_tab[DEFAULT_AP_VIF].mac_addr), &(fhost_vif->mac_addr));
65 
66     return WIFI_SUCCESS;
67 }
68 
EnableHotspot(void)69 WifiErrorCode EnableHotspot(void)
70 {
71     if (WifiCreateLock() != WIFI_SUCCESS) {
72         return ERROR_WIFI_NOT_AVAILABLE;
73     }
74 
75     if (g_apData.state == WIFI_HOTSPOT_ACTIVE) {
76         dbg("ap has enabled\r\n");
77         WifiUnlock();
78         return ERROR_WIFI_UNKNOWN;
79     }
80 
81     LOS_ListInit(&g_apData.stationHead);
82 
83     if (g_apData.vifApCfg.ssid.length == 0) {
84         dbg("Failed to start AP, check ssid\r\n");
85         goto enable_err;
86     }
87 
88     if (SetApVif() != WIFI_SUCCESS) {
89         dbg("SetApVif err\r\n");
90         goto enable_err;
91     }
92 
93     if (fhost_ap_cfg(DEFAULT_AP_VIF, &g_apData.vifApCfg)) {
94         dbg("Failed to start AP, check your configuration\r\n");
95         goto enable_err;
96     }
97 
98     net_if_t *net_if = fhost_to_net_if(DEFAULT_AP_VIF);
99     if (net_if == NULL) {
100         dbg("[CS] net_if_find_from_wifi_idx fail\r\n");
101         goto enable_err;
102     }
103 
104     uint32_t ip_addr = get_ap_ip_addr();
105     net_if_set_ip(net_if, ip_addr, IP_MASK, 0);
106 
107     //set up DHCP server
108     dhcpServerStart(net_if);
109 
110     // Now that we got an IP address use this interface as default
111     net_if_set_default(net_if);
112 
113     fhost_tx_task_init();
114 
115     dbg("DHCPS init: ip=%d.%d.%d.%d\r\n", (ip_addr)&0xFF, (ip_addr>>8)&0xFF, (ip_addr>>16)&0xFF, (ip_addr>>24)&0xFF);
116 
117     g_apData.state = WIFI_HOTSPOT_ACTIVE;
118     DoApStateCallBack(WIFI_STATE_AVAILABLE);
119     WifiUnlock();
120     return WIFI_SUCCESS;
121 enable_err:
122     DoApStateCallBack(WIFI_STATE_NOT_AVAILABLE);
123     WifiUnlock();
124     return ERROR_WIFI_UNKNOWN;
125 }
126 
DisableHotspot(void)127 WifiErrorCode DisableHotspot(void)
128 {
129     WifiStationNode *pos = NULL;
130     if (WifiCreateLock() != WIFI_SUCCESS) {
131         return ERROR_WIFI_NOT_AVAILABLE;
132     }
133     if (g_apData.state == WIFI_HOTSPOT_NOT_ACTIVE) {
134         dbg("wifi ap has closed\r\n");
135         WifiUnlock();
136         return ERROR_WIFI_NOT_AVAILABLE;
137     }
138 
139     wlan_stop_ap();
140     LOS_DL_LIST_FOR_EACH_ENTRY(pos, &g_apData.stationHead, WifiStationNode, node) {
141         LOS_ListDelete(&pos->node);
142         rtos_free(pos);
143     }
144     g_apData.stationCnt = 0;
145     g_apData.state = WIFI_HOTSPOT_NOT_ACTIVE;
146     DoApStateCallBack(WIFI_STATE_NOT_AVAILABLE);
147     WifiUnlock();
148     return WIFI_SUCCESS;
149 }
150 
SetSecType(WifiSecurityType security_type,struct fhost_vif_ap_cfg * cfg)151 static void SetSecType(WifiSecurityType security_type,struct fhost_vif_ap_cfg *cfg)
152 {
153     cfg->akm = 0;
154     switch (security_type) {
155         case WIFI_SEC_TYPE_WEP:
156             cfg->akm |= CO_BIT(MAC_AKM_PRE_RSN);
157             break;
158         case WIFI_SEC_TYPE_PSK:
159             cfg->akm |= CO_BIT(MAC_AKM_PRE_RSN) | CO_BIT(MAC_AKM_PSK);
160             break;
161         case WIFI_SEC_TYPE_SAE:
162             cfg->akm |= CO_BIT(MAC_AKM_SAE);
163             break;
164         default:
165             cfg->akm |= CO_BIT(MAC_AKM_NONE);
166             break;
167     }
168     dbg("WifiAp:set akm =%d\r\n", cfg->akm);
169 }
170 
SetChannel(int channelNum,int band,struct fhost_vif_ap_cfg * cfg)171 static int32_t SetChannel(int channelNum, int band, struct fhost_vif_ap_cfg *cfg)
172 {
173     if (band == HOTSPOT_BAND_TYPE_2G) {
174         cfg->chan.band = PHY_BAND_2G4;
175     } else if (band == HOTSPOT_BAND_TYPE_5G) {
176         cfg->chan.band = PHY_BAND_5G;
177     } else {
178         dbg("Invalid band set default 2G4\r\n");
179         cfg->chan.band = DEFAULT_BAND;
180     }
181 
182     channelNum = (channelNum == 0) ? DEFAULT_CHANNLE : channelNum;
183     cfg->chan.prim20_freq = phy_channel_to_freq(cfg->chan.band, channelNum);
184     cfg->chan.type = PHY_CHNL_BW_20;
185     cfg->chan.center1_freq = cfg->chan.prim20_freq;
186     return WIFI_SUCCESS;
187 }
188 
SetHotspotConfig(const HotspotConfig * config)189 WifiErrorCode SetHotspotConfig(const HotspotConfig *config)
190 {
191     PARAM_CHECK(config);
192 
193     if (WifiCreateLock() != WIFI_SUCCESS) {
194         return ERROR_WIFI_NOT_AVAILABLE;
195     }
196     memset(&g_apData.vifApCfg, 0, sizeof(struct fhost_vif_ap_cfg));
197 
198     if (strcpy_s((char *)g_apData.vifApCfg.ssid.array, MAC_SSID_LEN, config->ssid) != EOK) {
199         dbg("Invalid SSID\r\n");
200         WifiUnlock();
201         return ERROR_WIFI_UNKNOWN;
202     }
203     g_apData.vifApCfg.ssid.length = strlen(config->ssid);
204 
205     SetSecType(config->securityType, &g_apData.vifApCfg);
206 
207     if (SetChannel(config->channelNum, config->band, &g_apData.vifApCfg) != WIFI_SUCCESS) {
208         dbg("set channel err chan = %d.band = %d\r\n", config->channelNum, config->band);
209         WifiUnlock();
210         return ERROR_WIFI_UNKNOWN;
211     }
212 
213     if (strcpy_s(g_apData.vifApCfg.key, sizeof(g_apData.vifApCfg.key), config->preSharedKey) != EOK) {
214         dbg("Invalid key\r\n");
215         WifiUnlock();
216         return ERROR_WIFI_UNKNOWN;
217     }
218 
219     memcpy(&g_apData.hostpotCfg, config, sizeof(HotspotConfig));
220     WifiUnlock();
221     return WIFI_SUCCESS;
222 }
223 
GetHotspotConfig(HotspotConfig * result)224 WifiErrorCode GetHotspotConfig(HotspotConfig *result)
225 {
226     PARAM_CHECK(result);
227     memcpy(result, &g_apData.hostpotCfg, sizeof(HotspotConfig));
228     return WIFI_SUCCESS;
229 }
230 
IsHotspotActive(void)231 int IsHotspotActive(void)
232 {
233     return g_apData.state;
234 }
235 
GetStationList(StationInfo * result,unsigned int * size)236 WifiErrorCode GetStationList(StationInfo *result, unsigned int *size)
237 {
238     uint8_t cnt = 0;
239     WifiStationNode *pos = NULL;
240 
241     if (g_apData.state != WIFI_HOTSPOT_ACTIVE) {
242         dbg("hotspot not enable\r\n");
243         return ERROR_WIFI_UNKNOWN;
244     }
245 
246     LOS_DL_LIST_FOR_EACH_ENTRY(pos, &g_apData.stationHead, WifiStationNode, node) {
247         (void)memcpy_s(result, sizeof(StationInfo), &(pos->station), sizeof(StationInfo));
248         cnt++;
249     }
250 
251     *size = cnt;
252     return WIFI_SUCCESS;
253 }
254 
SetBand(int band)255 WifiErrorCode SetBand(int band)
256 {
257     dbg("SetBand = %d\r\n", band);
258     g_apData.hostpotCfg.band = band;
259     if (band == HOTSPOT_BAND_TYPE_2G) {
260         g_apData.vifApCfg.chan.band = PHY_BAND_2G4;
261     } else if (band == HOTSPOT_BAND_TYPE_5G) {
262         g_apData.vifApCfg.chan.band = PHY_BAND_5G;
263     } else {
264         dbg("Invalid band\r\n");
265         return ERROR_WIFI_UNKNOWN;
266     }
267     return WIFI_SUCCESS;
268 }
269 
GetBand(int * result)270 WifiErrorCode GetBand(int *result)
271 {
272     PARAM_CHECK(result);
273     *result = g_apData.hostpotCfg.band;
274     if ((*result != HOTSPOT_BAND_TYPE_2G) && (*result != HOTSPOT_BAND_TYPE_5G)) {
275         dbg("Invalid band = %d\r\n", g_apData.hostpotCfg.band);
276         return ERROR_WIFI_UNKNOWN;
277     }
278     return WIFI_SUCCESS;
279 }
280 
GetSignalLevel(int rssi,int band)281 int GetSignalLevel(int rssi, int band)
282 {
283     if (band == HOTSPOT_BAND_TYPE_2G) {
284         if (rssi >= RSSI_LEVEL_4_2_G)
285             return RSSI_LEVEL_4;
286         if (rssi >= RSSI_LEVEL_3_2_G)
287             return RSSI_LEVEL_3;
288         if (rssi >= RSSI_LEVEL_2_2_G)
289             return RSSI_LEVEL_2;
290         if (rssi >= RSSI_LEVEL_1_2_G)
291             return RSSI_LEVEL_1;
292     }
293 
294     if (band == HOTSPOT_BAND_TYPE_5G) {
295         if (rssi >= RSSI_LEVEL_4_5_G)
296             return RSSI_LEVEL_4;
297         if (rssi >= RSSI_LEVEL_3_5_G)
298             return RSSI_LEVEL_3;
299         if (rssi >= RSSI_LEVEL_2_5_G)
300             return RSSI_LEVEL_2;
301         if (rssi >= RSSI_LEVEL_1_5_G)
302             return RSSI_LEVEL_1;
303     }
304     return ERROR_WIFI_INVALID_ARGS;
305 }
306 
HandleStaConnect(uint8_t * macAddr,ip4_addr_t clientIP)307 void HandleStaConnect(uint8_t *macAddr, ip4_addr_t clientIP)
308 {
309     if (g_apData.state != WIFI_HOTSPOT_ACTIVE) {
310         dbg("ap not enabled\r\n");
311         return;
312     }
313 
314     if (macAddr == NULL) {
315         dbg("null check err\r\n");
316         return;
317     }
318     if (WifiCreateLock() != WIFI_SUCCESS) {
319         return;
320     }
321 
322     if (g_apData.stationCnt > WIFI_MAX_STA_NUM) {
323         dbg("station cnt over flow\r\n");
324         WifiUnlock();
325         return;
326     }
327 
328     WifiStationNode *stationNode = (WifiStationNode *)rtos_calloc(1, sizeof(*stationNode));
329     if (stationNode == NULL) {
330         WifiUnlock();
331         return;
332     }
333     memcpy(&stationNode->station.macAddress, macAddr, WIFI_MAC_LEN);
334     stationNode->station.ipAddress = ntohl(ip4_addr_get_u32(&clientIP));
335 
336     LOS_ListTailInsert(&g_apData.stationHead, &stationNode->node);
337     g_apData.stationCnt++;
338     dbg("station join: mac->%02X:%02X:%02X:%02X:%02X:%02X ip-> %s,cnt= %d\r\n", macAddr[0], macAddr[1],
339          macAddr[2], macAddr[3], macAddr[4], macAddr[5], inet_ntoa(clientIP), g_apData.stationCnt);
340     DoStaJoinCallBack(&stationNode->station);
341     WifiUnlock();
342 }
343 
HandleStaDisconnect(uint8_t * macAddr)344 void HandleStaDisconnect(uint8_t *macAddr)
345 {
346     if (g_apData.state != WIFI_HOTSPOT_ACTIVE) {
347         dbg("ap not enabled\r\n");
348         return;
349     }
350 
351     if (macAddr == NULL) {
352         dbg("null check err\r\n");
353         return;
354     }
355     if (WifiCreateLock() != WIFI_SUCCESS) {
356         return;
357     }
358 
359     WifiStationNode *pos = NULL;
360 
361     LOS_DL_LIST_FOR_EACH_ENTRY(pos, &g_apData.stationHead, WifiStationNode, node) {
362         if (memcmp(&pos->station.macAddress, macAddr, WIFI_MAC_LEN) == 0) {
363             LOS_ListDelete(&pos->node);
364             rtos_free(pos);
365             g_apData.stationCnt--;
366             DoStaLeaveCallBack(&pos->station);
367             dbg("station leave: %02X:%02X:%02X:%02X:%02X:%02X -> %s,cnt= %d\r\n", macAddr[0],
368                 macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5], g_apData.stationCnt);
369             break;
370         }
371     }
372     WifiUnlock();
373 }
374