• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 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 #include "lwip/netifapi.h"
17 #include "wifi_hotspot.h"
18 #include "wifi_hotspot_config.h"
19 #include "td_base.h"
20 #include "td_type.h"
21 #include "stdlib.h"
22 #include "uart.h"
23 #include "cmsis_os2.h"
24 #include "app_init.h"
25 #include "soc_osal.h"
26 
27 #define WIFI_IFNAME_MAX_SIZE             16
28 #define WIFI_MAX_SSID_LEN                33
29 #define WIFI_SCAN_AP_LIMIT               64
30 #define WIFI_MAC_LEN                     6
31 #define WIFI_STA_SAMPLE_LOG              "[WIFI_STA_SAMPLE]"
32 #define WIFI_NOT_AVALLIABLE              0
33 #define WIFI_AVALIABE                    1
34 #define WIFI_GET_IP_MAX_COUNT            300
35 
36 #define WIFI_TASK_PRIO                  (osPriority_t)(13)
37 #define WIFI_TASK_DURATION_MS           2000
38 #define WIFI_TASK_STACK_SIZE            0x1000
39 
40 static td_void wifi_scan_state_changed(td_s32 state, td_s32 size);
41 static td_void wifi_connection_changed(td_s32 state, const wifi_linked_info_stru *info, td_s32 reason_code);
42 
43 wifi_event_stru wifi_event_cb = {
44     .wifi_event_connection_changed      = wifi_connection_changed,
45     .wifi_event_scan_state_changed      = wifi_scan_state_changed,
46 };
47 
48 enum {
49     WIFI_STA_SAMPLE_INIT = 0,       /* 0:初始态 */
50     WIFI_STA_SAMPLE_SCANING,        /* 1:扫描中 */
51     WIFI_STA_SAMPLE_SCAN_DONE,      /* 2:扫描完成 */
52     WIFI_STA_SAMPLE_FOUND_TARGET,   /* 3:匹配到目标AP */
53     WIFI_STA_SAMPLE_CONNECTING,     /* 4:连接中 */
54     WIFI_STA_SAMPLE_CONNECT_DONE,   /* 5:关联成功 */
55     WIFI_STA_SAMPLE_GET_IP,         /* 6:获取IP */
56 } wifi_state_enum;
57 
58 static td_u8 g_wifi_state = WIFI_STA_SAMPLE_INIT;
59 
60 /*****************************************************************************
61   STA 扫描事件回调函数
62 *****************************************************************************/
wifi_scan_state_changed(td_s32 state,td_s32 size)63 static td_void wifi_scan_state_changed(td_s32 state, td_s32 size)
64 {
65     UNUSED(state);
66     UNUSED(size);
67     PRINT("%s::Scan done!.\r\n", WIFI_STA_SAMPLE_LOG);
68     g_wifi_state = WIFI_STA_SAMPLE_SCAN_DONE;
69     return;
70 }
71 
72 /*****************************************************************************
73   STA 关联事件回调函数
74 *****************************************************************************/
wifi_connection_changed(td_s32 state,const wifi_linked_info_stru * info,td_s32 reason_code)75 static td_void wifi_connection_changed(td_s32 state, const wifi_linked_info_stru *info, td_s32 reason_code)
76 {
77     UNUSED(info);
78     UNUSED(reason_code);
79 
80     if (state == WIFI_NOT_AVALLIABLE) {
81         PRINT("%s::Connect fail!. try agin !\r\n", WIFI_STA_SAMPLE_LOG);
82         g_wifi_state = WIFI_STA_SAMPLE_INIT;
83     } else {
84         PRINT("%s::Connect succ!.\r\n", WIFI_STA_SAMPLE_LOG);
85         g_wifi_state = WIFI_STA_SAMPLE_CONNECT_DONE;
86     }
87 }
88 
89 /*****************************************************************************
90   STA 匹配目标AP
91 *****************************************************************************/
example_get_match_network(wifi_sta_config_stru * expected_bss)92 td_s32 example_get_match_network(wifi_sta_config_stru *expected_bss)
93 {
94     td_s32  ret;
95     td_u32  num = 64; /* 64:扫描到的Wi-Fi网络数量 */
96     td_char expected_ssid[] = "my_softAP";
97     td_char key[] = "my_password"; /* 待连接的网络接入密码 */
98     td_bool find_ap = TD_FALSE;
99     td_u8   bss_index;
100     /* 获取扫描结果 */
101     td_u32 scan_len = sizeof(wifi_scan_info_stru) * WIFI_SCAN_AP_LIMIT;
102     wifi_scan_info_stru *result = osal_kmalloc(scan_len, OSAL_GFP_ATOMIC);
103     if (result == TD_NULL) {
104         return -1;
105     }
106     memset_s(result, scan_len, 0, scan_len);
107     ret = wifi_sta_get_scan_info(result, &num);
108     if (ret != 0) {
109         osal_kfree(result);
110         return -1;
111     }
112     /* 筛选扫描到的Wi-Fi网络,选择待连接的网络 */
113     for (bss_index = 0; bss_index < num; bss_index ++) {
114         if (strlen(expected_ssid) == strlen(result[bss_index].ssid)) {
115             if (memcmp(expected_ssid, result[bss_index].ssid, strlen(expected_ssid)) == 0) {
116                 find_ap = TD_TRUE;
117                 break;
118             }
119         }
120     }
121     /* 未找到待连接AP,可以继续尝试扫描或者退出 */
122     if (find_ap == TD_FALSE) {
123         osal_kfree(result);
124         return -1;
125     }
126     /* 找到网络后复制网络信息和接入密码 */
127     if (memcpy_s(expected_bss->ssid, WIFI_MAX_SSID_LEN, expected_ssid, strlen(expected_ssid)) != 0) {
128         osal_kfree(result);
129         return -1;
130     }
131     if (memcpy_s(expected_bss->bssid, WIFI_MAC_LEN, result[bss_index].bssid, WIFI_MAC_LEN) != 0) {
132         osal_kfree(result);
133         return -1;
134     }
135     expected_bss->security_type = result[bss_index].security_type;
136     if (memcpy_s(expected_bss->pre_shared_key, WIFI_MAX_SSID_LEN, key, strlen(key)) != 0) {
137         osal_kfree(result);
138         return -1;
139     }
140     expected_bss->ip_type = 1; /* 1:IP类型为动态DHCP获取 */
141     osal_kfree(result);
142     return 0;
143 }
144 
145 /*****************************************************************************
146   STA 关联状态查询
147 *****************************************************************************/
example_check_connect_status(td_void)148 td_bool example_check_connect_status(td_void)
149 {
150     td_u8 index;
151     wifi_linked_info_stru wifi_status;
152     /* 获取网络连接状态,共查询5次,每次间隔500ms */
153     for (index = 0; index < 5; index ++) {
154         (void)osDelay(50); /* 50: 延时500ms */
155         memset_s(&wifi_status, sizeof(wifi_linked_info_stru), 0, sizeof(wifi_linked_info_stru));
156         if (wifi_sta_get_ap_info(&wifi_status) != 0) {
157             continue;
158         }
159         if (wifi_status.conn_state == 1) {
160             return 0; /* 连接成功退出循环 */
161         }
162     }
163     return -1;
164 }
165 
166 /*****************************************************************************
167   STA DHCP状态查询
168 *****************************************************************************/
example_check_dhcp_status(struct netif * netif_p,td_u32 * wait_count)169 td_bool example_check_dhcp_status(struct netif *netif_p, td_u32 *wait_count)
170 {
171     if ((ip_addr_isany(&(netif_p->ip_addr)) == 0) && (*wait_count <= WIFI_GET_IP_MAX_COUNT)) {
172         /* DHCP成功 */
173         PRINT("%s::STA DHCP success.\r\n", WIFI_STA_SAMPLE_LOG);
174         return 0;
175     }
176 
177     if (*wait_count > WIFI_GET_IP_MAX_COUNT) {
178         PRINT("%s::STA DHCP timeout, try again !.\r\n", WIFI_STA_SAMPLE_LOG);
179         *wait_count = 0;
180         g_wifi_state = WIFI_STA_SAMPLE_INIT;
181     }
182     return -1;
183 }
184 
example_sta_function(td_void)185 td_s32 example_sta_function(td_void)
186 {
187     td_char ifname[WIFI_IFNAME_MAX_SIZE + 1] = "wlan0"; /* 创建的STA接口名 */
188     wifi_sta_config_stru expected_bss = {0}; /* 连接请求信息 */
189     struct netif *netif_p = TD_NULL;
190     td_u32 wait_count = 0;
191 
192     /* 创建STA接口 */
193     if (wifi_sta_enable() != 0) {
194         return -1;
195     }
196     PRINT("%s::STA enable succ.\r\n", WIFI_STA_SAMPLE_LOG);
197 
198     do {
199         (void)osDelay(1); /* 1: 等待10ms后判断状态 */
200         if (g_wifi_state == WIFI_STA_SAMPLE_INIT) {
201             PRINT("%s::Scan start!\r\n", WIFI_STA_SAMPLE_LOG);
202             g_wifi_state = WIFI_STA_SAMPLE_SCANING;
203             /* 启动STA扫描 */
204             if (wifi_sta_scan() != 0) {
205                 g_wifi_state = WIFI_STA_SAMPLE_INIT;
206                 continue;
207             }
208         } else if (g_wifi_state == WIFI_STA_SAMPLE_SCAN_DONE) {
209             /* 获取待连接的网络 */
210             if (example_get_match_network(&expected_bss) != 0) {
211                 PRINT("%s::Do not find AP, try again !\r\n", WIFI_STA_SAMPLE_LOG);
212                 g_wifi_state = WIFI_STA_SAMPLE_INIT;
213                 continue;
214             }
215             g_wifi_state = WIFI_STA_SAMPLE_FOUND_TARGET;
216         } else if (g_wifi_state == WIFI_STA_SAMPLE_FOUND_TARGET) {
217             PRINT("%s::Connect start.\r\n", WIFI_STA_SAMPLE_LOG);
218             g_wifi_state = WIFI_STA_SAMPLE_CONNECTING;
219             /* 启动连接 */
220             if (wifi_sta_connect(&expected_bss) != 0) {
221                 g_wifi_state = WIFI_STA_SAMPLE_INIT;
222                 continue;
223             }
224         } else if (g_wifi_state == WIFI_STA_SAMPLE_CONNECT_DONE) {
225             PRINT("%s::DHCP start.\r\n", WIFI_STA_SAMPLE_LOG);
226             g_wifi_state = WIFI_STA_SAMPLE_GET_IP;
227             netif_p = netifapi_netif_find(ifname);
228             if (netif_p == TD_NULL || netifapi_dhcp_start(netif_p) != 0) {
229                 PRINT("%s::find netif or start DHCP fail, try again !\r\n", WIFI_STA_SAMPLE_LOG);
230                 g_wifi_state = WIFI_STA_SAMPLE_INIT;
231                 continue;
232             }
233         } else if (g_wifi_state == WIFI_STA_SAMPLE_GET_IP) {
234             if (example_check_dhcp_status(netif_p, &wait_count) == 0) {
235                 break;
236             }
237             wait_count++;
238         }
239     } while (1);
240 
241     return 0;
242 }
243 
sta_sample_init(void * param)244 int sta_sample_init(void *param)
245 {
246     param = param;
247 
248     /* 注册事件回调 */
249     if (wifi_register_event_cb(&wifi_event_cb) != 0) {
250         PRINT("%s::wifi_event_cb register fail.\r\n", WIFI_STA_SAMPLE_LOG);
251         return -1;
252     }
253     PRINT("%s::wifi_event_cb register succ.\r\n", WIFI_STA_SAMPLE_LOG);
254 
255     /* 等待wifi初始化完成 */
256     while (wifi_is_wifi_inited() == 0) {
257         (void)osDelay(10); /* 1: 等待100ms后判断状态 */
258     }
259     PRINT("%s::wifi init succ.\r\n", WIFI_STA_SAMPLE_LOG);
260 
261     if (example_sta_function() != 0) {
262         PRINT("%s::example_sta_function fail.\r\n", WIFI_STA_SAMPLE_LOG);
263         return -1;
264     }
265     return 0;
266 }
267 
sta_sample_entry(void)268 static void sta_sample_entry(void)
269 {
270     osThreadAttr_t attr;
271     attr.name       = "sta_sample_task";
272     attr.attr_bits  = 0U;
273     attr.cb_mem     = NULL;
274     attr.cb_size    = 0U;
275     attr.stack_mem  = NULL;
276     attr.stack_size = WIFI_TASK_STACK_SIZE;
277     attr.priority   = WIFI_TASK_PRIO;
278     if (osThreadNew((osThreadFunc_t)sta_sample_init, NULL, &attr) == NULL) {
279         PRINT("%s::Create sta_sample_task fail.\r\n", WIFI_STA_SAMPLE_LOG);
280     }
281     PRINT("%s::Create sta_sample_task succ.\r\n", WIFI_STA_SAMPLE_LOG);
282 }
283 
284 /* Run the sta_sample_task. */
285 app_run(sta_sample_entry);