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