1 /*
2 * Copyright (c) 2022 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 "lnn_lane.h"
17
18 #include <securec.h>
19 #include <string.h>
20
21 #include "common_list.h"
22 #include "lnn_async_callback_utils.h"
23 #include "lnn_lane_assign.h"
24 #include "lnn_lane_common.h"
25 #include "lnn_lane_def.h"
26 #include "lnn_lane_interface.h"
27 #include "lnn_lane_link.h"
28 #include "lnn_lane_model.h"
29 #include "lnn_lane_score.h"
30 #include "lnn_lane_select.h"
31 #include "lnn_trans_lane.h"
32 #include "message_handler.h"
33 #include "softbus_adapter_mem.h"
34 #include "softbus_common.h"
35 #include "softbus_def.h"
36 #include "softbus_errcode.h"
37 #include "softbus_log.h"
38 #include "softbus_utils.h"
39
40 #define ID_SHIFT_STEP 5
41 #define ID_CALC_MASK 0x1F
42 #define IS_USED 1
43 #define IS_NOT_USED 0
44 #define LANE_ID_BITMAP_COUNT ((MAX_LANE_ID_NUM + ID_CALC_MASK) >> ID_SHIFT_STEP)
45 #define LANE_ID_TYPE_SHIFT 28
46 #define LANE_RANDOM_ID_MASK 0xFFFFFFF
47
48 #define LANE_SCORING_INTERVAL 300 /* 5min */
49 #define CHANNEL_RATING_DELAY (5 * 60 * 1000)
50
51 typedef struct {
52 ListNode node;
53 ILaneIdStateListener listener;
54 } LaneIdListenerNode;
55
56 typedef struct {
57 ListNode list;
58 uint32_t cnt;
59 } LaneListenerList;
60
61 static uint32_t g_laneIdBitmap[LANE_ID_BITMAP_COUNT];
62 static SoftBusMutex g_laneMutex;
63 static LaneListenerList g_laneListenerList;
64 static LaneInterface *g_laneObject[LANE_TYPE_BUTT];
65 static ILaneIdStateListener g_laneIdListener;
66
Lock(void)67 static int32_t Lock(void)
68 {
69 return SoftBusMutexLock(&g_laneMutex);
70 }
71
Unlock(void)72 static void Unlock(void)
73 {
74 (void)SoftBusMutexUnlock(&g_laneMutex);
75 }
76
77 /*
78 * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
79 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
80 * | type | randomId(1 ~ MAX_LANE_ID_NUM) |
81 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
82 */
AllocLaneId(LaneType type)83 static uint32_t AllocLaneId(LaneType type)
84 {
85 if (Lock() != SOFTBUS_OK) {
86 return INVALID_LANE_ID;
87 }
88 uint32_t laneId, randomId;
89 for (uint32_t idIndex = 0; idIndex < MAX_LANE_ID_NUM; idIndex++) {
90 if (((g_laneIdBitmap[idIndex >> ID_SHIFT_STEP] >> (idIndex & ID_CALC_MASK)) & IS_USED) == IS_NOT_USED) {
91 g_laneIdBitmap[idIndex >> ID_SHIFT_STEP] |= (IS_USED << (idIndex & ID_CALC_MASK));
92 randomId = idIndex + 1;
93 laneId = randomId | ((uint32_t)type << LANE_ID_TYPE_SHIFT);
94 Unlock();
95 return laneId;
96 }
97 }
98 Unlock();
99 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "laneId num exceeds the limit");
100 return INVALID_LANE_ID;
101 }
102
DestroyLaneId(uint32_t laneId)103 static void DestroyLaneId(uint32_t laneId)
104 {
105 uint32_t randomId = laneId & LANE_RANDOM_ID_MASK;
106 if ((randomId == INVALID_LANE_ID) || (randomId > MAX_LANE_ID_NUM)) {
107 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "[DestroyLaneId]invalid laneId");
108 return;
109 }
110 if (Lock() != SOFTBUS_OK) {
111 return;
112 }
113 uint32_t idIndex = randomId - 1;
114 g_laneIdBitmap[idIndex >> ID_SHIFT_STEP] &= (~(IS_USED << (idIndex & ID_CALC_MASK)));
115 Unlock();
116 return;
117 }
118
CheckListener(const ILaneIdStateListener * listener)119 static bool CheckListener(const ILaneIdStateListener *listener)
120 {
121 if (listener == NULL) {
122 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "laneIdListener is null");
123 return false;
124 }
125 if ((listener->OnLaneIdEnabled == NULL) && (listener->OnLaneIdDisabled == NULL)) {
126 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "listener invalid");
127 return false;
128 }
129 if (Lock() != SOFTBUS_OK) {
130 return false;
131 }
132 LaneIdListenerNode *item = NULL;
133 LIST_FOR_EACH_ENTRY(item, &g_laneListenerList.list, LaneIdListenerNode, node) {
134 if (memcmp(&item->listener, listener, sizeof(ILaneIdStateListener)) == 0) {
135 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_WARN, "the listener has been registered");
136 Unlock();
137 return false;
138 }
139 }
140 Unlock();
141 return true;
142 }
143
RegisterLaneIdListener(const ILaneIdStateListener * listener)144 NO_SANITIZE("cfi") void RegisterLaneIdListener(const ILaneIdStateListener *listener)
145 {
146 if (CheckListener(listener) == false) {
147 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "register fail");
148 return;
149 }
150 LaneIdListenerNode *newNode = (LaneIdListenerNode *)SoftBusCalloc(sizeof(LaneIdListenerNode));
151 if (newNode == NULL) {
152 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "register laneIdListener malloc fail");
153 return;
154 }
155 ListInit(&newNode->node);
156 if (memcpy_s(&newNode->listener, sizeof(ILaneIdStateListener), listener, sizeof(ILaneIdStateListener)) != EOK) {
157 SoftBusFree(newNode);
158 return;
159 }
160 if (Lock() != SOFTBUS_OK) {
161 SoftBusFree(newNode);
162 return;
163 }
164 ListTailInsert(&g_laneListenerList.list, &newNode->node);
165 g_laneListenerList.cnt++;
166 Unlock();
167 }
168
UnregisterLaneIdListener(const ILaneIdStateListener * listener)169 NO_SANITIZE("cfi") void UnregisterLaneIdListener(const ILaneIdStateListener *listener)
170 {
171 if (listener == NULL) {
172 return;
173 }
174 if (Lock() != SOFTBUS_OK) {
175 return;
176 }
177 LaneIdListenerNode *item = NULL;
178 LaneIdListenerNode *next = NULL;
179 LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_laneListenerList.list, LaneIdListenerNode, node) {
180 if (memcmp(&item->listener, listener, sizeof(ILaneIdStateListener)) == 0) {
181 ListDelete(&item->node);
182 SoftBusFree(item);
183 g_laneListenerList.cnt--;
184 break;
185 }
186 }
187 Unlock();
188 }
189
GetAllLaneIdListener(ILaneIdStateListener ** listener,uint32_t * listenerNum)190 static int32_t GetAllLaneIdListener(ILaneIdStateListener **listener, uint32_t *listenerNum)
191 {
192 if (Lock() != SOFTBUS_OK) {
193 return SOFTBUS_ERR;
194 }
195 if (g_laneListenerList.cnt == 0) {
196 Unlock();
197 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "laneIdListener num is zero");
198 return SOFTBUS_ERR;
199 }
200 uint32_t num = g_laneListenerList.cnt;
201 *listener = (ILaneIdStateListener *)SoftBusCalloc(sizeof(ILaneIdStateListener) * num);
202 if (*listener == NULL) {
203 Unlock();
204 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "malloc laneIdListener fail");
205 return SOFTBUS_MALLOC_ERR;
206 }
207 LaneIdListenerNode *item = NULL;
208 num = 0;
209 LIST_FOR_EACH_ENTRY(item, &g_laneListenerList.list, LaneIdListenerNode, node) {
210 if (memcpy_s(*listener + num, sizeof(ILaneIdStateListener),
211 &item->listener, sizeof(ILaneIdStateListener)) != EOK) {
212 continue;
213 }
214 num++;
215 }
216 *listenerNum = num;
217 Unlock();
218 return SOFTBUS_OK;
219 }
220
LaneIdEnabled(uint32_t laneId,uint32_t profileId)221 NO_SANITIZE("cfi") static void LaneIdEnabled(uint32_t laneId, uint32_t profileId)
222 {
223 ILaneIdStateListener *listener = NULL;
224 uint32_t listenerNum = 0;
225 if (GetAllLaneIdListener(&listener, &listenerNum) != SOFTBUS_OK) {
226 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "get laneListener fail");
227 return;
228 }
229 for (uint32_t i = 0; i < listenerNum; i++) {
230 if (listener[i].OnLaneIdEnabled != NULL) {
231 listener[i].OnLaneIdEnabled(laneId, profileId);
232 }
233 }
234 SoftBusFree(listener);
235 }
236
LaneIdDisabled(uint32_t laneId,uint32_t laneProfileId)237 NO_SANITIZE("cfi") static void LaneIdDisabled(uint32_t laneId, uint32_t laneProfileId)
238 {
239 ILaneIdStateListener *listener = NULL;
240 uint32_t listenerNum = 0;
241 if (GetAllLaneIdListener(&listener, &listenerNum) != SOFTBUS_OK) {
242 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "get laneListener fail");
243 return;
244 }
245 for (uint32_t i = 0; i < listenerNum; i++) {
246 if (listener[i].OnLaneIdDisabled != NULL) {
247 listener[i].OnLaneIdDisabled(laneId, laneProfileId);
248 }
249 }
250 SoftBusFree(listener);
251 }
252
RequestInfoCheck(const LaneRequestOption * request,const ILaneListener * listener)253 static bool RequestInfoCheck(const LaneRequestOption *request, const ILaneListener *listener)
254 {
255 if ((request == NULL) || (listener == NULL)) {
256 return false;
257 }
258 if ((request->type >= LANE_TYPE_BUTT) || (request->type < 0)) {
259 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "laneType[%d] is invalid", request->type);
260 return false;
261 }
262 return true;
263 }
264
265 /* return laneId if the operation is successful, return 0 otherwise. */
ApplyLaneId(LaneType type)266 NO_SANITIZE("cfi") uint32_t ApplyLaneId(LaneType type)
267 {
268 return AllocLaneId(type);
269 }
270
LnnRequestLane(uint32_t laneId,const LaneRequestOption * request,const ILaneListener * listener)271 NO_SANITIZE("cfi") int32_t LnnRequestLane(uint32_t laneId, const LaneRequestOption *request,
272 const ILaneListener *listener)
273 {
274 if (RequestInfoCheck(request, listener) == false) {
275 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "lane requestInfo invalid");
276 return SOFTBUS_ERR;
277 }
278 if (g_laneObject[request->type] == NULL) {
279 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "lane type[%d] is not supported", request->type);
280 return SOFTBUS_ERR;
281 }
282 int32_t result;
283 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "laneRequest, laneId %u, lane type %d, trans type is %d",
284 laneId, request->type, request->requestInfo.trans.transType);
285 result = g_laneObject[request->type]->AllocLane(laneId, request, listener);
286 if (result != SOFTBUS_OK) {
287 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "alloc lane fail, result:%d", result);
288 DestroyLaneId(laneId);
289 return SOFTBUS_ERR;
290 }
291 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "request lane success, lane:%u", laneId);
292 return SOFTBUS_OK;
293 }
294
LnnFreeLane(uint32_t laneId)295 NO_SANITIZE("cfi") int32_t LnnFreeLane(uint32_t laneId)
296 {
297 uint32_t laneType = laneId >> LANE_ID_TYPE_SHIFT;
298 if (laneType >= LANE_TYPE_BUTT) {
299 LLOGE("[LnnFreeLane]laneType invalid");
300 return SOFTBUS_ERR;
301 }
302 if (g_laneObject[laneType] == NULL) {
303 return SOFTBUS_ERR;
304 }
305 int32_t result = g_laneObject[laneType]->FreeLane(laneId);
306 if (result != SOFTBUS_OK) {
307 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "freeLane fail, result:%d", result);
308 return SOFTBUS_ERR;
309 }
310 DestroyLaneId(laneId);
311 return SOFTBUS_OK;
312 }
313
LnnQueryLaneResource(const LaneQueryInfo * queryInfo)314 NO_SANITIZE("cfi") QueryResult LnnQueryLaneResource(const LaneQueryInfo *queryInfo)
315 {
316 if (queryInfo == NULL) {
317 return QUERY_RESULT_REQUEST_ILLEGAL;
318 }
319 return QUERY_RESULT_OK;
320 }
321
LaneInitChannelRatingDelay(void * para)322 static void LaneInitChannelRatingDelay(void *para)
323 {
324 (void)para;
325 if (LnnInitScore() != SOFTBUS_OK) {
326 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "[InitLane]init laneScoring fail");
327 return;
328 }
329 if (LnnStartScoring(LANE_SCORING_INTERVAL) != SOFTBUS_OK) {
330 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "start laneScoring fail");
331 }
332 }
333
LaneDelayInit(void)334 static int32_t LaneDelayInit(void)
335 {
336 int32_t ret = LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), LaneInitChannelRatingDelay,
337 NULL, CHANNEL_RATING_DELAY);
338 if (ret != SOFTBUS_OK) {
339 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "laneDelayInit post channelRating msg fail");
340 }
341 return ret;
342 }
343
InitLane(void)344 NO_SANITIZE("cfi") int32_t InitLane(void)
345 {
346 if (LnnInitLaneLooper() != SOFTBUS_OK) {
347 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "[InitLane]init laneLooper fail");
348 return SOFTBUS_ERR;
349 }
350 if (InitLaneModel() != SOFTBUS_OK) {
351 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "[InitLane]init laneModel fail");
352 return SOFTBUS_ERR;
353 }
354 if (InitLaneLink() != SOFTBUS_OK) {
355 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "[InitLane]init laneLink fail");
356 return SOFTBUS_ERR;
357 }
358 if (LaneDelayInit() != SOFTBUS_OK) {
359 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "[InitLane]laneDelayInit fail");
360 return SOFTBUS_ERR;
361 }
362 if (SoftBusMutexInit(&g_laneMutex, NULL) != SOFTBUS_OK) {
363 return SOFTBUS_ERR;
364 }
365 g_laneIdListener.OnLaneIdEnabled = LaneIdEnabled;
366 g_laneIdListener.OnLaneIdDisabled = LaneIdDisabled;
367 g_laneObject[LANE_TYPE_TRANS] = TransLaneGetInstance();
368 if (g_laneObject[LANE_TYPE_TRANS] != NULL) {
369 SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_INFO, "transLane get instance succ");
370 g_laneObject[LANE_TYPE_TRANS]->Init(&g_laneIdListener);
371 }
372 ListInit(&g_laneListenerList.list);
373 g_laneListenerList.cnt = 0;
374 return SOFTBUS_OK;
375 }
376
DeinitLane(void)377 NO_SANITIZE("cfi") void DeinitLane(void)
378 {
379 DeinitLaneModel();
380 DeinitLaneLink();
381 LnnDeinitScore();
382 LnnDeinitLaneLooper();
383 if (g_laneObject[LANE_TYPE_TRANS] != NULL) {
384 g_laneObject[LANE_TYPE_TRANS]->Deinit();
385 }
386 (void)SoftBusMutexDestroy(&g_laneMutex);
387 }
388