1 /*
2 * Copyright (c) 2020 Huawei Device Co., Ltd.
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
18 #include "lwip/ip4_addr.h"
19 #include "lwip/netif.h"
20 #include "lwip/netifapi.h"
21
22 #include "cmsis_os2.h"
23 #include "ohos_init.h"
24 #include "ohos_types.h"
25 #include "wifi_device_config.h"
26 #include "wifiiot_gpio.h"
27 #include "wifiiot_gpio_ex.h"
28
29 enum LedState {
30 LED_OFF = 0,
31 LED_ON,
32 LED_SPARK,
33 };
34
35 WifiDeviceConfig g_netCfg = {0};
36 WifiEvent g_staEventHandler = {0};
37 struct netif *g_staNetif = NULL;
38 int g_ledState = LED_OFF;
39 int g_connectRetryCount = 0;
40
41 #define SAMPLE_SEND_BUF_SIZE 400
42 int g_recvFlag = 0;
43 char g_buf[SAMPLE_SEND_BUF_SIZE] = {0};
44 int g_bufLen = 0;
45
46 #define SAMPLE_LED_INTERVAL_TIME_US 300000
47 #define SAMPLE_BIZ_SLEEP_TIME_US 1000000
48
LedTask(const char * arg)49 static void *LedTask(const char *arg)
50 {
51 (void)arg;
52 while (1) {
53 switch (g_ledState) {
54 case LED_OFF:
55 GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 1);
56 usleep(SAMPLE_LED_INTERVAL_TIME_US);
57 break;
58 case LED_ON:
59 GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 0);
60 usleep(SAMPLE_LED_INTERVAL_TIME_US);
61 break;
62 case LED_SPARK:
63 GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 0);
64 usleep(SAMPLE_LED_INTERVAL_TIME_US);
65 GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 1);
66 usleep(SAMPLE_LED_INTERVAL_TIME_US);
67 break;
68 default:
69 usleep(SAMPLE_LED_INTERVAL_TIME_US);
70 break;
71 }
72 }
73
74 return NULL;
75 }
76
77 #define SAMPLE_TASK_STACK_SIZE 4048
78 #define SAMPLE_TASK_PRIO 25
LedInit(void)79 static void LedInit(void)
80 {
81 osThreadAttr_t attr;
82
83 GpioInit();
84 IoSetFunc(WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_IO_FUNC_GPIO_9_GPIO);
85 GpioSetDir(WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_GPIO_DIR_OUT);
86
87 attr.name = "LedTask";
88 attr.attr_bits = 0U;
89 attr.cb_mem = NULL;
90 attr.cb_size = 0U;
91 attr.stack_mem = NULL;
92 attr.stack_size = SAMPLE_TASK_STACK_SIZE;
93 attr.priority = SAMPLE_TASK_PRIO;
94
95 if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL) {
96 printf("[sample] Falied to create LedTask!\n");
97 }
98 }
99
LedOn(void)100 static void LedOn(void)
101 {
102 printf("[sample] led spark.\n");
103 g_ledState = LED_ON;
104 }
105
PreTransferProc(void)106 static void PreTransferProc(void)
107 {
108 printf("[sample] oncall pretransfer event.\n");
109 g_ledState = LED_SPARK;
110 }
111
DisconnectEventProc(void)112 static void DisconnectEventProc(void)
113 {
114 printf("[sample] oncall disconnect event.\n");
115 }
116
RecvMessageEventProc(char * msg,int len)117 static void RecvMessageEventProc(char *msg, int len)
118 {
119 printf("[sample] oncall recv message %s(%d).\n", msg, len);
120 if (memcpy_s(g_buf, sizeof(g_buf), msg, len) != 0) {
121 printf("[sample] memcpy ctrl msg fail.\n");
122 }
123 g_recvFlag = 1;
124 g_bufLen = len;
125 }
126
TimeoutProc(void)127 static void TimeoutProc(void)
128 {
129 printf("[sample] oncall network config service timeout with phone.\n");
130 }
131
NetCfgResult(signed char result)132 static void NetCfgResult(signed char result)
133 {
134 printf("[sample] network configure done.(result=%d)\n", result);
135 DisableWifi();
136 UnRegisterWifiEvent(&g_staEventHandler);
137 NotifyConfigWifiResult(result);
138 if (result == NETCFG_RST_SUCC) {
139 LedOn();
140 } else if (result == NETCFG_RST_FAIL) {
141 printf("[sample] conn ap fail.\n");
142 }
143 // -1: fail 0: succ
144 }
145
StaResetAddr(struct netif * ptrLwipNetif)146 static void StaResetAddr(struct netif *ptrLwipNetif)
147 {
148 ip4_addr_t staGW;
149 ip4_addr_t staIpaddr;
150 ip4_addr_t staNetmask;
151
152 if (ptrLwipNetif == NULL) {
153 printf("[sample] Null param of netdev\r\n");
154 return;
155 }
156
157 IP4_ADDR(&staGW, 0, 0, 0, 0);
158 IP4_ADDR(&staIpaddr, 0, 0, 0, 0);
159 IP4_ADDR(&staNetmask, 0, 0, 0, 0);
160
161 netifapi_netif_set_addr(ptrLwipNetif, &staIpaddr, &staNetmask, &staGW);
162 }
163
164 #define TEST_NUM_2 2
165 #define TEST_NUM_3 3
166 #define TEST_NUM_4 4
167 #define TEST_NUM_5 5
168 #define TEST_CONNECT_RETRY_COUNT 5
WifiConnectionChangedHandler(int state,WifiLinkedInfo * info)169 static void WifiConnectionChangedHandler(int state, WifiLinkedInfo *info)
170 {
171 if (state == WIFI_STATE_AVALIABLE) {
172 NetCfgResult(NETCFG_RST_SUCC);
173 NetCfgResult(TEST_NUM_2);
174 NetCfgResult(TEST_NUM_3);
175 NetCfgResult(TEST_NUM_4);
176 NetCfgResult(TEST_NUM_5);
177 printf("[sample] WiFi: Connected.\n");
178 netifapi_dhcp_start(g_staNetif);
179 } else if (state == WIFI_STATE_NOT_AVALIABLE) {
180 printf("[sample] WiFi: Disconnected retry = %d, reason = %d\n", g_connectRetryCount, info->disconnectedReason);
181 if (g_connectRetryCount < TEST_CONNECT_RETRY_COUNT) {
182 g_connectRetryCount++;
183 return;
184 }
185 NetCfgResult(NETCFG_RST_FAIL);
186 netifapi_dhcp_stop(g_staNetif);
187 StaResetAddr(g_staNetif);
188 }
189 }
190
StaStart(void)191 static int StaStart(void)
192 {
193 WifiErrorCode error;
194 error = EnableWifi();
195 if (error == ERROR_WIFI_BUSY) {
196 printf("[sample] Sta had already connnected.\n");
197 NetCfgResult(NETCFG_RST_SUCC);
198 return -1;
199 }
200 if (error != WIFI_SUCCESS) {
201 printf("[sample] EnableWifi fail, error = %d\n", error);
202 return -1;
203 }
204
205 g_staNetif = netif_find("wlan0");
206 if (g_staNetif == NULL) {
207 printf("[sample] Get netif failed\n");
208 return -1;
209 }
210
211 g_staEventHandler.OnWifiConnectionChanged = WifiConnectionChangedHandler;
212 error = RegisterWifiEvent(&g_staEventHandler);
213 if (error != WIFI_SUCCESS) {
214 printf("[sample] RegisterWifiEvent fail, error = %d\n", error);
215 return -1;
216 }
217
218 if (IsWifiActive() == 0) {
219 printf("[sample] Wifi station is not actived.\n");
220 return -1;
221 }
222
223 return 0;
224 }
225
WapStaConnect(const WifiDeviceConfig * config)226 static int WapStaConnect(const WifiDeviceConfig *config)
227 {
228 int netId = 0;
229 WifiErrorCode error;
230
231 error = AddDeviceConfig(config, &netId);
232 if (error != WIFI_SUCCESS) {
233 printf("[sample] AddDeviceConfig add config failed %d\n", error);
234 return -1;
235 }
236
237 error = ConnectTo(netId);
238 if (error != WIFI_SUCCESS) {
239 printf("[sample] ConnectTo conn failed %d\n", error);
240 return -1;
241 }
242
243 printf("[sample] WapSta connecting...\n");
244 return 0;
245 }
246
CfgNetTask(const char * arg)247 static void *CfgNetTask(const char *arg)
248 {
249 (void)arg;
250
251 if (StaStart() != 0) {
252 return NULL;
253 }
254
255 if (WapStaConnect(&g_netCfg) != 0) {
256 return NULL;
257 }
258
259 return NULL;
260 }
261
CreateCfgNetTask(void)262 static int CreateCfgNetTask(void)
263 {
264 osThreadAttr_t attr;
265 attr.name = "CfgNetTask";
266 attr.attr_bits = 0U;
267 attr.cb_mem = NULL;
268 attr.cb_size = 0U;
269 attr.stack_mem = NULL;
270 attr.stack_size = SAMPLE_TASK_STACK_SIZE;
271 attr.priority = SAMPLE_TASK_PRIO;
272
273 if (osThreadNew((osThreadFunc_t)CfgNetTask, NULL, &attr) == NULL) {
274 printf("[NAN] Falied to create NanCfgNetTask!\n");
275 return -1;
276 }
277
278 return 0;
279 }
280
DealSsidPwd(struct NetCfgConfig * config)281 static void DealSsidPwd(struct NetCfgConfig *config)
282 {
283 if (config == NULL) {
284 printf("[sample] input config is illegal.\n");
285 return;
286 }
287
288 if (memcpy_s(&g_netCfg, sizeof(WifiDeviceConfig), &(config->config), sizeof(WifiDeviceConfig)) != 0) {
289 printf("[sample] memcpy netCfg fail.\n");
290 return;
291 }
292 g_netCfg.securityType = ((config->config.preSharedKey[0] == '\0') ? WIFI_SEC_TYPE_OPEN : WIFI_SEC_TYPE_PSK);
293 g_connectRetryCount = 0;
294 if (CreateCfgNetTask() != 0) {
295 printf("[sample] create cfgnet task fail.\n");
296 }
297 }
298 #define SAMPLE_NETCFG_DEFAULT_DB (-61)
299 #define SAMPLE_NETCFG_DEFAULT_ACK_TIMEOUT 3
300 #define SAMPLE_NETCFG_DEFAULT_HEARTBEAT_TIMEOUT 60;
301 #define SAMPLE_TIME_COUNT 5
302 struct DevPara g_devPara = {0};
303 struct NetCfgPara g_netCfgPara = {0};
304
SampleBizTask(const char * arg)305 static void *SampleBizTask(const char *arg)
306 {
307 (void)arg;
308 int ret;
309 LedInit();
310 struct WifiConfigureEvent event = {0};
311 event.OnPreTransferConfig = PreTransferProc;
312 event.OnTransferConfig = DealSsidPwd;
313 event.OnDisconnected = DisconnectEventProc;
314 event.OnMessageReceived = RecvMessageEventProc;
315 event.OnTimeout = TimeoutProc;
316 ret = RegConfigWifiCallback(&event);
317 if (ret != 0) {
318 printf("[sample] register event fail.\n");
319 return NULL;
320 }
321
322 HotspotConfig config = {0};
323 if (strcpy_s(config.ssid, sizeof(config.ssid), "netcfg_softap") != 0) {
324 printf("[sample] strcpy ssid fail.\n");
325 return NULL;
326 }
327 config.securityType = WIFI_SEC_TYPE_OPEN;
328
329 char *pin = "0123456789012345";
330 char *productId = "1";
331 char *sn = "01234567890123450123456789012345";
332
333 memset_s(&g_devPara, sizeof(g_devPara), 0, sizeof(g_devPara));
334 memcpy_s(g_devPara.pin, sizeof(g_devPara.pin), pin, sizeof(g_devPara.pin));
335 memcpy_s(g_devPara.productId, sizeof(g_devPara.productId), productId, sizeof(g_devPara.productId));
336 memcpy_s(g_devPara.sn, sizeof(g_devPara.sn), sn, sizeof(g_devPara.sn));
337
338 g_netCfgPara.db = SAMPLE_NETCFG_DEFAULT_DB;
339 g_netCfgPara.nanAckTimout = SAMPLE_NETCFG_DEFAULT_ACK_TIMEOUT;
340 g_netCfgPara.hbTimout = SAMPLE_NETCFG_DEFAULT_HEARTBEAT_TIMEOUT;
341 ret += StartConfigWifi(&config, &g_devPara, &g_netCfgPara);
342 if (ret != 0) {
343 printf("[sample] start config wifi fail.\n");
344 return NULL;
345 }
346
347 while (1) {
348 printf("[sample] main biz.\n");
349 if (g_recvFlag) {
350 g_recvFlag = 0;
351 printf("[sample] send usr msg.\n");
352 SendMessage(g_buf, g_bufLen);
353 }
354 usleep(SAMPLE_BIZ_SLEEP_TIME_US);
355 }
356
357 return NULL;
358 }
359
SampleBiz(void)360 void SampleBiz(void)
361 {
362 osThreadAttr_t attr;
363
364 attr.name = "samplebiztask";
365 attr.attr_bits = 0U;
366 attr.cb_mem = NULL;
367 attr.cb_size = 0U;
368 attr.stack_mem = NULL;
369 attr.stack_size = SAMPLE_TASK_STACK_SIZE;
370 attr.priority = SAMPLE_TASK_PRIO;
371
372 if (osThreadNew((osThreadFunc_t)SampleBizTask, NULL, &attr) == NULL) {
373 printf("[sample] Falied to create SampleBizTask!\n");
374 }
375 }
376