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