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