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 * Description: Sample file of the power distribution service
16 */
17
18 #include <unistd.h>
19
20 #include "lwip/netif.h"
21 #include "lwip/netifapi.h"
22 #include "lwip/ip4_addr.h"
23
24 #include "base64.h"
25 #include "cmsis_os2.h"
26 #include "ohos_types.h"
27 #include "network_config_service.h"
28 #include "wifi_device_config.h"
29 #include "wifiiot_gpio.h"
30 #include "wifiiot_gpio_ex.h"
31
32 enum LedState {
33 LED_OFF = 0,
34 LED_ON,
35 LED_SPARK,
36 };
37
38 WifiDeviceConfig g_netCfg = {0};
39 WifiEvent g_staEventHandler = {0};
40 struct netif *g_staNetif = NULL;
41 int g_ledState = LED_OFF;
42 int g_connectRetryCount = 0;
43
44 const char *g_ssid = "Hi-xxx-Switchs-XXXXX ";
45 const char *g_pinCode = "11111111";
46 const char *g_productId = "1";
47 const char *g_sn = "01234567890123450123456789012345";
48
49 #define SAMPLE_LED_INTERVAL_TIME_US 300000
50 #define SAMPLE_BIZ_SLEEP_TIME_US 1000000
51 #define SAMPLE_TIME_COUNT 5
52 #define DEVICE_INFO_NUM 2
53 #define POWER_NUM (-52)
54 #define MAX_DATA_LEN 4096
55
56 #define CHANNEL_80211B_ONLY 14
57 #define FREQ_OF_CHANNEL_1 2412
58 #define FREQ_OF_CHANNEL_80211B_ONLY 2484
59 #define WIFI_MIN_CHANNEL 1
60 #define WIFI_FREQ_INTERVAL 5
61
ChannelToFrequency(unsigned int channel)62 static unsigned int ChannelToFrequency(unsigned int channel)
63 {
64 if (channel <= 0) {
65 return 0;
66 }
67
68 if (channel == CHANNEL_80211B_ONLY) {
69 return FREQ_OF_CHANNEL_80211B_ONLY;
70 }
71
72 return (((channel - WIFI_MIN_CHANNEL) * WIFI_FREQ_INTERVAL) + FREQ_OF_CHANNEL_1);
73 }
74
LedTask(const char * arg)75 static void *LedTask(const char *arg)
76 {
77 (void)arg;
78 while (1) {
79 switch (g_ledState) {
80 case LED_OFF:
81 GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 1);
82 usleep(SAMPLE_LED_INTERVAL_TIME_US);
83 break;
84 case LED_ON:
85 GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 0);
86 usleep(SAMPLE_LED_INTERVAL_TIME_US);
87 break;
88 case LED_SPARK:
89 GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 0);
90 usleep(SAMPLE_LED_INTERVAL_TIME_US);
91 GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 1);
92 usleep(SAMPLE_LED_INTERVAL_TIME_US);
93 break;
94 default:
95 usleep(SAMPLE_LED_INTERVAL_TIME_US);
96 break;
97 }
98 }
99
100 return NULL;
101 }
102
103 #define SAMPLE_TASK_STACK_SIZE 4048
104 #define SAMPLE_TASK_PRIO 25
105
LedInit(void)106 static void LedInit(void)
107 {
108 osThreadAttr_t attr;
109
110 GpioInit();
111 IoSetFunc(WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_IO_FUNC_GPIO_9_GPIO);
112 GpioSetDir(WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_GPIO_DIR_OUT);
113
114 attr.name = "LedTask";
115 attr.attr_bits = 0U;
116 attr.cb_mem = NULL;
117 attr.cb_size = 0U;
118 attr.stack_mem = NULL;
119 attr.stack_size = SAMPLE_TASK_STACK_SIZE;
120 attr.priority = SAMPLE_TASK_PRIO;
121
122 if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL) {
123 printf("[sample] Falied to create LedTask!\n");
124 }
125 }
126
LedOn(void)127 static void LedOn(void)
128 {
129 printf("[sample] led spark.\n");
130 g_ledState = LED_ON;
131 }
132
LedOff(void)133 static void LedOff(void)
134 {
135 printf("[sample] led off.\n");
136 g_ledState = LED_OFF;
137 }
138
NetCfgResult(signed char result)139 static void NetCfgResult(signed char result)
140 {
141 printf("[sample] Network configure done.(result=%d)\n", result);
142 UnRegisterWifiEvent(&g_staEventHandler);
143 NotifyNetCfgResult(result);
144 if (result == 0) {
145 LedOff();
146 printf("[sample] Led off.\n");
147 } else if (result == 1) {
148 LedOn();
149 printf("[sample] Led on.\n");
150 } else if (result == -1) {
151 printf("[sample] Connect ap fail.\n");
152 }
153 }
154
StaResetAddr(struct netif * ptrLwipNetif)155 static void StaResetAddr(struct netif *ptrLwipNetif)
156 {
157 ip4_addr_t staGW;
158 ip4_addr_t staIpaddr;
159 ip4_addr_t staNetmask;
160
161 if (ptrLwipNetif == NULL) {
162 printf("[sample] Null param of netdev\r\n");
163 return;
164 }
165
166 IP4_ADDR(&staGW, 0, 0, 0, 0);
167 IP4_ADDR(&staIpaddr, 0, 0, 0, 0);
168 IP4_ADDR(&staNetmask, 0, 0, 0, 0);
169
170 netifapi_netif_set_addr(ptrLwipNetif, &staIpaddr, &staNetmask, &staGW);
171 }
172
173 #define TEST_NUM_2 2
174 #define TEST_NUM_3 3
175 #define TEST_NUM_4 4
176 #define TEST_NUM_5 5
177 #define TEST_CONNECT_RETRY_COUNT 5
178
179 static int g_state;
180
WifiConnectTask(const char * arg)181 static void *WifiConnectTask(const char *arg)
182 {
183 (void)arg;
184 if (g_state == WIFI_STATE_AVAILABLE) {
185 NetCfgResult(0);
186 printf("[sample] WiFi: Connected.\n");
187 netifapi_dhcp_start(g_staNetif);
188 } else if (g_state == WIFI_STATE_NOT_AVAILABLE) {
189 printf("[sample] WiFi: Disconnected retry = %d\n", g_connectRetryCount);
190 if (g_connectRetryCount < TEST_CONNECT_RETRY_COUNT) {
191 g_connectRetryCount++;
192 return NULL;
193 }
194 NetCfgResult(-1);
195 netifapi_dhcp_stop(g_staNetif);
196 StaResetAddr(g_staNetif);
197 }
198 return NULL;
199 }
200
WifiConnectionChangedHandler(int state,WifiLinkedInfo * info)201 static void WifiConnectionChangedHandler(int state, WifiLinkedInfo *info)
202 {
203 (void)info;
204 osThreadAttr_t attr;
205 attr.name = "WifiConnectTask";
206 attr.attr_bits = 0U;
207 attr.cb_mem = NULL;
208 attr.cb_size = 0U;
209 attr.stack_mem = NULL;
210 attr.stack_size = SAMPLE_TASK_STACK_SIZE;
211 attr.priority = SAMPLE_TASK_PRIO;
212 g_state = state;
213 if (osThreadNew((osThreadFunc_t)WifiConnectTask, NULL, &attr) == NULL) {
214 printf("[sample] Falied to create WifiConnectTask!\n");
215 }
216 }
217
StaStart(void)218 static int StaStart(void)
219 {
220 WifiErrorCode error;
221 error = EnableWifi();
222 if (error == ERROR_WIFI_BUSY) {
223 printf("[sample] Sta had already connnected.\n");
224 NetCfgResult(0);
225 }
226 if ((error != ERROR_WIFI_BUSY) && (error != WIFI_SUCCESS)) {
227 printf("[sample] EnableWifi failed, error = %d\n", error);
228 return -1;
229 }
230
231 g_staEventHandler.OnWifiConnectionChanged = WifiConnectionChangedHandler;
232 error = RegisterWifiEvent(&g_staEventHandler);
233 if (error != WIFI_SUCCESS) {
234 printf("[sample] RegisterWifiEvent failed, error = %d\n", error);
235 return -1;
236 }
237
238 if (IsWifiActive() == 0) {
239 printf("[sample] Wifi station is not actived.\n");
240 return -1;
241 }
242
243 g_staNetif = netif_find("wlan0");
244 if (g_staNetif == NULL) {
245 printf("[sample] Get netif failed\n");
246 return -1;
247 }
248
249 return 0;
250 }
251
WapStaConnect(WifiDeviceConfig * config)252 static int WapStaConnect(WifiDeviceConfig *config)
253 {
254 int netId = 0;
255 WifiErrorCode error;
256 config->securityType = (config->preSharedKey[0] == '\0') ? WIFI_SEC_TYPE_OPEN : WIFI_SEC_TYPE_PSK;
257 error = AddDeviceConfig(config, &netId);
258 if (error != WIFI_SUCCESS) {
259 printf("[sample] AddDeviceConfig add config failed, error=%d\n", error);
260 return -1;
261 }
262
263 error = ConnectTo(netId);
264 if (error != WIFI_SUCCESS) {
265 printf("[sample] ConnectTo conn failed %d\n", error);
266 return -1;
267 }
268
269 printf("[sample] WapSta connecting...\n");
270 return 0;
271 }
272
CfgNetTask(const char * arg)273 static void *CfgNetTask(const char *arg)
274 {
275 (void)arg;
276
277 if (StaStart() != 0) {
278 return NULL;
279 }
280
281 if (WapStaConnect(&g_netCfg) != 0) {
282 return NULL;
283 }
284
285 return NULL;
286 }
287
CreateCfgNetTask(void)288 static int CreateCfgNetTask(void)
289 {
290 osThreadAttr_t attr;
291 attr.name = "CfgNetTask";
292 attr.attr_bits = 0U;
293 attr.cb_mem = NULL;
294 attr.cb_size = 0U;
295 attr.stack_mem = NULL;
296 attr.stack_size = SAMPLE_TASK_STACK_SIZE;
297 attr.priority = SAMPLE_TASK_PRIO;
298
299 if (osThreadNew((osThreadFunc_t)CfgNetTask, NULL, &attr) == NULL) {
300 printf("[sample] Falied to create NanCfgNetTask!\n");
301 return -1;
302 }
303
304 return 0;
305 }
306
DealSsidPwd(const WifiDeviceConfig * config)307 static void DealSsidPwd(const WifiDeviceConfig *config)
308 {
309 if (config == NULL) {
310 printf("[sample] Input config is illegal.\n");
311 return;
312 }
313
314 if (memcpy_s(&g_netCfg, sizeof(WifiDeviceConfig), config, sizeof(WifiDeviceConfig)) != 0) {
315 printf("[sample] memcpy netCfg failed.\n");
316 return;
317 }
318 printf("[sample] DealSsidPwd\n");
319 g_connectRetryCount = 0;
320 if (CreateCfgNetTask() != 0) {
321 printf("[sample] Create cfgnet task failed.\n");
322 }
323 }
324
GetPinCode(unsigned char * pinCode,unsigned int size,unsigned int * len)325 int GetPinCode(unsigned char *pinCode, unsigned int size, unsigned int *len)
326 {
327 if (pinCode == NULL) {
328 }
329 memset_s(pinCode, size, 0, size);
330 if (strncpy_s((char *)pinCode, size, g_pinCode, strlen(g_pinCode)) != 0) {
331 printf("[sample] GetPinCode copy pinCode failed\n");
332 return -1;
333 }
334 *len = strlen((char *)pinCode);
335 return 0;
336 }
337
FastConnect(const struct WifiInfo * wifiInfo,WifiDeviceConfig * destCfg)338 int FastConnect(const struct WifiInfo *wifiInfo, WifiDeviceConfig *destCfg)
339 {
340 if (memcpy_s(destCfg->ssid, sizeof(destCfg->ssid), wifiInfo->ssid, wifiInfo->ssidLen) != EOK) {
341 printf("[sample] FastConnect copy ssid failed\n");
342 return -1;
343 }
344 if (memcpy_s(destCfg->preSharedKey, sizeof(destCfg->preSharedKey), wifiInfo->psk, wifiInfo->pskLen) != EOK) {
345 printf("[sample] FastConnect copy pwd failed\n");
346 return -1;
347 }
348 if (memcpy_s(destCfg->bssid, sizeof(destCfg->bssid), wifiInfo->bssid, wifiInfo->bssidLen) != EOK) {
349 printf("[sample] FastConnect copy bssid failed\n");
350 return -1;
351 }
352 destCfg->securityType = wifiInfo->authMode;
353 destCfg->freq = ChannelToFrequency(wifiInfo->channelNumber);
354 destCfg->wapiPskType = WIFI_PSK_TYPE_HEX;
355 return 0;
356 }
357
NormalConnect(const struct WifiInfo * wifiInfo,WifiDeviceConfig * destCfg)358 int NormalConnect(const struct WifiInfo *wifiInfo, WifiDeviceConfig *destCfg)
359 {
360 if (memcpy_s(destCfg->ssid, sizeof(destCfg->ssid), wifiInfo->ssid, wifiInfo->ssidLen) != EOK) {
361 printf("[sample] NormalConnect copy ssid failed\n");
362 return -1;
363 }
364 if (memcpy_s(destCfg->preSharedKey, sizeof(destCfg->preSharedKey), wifiInfo->pwd, wifiInfo->pwdLen) != EOK) {
365 printf("[sample] NormalConnect copy pwd failed\n");
366 return -1;
367 }
368 return 0;
369 }
370
ParseNetCfgData(const struct WifiInfo * wifiInfo,const unsigned char * vendorData,unsigned int len)371 int ParseNetCfgData(const struct WifiInfo *wifiInfo, const unsigned char *vendorData, unsigned int len)
372 {
373 printf("[sample] ParseWifiData vendorData len:%d\n", len);
374 if (wifiInfo == NULL) {
375 printf("[sample] wifiInfo is NULL\n");
376 return -1;
377 }
378
379 WifiDeviceConfig netConfig;
380 memset_s(&netConfig, sizeof(netConfig), 0, sizeof(netConfig));
381 FastConnect(wifiInfo, &netConfig);
382
383 if (vendorData != NULL) {
384 /* process vendorData */
385 }
386
387 DealSsidPwd(&netConfig);
388 return 0;
389 }
390
SendRawEncodeData(const unsigned char * data,size_t len)391 int SendRawEncodeData(const unsigned char *data, size_t len)
392 {
393 size_t writeLen = 0;
394 int ret = mbedtls_base64_encode(NULL, 0, &writeLen, (const unsigned char *)data, len);
395 if (ret != 0) {
396 printf("[sample] SendRawEncodeData base64 encode fial\n");
397 return -1;
398 }
399 size_t encodeBufLen = writeLen;
400 if (writeLen > MAX_DATA_LEN) {
401 printf("[sample] SendRawEncodeData dataLen overSize\n");
402 return -1;
403 }
404 char *buf = malloc(writeLen + 1);
405 if (buf == NULL) {
406 printf("[sample] malloc failed\r\n");
407 return -1;
408 }
409 (void)memset_s(buf, writeLen + 1, 0, writeLen + 1);
410 if (mbedtls_base64_encode((unsigned char *)buf, encodeBufLen, &writeLen, (const unsigned char *)data, len) != 0) {
411 printf("[sample] SendRawEncodeData base64 encode failed\r\n");
412 free(buf);
413 buf = NULL;
414 return -1;
415 }
416
417 printf("[sample] SendRawEncodeData encode buf = %s\n", buf);
418 SendRawData((const char*)buf);
419 if (buf != NULL) {
420 free(buf);
421 }
422
423 return 0;
424 }
425
RecvRawData(const char * svcId,unsigned int mode,const char * data)426 int RecvRawData(const char *svcId, unsigned int mode, const char *data)
427 {
428 (void)svcId;
429 (void)mode;
430 if (data == NULL) {
431 return -1;
432 }
433 printf("[sample] RecvRawData data : %s \n", data);
434
435 size_t decodeLen = 0;
436 int ret = mbedtls_base64_decode(NULL, 0, &decodeLen, (const unsigned char *)data, strlen(data));
437 if ((ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) || (decodeLen == 0)) {
438 printf("[sample] RecvRawData calc decodeLen fail(%d)\n", ret);
439 return -1;
440 }
441
442 if (decodeLen > MAX_DATA_LEN) {
443 printf("[sample] RecvRawData decodeLen overSize\n");
444 return -1;
445 }
446 unsigned char *decodeData = (unsigned char *)malloc(decodeLen);
447 if (decodeData == NULL) {
448 return -1;
449 }
450 (void)memset_s(decodeData, decodeLen, 0, decodeLen);
451 size_t outLen = 0;
452 if (mbedtls_base64_decode(decodeData, decodeLen, &outLen, (const unsigned char *)data, strlen(data)) != 0) {
453 printf("[sample] RecvRawData encode data fail\r\n");
454 free(decodeData);
455 return -1;
456 }
457 for (int i = 0; i < (int)outLen; i++) {
458 printf("%02x ", decodeData[i]);
459 }
460 printf("\n");
461 SendRawEncodeData(decodeData, outLen);
462 if (decodeData != NULL) {
463 free(decodeData);
464 }
465 return 0;
466 }
467
NotifyNetCfgStatus(enum NetCfgStatus status)468 void NotifyNetCfgStatus(enum NetCfgStatus status)
469 {
470 (void)status;
471 return;
472 }
473
SampleBizTask(const char * arg)474 static void *SampleBizTask(const char *arg)
475 {
476 (void)arg;
477 int ret;
478 LedInit();
479
480 /* Parameter Settings */
481 ret = SetSafeDistancePower(POWER_NUM);
482 if (ret != 0) {
483 printf("[sample] Set saft distance power failed\n");
484 return NULL;
485 }
486
487 struct SoftAPParam config = {0};
488 memset_s(&config, sizeof(struct SoftAPParam), 0, sizeof(struct SoftAPParam));
489 strncpy_s(config.ssid, sizeof(config.ssid), g_ssid, strlen(g_ssid));
490 config.authType = WIFI_SECURITY_OPEN;
491 ret = SetSoftAPParameter(&config);
492 if (ret != 0) {
493 printf("[sample] Set softAP parameters failed\n");
494 return NULL;
495 }
496
497 /* Register callback */
498 NetCfgCallback hook;
499 memset_s(&hook, sizeof(NetCfgCallback), 0, sizeof(NetCfgCallback));
500 hook.GetPinCode = GetPinCode;
501 hook.ParseNetCfgData = ParseNetCfgData;
502 hook.RecvRawData = RecvRawData;
503 hook.NotifyNetCfgStatus = NotifyNetCfgStatus;
504 ret = RegNetCfgCallback(&hook);
505 if (ret != 0) {
506 printf("[sample] Regist config callback failed\n");
507 return NULL;
508 }
509
510 /* Starting the SoftAP Network Configuration Service */
511 struct DevInfo devInfo[DEVICE_INFO_NUM];
512 memset_s(&devInfo, sizeof(devInfo), 0, sizeof(devInfo));
513 devInfo[0].key = "productId";
514 devInfo[1].key = "sn";
515 devInfo[0].value = g_productId;
516 devInfo[1].value = g_sn;
517 ret = StartNetCfg(devInfo, DEVICE_INFO_NUM, NETCFG_SOFTAP_NAN);
518 if (ret != 0) {
519 printf("[sample] Start config wifi fail.\n");
520 return NULL;
521 }
522
523 while (1) {
524 printf("[sample] main biz.\n");
525 usleep(SAMPLE_BIZ_SLEEP_TIME_US * SAMPLE_TIME_COUNT);
526 }
527
528 return NULL;
529 }
530
NetCfgSampleBiz(void)531 void NetCfgSampleBiz(void)
532 {
533 printf("[sample] new demo, NetCfgSampleBiz enter.\n");
534 osThreadAttr_t attr;
535
536 attr.name = "samplebiztask";
537 attr.attr_bits = 0U;
538 attr.cb_mem = NULL;
539 attr.cb_size = 0U;
540 attr.stack_mem = NULL;
541 attr.stack_size = SAMPLE_TASK_STACK_SIZE;
542 attr.priority = SAMPLE_TASK_PRIO;
543
544 if (osThreadNew((osThreadFunc_t)SampleBizTask, NULL, &attr) == NULL) {
545 printf("[sample] Falied to create SampleBizTask!\n");
546 }
547 }
548