• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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