• 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_model.h"
17 
18 #include <securec.h>
19 
20 #include "common_list.h"
21 #include "lnn_lane.h"
22 #include "lnn_lane_common.h"
23 #include "lnn_lane_def.h"
24 #include "lnn_map.h"
25 #include "softbus_adapter_mem.h"
26 #include "softbus_def.h"
27 #include "softbus_errcode.h"
28 #include "softbus_log.h"
29 
30 #define LINK_TYPE_SHIFT 26
31 #define TRANS_TYPE_SHIFT 22
32 #define PRIORITY_SHIFT 18
33 
34 typedef struct {
35     ListNode node;
36     uint32_t laneId;
37 } LaneIdInfo;
38 
39 typedef struct {
40     LaneProfile profile;
41     uint32_t ref;
42     ListNode laneIdList;
43 } LaneModel;
44 
45 static Map g_profileMap;
46 static SoftBusMutex g_laneModelMutex;
47 
ModelLock(void)48 static int32_t ModelLock(void)
49 {
50     return SoftBusMutexLock(&g_laneModelMutex);
51 }
52 
ModelUnlock(void)53 static void ModelUnlock(void)
54 {
55     (void)SoftBusMutexUnlock(&g_laneModelMutex);
56 }
57 
58 /*
59  *  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
60  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61  * |  LinkType |TxType |  Pri  |              Reserved             |
62  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63  */
GenerateLaneProfileId(const LaneGenerateParam * param)64 NO_SANITIZE("cfi") uint32_t GenerateLaneProfileId(const LaneGenerateParam *param)
65 {
66     uint32_t laneProfileId = 0;
67     laneProfileId |= ((param->linkType << LINK_TYPE_SHIFT) |
68         (param->transType << TRANS_TYPE_SHIFT) | (param->priority << PRIORITY_SHIFT));
69     return laneProfileId;
70 }
71 
AddLaneIdNode(uint32_t laneId,LaneModel * laneModel)72 static void AddLaneIdNode(uint32_t laneId, LaneModel *laneModel)
73 {
74     LaneIdInfo *infoNode = NULL;
75     LIST_FOR_EACH_ENTRY(infoNode, &laneModel->laneIdList, LaneIdInfo, node) {
76         if (infoNode->laneId == laneId) {
77             SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "laneId has been added");
78             return;
79         }
80     }
81     LaneIdInfo *newNode = (LaneIdInfo *)SoftBusCalloc(sizeof(LaneIdInfo));
82     if (newNode == NULL) {
83         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "laneId add to list fail");
84         return;
85     }
86     ListInit(&newNode->node);
87     newNode->laneId = laneId;
88     ListAdd(&laneModel->laneIdList, &newNode->node);
89     laneModel->ref++;
90 }
91 
DeleteLaneIdNode(uint32_t laneId,LaneModel * laneModel)92 static void DeleteLaneIdNode(uint32_t laneId, LaneModel *laneModel)
93 {
94     LaneIdInfo *item = NULL;
95     LaneIdInfo *next = NULL;
96     LIST_FOR_EACH_ENTRY_SAFE(item, next, &laneModel->laneIdList, LaneIdInfo, node) {
97         if (item->laneId == laneId) {
98             ListDelete(&item->node);
99             SoftBusFree(item);
100             laneModel->ref--;
101             return;
102         }
103     }
104 }
105 
AddLaneModel(uint32_t laneId,uint32_t profileId,LaneProfile * laneProfile)106 static int32_t AddLaneModel(uint32_t laneId, uint32_t profileId, LaneProfile *laneProfile)
107 {
108     if (ModelLock() != SOFTBUS_OK) {
109         return SOFTBUS_ERR;
110     }
111     LaneModel *laneModel = (LaneModel *)LnnReadData(&g_profileMap, profileId);
112     if (laneModel != NULL) {
113         AddLaneIdNode(laneId, laneModel);
114         ModelUnlock();
115         return SOFTBUS_OK;
116     }
117 
118     LaneModel newModel;
119     (void)memset_s(&newModel, sizeof(LaneModel), 0, sizeof(LaneModel));
120     if (memcpy_s(&newModel.profile, sizeof(LaneProfile), laneProfile, sizeof(LaneProfile)) != EOK) {
121         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "addLaneModel memcpy fail");
122         ModelUnlock();
123         return SOFTBUS_ERR;
124     }
125 
126     if (LnnCreateData(&g_profileMap, profileId, &newModel, sizeof(LaneModel)) != SOFTBUS_OK) {
127         ModelUnlock();
128         return SOFTBUS_ERR;
129     }
130     laneModel = (LaneModel *)LnnReadData(&g_profileMap, profileId);
131     if (laneModel != NULL) {
132         ListInit(&(laneModel->laneIdList));
133         AddLaneIdNode(laneId, laneModel);
134     }
135     ModelUnlock();
136     return SOFTBUS_OK;
137 }
138 
BindLaneIdToProfile(uint32_t laneId,LaneProfile * profile)139 NO_SANITIZE("cfi") int32_t BindLaneIdToProfile(uint32_t laneId, LaneProfile *profile)
140 {
141     if (profile == NULL) {
142         return SOFTBUS_ERR;
143     }
144     LaneGenerateParam param;
145     param.linkType = profile->linkType;
146     param.transType = profile->content;
147     param.priority = profile->priority;
148     uint32_t profileId = GenerateLaneProfileId(&param);
149     profile->serialNum = profileId;
150     if (AddLaneModel(laneId, profileId, profile) != SOFTBUS_OK) {
151         return SOFTBUS_ERR;
152     }
153     return SOFTBUS_OK;
154 }
155 
UnbindLaneIdFromProfile(uint32_t laneId,uint32_t profileId)156 NO_SANITIZE("cfi") void UnbindLaneIdFromProfile(uint32_t laneId, uint32_t profileId)
157 {
158     if (ModelLock() != SOFTBUS_OK) {
159         return;
160     }
161     LaneModel *laneModel = (LaneModel *)LnnReadData(&g_profileMap, profileId);
162     if (laneModel == NULL) {
163         ModelUnlock();
164         return;
165     }
166     DeleteLaneIdNode(laneId, laneModel);
167     if (laneModel->ref == 0) {
168         LnnDeleteData(&g_profileMap, profileId);
169     }
170     ModelUnlock();
171 }
172 
GetLaneProfile(uint32_t profileId,LaneProfile * profile)173 NO_SANITIZE("cfi") int32_t GetLaneProfile(uint32_t profileId, LaneProfile *profile)
174 {
175     if (profile == NULL) {
176         return SOFTBUS_ERR;
177     }
178     if (ModelLock() != SOFTBUS_OK) {
179         return SOFTBUS_ERR;
180     }
181     LaneModel *laneModel = (LaneModel *)LnnReadData(&g_profileMap, profileId);
182     if (laneModel == NULL) {
183         ModelUnlock();
184         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "read laneModel fail");
185         return SOFTBUS_ERR;
186     }
187     if (memcpy_s(profile, sizeof(LaneProfile), &laneModel->profile, sizeof(LaneProfile)) != EOK) {
188         ModelUnlock();
189         return SOFTBUS_ERR;
190     }
191     ModelUnlock();
192     return SOFTBUS_OK;
193 }
194 
GetLaneIdList(uint32_t profileId,uint32_t ** laneIdList,uint32_t * listSize)195 NO_SANITIZE("cfi") int32_t GetLaneIdList(uint32_t profileId, uint32_t **laneIdList, uint32_t *listSize)
196 {
197     if (ModelLock() != SOFTBUS_OK) {
198         return SOFTBUS_ERR;
199     }
200     LaneModel *laneModel = (LaneModel *)LnnReadData(&g_profileMap, profileId);
201     if (laneModel == NULL) {
202         ModelUnlock();
203         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "read laneModel fail");
204         return SOFTBUS_ERR;
205     }
206     if (laneModel->ref == 0) {
207         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "ref count is zero");
208         ModelUnlock();
209         return SOFTBUS_ERR;
210     }
211     *laneIdList = (uint32_t *)SoftBusCalloc(sizeof(uint32_t) * laneModel->ref);
212     if (*laneIdList == NULL) {
213         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "laneIdList malloc fail");
214         ModelUnlock();
215         return SOFTBUS_ERR;
216     }
217     uint32_t cnt = 0;
218     LaneIdInfo *infoNode = NULL;
219     LIST_FOR_EACH_ENTRY(infoNode, &laneModel->laneIdList, LaneIdInfo, node) {
220         (*laneIdList)[cnt] = infoNode->laneId;
221         cnt++;
222     }
223     *listSize = cnt;
224     ModelUnlock();
225     return SOFTBUS_OK;
226 }
227 
GetActiveProfileNum(void)228 NO_SANITIZE("cfi") uint32_t GetActiveProfileNum(void)
229 {
230     uint32_t num = 0;
231     if (ModelLock() != SOFTBUS_OK) {
232         return num;
233     }
234     num = g_profileMap.nodeSize;
235     ModelUnlock();
236     return num;
237 }
238 
InitLaneModel(void)239 NO_SANITIZE("cfi") int32_t InitLaneModel(void)
240 {
241     LnnMapInit(&g_profileMap);
242     if (SoftBusMutexInit(&g_laneModelMutex, NULL) != SOFTBUS_OK) {
243         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "laneModel mutex init fail");
244         return SOFTBUS_ERR;
245     }
246     return SOFTBUS_OK;
247 }
248 
ClearProfileMap(void)249 static void ClearProfileMap(void)
250 {
251     MapIterator *it = LnnMapInitIterator(&g_profileMap);
252     if (it == NULL) {
253         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "clear profileMap fail");
254         return;
255     }
256     while (LnnMapHasNext(it)) {
257         it = LnnMapNext(it);
258         if (it == NULL || it->node->value == NULL) {
259             break;
260         }
261         LaneModel *laneModel = (LaneModel *)it->node->value;
262         LaneIdInfo *infoNode = NULL;
263         LaneIdInfo *nextNode = NULL;
264         LIST_FOR_EACH_ENTRY_SAFE(infoNode, nextNode, &laneModel->laneIdList, LaneIdInfo, node) {
265             ListDelete(&infoNode->node);
266             SoftBusFree(infoNode);
267             laneModel->ref--;
268         }
269     }
270     LnnMapDeinitIterator(it);
271     LnnMapDelete(&g_profileMap);
272 }
273 
DeinitLaneModel(void)274 NO_SANITIZE("cfi") void DeinitLaneModel(void)
275 {
276     ClearProfileMap();
277     (void)SoftBusMutexDestroy(&g_laneModelMutex);
278 }