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