1 /*
2  * Copyright (c) 2023-2024 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 "softbus_adapter.h"
17 
18 #include <stdio.h>
19 #include <unistd.h>
20 
21 #include "cJSON.h"
22 #include "cmsis_os2.h"
23 #include "discovery_service.h"
24 #include "hichain_adapter.h"
25 #include "inner_session.h"
26 #include "los_config.h"
27 #include "los_mux.h"
28 #include "los_sem.h"
29 #include "los_swtmr.h"
30 #include "ohos_init.h"
31 #include "parameter.h"
32 #include "securec.h"
33 #include "session.h"
34 #include "softbus_bus_center.h"
35 #include "softbus_common.h"
36 #include "softbus_errcode.h"
37 
38 #define NOT_FILTER (-1)
39 #define SESSION_SIDE_CLIENT (1)
40 #define SOFTBUS_DELAY_TICK_COUNT (10 * LOSCFG_BASE_CORE_TICK_PER_SECOND)  // 10s
41 #define DM_MAX_DEVICE_SIZE (100)
42 
43 static const char * const DM_CAPABILITY_OSD = "osdCapability";
44 static const char * const DM_PKG_NAME = "com.ohos.devicemanager";
45 static const char * const FILTER_CREDIBLE = "credible";
46 static const char * const FILTER_RANGE = "range";
47 static const char * const FILTER_ISTRUSTED = "isTrusted";
48 static const char * const FILTER_AUTHFORM = "authform";
49 static const char * const FILTER_DEVICE_TYPE = "deviceType";
50 static const char * const FILED_MSG_TYPE = "MSG_TYPE";
51 static const char * const FILED_BIND_TYPE = "AUTHTYPE";
52 static const char * const FILED_REPLY = "REPLY";
53 static const char * const FILED_IS_CRE_EXISTED = "isCreExist";
54 static const char * const FILED_IS_BIND_TYPE_SUPPORTED = "isBindTypeSupported";
55 static const char * const DM_SESSION_NAME = "ohos.distributedhardware.devicemanager.resident";
56 static const int MSG_NEGOTIATE = 80;
57 static const int MSG_NEGOTIATE_RESP = 90;
58 
59 static const unsigned int DEVICEMANAGER_SA_ID = 4802;
60 
61 typedef struct {
62     int credible;
63     int range;
64     int deviceType;
65     int isTrusted;
66     int authForm;
67 } FilterOption;
68 
69 static int CreateSoftbusSemaphoreAndMutex(void);
70 static int DeleteSoftbusSemaphoreAndMutex(void);
71 
72 static bool IsValidStartDiscoveryInput(const char *pkgName, const char *filterOption,
73     OnTargetFound callback);
74 static int StartSoftbusDiscovering(const char *pkgName, const int subscribeId, OnTargetFound callback);
75 static int ParseDiscoverFilterOption(const char *filterOption);
76 static bool ImportPkgNameToDiscoveryMap(const char *pkgName, const int subscribeId, OnTargetFound callback);
77 static int SoftbusRefreshLNN(const char *pkgName, const int subscribeId);
78 static int StopSoftbusRefreshLNN(const char *pkgName, const int subscribeId);
79 
80 static bool DeletePkgNameFromStateMap(const char *pkgName);
81 static bool ImportPkgNameToStateMap(const char *pkgName, DevStatusCallback callback);
82 static void DeviceInfoCopyToDmDevice(DmDeviceInfo *dmDeviceInfo, const DeviceInfo *deviceInfo);
83 static void NodeBasicInfoCopyToDmDevice(DmDeviceBasicInfo *dmDeviceInfo, const NodeBasicInfo *nodeBasicInfo);
84 static void DmDeviceInfoToDmBasicInfo(const DmDeviceInfo *dmDeviceInfo, DmDeviceBasicInfo *dmBasicInfo);
85 
86 static void OnPublishLNNResult(int publishId, PublishResult reason);
87 static void OnRefreshDiscoveryResult(int32_t refreshId, RefreshResult reason);
88 static void OnDiscoveryDeviceFound(const DeviceInfo *deviceInfo);
89 static void OnSoftbusDeviceOnline(NodeBasicInfo *deviceInfo);
90 static void OnSoftbusDeviceOffline(NodeBasicInfo *deviceInfo);
91 static void OnBytesReceived(int sessionId, const void *data, unsigned int dataLen);
92 static int OnSessionOpened(int sessionId, int result);
93 static void OnSessionClosed(int sessionId);
94 static void OnJoinLNNCallback(ConnectionAddr *addr, const char *networkId, int32_t retCode);
95 static void OnLeaveLNNCallback(const char *networkId, int32_t retCode);
96 
97 static void ProcessSinkMsg(const char *data, unsigned int dataLen);
98 static void ProcessSourceMsg(const char *data, unsigned int dataLen);
99 static int GetConnAddrByDeviceId(const char *deviceId, ConnectionAddr *addr);
100 static bool ImportDeviceToAddrMap(const DmDeviceInfo *deviceInfo);
101 static bool IsPkgNameValid(const char *pkgName);
102 static bool IsDeviceIdValid(const char *deviceId);
103 static char* CreateRespNegotiateMsg(const int bindType);
104 static int AbilityNegotiate(const int bindType);
105 
106 static UINT32 g_bindSem = 0;
107 static bool g_publishLNNFlag = false;
108 static bool g_startDiscoveryFlag = false;
109 static ConnectionAddr g_bindAddr;
110 static char *g_bindDeviceId = NULL;
111 static int g_bindType = -1;
112 static int g_sessionId = -1;
113 
114 #define DM_MUTEX_TIMEOUT osWaitForever
115 static osMutexId_t g_dmGlobalLock = NULL;
116 static osMutexId_t g_dmBindLock = NULL;
117 
InitDmGlobalLock(void)118 static void InitDmGlobalLock(void)
119 {
120     if (g_dmGlobalLock == NULL) {
121         osMutexAttr_t globalMutexAttr = {
122             "DmGloablLock",
123             osMutexRecursive | osMutexPrioInherit,
124             NULL,
125             0U
126         };
127         g_dmGlobalLock = osMutexNew(&globalMutexAttr);
128     }
129     DMLOGI("InitDmGlobalLock successfully.");
130 }
131 
InitDmBindLock(void)132 static void InitDmBindLock(void)
133 {
134     if (g_dmBindLock == NULL) {
135         osMutexAttr_t bindMutexAttr = {
136             "DmBindlLock",
137             osMutexRecursive | osMutexPrioInherit,
138             NULL,
139             0U
140         };
141         g_dmBindLock = osMutexNew(&bindMutexAttr);
142     }
143     DMLOGI("InitDmBindLock successfully.");
144 }
145 
LockDmGlobalLock(void)146 int LockDmGlobalLock(void)
147 {
148     if (g_dmGlobalLock == NULL) {
149         InitDmGlobalLock();
150     }
151 
152     osStatus_t ret = osMutexAcquire(g_dmGlobalLock, DM_MUTEX_TIMEOUT);
153     if (ret != osOK) {
154         printf("[dm_service] osMutexAcquire failed \n");
155         return ERR_DM_FAILED;
156     }
157 
158     return DM_OK;
159 }
160 
UnlockDmGlobalLock(void)161 int UnlockDmGlobalLock(void)
162 {
163     if (g_dmGlobalLock == NULL) {
164         return ERR_DM_FAILED;
165     }
166 
167     osStatus_t ret = osMutexRelease(g_dmGlobalLock);
168     if (ret != osOK) {
169         printf("[dm_service] osMutexUnlock failed \n");
170         return ERR_DM_FAILED;
171     }
172 
173     return DM_OK;
174 }
175 
LockDmBindLock(void)176 int LockDmBindLock(void)
177 {
178     if (g_dmBindLock == NULL) {
179         InitDmBindLock();
180     }
181 
182     osStatus_t ret = osMutexAcquire(g_dmBindLock, DM_MUTEX_TIMEOUT);
183     if (ret != osOK) {
184         printf("[dm_service] osMutexAcquire failed \n");
185         return ERR_DM_FAILED;
186     }
187 
188     return DM_OK;
189 }
190 
UnlockDmBindLock(void)191 int UnlockDmBindLock(void)
192 {
193     if (g_dmBindLock == NULL) {
194         return ERR_DM_FAILED;
195     }
196 
197     osStatus_t ret = osMutexRelease(g_dmBindLock);
198     if (ret != osOK) {
199         printf("[dm_service] osMutexUnlock failed \n");
200         return ERR_DM_FAILED;
201     }
202 
203     return DM_OK;
204 }
205 
206 static struct {
207     int subscribeId;
208     char pkgName[DM_MAX_PKG_NAME_LEN + 1];
209     OnTargetFound discoveryCallback;
210     bool valid;
211     FilterOption filterOption;
212 } g_discoveryCallbackMap;
213 
214 static struct {
215     char pkgName[DM_MAX_PKG_NAME_LEN + 1];
216     OnAdvertisingResult advCallback;
217     bool valid;
218 } g_advertisingCallbackMap;
219 
220 static struct {
221     char pkgName[DM_MAX_PKG_NAME_LEN + 1];
222     OnBindResult bindRetCallback;
223     bool valid;
224 } g_bindRetCallbackMap;
225 
226 static struct {
227     char pkgName[DM_MAX_PKG_NAME_LEN + 1];
228     DevStatusCallback stateCallback;
229     bool valid;
230 } g_stateCallbackMap[DM_MAX_REG_PKG_NUMBER];
231 
232 static struct {
233     char deviceId[DM_MAX_DEVICE_ID_LEN + 1];
234     ConnectionAddr connectAddr;
235     bool valid;
236 } g_deviceIdAddrMap[DM_MAX_DEVICE_SIZE];
237 
238 static struct {
239     char deviceId[DM_MAX_DEVICE_ID_LEN + 1];
240     char networkId[DM_MAX_DEVICE_NETWORKID_LEN + 1];
241     bool valid;
242 } g_devIdMap[DM_MAX_DEVICE_SIZE];
243 
244 IPublishCb g_publishLNNCallback = {
245     .OnPublishResult = OnPublishLNNResult
246 };
247 
248 INodeStateCb g_softbusStatusChangeCb = {
249     .events = EVENT_NODE_STATE_ONLINE | EVENT_NODE_STATE_OFFLINE,
250     .onNodeOnline = OnSoftbusDeviceOnline,
251     .onNodeOffline = OnSoftbusDeviceOffline,
252     .onNodeBasicInfoChanged = NULL
253 };
254 
255 IRefreshCallback g_refreshDiscoveryCallback = {
256     .OnDeviceFound = OnDiscoveryDeviceFound,
257     .OnDiscoverResult = OnRefreshDiscoveryResult
258 };
259 
260 ISessionListener g_sessionListener = {
261     .OnSessionOpened = OnSessionOpened,
262     .OnSessionClosed = OnSessionClosed,
263     .OnBytesReceived = OnBytesReceived,
264     .OnMessageReceived = NULL,
265     .OnStreamReceived = NULL
266 };
267 
268 OnJoinLNNResult g_joinLNNResult = OnJoinLNNCallback;
269 OnLeaveLNNResult g_leaveLNNResult = OnLeaveLNNCallback;
270 
InitSoftbusModle(void)271 int InitSoftbusModle(void)
272 {
273     int retValue = DM_OK;
274     g_discoveryCallbackMap.valid = false;
275     for (int i = 0; i < DM_MAX_REG_PKG_NUMBER; i++) {
276         g_stateCallbackMap[i].valid = false;
277     }
278     for (int i = 0; i < DM_MAX_DEVICE_SIZE; i++) {
279         g_deviceIdAddrMap[i].valid = false;
280         g_devIdMap[i].valid = false;
281     }
282 
283     do {
284         InitSoftBusServer();
285         DMLOGI("Softbus adapter create session session server start.");
286         int32_t ret = CreateSessionServer(DM_PKG_NAME, DM_SESSION_NAME, &g_sessionListener);
287         if (ret != DM_OK) {
288             DMLOGE("[SOFTBUS]CreateSessionServer failed, ret: %d.", ret);
289         } else {
290             DMLOGI("[SOFTBUS]CreateSessionServer ok.");
291         }
292         retValue = RegNodeDeviceStateCb(DM_PKG_NAME, &g_softbusStatusChangeCb);
293         if (retValue != SOFTBUS_OK) {
294             DMLOGE("failed to Register callback to softbus with ret: %d.", retValue);
295             retValue = ERR_DM_SOFTBUS_REG_STATE_CALLBACK;
296             break;
297         }
298         if (CreateSoftbusSemaphoreAndMutex() != DM_OK) {
299             DMLOGE("failed to create mutex and semaphore.");
300             retValue = ERR_DM_LITEOS_CREATE_MUTEX_OR_SEM;
301             break;
302         }
303     } while (false);
304 
305     if (retValue != DM_OK) {
306         DMLOGE("failed to init softbus modle with ret: %d.", retValue);
307         UnInitSoftbusModle();
308         return retValue;
309     }
310     DMLOGI("init softbus modle successfully.");
311     return DM_OK;
312 }
313 
UnInitSoftbusModle(void)314 int UnInitSoftbusModle(void)
315 {
316     int returnResult = DM_OK;
317     int retValue = UnregNodeDeviceStateCb(&g_softbusStatusChangeCb);
318     if (retValue != SOFTBUS_OK) {
319         DMLOGE("failed to unregister device state callback with ret: %d.", retValue);
320         returnResult = ERR_DM_SOFTBUS_UNREG_STATE_CALLBACK;
321     }
322     if (DeleteSoftbusSemaphoreAndMutex() != DM_OK) {
323         DMLOGE("failed to delete semaphore.");
324         returnResult = ERR_DM_LITEOS_DELETE_MUTEX_OR_SEM;
325     }
326     if (returnResult != DM_OK) {
327         DMLOGE("failed to uninti softbus modle with ret: %d.", returnResult);
328         return returnResult;
329     }
330     DMLOGI("uninit softbus modle successfully.");
331     return DM_OK;
332 }
333 
RegisterSoftbusDevStateCallback(const char * pkgName,DevStatusCallback callback)334 int RegisterSoftbusDevStateCallback(const char *pkgName, DevStatusCallback callback)
335 {
336     DMLOGI("RegisterSoftbusDevStateCallback start.");
337     if (!IsPkgNameValid(pkgName)) {
338         DMLOGE("pkgName is invalid.");
339         return ERR_DM_INPUT_INVALID_VALUE;
340     }
341     if (callback.onTargetOnline == NULL || callback.onTargetOffline == NULL) {
342         DMLOGE("callback is NULL.");
343         return ERR_DM_INPUT_INVALID_VALUE;
344     }
345 
346     DMLOGI("start to register State Callback with pkgName: %s.", pkgName);
347     int returnResult = DM_OK;
348     if (LockDmGlobalLock() != DM_OK) {
349         DMLOGE("LockDmGlobalLock failed.");
350         return ERR_DM_FAILED;
351     }
352     if (!ImportPkgNameToStateMap(pkgName, callback)) {
353         DMLOGE("no memory for a new callback register with pkgName: %s.", pkgName);
354         returnResult = ERR_DM_IMPORT_PKGNAME;
355     }
356     if (UnlockDmGlobalLock() != DM_OK) {
357         DMLOGE("UnlockDmGlobalLock failed.");
358         return ERR_DM_FAILED;
359     }
360     if (returnResult != DM_OK) {
361         DMLOGE("failed to register state callback with pkgName: %s, ret: %d.", pkgName, returnResult);
362         return returnResult;
363     }
364     DMLOGI("register state callback successfully.");
365     return DM_OK;
366 }
367 
UnRegisterSoftbusDevStateCallback(const char * pkgName)368 int UnRegisterSoftbusDevStateCallback(const char *pkgName)
369 {
370     if (!IsPkgNameValid(pkgName)) {
371         DMLOGE("pkgName is invalid.");
372         return ERR_DM_INPUT_INVALID_VALUE;
373     }
374 
375     DMLOGI("start to unregister State Callback with pkgName: %s.", pkgName);
376     int returnResult = DM_OK;
377     if (LockDmGlobalLock() != DM_OK) {
378         DMLOGE("LockDmGlobalLock failed.");
379         return ERR_DM_FAILED;
380     }
381     if (!DeletePkgNameFromStateMap(pkgName)) {
382         DMLOGE("no callback for this pkgName: %s.", pkgName);
383         returnResult = ERR_DM_DELETE_PKGNAME;
384     }
385     if (UnlockDmGlobalLock() != DM_OK) {
386         DMLOGE("UnlockDmGlobalLock failed.");
387         return ERR_DM_FAILED;
388     }
389     if (returnResult != DM_OK) {
390         DMLOGE("failed to unregister state callback with pkgName: %s, ret: %d.", pkgName, returnResult);
391         return returnResult;
392     }
393     DMLOGI("unregister state callback successfully.");
394     return DM_OK;
395 }
396 
GetSoftbusTrustedDeviceList(const char * pkgName,DmDeviceBasicInfo * deviceList,const int deviceListLen,int * trustListLen)397 int GetSoftbusTrustedDeviceList(const char *pkgName, DmDeviceBasicInfo *deviceList, const int deviceListLen,
398     int *trustListLen)
399 {
400     DMLOGI("GetSoftbusTrustedDeviceList.");
401     if (!IsPkgNameValid(pkgName)) {
402         DMLOGE("pkgName is invalid.");
403         return ERR_DM_INPUT_INVALID_VALUE;
404     }
405     if (deviceList == NULL || trustListLen == NULL) {
406         DMLOGE("input point is NULL.");
407         return ERR_DM_INPUT_INVALID_VALUE;
408     }
409     NodeBasicInfo *nodeInfo = NULL;
410     int retValue = GetAllNodeDeviceInfo(DM_PKG_NAME, &nodeInfo, trustListLen);
411     if (retValue != SOFTBUS_OK || *trustListLen < 0) {
412         DMLOGE("get all node device info error: %d, trustListLen: %d.", retValue, *trustListLen);
413         FreeNodeInfo(nodeInfo);
414         return ERR_DM_SOFTBUS_GET_ALL_DEVICE_INFO;
415     }
416     int minLen = (deviceListLen > *trustListLen ? *trustListLen : deviceListLen);
417     for (int i = 0; i < minLen; i++) {
418         NodeBasicInfoCopyToDmDevice(&deviceList[i], &nodeInfo[i]);
419     }
420     FreeNodeInfo(nodeInfo);
421     DMLOGI("get trusted device with trustDeviceCount: %d.", *trustListLen);
422     return DM_OK;
423 }
424 
StartSoftbusDiscovery(const char * pkgName,const int subscribeId,const char * filterOption,OnTargetFound callback)425 int StartSoftbusDiscovery(const char *pkgName, const int subscribeId, const char *filterOption,
426     OnTargetFound callback)
427 {
428     DMLOGI("StartSoftbusDiscovery start.");
429     if (!IsValidStartDiscoveryInput(pkgName, filterOption, callback)) {
430         DMLOGE("input parameter is invalid.");
431         return ERR_DM_INPUT_INVALID_VALUE;
432     }
433 
434     int returnResult = DM_OK;
435     if (LockDmGlobalLock() != DM_OK) {
436         DMLOGE("LockDmGlobalLock failed.");
437         return ERR_DM_FAILED;
438     }
439     if (ParseDiscoverFilterOption(filterOption) != DM_OK) {
440         DMLOGE("failed to parse filterOption with pkgName: %s.", pkgName);
441         return ERR_DM_CJSON_PARSE_STRING;
442     }
443     returnResult = StartSoftbusDiscovering(pkgName, subscribeId, callback);
444     if (returnResult != DM_OK) {
445         DMLOGE("failed to parse filterOption and send with pkgName: %s.", pkgName);
446         UnlockDmGlobalLock();
447         return returnResult;
448     }
449     DMLOGI("start discovery successfully with pkgName: %s.", pkgName);
450     return returnResult;
451 }
452 
IsPkgNameValid(const char * pkgName)453 static bool IsPkgNameValid(const char *pkgName)
454 {
455     if (pkgName == NULL) {
456         DMLOGE("input point is NULL.");
457         return false;
458     }
459     size_t pkgNameLen = strlen(pkgName);
460     if (pkgNameLen == 0 || pkgNameLen >= DM_MAX_PKG_NAME_LEN) {
461         DMLOGE("not meet the condition with pkgNameLen: %u.", pkgNameLen);
462         return false;
463     }
464     return true;
465 }
466 
IsDeviceIdValid(const char * deviceId)467 static bool IsDeviceIdValid(const char *deviceId)
468 {
469     if (deviceId == NULL) {
470         DMLOGE("input point is NULL.");
471         return false;
472     }
473     size_t deviceIdLen = strlen(deviceId);
474     if (deviceIdLen == 0 || deviceIdLen >= DM_MAX_DEVICE_ID_LEN) {
475         DMLOGE("not meet the condition with deviceIdLen: %u.", deviceIdLen);
476         return false;
477     }
478     return true;
479 }
480 
IsValidStartDiscoveryInput(const char * pkgName,const char * filterOption,OnTargetFound callback)481 static bool IsValidStartDiscoveryInput(const char *pkgName, const char *filterOption,
482     OnTargetFound callback)
483 {
484     (void)filterOption;
485     if (!IsPkgNameValid(pkgName)) {
486         DMLOGE("pkgName is invalid.");
487         return false;
488     }
489     if (callback.onTargetFound == NULL) {
490         DMLOGE("callback is NULL.");
491         return false;
492     }
493     return true;
494 }
495 
StartSoftbusDiscovering(const char * pkgName,const int subscribeId,OnTargetFound callback)496 static int StartSoftbusDiscovering(const char *pkgName, const int subscribeId, OnTargetFound callback)
497 {
498     DMLOGI("StartSoftbusDiscovering start.");
499     if (g_discoveryCallbackMap.valid) {
500         DMLOGE("failed to start discovery because discovery behavior already exists.");
501         return ERR_DM_SOFTBUS_REPEAT_DISCOVERY_DEVICE;
502     }
503     if (SoftbusRefreshLNN(pkgName, subscribeId) != DM_OK) {
504         DMLOGE("failed to start discovery because sending broadcast info.");
505         return ERR_DM_SOFTBUS_SEND_BROADCAST;
506     }
507     if (!ImportPkgNameToDiscoveryMap(pkgName, subscribeId, callback)) {
508         DMLOGE("failed to import pkgName to discovery map.");
509         return ERR_DM_IMPORT_PKGNAME;
510     }
511     DMLOGI("StartSoftbusDiscovering end.");
512     return DM_OK;
513 }
514 
StopSoftbusDiscovery(const char * pkgName,const int subscribeId)515 int StopSoftbusDiscovery(const char *pkgName, const int subscribeId)
516 {
517     DMLOGI("StopSoftbusDiscovery start.");
518     if (!IsPkgNameValid(pkgName)) {
519         DMLOGE("pkgName is invalid.");
520         return ERR_DM_INPUT_INVALID_VALUE;
521     }
522     int returnResult = DM_OK;
523     if (LockDmGlobalLock() != DM_OK) {
524         DMLOGE("LockDmGlobalLock failed.");
525         return ERR_DM_FAILED;
526     }
527     returnResult = StopSoftbusRefreshLNN(pkgName, subscribeId);
528     if (returnResult != DM_OK) {
529         DMLOGE("failed to stop discovery with pkgName: %s.", pkgName);
530     }
531     if (UnlockDmGlobalLock() != DM_OK) {
532         DMLOGE("UnlockDmGlobalLock failed.");
533         return ERR_DM_FAILED;
534     }
535     if (returnResult != DM_OK) {
536         DMLOGE("failed to stop discovery with pkgName: %s.", pkgName);
537         return returnResult;
538     }
539     DMLOGI("stop discovery successfully with pkgName: %s.", pkgName);
540     return returnResult;
541 }
542 
StopSoftbusRefreshLNN(const char * pkgName,const int subscribeId)543 static int StopSoftbusRefreshLNN(const char *pkgName, const int subscribeId)
544 {
545     if (!g_startDiscoveryFlag) {
546         DMLOGI("already stopped.");
547         return DM_OK;
548     }
549     if (!g_discoveryCallbackMap.valid) {
550         DMLOGI("pkgName has been released with pkgName: %s, subscribeId: %d.", pkgName, subscribeId);
551         return DM_OK;
552     }
553     if (subscribeId != g_discoveryCallbackMap.subscribeId ||
554         strcmp(g_discoveryCallbackMap.pkgName, pkgName) != 0) {
555         DMLOGE("pkgName: %s and subscribeId: %d do not match.", pkgName, subscribeId);
556         return ERR_DM_SOFTBUS_STOP_DISCOVERY_DEVICE;
557     }
558     g_discoveryCallbackMap.valid = false;
559     DMLOGI("stop refreshLNN successfully.");
560     return DM_OK;
561 }
562 
ParseDiscoverFilterOption(const char * filterOption)563 static int ParseDiscoverFilterOption(const char *filterOption)
564 {
565     int retValue = DM_OK;
566     g_discoveryCallbackMap.filterOption.credible = NOT_FILTER;
567     g_discoveryCallbackMap.filterOption.range = NOT_FILTER;
568     g_discoveryCallbackMap.filterOption.isTrusted = NOT_FILTER;
569     g_discoveryCallbackMap.filterOption.authForm = NOT_FILTER;
570     g_discoveryCallbackMap.filterOption.deviceType = NOT_FILTER;
571     if (filterOption == NULL) {
572         g_discoveryCallbackMap.filterOption.credible = 0;
573         return retValue;
574     }
575     cJSON *root = cJSON_Parse(filterOption);
576     if (root == NULL) {
577         DMLOGE("failed to parse filter option string.");
578         cJSON_Delete(root);
579         return ERR_DM_CJSON_CREATE_OBJECT;
580     }
581     cJSON *object = cJSON_GetObjectItem(root, FILTER_CREDIBLE);
582     if (object != NULL && cJSON_IsNumber(object)) {
583         g_discoveryCallbackMap.filterOption.credible = object->valueint;
584         DMLOGI("key %s value: %d.", FILTER_CREDIBLE, g_discoveryCallbackMap.filterOption.credible);
585     }
586     object = cJSON_GetObjectItem(root, FILTER_RANGE);
587     if (object != NULL && cJSON_IsNumber(object)) {
588         g_discoveryCallbackMap.filterOption.range = object->valueint;
589         DMLOGI("key %s value: %d.", FILTER_RANGE, g_discoveryCallbackMap.filterOption.range);
590     }
591     object = cJSON_GetObjectItem(root, FILTER_ISTRUSTED);
592     if (object != NULL && cJSON_IsNumber(object)) {
593         g_discoveryCallbackMap.filterOption.isTrusted = object->valueint;
594         DMLOGI("key %s value: %d.", FILTER_ISTRUSTED, g_discoveryCallbackMap.filterOption.isTrusted);
595     }
596     object = cJSON_GetObjectItem(root, FILTER_AUTHFORM);
597     if (object != NULL && cJSON_IsNumber(object)) {
598         g_discoveryCallbackMap.filterOption.authForm = object->valueint;
599         DMLOGI("key %s value: %d.", FILTER_AUTHFORM, g_discoveryCallbackMap.filterOption.authForm);
600     }
601     object = cJSON_GetObjectItem(root, FILTER_DEVICE_TYPE);
602     if (object != NULL && cJSON_IsNumber(object)) {
603         g_discoveryCallbackMap.filterOption.deviceType = object->valueint;
604         DMLOGI("key %s value: %d.", FILTER_DEVICE_TYPE, g_discoveryCallbackMap.filterOption.deviceType);
605     }
606     cJSON_Delete(root);
607     DMLOGI("parse filterOption json successfully.");
608     return DM_OK;
609 }
610 
SoftbusRefreshLNN(const char * pkgName,const int subscribeId)611 static int SoftbusRefreshLNN(const char *pkgName, const int subscribeId)
612 {
613     SubscribeInfo subscribeInfo;
614     subscribeInfo.mode = DISCOVER_MODE_ACTIVE;
615     subscribeInfo.medium = AUTO;
616     subscribeInfo.freq = HIGH;
617     subscribeInfo.isSameAccount = false;
618     subscribeInfo.isWakeRemote = false;
619     subscribeInfo.capability = DM_CAPABILITY_OSD;
620     subscribeInfo.capabilityData = NULL;
621     subscribeInfo.dataLen = 0;
622     subscribeInfo.subscribeId = subscribeId;
623     int retValue = RefreshLNN(pkgName, &subscribeInfo, &g_refreshDiscoveryCallback);
624     if (retValue != SOFTBUS_OK) {
625         DMLOGE("failed to start to refresh discovery with ret: %d.", retValue);
626         return ERR_DM_FAILED;
627     }
628     DMLOGI("softbus RefreshLNN successfully.");
629     return DM_OK;
630 }
631 
DeletePkgNameFromStateMap(const char * pkgName)632 static bool DeletePkgNameFromStateMap(const char *pkgName)
633 {
634     for (int i = 0; i < DM_MAX_REG_PKG_NUMBER; i++) {
635         if (g_stateCallbackMap[i].valid && strcmp(g_stateCallbackMap[i].pkgName, pkgName) == 0) {
636             g_stateCallbackMap[i].valid = false;
637             DMLOGI("pkgName: %s has been deleted from state map.", pkgName);
638             return true;
639         }
640     }
641     DMLOGE("pkgName: %s not exist in state map.", pkgName);
642     return false;
643 }
644 
ImportPkgNameToStateMap(const char * pkgName,DevStatusCallback callback)645 static bool ImportPkgNameToStateMap(const char *pkgName, DevStatusCallback callback)
646 {
647     for (int i = 0; i < DM_MAX_REG_PKG_NUMBER; i++) {
648         if (g_stateCallbackMap[i].valid && strcmp(g_stateCallbackMap[i].pkgName, pkgName) == 0) {
649             DMLOGE("pkgName: %s has been exist in state map.", pkgName);
650             return false;
651         }
652     }
653     for (int i = 0; i < DM_MAX_REG_PKG_NUMBER; i++) {
654         if (g_stateCallbackMap[i].valid) {
655             continue;
656         }
657         errno_t retValue = strcpy_s(g_stateCallbackMap[i].pkgName, DM_MAX_PKG_NAME_LEN, pkgName);
658         if (retValue != EOK) {
659             DMLOGE("failed to copy pkgName: %s to state map.", pkgName);
660             return false;
661         }
662         g_stateCallbackMap[i].stateCallback = callback;
663         g_stateCallbackMap[i].valid = true;
664         return true;
665     }
666     DMLOGE("state map not memory for a new callback register with pkgName: %s.", pkgName);
667     return false;
668 }
669 
ImportPkgNameToDiscoveryMap(const char * pkgName,const int subscribeId,OnTargetFound callback)670 static bool ImportPkgNameToDiscoveryMap(const char *pkgName, const int subscribeId, OnTargetFound callback)
671 {
672     errno_t retValue = strcpy_s(g_discoveryCallbackMap.pkgName, DM_MAX_PKG_NAME_LEN, pkgName);
673     if (retValue != EOK) {
674         DMLOGE("failed to copy pkgName: %s to discovery map.", pkgName);
675         return false;
676     }
677     g_discoveryCallbackMap.subscribeId = subscribeId;
678     g_discoveryCallbackMap.discoveryCallback = callback;
679     g_discoveryCallbackMap.valid = true;
680     return true;
681 }
682 
ImportToDevIdMap(const char * networkId,const char * deviceId)683 static bool ImportToDevIdMap(const char *networkId, const char *deviceId)
684 {
685     for (int i = 0; i < DM_MAX_DEVICE_SIZE; i++) {
686         if (g_devIdMap[i].valid) {
687             continue;
688         }
689         errno_t retValue = strcpy_s(g_devIdMap[i].networkId, DM_MAX_DEVICE_NETWORKID_LEN, networkId);
690         if (retValue != EOK) {
691             DMLOGE("failed to copy networkId to discovery map.");
692             return false;
693         }
694         retValue = strcpy_s(g_devIdMap[i].deviceId, DM_MAX_DEVICE_ID_LEN, deviceId);
695         if (retValue != EOK) {
696             DMLOGE("failed to copy deviceId to discovery map.");
697             return false;
698         }
699         g_devIdMap[i].valid = true;
700         return true;
701     }
702     return false;
703 }
704 
GetDeviceIdByNetworkId(const char * networkId,char * deviceId)705 static int GetDeviceIdByNetworkId(const char *networkId, char *deviceId)
706 {
707     for (int i = 0; i < DM_MAX_DEVICE_SIZE; i++) {
708         if (!g_devIdMap[i].valid) {
709             continue;
710         }
711         if (strcmp(g_devIdMap[i].networkId, networkId) != 0) {
712             continue;
713         }
714         errno_t retValue = strcpy_s(deviceId, DM_MAX_DEVICE_NETWORKID_LEN, g_devIdMap[i].deviceId);
715         if (retValue != EOK) {
716             DMLOGE("failed to copy deviceId.");
717             return false;
718         }
719         return true;
720     }
721     return false;
722 }
723 
CreateSoftbusSemaphoreAndMutex(void)724 static int CreateSoftbusSemaphoreAndMutex(void)
725 {
726     DMLOGI("CreateSoftbusSemaphoreAndMutex start.");
727     if (g_dmGlobalLock == NULL) {
728         InitDmGlobalLock();
729     }
730     if (g_dmBindLock == NULL) {
731         InitDmBindLock();
732     }
733     return DM_OK;
734 }
735 
DeleteSoftbusSemaphoreAndMutex(void)736 static int DeleteSoftbusSemaphoreAndMutex(void)
737 {
738     DMLOGI("DeleteSoftbusSemaphoreAndMutex start.");
739     return DM_OK;
740 }
741 
FilterDevice(const DmDeviceInfo * dmDeviceInfo)742 static int FilterDevice(const DmDeviceInfo *dmDeviceInfo)
743 {
744     DMLOGI("FilterDevice start.");
745     int ret = DM_OK;
746     if (g_discoveryCallbackMap.filterOption.isTrusted != NOT_FILTER &&
747         dmDeviceInfo->isLocalExistCredential != g_discoveryCallbackMap.filterOption.isTrusted) {
748         ret = ERR_DM_FAILED;
749     }
750     if (g_discoveryCallbackMap.filterOption.deviceType != NOT_FILTER &&
751         dmDeviceInfo->deviceTypeId != (uint16_t)g_discoveryCallbackMap.filterOption.deviceType) {
752         ret = ERR_DM_FAILED;
753     }
754     if (g_discoveryCallbackMap.filterOption.range != NOT_FILTER &&
755         dmDeviceInfo->range > g_discoveryCallbackMap.filterOption.range) {
756         ret = ERR_DM_FAILED;
757     }
758     if (g_discoveryCallbackMap.filterOption.credible != NOT_FILTER &&
759         dmDeviceInfo->credible != g_discoveryCallbackMap.filterOption.credible) {
760         ret = ERR_DM_FAILED;
761     }
762     if (g_discoveryCallbackMap.filterOption.authForm != NOT_FILTER &&
763         dmDeviceInfo->authForm != g_discoveryCallbackMap.filterOption.authForm) {
764         ret = ERR_DM_FAILED;
765     }
766     return ret;
767 }
768 
ImportDeviceToAddrMap(const DmDeviceInfo * deviceInfo)769 static bool ImportDeviceToAddrMap(const DmDeviceInfo *deviceInfo)
770 {
771     const char *deviceId = deviceInfo->deviceId;
772     for (int i = 0; i < DM_MAX_DEVICE_SIZE; i++) {
773         if (g_deviceIdAddrMap[i].valid && strcmp(g_deviceIdAddrMap[i].deviceId, deviceId) == 0) {
774             DMLOGE("deviceId has been exist in addr map.");
775             return false;
776         }
777     }
778     for (int i = 0; i < DM_MAX_DEVICE_SIZE; i++) {
779         if (g_deviceIdAddrMap[i].valid) {
780             continue;
781         }
782         errno_t retValue = strcpy_s(g_deviceIdAddrMap[i].deviceId, DM_MAX_DEVICE_ID_LEN, deviceId);
783         if (retValue != EOK) {
784             DMLOGE("failed to copy deviceId to addr map.");
785             return false;
786         }
787         g_deviceIdAddrMap[i].valid = true;
788         g_deviceIdAddrMap[i].connectAddr = deviceInfo->connectAddr;
789         return true;
790     }
791     DMLOGE("addr map not memory for a new deviceid.");
792     return false;
793 }
794 
GetConnAddrByDeviceId(const char * deviceId,ConnectionAddr * addr)795 static int GetConnAddrByDeviceId(const char *deviceId, ConnectionAddr *addr)
796 {
797     (void)addr;
798     addr = NULL;
799     if (deviceId == NULL) {
800         DMLOGE("get connect addr failed input param is null.");
801         return ERR_DM_INPUT_INVALID_VALUE;
802     }
803     for (int i = 0; i < DM_MAX_DEVICE_SIZE; i++) {
804         if (g_deviceIdAddrMap[i].valid && strcmp(g_deviceIdAddrMap[i].deviceId, deviceId) == 0) {
805             DMLOGE("deviceId has been exist in addr map.");
806             addr = &(g_deviceIdAddrMap[i].connectAddr);
807             return DM_OK;
808         }
809     }
810     return ERR_DM_FAILED;
811 }
812 
OnDiscoveryDeviceFound(const DeviceInfo * deviceInfo)813 static void OnDiscoveryDeviceFound(const DeviceInfo *deviceInfo)
814 {
815     if (deviceInfo == NULL) {
816         DMLOGE("deviceInfo is Null.");
817         return;
818     }
819 
820     if (LockDmGlobalLock() != DM_OK) {
821         DMLOGE("LockDmGlobalLock failed.");
822         return;
823     }
824     DMLOGI("will notify the user that a new device has been discovered.");
825     DmDeviceInfo dmDeviceInfo;
826     DeviceInfoCopyToDmDevice(&dmDeviceInfo, deviceInfo);
827     if (FilterDevice(&dmDeviceInfo) == DM_OK) {
828         ImportToDevIdMap(dmDeviceInfo.networkId, dmDeviceInfo.deviceId);
829         DmDeviceBasicInfo dmBasicInfo;
830         DmDeviceInfoToDmBasicInfo(&dmDeviceInfo, &dmBasicInfo);
831         ImportDeviceToAddrMap(&dmDeviceInfo);
832         g_discoveryCallbackMap.discoveryCallback.onTargetFound(&dmBasicInfo);
833     }
834 
835     if (UnlockDmGlobalLock() != DM_OK) {
836         DMLOGE("UnlockDmGlobalLock failed.");
837         return;
838     }
839     DMLOGI("OnDiscoveryDeviceFound callback complete.");
840 }
841 
OnRefreshDiscoveryResult(int32_t refreshId,RefreshResult reason)842 static void OnRefreshDiscoveryResult(int32_t refreshId, RefreshResult reason)
843 {
844     if (reason == REFRESH_LNN_SUCCESS) {
845         DMLOGI("refresh discovery result successfully with refreshId: %d.", refreshId);
846         g_startDiscoveryFlag = true;
847     } else {
848         DMLOGI("failed to refresh discovery result with refreshId: %d, reason: %d.", refreshId, (int)reason);
849         g_startDiscoveryFlag = false;
850     }
851     if (UnlockDmGlobalLock() != DM_OK) {
852         DMLOGE("UnlockDmGlobalLock failed.");
853         return;
854     }
855 }
856 
OnPublishLNNResult(int publishId,PublishResult reason)857 static void OnPublishLNNResult(int publishId, PublishResult reason)
858 {
859     if (g_advertisingCallbackMap.advCallback.onAdvertisingResult != NULL) {
860         g_advertisingCallbackMap.advCallback.onAdvertisingResult(publishId, reason);
861     }
862 
863     if (reason == PUBLISH_LNN_SUCCESS) {
864         DMLOGI("publishLNN successfully with publishId: %d.", publishId);
865     } else {
866         DMLOGI("failed to publishLNN with publishId: %d, reason: %d.", publishId, (int)reason);
867     }
868 }
869 
ImportPkgNameToAdvertisingMap(const char * pkgName,OnAdvertisingResult cb)870 static bool ImportPkgNameToAdvertisingMap(const char *pkgName, OnAdvertisingResult cb)
871 {
872     errno_t retValue = strcpy_s(g_advertisingCallbackMap.pkgName, DM_MAX_PKG_NAME_LEN, pkgName);
873     if (retValue != EOK) {
874         DMLOGE("failed to copy pkgName: %s to advertising map.", pkgName);
875         return false;
876     }
877     g_advertisingCallbackMap.advCallback = cb;
878     g_advertisingCallbackMap.valid = true;
879     return true;
880 }
881 
ImportPkgNameToBindMap(const char * pkgName,OnBindResult cb)882 static bool ImportPkgNameToBindMap(const char *pkgName, OnBindResult cb)
883 {
884     errno_t retValue = strcpy_s(g_bindRetCallbackMap.pkgName, DM_MAX_PKG_NAME_LEN, pkgName);
885     if (retValue != EOK) {
886         DMLOGE("failed to copy pkgName: %s to advertising map.", pkgName);
887         return false;
888     }
889     g_bindRetCallbackMap.bindRetCallback = cb;
890     g_bindRetCallbackMap.valid = true;
891     return true;
892 }
893 
StartSoftbusPublish(const char * pkgName,OnAdvertisingResult cb)894 int StartSoftbusPublish(const char *pkgName, OnAdvertisingResult cb)
895 {
896     DMLOGI("StartSoftbusPublish start.");
897     if (!IsPkgNameValid(pkgName)) {
898         DMLOGE("pkgName is invalid.");
899         return ERR_DM_INPUT_INVALID_VALUE;
900     }
901     PublishInfo publishInfo;
902     publishInfo.publishId = DEVICEMANAGER_SA_ID;
903     publishInfo.mode = DISCOVER_MODE_PASSIVE;
904     publishInfo.medium = AUTO;
905     publishInfo.freq = HIGH;
906     publishInfo.capability = DM_CAPABILITY_OSD;
907     publishInfo.capabilityData = NULL;
908     publishInfo.dataLen = 0;
909     int retValue = PublishLNN(pkgName, &publishInfo, &g_publishLNNCallback);
910     if (retValue != SOFTBUS_OK) {
911         DMLOGE("failed to call softbus publishLNN function with ret: %d.", retValue);
912         return ERR_DM_SOFTBUS_PUBLISH_LNN;
913     }
914     g_publishLNNFlag = true;
915     if (!ImportPkgNameToAdvertisingMap(pkgName, cb)) {
916         DMLOGE("failed to import pkgName to advertising map.");
917         return ERR_DM_IMPORT_PKGNAME;
918     }
919     DMLOGI("StartSoftbusPublish end.");
920     return DM_OK;
921 }
922 
StopSoftbusPublish(const char * pkgName)923 int StopSoftbusPublish(const char *pkgName)
924 {
925     DMLOGI("StopSoftbusPublish start.");
926     if (!g_publishLNNFlag) {
927         DMLOGI("stop publish already stopped.");
928         return DM_OK;
929     }
930     if (!IsPkgNameValid(pkgName)) {
931         DMLOGE("pkgName is invalid.");
932         return ERR_DM_INPUT_INVALID_VALUE;
933     }
934     int retValue = StopPublishLNN(pkgName, DEVICEMANAGER_SA_ID);
935     if (retValue != SOFTBUS_OK) {
936         DMLOGE("failed to call stop softbus publishLNN function with ret: %d.", retValue);
937         return ERR_DM_SOFTBUS_STOP_PUBLISH_LNN;
938     }
939     g_publishLNNFlag = false;
940     g_advertisingCallbackMap.valid = false;
941     DMLOGI("StopSoftbusPublish end.");
942     return DM_OK;
943 }
944 
OnSoftbusDeviceOnline(NodeBasicInfo * deviceInfo)945 static void OnSoftbusDeviceOnline(NodeBasicInfo *deviceInfo)
946 {
947     if (deviceInfo == NULL) {
948         DMLOGE("deviceInfo is NULL.");
949         return;
950     }
951     DMLOGI("softbus notify that a device goes online.");
952     DmDeviceBasicInfo dmDeviceInfo;
953     NodeBasicInfoCopyToDmDevice(&dmDeviceInfo, deviceInfo);
954     if (LockDmGlobalLock() != DM_OK) {
955         DMLOGE("LockDmGlobalLock failed.");
956         return;
957     }
958     for (int i = 0; i < DM_MAX_REG_PKG_NUMBER; i++) {
959         if (g_stateCallbackMap[i].valid) {
960             DMLOGI("notify device to go online with pkgName: %s.", g_stateCallbackMap[i].pkgName);
961             g_stateCallbackMap[i].stateCallback.onTargetOnline(&dmDeviceInfo);
962         }
963     }
964     if (UnlockDmGlobalLock() != DM_OK) {
965         DMLOGE("UnlockDmGlobalLock failed.");
966         return;
967     }
968     DMLOGI("OnSoftbusDeviceOnline callback complete.");
969 }
970 
OnSoftbusDeviceOffline(NodeBasicInfo * deviceInfo)971 static void OnSoftbusDeviceOffline(NodeBasicInfo *deviceInfo)
972 {
973     if (deviceInfo == NULL) {
974         DMLOGE("deviceInfo is NULL.");
975         return;
976     }
977     DMLOGI("softbus notify that a device goes offline.");
978     DmDeviceBasicInfo dmDeviceInfo;
979     NodeBasicInfoCopyToDmDevice(&dmDeviceInfo, deviceInfo);
980     if (LockDmGlobalLock() != DM_OK) {
981         DMLOGE("LockDmGlobalLock failed.");
982         return;
983     }
984     for (int i = 0; i < DM_MAX_REG_PKG_NUMBER; i++) {
985         if (g_stateCallbackMap[i].valid) {
986             DMLOGI("notify device to go offline with pkgName: %s.", g_stateCallbackMap[i].pkgName);
987             g_stateCallbackMap[i].stateCallback.onTargetOffline(&dmDeviceInfo);
988         }
989     }
990     if (UnlockDmGlobalLock() != DM_OK) {
991         DMLOGE("UnlockDmGlobalLock failed.");
992         return;
993     }
994     DMLOGI("OnSoftbusDeviceOffline callback complete.");
995 }
996 
NodeBasicInfoCopyToDmDevice(DmDeviceBasicInfo * dmDeviceInfo,const NodeBasicInfo * nodeBasicInfo)997 static void NodeBasicInfoCopyToDmDevice(DmDeviceBasicInfo *dmDeviceInfo, const NodeBasicInfo *nodeBasicInfo)
998 {
999     (void)memset_s(dmDeviceInfo, sizeof(DmDeviceBasicInfo), 0, sizeof(DmDeviceBasicInfo));
1000     errno_t retValue = strcpy_s(dmDeviceInfo->deviceName, sizeof(dmDeviceInfo->deviceName), nodeBasicInfo->deviceName);
1001     if (retValue != EOK) {
1002         DMLOGE("failed to copy device name with ret: %d.", retValue);
1003     }
1004     retValue = strcpy_s(dmDeviceInfo->networkId, sizeof(dmDeviceInfo->networkId), nodeBasicInfo->networkId);
1005     if (retValue != EOK) {
1006         DMLOGE("failed to copy networkId with ret: %d.", retValue);
1007     }
1008     GetDeviceIdByNetworkId(nodeBasicInfo->networkId, dmDeviceInfo->deviceId);
1009     dmDeviceInfo->deviceTypeId = nodeBasicInfo->deviceTypeId;
1010 }
1011 
DeviceInfoCopyToDmDevice(DmDeviceInfo * dmDeviceInfo,const DeviceInfo * deviceInfo)1012 static void DeviceInfoCopyToDmDevice(DmDeviceInfo *dmDeviceInfo, const DeviceInfo *deviceInfo)
1013 {
1014     const size_t arrayStartPosition = 0;
1015     (void)memset_s(dmDeviceInfo, sizeof(DmDeviceInfo), 0, sizeof(DmDeviceInfo));
1016     errno_t retValue = strcpy_s(dmDeviceInfo->deviceId, sizeof(dmDeviceInfo->deviceId), deviceInfo->devId);
1017     if (retValue != EOK) {
1018         DMLOGE("failed to copy device id with ret: %d.", retValue);
1019     }
1020     retValue = strcpy_s(dmDeviceInfo->deviceName, sizeof(dmDeviceInfo->deviceName), deviceInfo->devName);
1021     if (retValue != EOK) {
1022         DMLOGE("failed to copy device name with ret: %d.", retValue);
1023     }
1024     dmDeviceInfo->credible = deviceInfo->isOnline;
1025     dmDeviceInfo->deviceTypeId = deviceInfo->devType;
1026     dmDeviceInfo->range = deviceInfo->range;
1027     dmDeviceInfo->connectAddr = deviceInfo->addr[arrayStartPosition];
1028     int ret = GetAuthFormByDeviceId(dmDeviceInfo->deviceId, dmDeviceInfo->authForm);
1029     if (ret != DM_OK) {
1030         DMLOGE("failed to get authForm from hichain, ret: %d.", ret);
1031         dmDeviceInfo->isLocalExistCredential = false;
1032         dmDeviceInfo->authForm = -1;
1033         return;
1034     }
1035     dmDeviceInfo->isLocalExistCredential = true;
1036 }
1037 
DmDeviceInfoToDmBasicInfo(const DmDeviceInfo * dmDeviceInfo,DmDeviceBasicInfo * dmBasicInfo)1038 static void DmDeviceInfoToDmBasicInfo(const DmDeviceInfo *dmDeviceInfo, DmDeviceBasicInfo *dmBasicInfo)
1039 {
1040     (void)memset_s(dmBasicInfo, sizeof(DmDeviceBasicInfo), 0, sizeof(DmDeviceBasicInfo));
1041     errno_t retValue = strcpy_s(dmBasicInfo->deviceId, sizeof(dmBasicInfo->deviceId), dmDeviceInfo->deviceId);
1042     if (retValue != EOK) {
1043         DMLOGE("failed to copy device id with ret: %d.", retValue);
1044     }
1045     retValue = strcpy_s(dmBasicInfo->deviceName, sizeof(dmBasicInfo->deviceName), dmDeviceInfo->deviceName);
1046     if (retValue != EOK) {
1047         DMLOGE("failed to copy device name with ret: %d.", retValue);
1048     }
1049     retValue = strcpy_s(dmBasicInfo->networkId, sizeof(dmBasicInfo->networkId), dmDeviceInfo->networkId);
1050     if (retValue != EOK) {
1051         DMLOGE("failed to copy device networkId with ret: %d.", retValue);
1052     }
1053     dmBasicInfo->deviceTypeId = dmDeviceInfo->deviceTypeId;
1054 }
1055 
IsSupportBindType(const int bindType)1056 static bool IsSupportBindType(const int bindType)
1057 {
1058     if (bindType != SUPPORT_BIND_TYPE) {
1059         DMLOGE("bindType %d is not supported.", bindType);
1060         return false;
1061     }
1062     return true;
1063 }
1064 
IsValidBindTargetInput(const char * pkgName,const char * deviceId,OnBindResult callback)1065 static bool IsValidBindTargetInput(const char *pkgName, const char *deviceId, OnBindResult callback)
1066 {
1067     if (!IsPkgNameValid(pkgName)) {
1068         DMLOGE("pkgName is invalid.");
1069         return false;
1070     }
1071     if (!IsDeviceIdValid(deviceId)) {
1072         DMLOGE("deviceId is invalid.");
1073         return false;
1074     }
1075     if (callback.onBindResult == NULL) {
1076         DMLOGE("callback is null.");
1077         return false;
1078     }
1079 
1080     return true;
1081 }
1082 
SoftbusBindTarget(const char * pkgName,const char * deviceId,const int bindType,OnBindResult callback)1083 int SoftbusBindTarget(const char *pkgName, const char *deviceId, const int bindType, OnBindResult callback)
1084 {
1085     DMLOGI("SoftbusBindTarget start.");
1086     if (!IsValidBindTargetInput(pkgName, deviceId, callback)) {
1087         DMLOGE("input parameter is invalid.");
1088         return ERR_DM_INPUT_INVALID_VALUE;
1089     }
1090     if (!ImportPkgNameToBindMap(pkgName, callback)) {
1091         DMLOGE("import pkg name to bind result map failed.");
1092         return ERR_DM_FAILED;
1093     }
1094     errno_t retValue = strcpy_s(g_bindDeviceId, DM_MAX_DEVICE_ID_LEN, deviceId);
1095     if (retValue != EOK) {
1096         DMLOGE("failed to copy pkgName: %s to state map.", pkgName);
1097         return false;
1098     }
1099     if (GetConnAddrByDeviceId(deviceId, &g_bindAddr) != DM_OK) {
1100         DMLOGE("bind invalid addr.");
1101         return ERR_DM_BIND_NO_ADDR;
1102     }
1103     if (!IsSupportBindType(bindType)) {
1104         DMLOGE("bind type is not supported.");
1105         return ERR_DM_BIND_TYPE_NOT_SUPPORT;
1106     }
1107     g_bindType = bindType;
1108     int authForm = -1;
1109     if (GetAuthFormByDeviceId(deviceId, authForm) != DM_OK) {
1110         DMLOGE("local device is not import credential.");
1111         return ERR_DM_NO_CREDENTIAL;
1112     }
1113 
1114     if (OpenAuthSession(deviceId, &g_bindAddr, 1, NULL) != SOFTBUS_OK) {
1115         DMLOGE("open auth session failed");
1116         return ERR_DM_SOFTBUS_OPEN_AUTH_SESSION_FAILED;
1117     }
1118 
1119     if (LockDmBindLock() != DM_OK) {
1120         DMLOGE("LockDmBindLock failed.");
1121         return ERR_DM_FAILED;
1122     }
1123     DMLOGI("SoftbusBindTarget end.");
1124     return DM_OK;
1125 }
1126 
CreateNegotiateMsg(void)1127 static char* CreateNegotiateMsg(void)
1128 {
1129     cJSON *msg = cJSON_CreateObject();
1130     if (msg == NULL) {
1131         DMLOGE("failed to create cjson object.");
1132         return NULL;
1133     }
1134     if (cJSON_AddNumberToObject(msg, FILED_MSG_TYPE, MSG_NEGOTIATE) == NULL) {
1135         DMLOGE("failed to add msg type to cjson object.");
1136         cJSON_Delete(msg);
1137         return NULL;
1138     }
1139     if (cJSON_AddNumberToObject(msg, FILED_BIND_TYPE, g_bindType) == NULL) {
1140         cJSON_Delete(msg);
1141         DMLOGE("failed to add bind type to cjson object.");
1142         return NULL;
1143     }
1144     char *retStr = cJSON_Print(msg);
1145     cJSON_Delete(msg);
1146     if (retStr == NULL) {
1147         DMLOGE("failed to print string from cjson object.");
1148         return NULL;
1149     }
1150     return retStr;
1151 }
1152 
AbilityNegotiate(const int bindType)1153 static int AbilityNegotiate(const int bindType)
1154 {
1155     char deviceUdid[DM_MAX_DEVICE_UDID_LEN + 1] = {0};
1156     int retValue = GetDevUdid(deviceUdid, DM_MAX_DEVICE_UDID_LEN);
1157     if (retValue != DM_OK) {
1158         DMLOGE("failed to get local device udid with ret: %d.", retValue);
1159         return retValue;
1160     }
1161     int authType = -1;
1162     bool isCredentialExist = false;
1163     retValue = GetAuthFormByDeviceId(deviceUdid, authType);
1164     if (retValue == DM_OK) {
1165         isCredentialExist = true;
1166     }
1167     bool isSupportBindType = IsSupportBindType(bindType);
1168     int reply = ERR_DM_FAILED;
1169     if (isCredentialExist && isSupportBindType) {
1170         reply = DM_OK;
1171     }
1172     return reply;
1173 }
1174 
CreateRespNegotiateMsg(const int bindType)1175 static char* CreateRespNegotiateMsg(const int bindType)
1176 {
1177     cJSON *msg = cJSON_CreateObject();
1178     if (msg == NULL) {
1179         DMLOGE("failed to create cjson object.");
1180         return NULL;
1181     }
1182     if (cJSON_AddNumberToObject(msg, FILED_MSG_TYPE, MSG_NEGOTIATE_RESP) == NULL) {
1183         DMLOGE("failed to add msg type to cjson object.");
1184         cJSON_Delete(msg);
1185         return NULL;
1186     }
1187     int reply = AbilityNegotiate(bindType);
1188     if (reply != DM_OK) {
1189         DMLOGE("failed to AbilityNegotiate with ret: %d.", reply);
1190         cJSON_Delete(msg);
1191         return NULL;
1192     }
1193 
1194     if (cJSON_AddNumberToObject(msg, FILED_REPLY, reply) == NULL) {
1195         DMLOGE("failed to add reply to cjson object.");
1196         cJSON_Delete(msg);
1197         return NULL;
1198     }
1199 
1200     char *retStr = cJSON_Print(msg);
1201     cJSON_Delete(msg);
1202     if (retStr == NULL) {
1203         DMLOGE("failed to print string from cjson object.");
1204         return NULL;
1205     }
1206     return retStr;
1207 }
1208 
OnSessionOpened(int sessionId,int result)1209 static int OnSessionOpened(int sessionId, int result)
1210 {
1211     if (result != SOFTBUS_OK) {
1212         DMLOGE("open auth session failed, ret: %d.", result);
1213         CloseSession(sessionId);
1214         return ERR_DM_FAILED;
1215     }
1216     g_sessionId = sessionId;
1217     int sessionSide = GetSessionSide(sessionId);
1218     if (sessionSide != SESSION_SIDE_CLIENT) {
1219         DMLOGI("not client session.");
1220         return DM_OK;
1221     }
1222     char *msg = CreateNegotiateMsg();
1223     int ret = SendBytes(sessionId, msg, strlen(msg));
1224     if (ret != SOFTBUS_OK) {
1225         DMLOGE("send byte failed, ret: %d.", ret);
1226         cJSON_free(msg);
1227         return ERR_DM_FAILED;
1228     }
1229     cJSON_free(msg);
1230     return DM_OK;
1231 }
1232 
OnSessionClosed(int sessionId)1233 static void OnSessionClosed(int sessionId)
1234 {
1235     g_sessionId = -1;
1236     DMLOGI("session %d closed.", sessionId);
1237 }
1238 
OnBytesReceived(int sessionId,const void * data,unsigned int dataLen)1239 static void OnBytesReceived(int sessionId, const void *data, unsigned int dataLen)
1240 {
1241     if (data == NULL) {
1242         DMLOGE("on byte received empty msg.");
1243         return;
1244     }
1245     DMLOGI("on byte received sessionId: %d.", sessionId);
1246     cJSON *msg = cJSON_Parse(data);
1247     if (msg == NULL) {
1248         DMLOGE("on byte received parse msg failed.");
1249         cJSON_Delete(msg);
1250         return;
1251     }
1252     cJSON *object = cJSON_GetObjectItem(msg, FILED_MSG_TYPE);
1253     int cmd = 0;
1254     if (object != NULL && cJSON_IsNumber(object)) {
1255         cmd = object->valueint;
1256         DMLOGI("on byte received cmd: %d.", cmd);
1257     }
1258     cJSON_Delete(msg);
1259     if (cmd == MSG_NEGOTIATE) {
1260         ProcessSinkMsg(data, dataLen);
1261         return;
1262     }
1263     if (cmd == MSG_NEGOTIATE_RESP) {
1264         ProcessSourceMsg(data, dataLen);
1265         return;
1266     }
1267     DMLOGE("unrecognized message.");
1268 }
1269 
ProcessSinkMsg(const char * data,unsigned int dataLen)1270 static void ProcessSinkMsg(const char *data, unsigned int dataLen)
1271 {
1272     (void)dataLen;
1273     cJSON *msgData = cJSON_Parse(data);
1274     if (msgData == NULL) {
1275         DMLOGE("on byte received parse msg failed.");
1276         return;
1277     }
1278     cJSON *object = cJSON_GetObjectItem(msgData, FILED_BIND_TYPE);
1279     cJSON_Delete(msgData);
1280     int bindType = -1;
1281     if (object != NULL && cJSON_IsNumber(object)) {
1282         bindType = object->valueint;
1283         DMLOGI("on byte received bindType: %d.", bindType);
1284     }
1285 
1286     char *retStr = CreateRespNegotiateMsg(bindType);
1287     if (retStr == NULL) {
1288         DMLOGE("failed to create response negotiate message.");
1289         return;
1290     }
1291 
1292     if (SendBytes(g_sessionId, retStr, strlen(retStr)) != SOFTBUS_OK) {
1293         DMLOGE("send bytes failed, cmd: %d.", MSG_NEGOTIATE_RESP);
1294         cJSON_free(retStr);
1295         return;
1296     }
1297     cJSON_free(retStr);
1298 }
1299 
OnJoinLNNCallback(ConnectionAddr * addr,const char * networkId,int32_t retCode)1300 static void OnJoinLNNCallback(ConnectionAddr *addr, const char *networkId, int32_t retCode)
1301 {
1302     (void)addr;
1303     if (g_bindRetCallbackMap.bindRetCallback.onBindResult != NULL) {
1304         g_bindRetCallbackMap.bindRetCallback.onBindResult(networkId, retCode);
1305     }
1306     if (retCode != SOFTBUS_OK) {
1307         DMLOGE("joinlnn failed, ret: %d.", retCode);
1308         return;
1309     }
1310     if (UnlockDmBindLock() != DM_OK) {
1311         DMLOGE("UnlockDmBindLock failed.");
1312         return;
1313     }
1314 }
1315 
ProcessSourceMsg(const char * data,unsigned int dataLen)1316 static void ProcessSourceMsg(const char *data, unsigned int dataLen)
1317 {
1318     (void)dataLen;
1319     cJSON *msg = cJSON_Parse(data);
1320     if (msg == NULL) {
1321         DMLOGE("on byte received parse msg failed.");
1322         cJSON_Delete(msg);
1323         return;
1324     }
1325     cJSON *object = cJSON_GetObjectItem(msg, FILED_IS_CRE_EXISTED);
1326     if (object == NULL || !cJSON_IsBool(object)) {
1327         cJSON_Delete(msg);
1328         DMLOGE("on byte received get isCreExisted failed.");
1329         return;
1330     }
1331     bool isCreExist = object->valueint;
1332     object = cJSON_GetObjectItem(msg, FILED_IS_BIND_TYPE_SUPPORTED);
1333     if (object == NULL || !cJSON_IsBool(object)) {
1334         cJSON_Delete(msg);
1335         DMLOGE("on byte received get isBindTypeSupported failed.");
1336         return;
1337     }
1338     bool isBindTypeSupported = object->valueint;
1339     cJSON_Delete(msg);
1340 
1341     if (isBindTypeSupported == false || isCreExist == false) {
1342         DMLOGE("remote client no credential or not support bind type.");
1343         return;
1344     }
1345     JoinLNN(DM_PKG_NAME, &g_bindAddr, g_joinLNNResult);
1346     CloseSession(g_sessionId);
1347     UINT32 osRet = LOS_SemPost(g_bindSem);
1348     if (osRet != LOS_OK) {
1349         DMLOGE("failed to post bind sem with ret: %u.", osRet);
1350         return;
1351     }
1352 }
1353 
OnLeaveLNNCallback(const char * networkId,int32_t retCode)1354 static void OnLeaveLNNCallback(const char *networkId, int32_t retCode)
1355 {
1356     DMLOGI("leave LNN called, retCode: %d.", retCode);
1357 }
1358 
SoftbusUnBindTarget(const char * pkgName,const char * networkId)1359 int SoftbusUnBindTarget(const char *pkgName, const char *networkId)
1360 {
1361     DMLOGI("SoftbusUnBindTarget start.");
1362     if (!IsPkgNameValid(pkgName)) {
1363         DMLOGE("pkg name is invalid.");
1364         return ERR_DM_INPUT_INVALID_VALUE;
1365     }
1366     if (networkId == NULL) {
1367         DMLOGE("input network id is null.");
1368         return ERR_DM_INPUT_INVALID_VALUE;
1369     }
1370     size_t len = strlen(networkId);
1371     if (len == 0 || len >= DM_MAX_DEVICE_NETWORKID_LEN) {
1372         DMLOGE("not meet the condition with network id len: %u.", len);
1373         return ERR_DM_INPUT_INVALID_VALUE;
1374     }
1375     LeaveLNN(DM_PKG_NAME, networkId, g_leaveLNNResult);
1376     DMLOGI("SoftbusUnBindTarget stop.");
1377     return DM_OK;
1378 }