• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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