1 /*
2  * Copyright (c) 2021 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 <securec.h>
17 #include <stdint.h>
18 #include <stdio.h>
19 #include <unistd.h>
20 
21 #include "cJSON.h"
22 #include "lwip/netif.h"
23 #include "lwip/netifapi.h"
24 #include "nstackx.h"
25 #include "ohos_init.h"
26 #include "softbus_errcode.h"
27 
28 #define DEVICE_NAME "HI3861"
29 #define DEVICE_ID "ABCDEFGFHIJKLMNOPQRSTVUWXYZ"
30 #define DEVICE_UDID "UDID"
31 #define NET_WORK_NAME "wlan0"
32 #define DEVICE_TYPE 0
33 #define VERSION "3.1.0"
34 #define AUTH_PORT 45576
35 
36 #define MAXT_WAIT_COUNT 6
37 #define WIFI_CONFIG_INTERVAL 10
38 #define TEST_COUNT_INTREVAL 10
39 #define MAX_TEST_COUNT 20
40 #define TEST_DISCOVERY_INTERVAL 10
41 #define TEST_DISCOVERY_COUNT 10
42 
43 static char *g_capData = NULL;
44 static int32_t g_onDeviceFoundCnt = 0;
45 
OnDeviceFound(const NSTACKX_DeviceInfo * deviceList,uint32_t deviceCount)46 static void OnDeviceFound(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount)
47 {
48     if (deviceCount == 0) {
49         return;
50     }
51 
52     for (uint32_t i = 0; i < deviceCount; i++) {
53         const NSTACKX_DeviceInfo *nstackxDeviceInfo = deviceList + i;
54         if (nstackxDeviceInfo == NULL) {
55             return;
56         }
57         if (((nstackxDeviceInfo->update) & 0x1) == 0) {
58             printf("duplicate  device is not reported.[%u]\n", i);
59             continue;
60         }
61         printf("deviceId = %s.\n", nstackxDeviceInfo->deviceId);
62         printf("deviceName = %s.\n", nstackxDeviceInfo->deviceName);
63         printf("capabilityBitmapNum = %d.\n", nstackxDeviceInfo->capabilityBitmapNum);
64         for (uint32_t j = 0; j < nstackxDeviceInfo->capabilityBitmapNum; j++) {
65             printf("capabilityBitmap = %d.\n", nstackxDeviceInfo->capabilityBitmap[j]);
66         }
67         printf("deviceType = %d.\n", nstackxDeviceInfo->deviceType);
68         printf("reservedInfo = %s.\n", nstackxDeviceInfo->reservedInfo);
69         g_onDeviceFoundCnt++;
70     }
71 }
72 
73 NSTACKX_Parameter g_nstackxParam = {
74     .onDeviceListChanged = OnDeviceFound,
75     .onDeviceFound = NULL,
76     .onMsgReceived = NULL,
77     .onDFinderMsgReceived = NULL
78 };
79 
GetLocalWifiIp(char * ip,int32_t len)80 static void GetLocalWifiIp(char *ip, int32_t len)
81 {
82     struct netif *wifiNetIf = NULL;
83     ip4_addr_t ipaddr;
84     int32_t ret;
85     int32_t cnt = 0;
86     while (cnt < MAXT_WAIT_COUNT) {
87         cnt++;
88         sleep(WIFI_CONFIG_INTERVAL);
89         wifiNetIf = netifapi_netif_find(NET_WORK_NAME);
90         if (wifiNetIf == NULL) {
91             printf("netif find device failed.\n");
92             continue;
93         }
94         ret = netifapi_netif_get_addr(wifiNetIf, &ipaddr, NULL, NULL);
95         if (ret != 0) {
96             printf("netif get ip addr failed, ret = %d.\n", ret);
97             continue;
98         }
99         if (ipaddr.addr == 0) {
100             printf("wifi is not connected.\n");
101             continue;
102         }
103         break;
104     }
105     inet_ntop(AF_INET, &ipaddr, ip, len);
106     printf("wifi connected, device ip = %s.\n", ip);
107 }
108 
GetDeviceId(void)109 static char *GetDeviceId(void)
110 {
111     char *formatString = NULL;
112     cJSON *deviceIdObj = NULL;
113     cJSON *deviceIdItem = NULL;
114 
115     do {
116         deviceIdObj = cJSON_CreateObject();
117         if (deviceIdObj == NULL) {
118             break;
119         }
120         deviceIdItem = cJSON_CreateString(DEVICE_ID);
121         if (deviceIdItem == NULL) {
122             break;
123         }
124         if (!cJSON_AddItemToObject(deviceIdObj, DEVICE_UDID, deviceIdItem)) {
125             break;
126         }
127         formatString = cJSON_PrintUnformatted(deviceIdObj);
128     } while (0);
129 
130     if (deviceIdObj != NULL) {
131         cJSON_Delete(deviceIdObj);
132     }
133     if (deviceIdItem != NULL) {
134         cJSON_Delete(deviceIdItem);
135     }
136     return formatString;
137 }
138 
TestRegisterDeviceInfo(const char * ip)139 static int32_t TestRegisterDeviceInfo(const char *ip)
140 {
141     NSTACKX_LocalDeviceInfo *localDevInfo = (NSTACKX_LocalDeviceInfo *)malloc(sizeof(NSTACKX_LocalDeviceInfo));
142     if (localDevInfo == NULL) {
143         printf("nstackx local device info malloc failed.\n");
144         return SOFTBUS_DISCOVER_TEST_CASE_ERRCODE;
145     }
146 
147     (void)memset_s(localDevInfo, sizeof(NSTACKX_LocalDeviceInfo), 0, sizeof(NSTACKX_LocalDeviceInfo));
148     char *udidStr = GetDeviceId();
149     if (udidStr == NULL) {
150         printf("get device id string failed.\n");
151         free(localDevInfo);
152         return SOFTBUS_DISCOVER_TEST_CASE_ERRCODE;
153     }
154 
155     if (strcpy_s(localDevInfo->deviceId, sizeof(localDevInfo->deviceId), udidStr) != EOK) {
156         cJSON_free(udidStr);
157         printf("strcpy_s device id failed.\n");
158         free(localDevInfo);
159         return SOFTBUS_DISCOVER_TEST_CASE_ERRCODE;
160     }
161     cJSON_free(udidStr);
162     if (strcpy_s(localDevInfo->name, sizeof(localDevInfo->name), DEVICE_NAME) != EOK ||
163         strcpy_s(localDevInfo->networkIpAddr, sizeof(localDevInfo->networkIpAddr), ip) != EOK ||
164         strcpy_s(localDevInfo->networkName, sizeof(localDevInfo->networkName), NET_WORK_NAME) != EOK ||
165         strcpy_s(localDevInfo->version, sizeof(localDevInfo->version), VERSION) != EOK) {
166         printf("strcpy_s failed.\n");
167         free(localDevInfo);
168         return SOFTBUS_DISCOVER_TEST_CASE_ERRCODE;
169     }
170     localDevInfo->deviceType = DEVICE_TYPE;
171 
172     if (NSTACKX_RegisterDevice(localDevInfo) != 0) {
173         printf("nstackx register device failed.\n");
174         NSTACKX_Deinit();
175         return SOFTBUS_DISCOVER_TEST_CASE_ERRCODE;
176     }
177     free(localDevInfo);
178     return SOFTBUS_OK;
179 }
180 
TestRegisterCap(uint32_t capBitMapNum,uint32_t capBitMap[])181 static int32_t TestRegisterCap(uint32_t capBitMapNum, uint32_t capBitMap[])
182 {
183     if (capBitMapNum == 0) {
184         return SOFTBUS_INVALID_PARAM;
185     }
186 
187     if (NSTACKX_RegisterCapability(capBitMapNum, capBitMap) != SOFTBUS_OK) {
188         return SOFTBUS_DISCOVER_COAP_REGISTER_CAP_FAIL;
189     }
190     return SOFTBUS_OK;
191 }
192 
TestSetFilterCap(uint32_t capBitMapNum,uint32_t capBitMap[])193 static int32_t TestSetFilterCap(uint32_t capBitMapNum, uint32_t capBitMap[])
194 {
195     if (capBitMapNum == 0) {
196         return SOFTBUS_INVALID_PARAM;
197     }
198 
199     if (NSTACKX_SetFilterCapability(capBitMapNum, capBitMap) != SOFTBUS_OK) {
200         return SOFTBUS_DISCOVER_COAP_SET_FILTER_CAP_FAIL;
201     }
202     return SOFTBUS_OK;
203 }
204 
TestRegisterServiceData(const unsigned char * serviceData,uint32_t dataLen)205 static int32_t TestRegisterServiceData(const unsigned char *serviceData, uint32_t dataLen)
206 {
207     (void)serviceData;
208     (void)dataLen;
209     if (g_capData == NULL) {
210         return SOFTBUS_DISCOVER_COAP_NOT_INIT;
211     }
212 
213     int32_t authPort = AUTH_PORT;
214     (void)memset_s(g_capData, NSTACKX_MAX_SERVICE_DATA_LEN, 0, NSTACKX_MAX_SERVICE_DATA_LEN);
215     int32_t ret = sprintf_s(g_capData, NSTACKX_MAX_SERVICE_DATA_LEN, "port:%d,", authPort);
216     if (ret == -1) {
217         return SOFTBUS_DISCOVER_TEST_CASE_ERRCODE;
218     }
219     if (NSTACKX_RegisterServiceData(g_capData) != SOFTBUS_OK) {
220         return SOFTBUS_DISCOVER_TEST_CASE_ERRCODE;
221     }
222     return SOFTBUS_OK;
223 }
224 
TestInit(void)225 static int32_t TestInit(void)
226 {
227     g_capData = (char *)malloc(NSTACKX_MAX_SERVICE_DATA_LEN);
228     if (g_capData == NULL) {
229         return SOFTBUS_DISCOVER_TEST_CASE_ERRCODE;
230     }
231 
232     (void)memset_s(g_capData, NSTACKX_MAX_SERVICE_DATA_LEN, 0, NSTACKX_MAX_SERVICE_DATA_LEN);
233     if (NSTACKX_Init(&g_nstackxParam) != 0) {
234         printf("nstackx init failed\n");
235         return SOFTBUS_DISCOVER_TEST_CASE_ERRCODE;
236     }
237     return SOFTBUS_OK;
238 }
239 
TestDeinit(void)240 static void TestDeinit(void)
241 {
242     if (g_capData != NULL) {
243         free(g_capData);
244         g_capData = NULL;
245     }
246 
247     NSTACKX_Deinit();
248 }
249 
NstackxTestEntry(void)250 static void NstackxTestEntry(void)
251 {
252     char ip[NSTACKX_MAX_IP_STRING_LEN] = {0};
253     int32_t testCnt = 0;
254     while (testCnt < MAX_TEST_COUNT) {
255         if (TestInit() != SOFTBUS_OK) {
256             printf("init failed\n");
257             return;
258         }
259 
260         GetLocalWifiIp(ip, NSTACKX_MAX_IP_STRING_LEN);
261         if (TestRegisterDeviceInfo(ip) != SOFTBUS_OK) {
262             printf("register device info failed.\n");
263             TestDeinit();
264             return;
265         }
266 
267         uint32_t cap[1] = {64};
268         if (TestRegisterCap(1, cap) != SOFTBUS_OK) {
269             printf("register cap info failed\n");
270             TestDeinit();
271             return;
272         }
273 
274         if (TestSetFilterCap(1, cap) != SOFTBUS_OK) {
275             printf("set filter cap failed\n");
276             TestDeinit();
277             return;
278         }
279 
280         if (TestRegisterServiceData(NULL, 0) != SOFTBUS_OK) {
281             printf("register service data failed\n");
282             TestDeinit();
283             return;
284         }
285 
286         for (int32_t discTestCnt = 0; discTestCnt < TEST_DISCOVERY_COUNT;) {
287             if (NSTACKX_StartDeviceFind() != 0) {
288                 printf("start device find failed\n");
289                 return;
290             }
291             sleep(TEST_DISCOVERY_INTERVAL);
292             if (NSTACKX_StopDeviceFind() != 0) {
293                 printf("stop device find failed\n");
294                 return;
295             }
296             printf("disc test cnt = %d / %d\n", ++discTestCnt, TEST_DISCOVERY_COUNT);
297         }
298 
299         testCnt++;
300         sleep(TEST_COUNT_INTREVAL);
301         TestDeinit();
302         printf("test cnt = %d / %d\n", testCnt, MAX_TEST_COUNT);
303     }
304     printf("ondevice found cnt = %d / %d\n", g_onDeviceFoundCnt, MAX_TEST_COUNT * TEST_DISCOVERY_COUNT);
305 }
306 
307 SYS_SERVICE_INIT_PRI(NstackxTestEntry, 4);
308