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