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