1 /*
2  * Copyright (C) 2021-2023 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 #ifndef NSTACKX_H
17 #define NSTACKX_H
18 
19 #include <stdbool.h>
20 #include <stddef.h>
21 #include <stdint.h>
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 #define NSTACKX_MAX_DEVICE_NAME_LEN 64
28 #define NSTACKX_MAX_MODULE_NAME_LEN 64
29 #define NSTACKX_MAX_DEVICE_ID_LEN 96
30 #define NSTACKX_MAX_SENDMSG_DATA_LEN 512
31 #define NSTACKX_MAX_MAC_STRING_LEN 18
32 #define NSTACKX_MAX_IP_STRING_LEN 16
33 #define NSTACKX_MAX_CAPABILITY_NUM 2
34 #define NSTACKX_MAX_INTERFACE_NAME_LEN 16
35 #define NSTACKX_MAX_SERVICE_DATA_LEN 64
36 #define NSTACKX_MAX_EXTEND_SERVICE_DATA_LEN 128
37 #ifndef NSTACKX_EXTEND_BUSINESSDATA
38 #define NSTACKX_MAX_BUSINESS_DATA_LEN 1
39 #else
40 #define NSTACKX_MAX_BUSINESS_DATA_LEN 300
41 #endif
42 #define NSTACKX_MAX_NOTIFICATION_DATA_LEN 800
43 
44 #ifdef DFINDER_SAVE_DEVICE_LIST
45 #define NSTACKX_MIN_DEVICE_NUM 1
46 #define NSTACKX_DEFAULT_DEVICE_NUM 20
47 #define NSTACKX_MAX_DEVICE_NUM 400
48 #define NSTACKX_DEFAULT_AGING_TIME 1
49 #define NSTACKX_MIN_AGING_TIME 1
50 #define NSTACKX_MAX_AGING_TIME 10
51 #else
52 #define NSTACKX_MAX_DEVICE_NUM 1
53 #endif
54 
55 // expand from 131 to 219 (+88) bytes to hold service data
56 // expand from 219 to 400 (+128 +53) bytes to hold extend service data
57 // expand from 400 to (420 + NSTACKX_MAX_BUSINESS_DATA_LEN) bytes to hold business data and type
58 #define NSTACKX_MAX_RESERVED_INFO_LEN (420 + NSTACKX_MAX_BUSINESS_DATA_LEN)
59 
60 #define DEVICE_HASH_LEN 21
61 enum {
62     DEFAULT_MODE = 0,
63     DISCOVER_MODE = 1,
64     PUBLISH_MODE_UPLINE = 2,
65     PUBLISH_MODE_OFFLINE = 3,
66     PUBLISH_MODE_PROACTIVE = 10
67 }; // discovery mode
68 #define PUBLISH_DEVICE_NUM 1
69 #define INNER_DISCOVERY 1
70 #define PUBLISH_NUM 1
71 #define COUNT_INIT 0
72 
73 enum {
74     NSTACKX_DISCOVERY_TYPE_PASSIVE = 1,
75     NSTACKX_DISCOVERY_TYPE_ACTIVE = 2
76 };
77 
78 #ifndef DFINDER_EXPORT
79 #ifdef _WIN32
80 #define DFINDER_EXPORT __declspec(dllexport)
81 #else
82 #define DFINDER_EXPORT
83 #endif
84 #endif
85 
86 /* Remote device information */
87 typedef struct NSTACKX_DeviceInfo {
88     char deviceId[NSTACKX_MAX_DEVICE_ID_LEN];
89     char deviceName[NSTACKX_MAX_DEVICE_NAME_LEN];
90     uint32_t capabilityBitmapNum;
91     uint32_t capabilityBitmap[NSTACKX_MAX_CAPABILITY_NUM];
92     uint32_t deviceType;
93     uint8_t mode;
94     uint8_t update : 1;
95     uint8_t reserved : 7;
96     char networkName[NSTACKX_MAX_INTERFACE_NAME_LEN];
97     uint8_t discoveryType;
98     uint8_t businessType;
99     char reservedInfo[NSTACKX_MAX_RESERVED_INFO_LEN];
100 } NSTACKX_DeviceInfo;
101 
102 #define NSTACKX_MAX_LISTENED_NIF_NUM 2
103 
104 typedef struct {
105     char networkName[NSTACKX_MAX_INTERFACE_NAME_LEN];
106     char networkIpAddr[NSTACKX_MAX_IP_STRING_LEN];
107 } NSTACKX_InterfaceInfo;
108 
109 
110 /* Local device information */
111 typedef struct {
112     char name[NSTACKX_MAX_DEVICE_NAME_LEN];
113     char deviceId[NSTACKX_MAX_DEVICE_ID_LEN];
114     char btMacAddr[NSTACKX_MAX_MAC_STRING_LEN];
115     char wifiMacAddr[NSTACKX_MAX_MAC_STRING_LEN];
116 
117     /* Configuration for network interface */
118     NSTACKX_InterfaceInfo localIfInfo[NSTACKX_MAX_LISTENED_NIF_NUM];
119     uint8_t ifNums;
120 
121     /* Obsoleted. Use localIfInfo instead. */
122     char networkIpAddr[NSTACKX_MAX_IP_STRING_LEN];
123     /* Obsoleted. Use localIfInfo instead. */
124     char networkName[NSTACKX_MAX_INTERFACE_NAME_LEN];
125     uint8_t is5GHzBandSupported;
126     uint8_t businessType;
127     uint32_t deviceType;
128 } NSTACKX_LocalDeviceInfo;
129 
130 typedef enum {
131     NSTACKX_BUSINESS_TYPE_NULL = 0,     /* if not set business type, type null will be used as default choice */
132     NSTACKX_BUSINESS_TYPE_HICOM = 1,    /* designed for hicom, but not used currently */
133     NSTACKX_BUSINESS_TYPE_SOFTBUS = 2,  /* designed for softbus-mineharmony to implement some customized features */
134     NSTACKX_BUSINESS_TYPE_NEARBY = 3,   /* designed to handle the interaction between two nearby service */
135     NSTACKX_BUSINESS_TYPE_AUTONET = 4,  /* designed for softbus-autonet to implement some customized features */
136     NSTACKX_BUSINESS_TYPE_STRATEGY = 5, /* designed for softbus-strategy to report disc result in different rounds */
137     NSTACKX_BUSINESS_TYPE_MAX           /* for parameter legality verification */
138 } NSTACKX_BusinessType;
139 
140 #define NSTACKX_MIN_ADVERTISE_COUNT 1
141 #define NSTACKX_MAX_ADVERTISE_COUNT 100
142 /* The unit is ms. */
143 #define NSTACKX_MIN_ADVERTISE_DURATION 5000
144 #define NSTACKX_MAX_ADVERTISE_DURATION 50000
145 #define NSTACKX_MIN_ADVERTISE_INTERVAL 10
146 #define NSTACKX_MAX_ADVERTISE_INTERVAL 10000
147 
148 typedef struct {
149     uint8_t businessType;       /* service identify */
150     uint8_t discoveryMode;      /* discovery mode, e.g. PUBLISH_MODE_PROACTIVE */
151     uint32_t advertiseCount;    /* the number of broadcasts to be sent */
152     uint32_t advertiseDuration; /* duration of discovery this time */
153     uint32_t length;            /* the length of business data, include '\0' */
154     char *businessData;         /* business data in broadcast: {"bData":"xxx"} */
155 } NSTACKX_DiscoverySettings;
156 
157 typedef struct {
158     uint8_t businessType;
159     uint8_t discoveryMode;
160     uint32_t intervalArrLen;
161     uint32_t *bcastInterval;
162     uint32_t businessDataLen;
163     char *businessData;
164 } DFinderDiscConfig;
165 
166 typedef struct {
167     const char *name;
168     const char *deviceId;
169     const NSTACKX_InterfaceInfo *localIfInfo;
170     uint32_t ifNums;
171     uint32_t deviceType;
172     uint64_t deviceHash;
173     bool hasDeviceHash;
174     uint8_t businessType;
175 } NSTACKX_LocalDeviceInfoV2;
176 
177 /* Register local device information */
178 DFINDER_EXPORT int32_t NSTACKX_RegisterDevice(const NSTACKX_LocalDeviceInfo *localDeviceInfo);
179 
180 /* Register local device name */
181 DFINDER_EXPORT int32_t NSTACKX_RegisterDeviceName(const char *devName);
182 
183 /* Register local device information with deviceHash */
184 DFINDER_EXPORT int32_t NSTACKX_RegisterDeviceAn(const NSTACKX_LocalDeviceInfo *localDeviceInfo, uint64_t deviceHash);
185 
186 /* New interface to register local device with multiple interfaces */
187 DFINDER_EXPORT int32_t NSTACKX_RegisterDeviceV2(const NSTACKX_LocalDeviceInfoV2 *localDeviceInfo);
188 
189 /* Device list change callback type */
190 typedef void (*NSTACKX_OnDeviceListChanged)(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount);
191 
192 typedef void (*NSTACKX_OnMsgReceived)(const char *moduleName, const char *deviceId,
193     const uint8_t *data, uint32_t len, const char *srcIp); /* Data receive callback type */
194 
195 /* DFinder message type list. */
196 typedef enum {
197     DFINDER_ON_TOO_BUSY = 1,
198     DFINDER_ON_INNER_ERROR,
199     DFINDER_ON_TOO_MANY_DEVICE,
200 } DFinderMsgType;
201 
202 /* store the notification config, used with interface: NSTACKX_SendNotification */
203 typedef struct {
204     char *msg;                /* notification data in json format */
205     size_t msgLen;            /* strlen of notification data */
206     uint16_t *intervalsMs;    /* pointer to intervals to send notification, first element should be 0 */
207     uint8_t intervalLen;      /* configured number of intervals */
208     uint8_t businessType;     /* service identify, see enum NSTACKX_BusinessType */
209 } NSTACKX_NotificationConfig;
210 
211 /* Data receive callback type */
212 typedef void (*NSTACKX_OnDFinderMsgReceived)(DFinderMsgType msgType);
213 
214 /**
215  * @brief define function pointer type, used to report the notification data received
216  *
217  * @param [out] element: notification data to report, see struct NSTACKX_NotificationConfig
218  */
219 typedef void (*NSTACKX_OnNotificationReceived)(const NSTACKX_NotificationConfig *notification);
220 
221 /* NSTACKX parameter, which contains callback list */
222 typedef struct {
223     NSTACKX_OnDeviceListChanged onDeviceListChanged;
224     NSTACKX_OnDeviceListChanged onDeviceFound;
225     NSTACKX_OnMsgReceived onMsgReceived;
226     NSTACKX_OnDFinderMsgReceived onDFinderMsgReceived;
227     NSTACKX_OnNotificationReceived onNotificationReceived;
228     uint32_t maxDeviceNum; // the size of the device list configured by the caller
229 } NSTACKX_Parameter;
230 
231 /* DFinder log level */
232 enum {
233     DFINDER_LOG_LEVEL_OFF     = 0,
234     DFINDER_LOG_LEVEL_FATAL   = 1,
235     DFINDER_LOG_LEVEL_ERROR   = 2,
236     DFINDER_LOG_LEVEL_WARNING = 3,
237     DFINDER_LOG_LEVEL_INFO    = 4,
238     DFINDER_LOG_LEVEL_DEBUG   = 5,
239     DFINDER_LOG_LEVEL_END,
240 };
241 
242 typedef enum {
243     DFINDER_EVENT_TYPE_FAULT,
244     DFINDER_EVENT_TYPE_STATISTIC,
245     DFINDER_EVENT_TYPE_SECURITY,
246     DFINDER_EVENT_TYPE_BEHAVIOR,
247 } DFinderEventType;
248 
249 typedef enum {
250     DFINDER_EVENT_LEVEL_CRITICAL,
251     DFINDER_EVENT_LEVEL_MINOR,
252 } DFinderEventLevel;
253 
254 typedef enum {
255     DFINDER_PARAM_TYPE_BOOL,
256     DFINDER_PARAM_TYPE_UINT8,
257     DFINDER_PARAM_TYPE_UINT16,
258     DFINDER_PARAM_TYPE_INT32,
259     DFINDER_PARAM_TYPE_UINT32,
260     DFINDER_PARAM_TYPE_UINT64,
261     DFINDER_PARAM_TYPE_FLOAT,
262     DFINDER_PARAM_TYPE_DOUBLE,
263     DFINDER_PARAM_TYPE_STRING,
264 } DFinderEventParamType;
265 
266 #define DFINDER_EVENT_NAME_LEN 32
267 #define DFINDER_EVENT_TAG_LEN 16
268 
269 typedef struct {
270     DFinderEventParamType type;
271     char name[DFINDER_EVENT_NAME_LEN];
272     union {
273         bool b;
274         uint8_t u8v;
275         uint16_t u16v;
276         int32_t i32v;
277         uint32_t u32v;
278         uint64_t u64v;
279         float f;
280         double d;
281         char str[DFINDER_EVENT_NAME_LEN];
282     } value;
283 } DFinderEventParam;
284 
285 typedef struct {
286     char eventName[DFINDER_EVENT_NAME_LEN];
287     DFinderEventType type;
288     DFinderEventLevel level;
289     char tag[DFINDER_EVENT_TAG_LEN];
290     char desc[DFINDER_EVENT_NAME_LEN];
291     DFinderEventParam *params;
292     uint32_t paramNum;
293 } DFinderEvent;
294 
295 typedef void (*DFinderEventFunc)(void *softObj, const DFinderEvent *info);
296 
297 DFINDER_EXPORT int NSTACKX_DFinderSetEventFunc(void *softobj, DFinderEventFunc func);
298 
299 typedef void (*DFinderDumpFunc)(void *softObj, const char *data, uint32_t len);
300 DFINDER_EXPORT int NSTACKX_DFinderDump(const char **argv, uint32_t argc, void *softObj, DFinderDumpFunc dump);
301 
302 /*
303  * NSTACKX Initialization
304  * return 0 on success, negative value on failure
305  */
306 DFINDER_EXPORT int32_t NSTACKX_Init(const NSTACKX_Parameter *parameter);
307 
308 /*
309  * NSTACKX Initialization V2
310  * support notify device info one by one
311  * return 0 on success, negative value on failure
312  */
313 DFINDER_EXPORT int32_t NSTACKX_InitV2(const NSTACKX_Parameter *parameter, bool isNotifyPerDevice);
314 
315 /* NSTACKX Destruction */
316 DFINDER_EXPORT void NSTACKX_Deinit(void);
317 
318 /*
319  * Start device discovery
320  * return 0 on success, negative value on failure
321  */
322 DFINDER_EXPORT int32_t NSTACKX_StartDeviceFind(void);
323 
324 /*
325  * Start device discovery by mode
326  * return 0 on success, negative value on failure
327  */
328 DFINDER_EXPORT int32_t NSTACKX_StartDeviceFindAn(uint8_t mode);
329 
330 /*
331  * Stop device discovery
332  * return 0 on success, negative value on failure
333  */
334 DFINDER_EXPORT int32_t NSTACKX_StopDeviceFind(void);
335 
336 /*
337  * subscribe module
338  * return 0 on success, negative value on failure
339  */
340 DFINDER_EXPORT int32_t NSTACKX_SubscribeModule(void);
341 
342 /*
343  * unsubscribe module
344  * return 0 on success, negative value on failure
345  */
346 DFINDER_EXPORT int32_t NSTACKX_UnsubscribeModule(void);
347 
348 /*
349  * Register the capability of local device.
350  * return 0 on success, negative value on failure
351  */
352 DFINDER_EXPORT int32_t NSTACKX_RegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]);
353 
354 /*
355  * Set the capability to filter remote devices.
356  * return 0 on success, negative value on failure
357  */
358 DFINDER_EXPORT int32_t NSTACKX_SetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]);
359 
360 /*
361  * Set the agingTime of the device list.
362  * The unit of agingTime is seconds, and the range is 1 to 10 seconds.
363  */
364 DFINDER_EXPORT int32_t NSTACKX_SetDeviceListAgingTime(uint32_t agingTime);
365 
366 /*
367  * Set the size of the device list.
368  * The range is 20 to 400.
369  */
370 DFINDER_EXPORT int32_t NSTACKX_SetMaxDeviceNum(uint32_t maxDeviceNum);
371 
372 /*
373  * dfinder set screen status
374  * param: isScreenOn, screen status
375  * return: always return 0 on success
376  */
377 DFINDER_EXPORT int32_t NSTACKX_ScreenStatusChange(bool isScreenOn);
378 
379 /*
380  * Register the serviceData of local device.
381  * return 0 on success, negative value on failure
382  */
383 DFINDER_EXPORT int32_t NSTACKX_RegisterServiceData(const char *serviceData);
384 
385 /**
386  * @brief register business data to local device, the data will be used as bData filed in json format in coap payload
387  *
388  * @param [in] (const char *) businessData: specific data which need to be put into the coap payload
389  *
390  * @return (int32_t)
391  *      0                operation success
392  *      negative value   a number indicating the rough cause of this failure
393  *
394  * @note 1. the length of businessData should be less than NSTACKX_MAX_BUSINESS_DATA_LEN
395  *       2. the registered business data will only be used in unicast which is confusing
396  *       3. this interface will be DEPRECATED soon, in some special case, you can replace it with:
397  *          NSTACKX_StartDeviceDiscovery && NSTACKX_SendDiscoveryRsp
398  *
399  * @exception
400  */
401 DFINDER_EXPORT int32_t NSTACKX_RegisterBusinessData(const char *businessData);
402 
403 /*
404  * Register the extendServiceData of local device.
405  * return 0 on success, negative value on failure
406  */
407 DFINDER_EXPORT int32_t NSTACKX_RegisterExtendServiceData(const char *extendServiceData);
408 
409 /*
410  * Send Msg to remote peer
411  * return 0 on success, negative value on failure
412  */
413 DFINDER_EXPORT int32_t NSTACKX_SendMsg(const char *moduleName, const char *deviceId, const uint8_t *data,
414                                        uint32_t len);
415 
416 /*
417  * Send Msg to remote peer
418  * return 0 on success, negative value on failure
419  */
420 DFINDER_EXPORT int32_t NSTACKX_SendMsgDirect(const char *moduleName, const char *deviceId, const uint8_t *data,
421     uint32_t len, const char *ipaddr, uint8_t sendType);
422 
423 /*
424  * Get device list from cache
425  * param: deviceList - Device list return from NSTACKX, user should prepare sufficient buffer to store
426  *                     device list.
427  * param: deviceCountPtr - In/Out parameter. It indicates buffer size (number of elements) in deviceList
428  *                         When returns, it indicates numbers of valid device in deviceList.
429  * return 0 on success, negative value on failure
430  */
431 DFINDER_EXPORT int32_t NSTACKX_GetDeviceList(NSTACKX_DeviceInfo *deviceList, uint32_t *deviceCountPtr);
432 
433 /*
434  * NSTACKX Initialization, only used for restart.
435  * return 0 on success, negative value on failure
436  */
437 DFINDER_EXPORT int32_t NSTACKX_InitRestart(const NSTACKX_Parameter *parameter);
438 
439 /*
440  * NSTACKX Initialization, only used for restart.
441  * return 0 on success, negative value on failure
442  */
443 DFINDER_EXPORT void NSTACKX_StartDeviceFindRestart(void);
444 
445 /**
446  * @brief start device find with configurable parameters
447  *
448  * @param [in] (const NSTACKX_DiscoverySettings *) discoverySettings: configurable discovery properties
449  *
450  * @return (int32_t)
451  *      0                operation success
452  *      negative value   a number indicating the rough cause of this failure
453  *
454  * @note 1. if the discovery is already running, calling this interface will stop the previous one and start a new one
455  *       2. if both advertiseCount and advertiseDuration in discoverySettings are zero, the discovery interval will
456  *          fallback to 5 sec 12 times(100 ms, 200, 200, 300...)
457  *       3. if advertiseCount is not zero, the broadcast interval equals advertiseDuration / advertiseCount
458  *
459  * @exception
460  */
461 DFINDER_EXPORT int32_t NSTACKX_StartDeviceDiscovery(const NSTACKX_DiscoverySettings *discoverySettings);
462 
463 /*
464  * Start device discovery with configured broadcast interval and other settings
465  * return 0 on success, negative value on failure
466  */
467 DFINDER_EXPORT int32_t NSTACKX_StartDeviceDiscoveryWithConfig(const DFinderDiscConfig *discConfig);
468 
469 typedef struct {
470     char localNetworkName[NSTACKX_MAX_INTERFACE_NAME_LEN];  /* nic name of local device */
471     char remoteIp[NSTACKX_MAX_IP_STRING_LEN];               /* ip of remote device */
472     char *businessData;                                     /* business data in unicast: {"bData":"xxx"} */
473     uint32_t length;                                        /* the length of business data, include '\0' */
474     uint8_t businessType;                                   /* service identify */
475 } NSTACKX_ResponseSettings;
476 
477 /**
478  * @brief reply unicast to remote device specified by remoteIp, using local nic specified by localNetworkName
479  *
480  * @param [in] (const NSTACKX_ResponseSettings *) responseSettings: configurable unicast reply properties
481  *
482  * @return (int32_t)
483  *      0                operation success
484  *      negative value   a number indicating the rough cause of this failure
485  *
486  * @note only one unicast reply will be sent each time this interface is called
487  *
488  * @exception
489  */
490 DFINDER_EXPORT int32_t NSTACKX_SendDiscoveryRsp(const NSTACKX_ResponseSettings *responseSettings);
491 
492 /**
493  * @brief start sending broadcast notifications
494  *
495  * @param [in] config: configurable properties to send notification, see struct NSTACKX_NotificationConfig
496  *
497  * @return (int32_t)
498  *      0                operation success
499  *      negative value   a number indicating the rough cause of this failure
500  *
501  * @note 1. if the sending is already running, calling this interface will stop the previous one and start a new one,
502  *          caller can update its notification msg through this way
503  *       2. caller should ensure the consistency of associated data
504  * @exception
505  */
506 DFINDER_EXPORT int32_t NSTACKX_SendNotification(const NSTACKX_NotificationConfig *config);
507 
508 /**
509  * @brief stop sending broadcast notifications
510  *
511  * @param [in] businessType: service identify, notification of which business we should stop
512  *
513  * @return (int32_t)
514  *      0                operation success
515  *      negative value   a number indicating the rough cause of this failure
516  *
517  * @note 1. calling this interface will stop the sending timer
518  *       2. if not business sensitive, should use NSTACKX_BUSINESS_TYPE_NULL, see struct NSTACKX_BusinessType
519  *
520  * @exception
521  */
522 DFINDER_EXPORT int32_t NSTACKX_StopSendNotification(uint8_t businessType);
523 
524 #ifdef ENABLE_USER_LOG
525 typedef void (*DFinderLogCallback)(const char *moduleName, uint32_t logLevel, const char *format, ...);
526 
527 /*
528  * Set the DFinder log implementation
529  */
530 DFINDER_EXPORT int32_t NSTACKX_DFinderRegisterLog(DFinderLogCallback userLogCallback);
531 #endif
532 
533 #ifdef __cplusplus
534 }
535 #endif
536 
537 #endif /* NSTACKX_H */
538