1 /*
2  * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 
16 // this demo make the wifi to connect to the specified AP
17 
18 #include <unistd.h>
19 #include <hi_wifi_api.h>
20 #include <lwip/ip_addr.h>
21 #include <lwip/netifapi.h>
22 #include <hi_types_base.h>
23 #include <hi_task.h>
24 #include <hi_mem.h>
25 #include "wifi_device_config.h"
26 #include "lwip/api_shell.h"
27 #include "wifi_device.h"
28 #include "cmsis_os2.h"
29 #include "iot_config.h"
30 #include "iot_log.h"
31 
32 
33 #define APP_INIT_VAP_NUM    2
34 #define APP_INIT_USR_NUM    2
35 
36 static struct netif *g_lwipNetif = NULL;
37 static hi_bool g_scanDone = HI_FALSE;
38 unsigned char g_wifiStatus = 0;
39 
40 unsigned char g_wifiFirstConnecting = 0;
41 unsigned char g_wifiSecondConnecting = 0;
42 unsigned char g_wifiSecondConnected = 0;
43 static struct netif *g_iFace = NULL;
44 void WifiStopSta(int netId);
45 static int WifiStartSta(void);
46 int g_netId = -1;
47 int g_connected = 0;
48 
49 #define WIFI_CONNECT_STATUS ((unsigned char)0x02)
50 
WifiReconnected(int connnetId)51 void WifiReconnected(int connnetId)
52 {
53     int id = connnetId;
54 
55     if (g_wifiFirstConnecting == WIFI_CONNECT_STATUS) {
56         g_wifiSecondConnecting = HI_TRUE;
57         g_wifiFirstConnecting = HI_FALSE;
58         WifiStopSta(id);
59         ip4_addr_t ipAddr;
60         ip4_addr_t ipAny;
61         IP4_ADDR(&ipAny, 0, 0, 0, 0);
62         IP4_ADDR(&ipAddr, 0, 0, 0, 0);
63         id = WifiStartSta();
64         netifapi_dhcp_start(g_lwipNetif);
65         while (memcmp(&ipAddr, &ipAny, sizeof(ip4_addr_t)) == 0) {
66             IOT_LOG_DEBUG("<Wifi reconnecting>:Wait the DHCP READY");
67             netifapi_netif_get_addr(g_lwipNetif, &ipAddr, NULL, NULL);
68             hi_sleep(1000); /* 休眠1000ms */
69         }
70         g_wifiSecondConnected = HI_FALSE;
71         g_wifiFirstConnecting = WIFI_CONNECT_STATUS;
72         g_wifiStatus = HI_WIFI_EVT_CONNECTED;
73     }
74 }
75 /* clear netif's ip, gateway and netmask */
StaResetAddr(struct netif *lwipNetif)76 static void StaResetAddr(struct netif *lwipNetif)
77 {
78     ip4_addr_t st_gw;
79     ip4_addr_t st_ipaddr;
80     ip4_addr_t st_netmask;
81 
82     if (lwipNetif == NULL) {
83         IOT_LOG_ERROR("hisi_reset_addr::Null param of netdev");
84         return;
85     }
86 
87     IP4_ADDR(&st_gw, 0, 0, 0, 0);
88     IP4_ADDR(&st_ipaddr, 0, 0, 0, 0);
89     IP4_ADDR(&st_netmask, 0, 0, 0, 0);
90 
91     netifapi_netif_set_addr(lwipNetif, &st_ipaddr, &st_netmask, &st_gw);
92 }
93 
WpaEventCB(const hi_wifi_event *hisiEvent)94 static void WpaEventCB(const hi_wifi_event *hisiEvent)
95 {
96     if (hisiEvent == NULL) {
97         return;
98     }
99 
100     IOT_LOG_DEBUG("EVENT_TYPE:%d", hisiEvent->event);
101     switch (hisiEvent->event) {
102         case HI_WIFI_EVT_SCAN_DONE:
103             IOT_LOG_DEBUG("WiFi: Scan results available");
104             g_scanDone = HI_TRUE;
105             break;
106         case HI_WIFI_EVT_CONNECTED:
107             IOT_LOG_DEBUG("WiFi: Connected");
108             netifapi_dhcp_start(g_lwipNetif);
109             g_wifiStatus = HI_WIFI_EVT_CONNECTED;
110             if (g_wifiSecondConnected) {
111                 g_wifiSecondConnected = HI_FALSE;
112                 g_wifiFirstConnecting = WIFI_CONNECT_STATUS;
113             }
114             break;
115         case HI_WIFI_EVT_DISCONNECTED:
116             IOT_LOG_DEBUG("WiFi: Disconnected");
117             netifapi_dhcp_stop(g_lwipNetif);
118             StaResetAddr(g_lwipNetif);
119             g_wifiStatus = HI_WIFI_EVT_DISCONNECTED;
120             break;
121         case HI_WIFI_EVT_WPS_TIMEOUT:
122             IOT_LOG_DEBUG("WiFi: wps is timeout");
123             g_wifiStatus = HI_WIFI_EVT_WPS_TIMEOUT;
124             break;
125         default:
126             break;
127     }
128 }
129 
StaStartConnect(void)130 static int StaStartConnect(void)
131 {
132     int ret;
133     errno_t rc;
134     hi_wifi_assoc_request assoc_req = {0};
135 
136     /* copy SSID to assoc_req */
137     rc = memcpy_s(assoc_req.ssid, HI_WIFI_MAX_SSID_LEN + 1, CONFIG_AP_SSID, strlen(CONFIG_AP_SSID)); /* 9:ssid length */
138     if (rc != EOK) {
139         return -1;
140     }
141 
142     /*
143      * OPEN mode
144      * for WPA2-PSK mode:
145      * set assoc_req.auth as HI_WIFI_SECURITY_WPA2PSK,
146      * then memcpy(assoc_req.key, "12345678", 8).
147      */
148     assoc_req.auth = HI_WIFI_SECURITY_WPA2PSK;
149     rc = memcpy_s(assoc_req.key, HI_WIFI_MAX_KEY_LEN + 1, CONFIG_AP_PWD, strlen(CONFIG_AP_PWD));
150     if (rc != EOK) {
151         return -1;
152     }
153     ret = hi_wifi_sta_connect(&assoc_req);
154     if (ret != HISI_OK) {
155         return -1;
156     }
157 
158     return 0;
159 }
160 
PrintLinkedInfo(WifiLinkedInfo* info)161 static void PrintLinkedInfo(WifiLinkedInfo* info)
162 {
163     int ret = 0;
164     if (!info) {
165         return;
166     }
167 
168     static char macAddress[32] = {0};
169     unsigned char* mac = info->bssid;
170     if (snprintf_s(macAddress, sizeof(macAddress) + 1, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
171         mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) < 0) { /* mac地址从0,1,2,3,4,5位 */
172             return;
173     }
174 }
175 
OnWifiConnectionChanged(int state, WifiLinkedInfo* info)176 static void OnWifiConnectionChanged(int state, WifiLinkedInfo* info)
177 {
178     if (!info) {
179         return;
180     }
181 
182     printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state);
183     PrintLinkedInfo(info);
184 
185     if (state == WIFI_STATE_AVAILABLE) {
186         g_connected = 1;
187     } else {
188         g_connected = 0;
189     }
190 }
191 
OnWifiScanStateChanged(int state, int size)192 static void OnWifiScanStateChanged(int state, int size)
193 {
194     printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size);
195 }
196 
197 static WifiEvent g_defaultWifiEventListener = {
198     .OnWifiConnectionChanged = OnWifiConnectionChanged,
199     .OnWifiScanStateChanged = OnWifiScanStateChanged
200 };
201 
WifiStartSta(void)202 static int WifiStartSta(void)
203 {
204     WifiDeviceConfig apConfig = {0};
205     (void)strcpy_s(apConfig.ssid, strlen(CONFIG_AP_SSID) + 1, CONFIG_AP_SSID);
206     (void)strcpy_s(apConfig.preSharedKey, strlen(CONFIG_AP_PWD) + 1, CONFIG_AP_PWD);
207     apConfig.securityType = WIFI_SEC_TYPE_PSK;
208 
209     WifiErrorCode errCode;
210     int netId = -1;
211 
212     errCode = RegisterWifiEvent(&g_defaultWifiEventListener);
213     printf("RegisterWifiEvent: %d\r\n", errCode);
214 
215     errCode = EnableWifi();
216     printf("EnableWifi: %d\r\n", errCode);
217 
218     errCode = AddDeviceConfig(&apConfig, &netId);
219     printf("AddDeviceConfig: %d\r\n", errCode);
220 
221     g_connected = 0;
222     errCode = ConnectTo(netId);
223     printf("ConnectTo(%d): %d\r\n", netId, errCode);
224 
225     while (!g_connected) { // wait until connect to AP
226         osDelay(10); /* 等待1000ms */
227     }
228     printf("g_connected: %d\r\n", g_connected);
229 
230     g_iFace = netifapi_netif_find("wlan0");
231     if (g_iFace) {
232         err_t ret = netifapi_dhcp_start(g_iFace);
233         printf("netifapi_dhcp_start: %d\r\n", ret);
234 
235         osDelay(100); // wait 100ms DHCP server give me IP
236         ret = netifapi_netif_common(g_iFace, dhcp_clients_info_show, NULL);
237         printf("netifapi_netif_common: %d\r\n", ret);
238     }
239     return netId;
240 }
241 
WifiStopSta(int netId)242 void WifiStopSta(int netId)
243 {
244     if (g_iFace) {
245         err_t ret = netifapi_dhcp_stop(g_iFace);
246         printf("netifapi_dhcp_stop: %d\r\n", ret);
247     }
248 
249     WifiErrorCode errCode = Disconnect(); // disconnect with your AP
250     printf("Disconnect: %d\r\n", errCode);
251 
252     errCode = UnRegisterWifiEvent(&g_defaultWifiEventListener);
253     printf("UnRegisterWifiEvent: %d\r\n", errCode);
254 
255     RemoveDevice(netId); // remove AP config
256     printf("RemoveDevice: %d\r\n", errCode);
257 
258     errCode = DisableWifi();
259     printf("DisableWifi: %d\r\n", errCode);
260 }
261 
WifiStaReadyWait(void)262 void WifiStaReadyWait(void)
263 {
264     ip4_addr_t ipAddr;
265     ip4_addr_t ipAny;
266     IP4_ADDR(&ipAny, 0, 0, 0, 0);
267     IP4_ADDR(&ipAddr, 0, 0, 0, 0);
268     g_netId = WifiStartSta();
269     IOT_LOG_DEBUG("wifi sta dhcp done");
270     NetDemoTest();
271     return;
272 }