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 }