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 #include <unistd.h>
17 #include "hi_wifi_api.h"
18 #include "lwip/ip_addr.h"
19 #include "lwip/netifapi.h"
20 #include "app_demo_get_mac_addr.h"
21 #include "wifi_sta.h"
22 
23 #define APP_INIT_VAP_NUM    2
24 #define APP_INIT_USR_NUM    2
25 
26 static struct netif *g_lwip_netif = NULL;
27 
28 /* clear netif's ip, gateway and netmask */
hi_sta_reset_addr(const struct netif *pst_lwip_netif)29 void hi_sta_reset_addr(const struct netif *pst_lwip_netif)
30 {
31     ip4_addr_t st_gw;
32     ip4_addr_t st_ipaddr;
33     ip4_addr_t st_netmask;
34 
35     if (pst_lwip_netif == NULL) {
36         printf("hisi_reset_addr::Null param of netdev\r\n");
37         return;
38     }
39 
40     IP4_ADDR(&st_gw, 0, 0, 0, 0);
41     IP4_ADDR(&st_ipaddr, 0, 0, 0, 0);
42     IP4_ADDR(&st_netmask, 0, 0, 0, 0);
43 
44     netifapi_netif_set_addr(pst_lwip_netif, &st_ipaddr, &st_netmask, &st_gw);
45 }
46 
wifi_wpa_event_cb(const hi_wifi_event *hisi_event)47 void wifi_wpa_event_cb(const hi_wifi_event *hisi_event)
48 {
49     if (hisi_event == NULL)
50         return;
51 
52     switch (hisi_event->event) {
53         case HI_WIFI_EVT_SCAN_DONE:
54             printf("WiFi: Scan results available\n");
55             break;
56         case HI_WIFI_EVT_CONNECTED:
57             printf("WiFi: Connected\n");
58             netifapi_dhcp_start(g_lwip_netif);
59             break;
60         case HI_WIFI_EVT_DISCONNECTED:
61             printf("WiFi: Disconnected\n");
62             netifapi_dhcp_stop(g_lwip_netif);
63             hi_sta_reset_addr(g_lwip_netif);
64             break;
65         case HI_WIFI_EVT_WPS_TIMEOUT:
66             printf("WiFi: wps is timeout\n");
67             break;
68         default:
69             break;
70     }
71 }
72 
hi_wifi_start_connect(void)73 int hi_wifi_start_connect(void)
74 {
75     int ret = 0;
76     errno_t rc = 0;
77     unsigned char *ssid = NULL;
78     hi_wifi_assoc_request assoc_req = {0};
79 
80     /* get Hi3861 mac addr */
81     hi3816_get_mac_addr();
82     ssid = GetSsid();
83     /* copy SSID to assoc_req */
84     rc = memcpy_s(assoc_req.ssid, HI_WIFI_MAX_SSID_LEN + 1, ssid, 20); /* 20:ssid length */
85     if (rc != EOK) {
86         return -1;
87     }
88 
89     /*
90      * OPEN mode
91      * for WPA2-PSK mode:
92      * set assoc_req.auth as HI_WIFI_SECURITY_WPA2PSK,
93      * then memcpy(assoc_req.key, "12345678", 8).
94      */
95     assoc_req.auth = HI_WIFI_SECURITY_OPEN;
96 
97     ret = hi_wifi_sta_connect(&assoc_req);
98     if (ret != HISI_OK) {
99         return -1;
100     }
101 
102     return 0;
103 }
104 
hi_wifi_start_sta(void)105 int hi_wifi_start_sta(void)
106 {
107     int ret;
108     char ifname[WIFI_IFNAME_MAX_SIZE + 1] = {0};
109     int len = sizeof(ifname);
110     const unsigned char wifi_vap_res_num = APP_INIT_VAP_NUM;
111     const unsigned char wifi_user_res_num = APP_INIT_USR_NUM;
112     unsigned int  num = WIFI_SCAN_AP_LIMIT;
113 
114     ret = hi_wifi_init(wifi_vap_res_num, wifi_user_res_num);
115     if (ret != HISI_OK) {
116         return -1;
117     }
118 
119     ret = hi_wifi_sta_start(ifname, &len);
120     if (ret != HISI_OK) {
121         return -1;
122     }
123 
124     /* register call back function to receive wifi event, etc scan results event,
125      * connected event, disconnected event.
126      */
127     ret = hi_wifi_register_event_callback(wifi_wpa_event_cb);
128     if (ret != HISI_OK) {
129         printf("register wifi event callback failed\n");
130     }
131 
132     /* acquire netif for IP operation */
133     g_lwip_netif = netifapi_netif_find(ifname);
134     if (g_lwip_netif == NULL) {
135         printf("%s: get netif failed\n", __FUNCTION__);
136         return -1;
137     }
138 
139     /* start scan, scan results event will be received soon */
140     ret = hi_wifi_sta_scan();
141     if (ret != HISI_OK) {
142         return -1;
143     }
144 
145     sleep(5);   /* sleep 5s, waiting for scan result. */
146 
147     hi_wifi_ap_info *pst_results = malloc(sizeof(hi_wifi_ap_info) * WIFI_SCAN_AP_LIMIT);
148     if (pst_results == NULL) {
149         return -1;
150     }
151 
152     ret = hi_wifi_sta_scan_results(pst_results, &num);
153     if (ret != HISI_OK) {
154         free(pst_results);
155         return -1;
156     }
157 
158     for (unsigned int loop = 0; (loop < num) && (loop < WIFI_SCAN_AP_LIMIT); loop++) {
159         printf("SSID: %s\n", pst_results[loop].ssid);
160     }
161     free(pst_results);
162 
163     /* if received scan results, select one SSID to connect */
164     ret = hi_wifi_start_connect();
165     if (ret != 0) {
166         return -1;
167     }
168 
169     return 0;
170 }
171 
hi_wifi_stop_sta(void)172 void hi_wifi_stop_sta(void)
173 {
174     int ret;
175 
176     ret = hi_wifi_sta_stop();
177     if (ret != HISI_OK) {
178         printf("failed to stop sta\n");
179     }
180 
181     ret = hi_wifi_deinit();
182     if (ret != HISI_OK) {
183         printf("failed to deinit wifi\n");
184     }
185 
186     g_lwip_netif = NULL;
187 }
188