1 /*
2 * Copyright (c) 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 "auth_lane.h"
17
18 #include <securec.h>
19
20 #include "auth_connection.h"
21 #include "auth_device.h"
22 #include "auth_log.h"
23 #include "bus_center_manager.h"
24 #include "lnn_ctrl_lane.h"
25 #include "lnn_lane_interface.h"
26 #include "lnn_lane_link.h"
27 #include "lnn_local_net_ledger.h"
28 #include "lnn_feature_capability.h"
29 #include "lnn_heartbeat_ctrl.h"
30 #include "lnn_map.h"
31 #include "lnn_net_builder.h"
32 #include "softbus_adapter_mem.h"
33
34 static SoftBusList *g_authReqList;
35
36 typedef struct {
37 ListNode node;
38 uint32_t laneHandle;
39 uint64_t laneId;
40 uint32_t authRequestId;
41 int64_t authId;
42 uint32_t authLinkType;
43 char networkId[NETWORK_ID_BUF_LEN];
44 AuthConnCallback callback;
45 } AuthReqInfo;
46
GetAuthConn(const char * uuid,LaneLinkType laneType,AuthConnInfo * connInfo)47 int32_t GetAuthConn(const char *uuid, LaneLinkType laneType, AuthConnInfo *connInfo)
48 {
49 if (uuid == NULL || connInfo == NULL) {
50 AUTH_LOGE(AUTH_CONN, "param invalid");
51 return SOFTBUS_INVALID_PARAM;
52 }
53 AuthLinkType authType = AUTH_LINK_TYPE_MAX;
54 switch (laneType) {
55 case LANE_BR:
56 authType = AUTH_LINK_TYPE_BR;
57 break;
58 case LANE_BLE:
59 authType = AUTH_LINK_TYPE_BLE;
60 break;
61 case LANE_SLE:
62 authType = AUTH_LINK_TYPE_SLE;
63 break;
64 case LANE_P2P:
65 authType = AUTH_LINK_TYPE_P2P;
66 break;
67 case LANE_HML:
68 authType = AUTH_LINK_TYPE_ENHANCED_P2P;
69 break;
70 case LANE_WLAN_2P4G:
71 case LANE_WLAN_5G:
72 authType = AUTH_LINK_TYPE_WIFI;
73 break;
74 case LANE_USB:
75 authType = AUTH_LINK_TYPE_USB;
76 break;
77 default:
78 return SOFTBUS_AUTH_CONN_TYPE_INVALID;
79 }
80 AUTH_LOGI(AUTH_CONN, "convert authType=%{public}d", authType);
81 return GetAuthConnInfoByUuid(uuid, authType, connInfo);
82 }
83
GetAuthLinkTypeList(const char * networkId,AuthLinkTypeList * linkTypeList)84 int32_t GetAuthLinkTypeList(const char *networkId, AuthLinkTypeList *linkTypeList)
85 {
86 if (networkId == NULL || linkTypeList == NULL) {
87 AUTH_LOGE(AUTH_CONN, "param invalid");
88 return SOFTBUS_INVALID_PARAM;
89 }
90 char uuid[UUID_BUF_LEN] = {0};
91 if (LnnGetRemoteStrInfo(networkId, STRING_KEY_UUID, uuid, UUID_BUF_LEN) != SOFTBUS_OK) {
92 AUTH_LOGE(AUTH_CONN, "get peer uuid fail");
93 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
94 }
95 AuthLinkType linkList[] = {AUTH_LINK_TYPE_ENHANCED_P2P, AUTH_LINK_TYPE_WIFI,
96 AUTH_LINK_TYPE_P2P, AUTH_LINK_TYPE_BR, AUTH_LINK_TYPE_BLE, AUTH_LINK_TYPE_SLE};
97 AuthConnInfo connInfo;
98 if (memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo)) != EOK) {
99 AUTH_LOGE(AUTH_CONN, "memset_s AuthConnInfo fail");
100 return SOFTBUS_MEM_ERR;
101 }
102 linkTypeList->linkTypeNum = 0;
103 for (uint32_t i = 0; i < sizeof(linkList) / sizeof(linkList[0]); ++i) {
104 if (GetAuthConnInfoByUuid(uuid, linkList[i], &connInfo) != SOFTBUS_OK) {
105 continue;
106 }
107 if ((linkList[i] == AUTH_LINK_TYPE_BLE || linkList[i] == AUTH_LINK_TYPE_BR) &&
108 !CheckActiveAuthConnection(&connInfo)) {
109 AUTH_LOGI(AUTH_CONN, "auth ble connection not active");
110 continue;
111 }
112 AUTH_LOGI(AUTH_CONN, "select auth type. i=%{public}d, authLinkType=%{public}d", i, linkList[i]);
113 linkTypeList->linkType[linkTypeList->linkTypeNum] = linkList[i];
114 linkTypeList->linkTypeNum++;
115 }
116 if (linkTypeList->linkTypeNum == 0) {
117 if (TryGetBrConnInfo(uuid, &connInfo) == SOFTBUS_OK) {
118 linkTypeList->linkType[linkTypeList->linkTypeNum] = AUTH_LINK_TYPE_BR;
119 linkTypeList->linkTypeNum++;
120 return SOFTBUS_OK;
121 }
122 AUTH_LOGE(AUTH_CONN, "no available auth link");
123 return SOFTBUS_AUTH_LINK_NOT_EXIST;
124 }
125 return SOFTBUS_OK;
126 }
127
InitAuthReqInfo(void)128 void InitAuthReqInfo(void)
129 {
130 if (g_authReqList == NULL) {
131 g_authReqList = CreateSoftBusList();
132 if (g_authReqList == NULL) {
133 AUTH_LOGE(AUTH_CONN, "create g_authReqList fail");
134 return;
135 }
136 }
137 AUTH_LOGI(AUTH_CONN, "g_authReqList init success");
138 }
139
DeInitAuthReqInfo(void)140 void DeInitAuthReqInfo(void)
141 {
142 if (g_authReqList == NULL) {
143 AUTH_LOGE(AUTH_CONN, "g_authReqList is NULL");
144 return;
145 }
146 AuthReqInfo *item = NULL;
147 AuthReqInfo *next = NULL;
148 if (SoftBusMutexLock(&g_authReqList->lock) != SOFTBUS_OK) {
149 AUTH_LOGE(AUTH_CONN, "get lock fail");
150 return;
151 }
152 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_authReqList->list, AuthReqInfo, node) {
153 ListDelete(&item->node);
154 SoftBusFree(item);
155 }
156 (void)SoftBusMutexUnlock(&g_authReqList->lock);
157 DestroySoftBusList(g_authReqList);
158 g_authReqList = NULL;
159 AUTH_LOGI(AUTH_CONN, "g_authReqList deinit success");
160 }
161
AddAuthReqNode(const char * networkId,uint32_t laneHandle,uint32_t authRequestId,AuthConnCallback * callback)162 static int32_t AddAuthReqNode(const char *networkId, uint32_t laneHandle, uint32_t authRequestId,
163 AuthConnCallback *callback)
164 {
165 if (networkId == NULL || laneHandle == INVALID_LANE_REQ_ID || callback == NULL) {
166 AUTH_LOGE(AUTH_CONN, "param invalid");
167 return SOFTBUS_INVALID_PARAM;
168 }
169 AuthReqInfo *newItem = (AuthReqInfo *)SoftBusCalloc(sizeof(AuthReqInfo));
170 if (newItem == NULL) {
171 AUTH_LOGE(AUTH_CONN, "AuthReqInfo calloc fail");
172 return SOFTBUS_MALLOC_ERR;
173 }
174 newItem->callback = *callback;
175 if (memcpy_s(&newItem->networkId, NETWORK_ID_BUF_LEN, networkId, NETWORK_ID_BUF_LEN) != EOK) {
176 AUTH_LOGE(AUTH_CONN, "memcpy_s networkId fail");
177 SoftBusFree(newItem);
178 return SOFTBUS_MEM_ERR;
179 }
180 newItem->laneHandle = laneHandle;
181 newItem->authRequestId = authRequestId;
182 ListInit(&newItem->node);
183
184 if (SoftBusMutexLock(&g_authReqList->lock) != SOFTBUS_OK) {
185 AUTH_LOGI(AUTH_CONN, "get lock fail");
186 SoftBusFree(newItem);
187 return SOFTBUS_LOCK_ERR;
188 }
189 ListTailInsert(&g_authReqList->list, &newItem->node);
190 (void)SoftBusMutexUnlock(&g_authReqList->lock);
191 return SOFTBUS_OK;
192 }
193
DelAuthReqInfoByAuthHandle(const AuthHandle * authHandle)194 int32_t DelAuthReqInfoByAuthHandle(const AuthHandle *authHandle)
195 {
196 if (authHandle == NULL) {
197 AUTH_LOGE(AUTH_CONN, "authHandle is null");
198 return SOFTBUS_INVALID_PARAM;
199 }
200 AUTH_LOGI(AUTH_CONN, "delete authReqInfo by authId=%{public}" PRId64, authHandle->authId);
201 AuthReqInfo *item = NULL;
202 AuthReqInfo *next = NULL;
203 if (SoftBusMutexLock(&g_authReqList->lock) != SOFTBUS_OK) {
204 AUTH_LOGE(AUTH_CONN, "get lock fail");
205 return SOFTBUS_LOCK_ERR;
206 }
207 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_authReqList->list, AuthReqInfo, node) {
208 if (item->authId == authHandle->authId && item->authLinkType == authHandle->type) {
209 ListDelete(&item->node);
210 SoftBusFree(item);
211 break;
212 }
213 }
214 (void)SoftBusMutexUnlock(&g_authReqList->lock);
215 return SOFTBUS_OK;
216 }
217
AuthFreeLane(const AuthHandle * authHandle)218 void AuthFreeLane(const AuthHandle *authHandle)
219 {
220 uint32_t laneHandle = INVALID_LANE_REQ_ID;
221 AuthReqInfo *item = NULL;
222 AuthReqInfo *next = NULL;
223 if (SoftBusMutexLock(&g_authReqList->lock) != SOFTBUS_OK) {
224 AUTH_LOGE(AUTH_CONN, "get lock fail");
225 return;
226 }
227 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_authReqList->list, AuthReqInfo, node) {
228 if (item->authId == authHandle->authId && item->authLinkType == authHandle->type) {
229 laneHandle = item->laneHandle;
230 break;
231 }
232 }
233 (void)SoftBusMutexUnlock(&g_authReqList->lock);
234
235 if (laneHandle != INVALID_LANE_REQ_ID) {
236 GetLaneManager()->lnnFreeLane(laneHandle);
237 AUTH_LOGI(AUTH_CONN, "auth free lane, laneHandle=%{public}u", laneHandle);
238 }
239 }
240
DelAuthRequestItem(uint32_t laneHandle)241 static void DelAuthRequestItem(uint32_t laneHandle)
242 {
243 AuthReqInfo *item = NULL;
244 AuthReqInfo *next = NULL;
245 if (SoftBusMutexLock(&g_authReqList->lock) != SOFTBUS_OK) {
246 AUTH_LOGE(AUTH_CONN, "get lock fail");
247 return;
248 }
249 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_authReqList->list, AuthReqInfo, node) {
250 if (item->laneHandle == laneHandle) {
251 ListDelete(&item->node);
252 SoftBusFree(item);
253 break;
254 }
255 }
256 (void)SoftBusMutexUnlock(&g_authReqList->lock);
257 }
258
OnAuthConnOpenedSucc(uint32_t authRequestId,AuthHandle authHandle)259 static void OnAuthConnOpenedSucc(uint32_t authRequestId, AuthHandle authHandle)
260 {
261 AUTH_LOGI(AUTH_CONN, "open auth success with authRequestId=%{public}u", authRequestId);
262 AuthConnCallback cb;
263 cb.onConnOpened = NULL;
264 AuthReqInfo *item = NULL;
265 AuthReqInfo *next = NULL;
266 if (SoftBusMutexLock(&g_authReqList->lock) != SOFTBUS_OK) {
267 AUTH_LOGE(AUTH_CONN, "get lock fail");
268 return;
269 }
270 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_authReqList->list, AuthReqInfo, node) {
271 if (item->authRequestId == authRequestId) {
272 item->authId = authHandle.authId;
273 item->authLinkType = authHandle.type;
274 cb.onConnOpened = item->callback.onConnOpened;
275 break;
276 }
277 }
278 (void)SoftBusMutexUnlock(&g_authReqList->lock);
279 if (cb.onConnOpened != NULL) {
280 cb.onConnOpened(authRequestId, authHandle);
281 }
282 }
283
OnAuthConnOpenedFail(uint32_t authRequestId,int32_t reason)284 static void OnAuthConnOpenedFail(uint32_t authRequestId, int32_t reason)
285 {
286 AUTH_LOGI(AUTH_CONN, "open auth fail with authRequestId=%{public}u", authRequestId);
287 uint32_t laneHandle = 0;
288 AuthConnCallback cb;
289 cb.onConnOpenFailed = NULL;
290 AuthReqInfo *item = NULL;
291 AuthReqInfo *next = NULL;
292 if (SoftBusMutexLock(&g_authReqList->lock) != SOFTBUS_OK) {
293 AUTH_LOGE(AUTH_CONN, "get lock fail");
294 return;
295 }
296 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_authReqList->list, AuthReqInfo, node) {
297 if (item->authRequestId == authRequestId) {
298 laneHandle = item->laneHandle;
299 cb.onConnOpenFailed = item->callback.onConnOpenFailed;
300 ListDelete(&item->node);
301 SoftBusFree(item);
302 break;
303 }
304 }
305 (void)SoftBusMutexUnlock(&g_authReqList->lock);
306 if (cb.onConnOpenFailed != NULL) {
307 cb.onConnOpenFailed(authRequestId, reason);
308 }
309 GetLaneManager()->lnnFreeLane(laneHandle);
310 }
311
AuthOnLaneAllocSuccess(uint32_t laneHandle,const LaneConnInfo * laneConnInfo)312 static void AuthOnLaneAllocSuccess(uint32_t laneHandle, const LaneConnInfo *laneConnInfo)
313 {
314 AUTH_LOGI(AUTH_CONN, "auth request success, laneHandle=%{public}u", laneHandle);
315 AuthReqInfo *item = NULL;
316 AuthReqInfo *next = NULL;
317 uint32_t authRequestId = 0;
318 if (SoftBusMutexLock(&g_authReqList->lock) != SOFTBUS_OK) {
319 AUTH_LOGE(AUTH_CONN, "get lock fail");
320 return;
321 }
322 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_authReqList->list, AuthReqInfo, node) {
323 if (item->laneHandle == laneHandle) {
324 authRequestId = item->authRequestId;
325 item->laneId = laneConnInfo->laneId;
326 break;
327 }
328 }
329 char uuid[UUID_BUF_LEN] = {0};
330 if (LnnGetRemoteStrInfo(item->networkId, STRING_KEY_UUID, uuid, UUID_BUF_LEN) != SOFTBUS_OK) {
331 AUTH_LOGE(AUTH_CONN, "get peer uuid fail");
332 (void)SoftBusMutexUnlock(&g_authReqList->lock);
333 return;
334 }
335 (void)SoftBusMutexUnlock(&g_authReqList->lock);
336 AuthConnInfo authConnInfo;
337 if (memset_s(&authConnInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo)) != EOK) {
338 AUTH_LOGE(AUTH_CONN, "memset_s authConnInfo fail");
339 return;
340 }
341 if (GetAuthConn(uuid, laneConnInfo->type, &authConnInfo) != SOFTBUS_OK &&
342 laneConnInfo->type == LANE_BR && TryGetBrConnInfo(uuid, &authConnInfo) != SOFTBUS_OK) {
343 AUTH_LOGE(AUTH_CONN, "GetAuthConn fail");
344 return;
345 }
346
347 AuthConnCallback cb = {
348 .onConnOpened = OnAuthConnOpenedSucc,
349 .onConnOpenFailed = OnAuthConnOpenedFail,
350 };
351 AUTH_LOGI(AUTH_CONN, "open auth with authRequestId=%{public}u", authRequestId);
352 if (AuthOpenConn(&authConnInfo, authRequestId, &cb, false) != SOFTBUS_OK) {
353 AUTH_LOGE(AUTH_CONN, "open auth conn fail");
354 DelAuthRequestItem(laneHandle);
355 }
356 }
357
AuthOnLaneAllocFail(uint32_t laneHandle,int32_t reason)358 static void AuthOnLaneAllocFail(uint32_t laneHandle, int32_t reason)
359 {
360 AUTH_LOGI(AUTH_CONN, "auth request failed, laneHandle=%{public}u, reason=%{public}d", laneHandle, reason);
361 AuthConnCallback cb;
362 cb.onConnOpenFailed = NULL;
363 AuthReqInfo *item = NULL;
364 AuthReqInfo *next = NULL;
365 uint32_t authRequestId = 0;
366 if (SoftBusMutexLock(&g_authReqList->lock) != SOFTBUS_OK) {
367 AUTH_LOGE(AUTH_CONN, "get lock fail");
368 return;
369 }
370 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_authReqList->list, AuthReqInfo, node) {
371 if (item->laneHandle == laneHandle) {
372 authRequestId = item->authRequestId;
373 cb.onConnOpenFailed = item->callback.onConnOpenFailed;
374 ListDelete(&item->node);
375 SoftBusFree(item);
376 break;
377 }
378 }
379 (void)SoftBusMutexUnlock(&g_authReqList->lock);
380 if (cb.onConnOpenFailed != NULL) {
381 cb.onConnOpenFailed(authRequestId, reason);
382 }
383 }
384
AuthGetLaneAllocInfo(const char * networkId,LaneAllocInfo * allocInfo)385 static int32_t AuthGetLaneAllocInfo(const char *networkId, LaneAllocInfo *allocInfo)
386 {
387 if (networkId == NULL || allocInfo == NULL) {
388 AUTH_LOGE(AUTH_CONN, "param invalid");
389 return SOFTBUS_INVALID_PARAM;
390 }
391 if (memcpy_s(allocInfo->networkId, NETWORK_ID_BUF_LEN, networkId, NETWORK_ID_BUF_LEN) != EOK) {
392 AUTH_LOGE(AUTH_CONN, "networkId memcpy_s fail");
393 return SOFTBUS_MEM_ERR;
394 }
395
396 #define DEFAULT_PID 0
397 allocInfo->type = LANE_TYPE_CTRL;
398 allocInfo->pid = DEFAULT_PID;
399 allocInfo->extendInfo.networkDelegate = false;
400 allocInfo->transType = LANE_T_MSG;
401 allocInfo->acceptableProtocols = LNN_PROTOCOL_ALL ^ LNN_PROTOCOL_NIP;
402 allocInfo->qosRequire.maxLaneLatency = 0;
403 allocInfo->qosRequire.minBW = 0;
404 allocInfo->qosRequire.minLaneLatency = 0;
405 char uuid[UUID_BUF_LEN] = {0};
406 if (LnnGetRemoteStrInfo(networkId, STRING_KEY_UUID, uuid, UUID_BUF_LEN) != SOFTBUS_OK) {
407 AUTH_LOGE(AUTH_CONN, "get peer uuid fail");
408 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
409 }
410 AuthConnInfo connInfo;
411 if (memset_s(&connInfo, sizeof(AuthConnInfo), 0, sizeof(AuthConnInfo)) != EOK) {
412 AUTH_LOGE(AUTH_CONN, "memset_s AuthConnInfo fail");
413 return SOFTBUS_MEM_ERR;
414 }
415 if (GetAuthConnInfoByUuid(uuid, AUTH_LINK_TYPE_BLE, &connInfo) == SOFTBUS_OK &&
416 CheckActiveAuthConnection(&connInfo)) {
417 if (memcpy_s(allocInfo->extendInfo.peerBleMac, BT_MAC_LEN, connInfo.info.bleInfo.bleMac, BT_MAC_LEN) != EOK) {
418 AUTH_LOGE(AUTH_CONN, "memcpy_s fail");
419 return SOFTBUS_MEM_ERR;
420 }
421 }
422 return SOFTBUS_OK;
423 }
424
AuthAllocLane(const char * networkId,uint32_t authRequestId,AuthConnCallback * callback)425 int32_t AuthAllocLane(const char *networkId, uint32_t authRequestId, AuthConnCallback *callback)
426 {
427 if (networkId == NULL || callback == NULL) {
428 AUTH_LOGE(AUTH_CONN, "param invalid");
429 return SOFTBUS_INVALID_PARAM;
430 }
431 uint32_t laneHandle = GetLaneManager()->lnnGetLaneHandle(LANE_TYPE_CTRL);
432 if (AddAuthReqNode(networkId, laneHandle, authRequestId, callback) != SOFTBUS_OK) {
433 AUTH_LOGE(AUTH_CONN, "add auth request node fail");
434 GetLaneManager()->lnnFreeLane(laneHandle);
435 return SOFTBUS_AUTH_ALLOC_LANE_FAIL;
436 }
437
438 LaneAllocInfo allocInfo;
439 if (memset_s(&allocInfo, sizeof(LaneAllocInfo), 0, sizeof(LaneAllocInfo) != EOK)) {
440 AUTH_LOGE(AUTH_CONN, "LaneRequestOption memset_s fail");
441 GetLaneManager()->lnnFreeLane(laneHandle);
442 return SOFTBUS_MEM_ERR;
443 }
444
445 if (AuthGetLaneAllocInfo(networkId, &allocInfo) != SOFTBUS_OK) {
446 AUTH_LOGE(AUTH_CONN, "auth get requestOption fail");
447 GetLaneManager()->lnnFreeLane(laneHandle);
448 return SOFTBUS_AUTH_ALLOC_LANE_FAIL;
449 }
450
451 LaneAllocListener listener;
452 listener.onLaneAllocSuccess = AuthOnLaneAllocSuccess;
453 listener.onLaneAllocFail = AuthOnLaneAllocFail;
454 AUTH_LOGI(AUTH_CONN, "auth alloc lane, laneHandle=%{public}u, authRequestId=%{public}u", laneHandle, authRequestId);
455 if (GetLaneManager()->lnnAllocLane(laneHandle, &allocInfo, &listener) != SOFTBUS_OK) {
456 AUTH_LOGE(AUTH_CONN, "auth alloc lane fail");
457 return SOFTBUS_AUTH_ALLOC_LANE_FAIL;
458 }
459 return SOFTBUS_OK;
460 }
461