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
24extern "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
61enum {
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
73enum {
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 */
87typedef 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
104typedef 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 */
111typedef 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
130typedef 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
148typedef 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
157typedef 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
166typedef 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 */
178DFINDER_EXPORT int32_t NSTACKX_RegisterDevice(const NSTACKX_LocalDeviceInfo *localDeviceInfo);
179
180/* Register local device name */
181DFINDER_EXPORT int32_t NSTACKX_RegisterDeviceName(const char *devName);
182
183/* Register local device information with deviceHash */
184DFINDER_EXPORT int32_t NSTACKX_RegisterDeviceAn(const NSTACKX_LocalDeviceInfo *localDeviceInfo, uint64_t deviceHash);
185
186/* New interface to register local device with multiple interfaces */
187DFINDER_EXPORT int32_t NSTACKX_RegisterDeviceV2(const NSTACKX_LocalDeviceInfoV2 *localDeviceInfo);
188
189/* Device list change callback type */
190typedef void (*NSTACKX_OnDeviceListChanged)(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount);
191
192typedef 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. */
196typedef 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 */
203typedef 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 */
212typedef 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 */
219typedef void (*NSTACKX_OnNotificationReceived)(const NSTACKX_NotificationConfig *notification);
220
221/* NSTACKX parameter, which contains callback list */
222typedef 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 */
232enum {
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
242typedef enum {
243    DFINDER_EVENT_TYPE_FAULT,
244    DFINDER_EVENT_TYPE_STATISTIC,
245    DFINDER_EVENT_TYPE_SECURITY,
246    DFINDER_EVENT_TYPE_BEHAVIOR,
247} DFinderEventType;
248
249typedef enum {
250    DFINDER_EVENT_LEVEL_CRITICAL,
251    DFINDER_EVENT_LEVEL_MINOR,
252} DFinderEventLevel;
253
254typedef 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
269typedef 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
285typedef 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
295typedef void (*DFinderEventFunc)(void *softObj, const DFinderEvent *info);
296
297DFINDER_EXPORT int NSTACKX_DFinderSetEventFunc(void *softobj, DFinderEventFunc func);
298
299typedef void (*DFinderDumpFunc)(void *softObj, const char *data, uint32_t len);
300DFINDER_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 */
306DFINDER_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 */
313DFINDER_EXPORT int32_t NSTACKX_InitV2(const NSTACKX_Parameter *parameter, bool isNotifyPerDevice);
314
315/* NSTACKX Destruction */
316DFINDER_EXPORT void NSTACKX_Deinit(void);
317
318/*
319 * Start device discovery
320 * return 0 on success, negative value on failure
321 */
322DFINDER_EXPORT int32_t NSTACKX_StartDeviceFind(void);
323
324/*
325 * Start device discovery by mode
326 * return 0 on success, negative value on failure
327 */
328DFINDER_EXPORT int32_t NSTACKX_StartDeviceFindAn(uint8_t mode);
329
330/*
331 * Stop device discovery
332 * return 0 on success, negative value on failure
333 */
334DFINDER_EXPORT int32_t NSTACKX_StopDeviceFind(void);
335
336/*
337 * subscribe module
338 * return 0 on success, negative value on failure
339 */
340DFINDER_EXPORT int32_t NSTACKX_SubscribeModule(void);
341
342/*
343 * unsubscribe module
344 * return 0 on success, negative value on failure
345 */
346DFINDER_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 */
352DFINDER_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 */
358DFINDER_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 */
364DFINDER_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 */
370DFINDER_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 */
377DFINDER_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 */
383DFINDER_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 */
401DFINDER_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 */
407DFINDER_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 */
413DFINDER_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 */
420DFINDER_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 */
431DFINDER_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 */
437DFINDER_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 */
443DFINDER_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 */
461DFINDER_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 */
467DFINDER_EXPORT int32_t NSTACKX_StartDeviceDiscoveryWithConfig(const DFinderDiscConfig *discConfig);
468
469typedef 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 */
490DFINDER_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 */
506DFINDER_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 */
522DFINDER_EXPORT int32_t NSTACKX_StopSendNotification(uint8_t businessType);
523
524#ifdef ENABLE_USER_LOG
525typedef void (*DFinderLogCallback)(const char *moduleName, uint32_t logLevel, const char *format, ...);
526
527/*
528 * Set the DFinder log implementation
529 */
530DFINDER_EXPORT int32_t NSTACKX_DFinderRegisterLog(DFinderLogCallback userLogCallback);
531#endif
532
533#ifdef __cplusplus
534}
535#endif
536
537#endif /* NSTACKX_H */
538