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_select_rule.h"
17
18 #include <securec.h>
19
20 #include "anonymizer.h"
21 #include "bus_center_manager.h"
22 #include "lnn_distributed_net_ledger.h"
23 #include "lnn_feature_capability.h"
24 #include "lnn_lane_interface.h"
25 #include "lnn_lane_link.h"
26 #include "lnn_lane_score.h"
27 #include "lnn_local_net_ledger.h"
28 #include "lnn_log.h"
29 #include "lnn_net_capability.h"
30 #include "softbus_adapter_crypto.h"
31 #include "softbus_adapter_mem.h"
32 #include "softbus_adapter_thread.h"
33 #include "softbus_def.h"
34 #include "softbus_errcode.h"
35 #include "softbus_hisysevt_bus_center.h"
36 #include "softbus_network_utils.h"
37 #include "softbus_utils.h"
38 #include "softbus_wifi_api_adapter.h"
39 #include "trans_event.h"
40
41 #define LNN_LINK_DEFAULT_SCORE 60 /* Indicates that scoring is not supported */
42 #define LNN_ONLINETIME_OUT 10000 /*BLE connection reuse time*/
43
44 #define LOW_BW (384 * 1024)
45 #define MID_BW (30 * 1024 * 1024)
46 #define HIGH_BW (160 * 1024 * 1024)
47
GetWlanLinkedFrequency(void)48 int32_t GetWlanLinkedFrequency(void)
49 {
50 LnnWlanLinkedInfo info;
51 int32_t ret = LnnGetWlanLinkedInfo(&info);
52 if (ret != SOFTBUS_OK) {
53 LNN_LOGE(LNN_LANE, "get linked info fail, reason=%{public}d", ret);
54 return ret;
55 }
56 LNN_LOGI(LNN_LANE, "wlan linked frequency=%{public}d", info.frequency);
57 return info.frequency;
58 }
59
GetNetCap(const char * networkId,uint32_t * local,uint32_t * remote)60 static bool GetNetCap(const char *networkId, uint32_t *local, uint32_t *remote)
61 {
62 int32_t ret = LnnGetLocalNumU32Info(NUM_KEY_NET_CAP, local);
63 if (ret != SOFTBUS_OK) {
64 LNN_LOGE(LNN_LANE, "LnnGetLocalNumInfo err, ret=%{public}d, local=%{public}u", ret, *local);
65 return false;
66 }
67 ret = LnnGetRemoteNumU32Info(networkId, NUM_KEY_NET_CAP, remote);
68 if (ret != SOFTBUS_OK) {
69 LNN_LOGE(LNN_LANE, "LnnGetRemoteNumInfo err, ret=%{public}d, remote=%{public}u", ret, *remote);
70 return false;
71 }
72 return true;
73 }
74
GetFeatureCap(const char * networkId,uint64_t * local,uint64_t * remote)75 static bool GetFeatureCap(const char *networkId, uint64_t *local, uint64_t *remote)
76 {
77 int32_t ret = LnnGetLocalNumU64Info(NUM_KEY_FEATURE_CAPA, local);
78 if (ret != SOFTBUS_OK || *local < 0) {
79 LNN_LOGE(LNN_LANE, "LnnGetLocalNumInfo err, ret=%{public}d, local=%{public}" PRIu64, ret, *local);
80 return false;
81 }
82 ret = LnnGetRemoteNumU64Info(networkId, NUM_KEY_FEATURE_CAPA, remote);
83 if (ret != SOFTBUS_OK || *remote < 0) {
84 LNN_LOGE(LNN_LANE, "LnnGetRemoteNumInfo err, ret=%{public}d, remote=%{public}" PRIu64, ret, *remote);
85 return false;
86 }
87 return true;
88 }
89
NodeStateCheck(const char * networkId)90 static int32_t NodeStateCheck(const char *networkId)
91 {
92 NodeInfo node;
93 (void)memset_s(&node, sizeof(NodeInfo), 0, sizeof(NodeInfo));
94 if (LnnGetRemoteNodeInfoById(networkId, CATEGORY_NETWORK_ID, &node) != SOFTBUS_OK) {
95 char *anonyNetworkId = NULL;
96 Anonymize(networkId, &anonyNetworkId);
97 LNN_LOGE(LNN_LANE, "get remote node info fail, networkId=%{public}s", AnonymizeWrapper(anonyNetworkId));
98 AnonymizeFree(anonyNetworkId);
99 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
100 }
101 if (!LnnHasDiscoveryType(&node, DISCOVERY_TYPE_WIFI) && !LnnHasDiscoveryType(&node, DISCOVERY_TYPE_LSA)) {
102 char *anonyNetworkId = NULL;
103 Anonymize(networkId, &anonyNetworkId);
104 LNN_LOGE(LNN_LANE, "wlan not online, anonyNetworkId=%{public}s", AnonymizeWrapper(anonyNetworkId));
105 AnonymizeFree(anonyNetworkId);
106 return SOFTBUS_LANE_WIFI_NOT_ONLINE;
107 }
108 return SOFTBUS_OK;
109 }
110
Wlan2P4GCapCheck(const char * networkId)111 static int32_t Wlan2P4GCapCheck(const char *networkId)
112 {
113 int32_t ret = NodeStateCheck(networkId);
114 if (ret != SOFTBUS_OK) {
115 return ret;
116 }
117 SoftBusBand band = SoftBusGetLinkBand();
118 if (band != BAND_24G && band != BAND_UNKNOWN) {
119 char *anonyNetworkId = NULL;
120 Anonymize(networkId, &anonyNetworkId);
121 LNN_LOGE(LNN_LANE, "band isn't 2.4G or unknown, networkId=%{public}s", AnonymizeWrapper(anonyNetworkId));
122 AnonymizeFree(anonyNetworkId);
123 return SOFTBUS_LANE_WIFI_BAND_ERR;
124 }
125 uint32_t local;
126 uint32_t remote;
127 if (!GetNetCap(networkId, &local, &remote)) {
128 LNN_LOGE(LNN_LANE, "GetNetCap error");
129 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
130 }
131 if (((local & (1 << BIT_WIFI_24G)) || (local & (1 << BIT_ETH)) || (local & (1 << BIT_WIFI_5G))) &&
132 ((remote & (1 << BIT_WIFI_24G)) || (remote & (1 << BIT_ETH)) ||
133 (remote & (1 << BIT_WIFI_5G)) || (local & (1 << BIT_WIFI_5G)))) {
134 return SOFTBUS_OK;
135 }
136 LNN_LOGE(LNN_LANE, "2.4G capa disable, local=%{public}u, remote=%{public}u", local, remote);
137 return ((local & (1 << BIT_WIFI_24G)) || (local & (1 << BIT_ETH)) || (local & (1 << BIT_WIFI_5G))) ?
138 SOFTBUS_LANE_REMOTE_NO_WIFI_CAP : SOFTBUS_LANE_LOCAL_NO_WIFI_CAP;
139 }
140
Wlan5GCapCheck(const char * networkId)141 static int32_t Wlan5GCapCheck(const char *networkId)
142 {
143 int32_t ret = NodeStateCheck(networkId);
144 if (ret != SOFTBUS_OK) {
145 return ret;
146 }
147 SoftBusBand band = SoftBusGetLinkBand();
148 if (band != BAND_5G && band != BAND_UNKNOWN) {
149 char *anonyNetworkId = NULL;
150 Anonymize(networkId, &anonyNetworkId);
151 LNN_LOGE(LNN_LANE, "band isn't 5G or unknown, networkId=%{public}s", AnonymizeWrapper(anonyNetworkId));
152 AnonymizeFree(anonyNetworkId);
153 return SOFTBUS_LANE_WIFI_BAND_ERR;
154 }
155 uint32_t local;
156 uint32_t remote;
157 if (!GetNetCap(networkId, &local, &remote)) {
158 LNN_LOGE(LNN_LANE, "GetNetCap error");
159 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
160 }
161 if (((local & (1 << BIT_WIFI_5G)) || (local & (1 << BIT_ETH)) || (local & (1 << BIT_WIFI_24G))) &&
162 ((remote & (1 << BIT_WIFI_5G)) || (remote & (1 << BIT_ETH)) ||
163 (remote & (1 << BIT_WIFI_24G)) || (local & (1 << BIT_WIFI_24G)))) {
164 return SOFTBUS_OK;
165 }
166 LNN_LOGE(LNN_LANE, "5G capa disable, local=%{public}u, remote=%{public}u", local, remote);
167 return ((local & (1 << BIT_WIFI_5G)) || (local & (1 << BIT_ETH)) || (local & (1 << BIT_WIFI_24G))) ?
168 SOFTBUS_LANE_REMOTE_NO_WIFI_CAP : SOFTBUS_LANE_LOCAL_NO_WIFI_CAP;
169 }
170
BrCapCheck(const char * networkId)171 static int32_t BrCapCheck(const char *networkId)
172 {
173 uint32_t local;
174 uint32_t remote;
175 if (!GetNetCap(networkId, &local, &remote)) {
176 LNN_LOGE(LNN_LANE, "GetNetCap error");
177 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
178 }
179 if ((local & (1 << BIT_BR)) && (remote & (1 << BIT_BR))) {
180 return SOFTBUS_OK;
181 }
182 LNN_LOGE(LNN_LANE, "BR capa disable, local=%{public}u, remote=%{public}u", local, remote);
183 return (local & (1 << BIT_BR)) ? SOFTBUS_LANE_REMOTE_NO_BR_CAP : SOFTBUS_LANE_LOCAL_NO_BR_CAP;
184 }
185
P2pCapCheck(const char * networkId)186 static int32_t P2pCapCheck(const char *networkId)
187 {
188 uint32_t local;
189 uint32_t remote;
190 if (!GetNetCap(networkId, &local, &remote)) {
191 LNN_LOGE(LNN_LANE, "GetNetCap error");
192 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
193 }
194 if ((local & (1 << BIT_WIFI_P2P)) == 0) {
195 SoftBusWifiDetailState wifiState = SoftBusGetWifiState();
196 if (wifiState == SOFTBUS_WIFI_STATE_INACTIVE || wifiState == SOFTBUS_WIFI_STATE_DEACTIVATING) {
197 LNN_LOGE(LNN_LANE, "p2p capa disable, local=%{public}u, remote=%{public}u", local, remote);
198 return SOFTBUS_LANE_LOCAL_NO_WIFI_DIRECT_CAP;
199 } else {
200 (void)LnnSetNetCapability(&local, BIT_WIFI_P2P);
201 (void)LnnSetLocalNumU32Info(NUM_KEY_NET_CAP, local);
202 }
203 }
204 if ((remote & (1 << BIT_WIFI_P2P)) == 0) {
205 LNN_LOGE(LNN_LANE, "p2p capa disable, local=%{public}u, remote=%{public}u", local, remote);
206 return SOFTBUS_LANE_REMOTE_NO_WIFI_DIRECT_CAP;
207 }
208 return SOFTBUS_OK;
209 }
210
HmlCapCheck(const char * networkId)211 static int32_t HmlCapCheck(const char *networkId)
212 {
213 int32_t ret = P2pCapCheck(networkId);
214 if (ret != SOFTBUS_OK) {
215 LNN_LOGE(LNN_LANE, "p2p cap check error");
216 return ret;
217 }
218 uint64_t local;
219 uint64_t remote;
220 if (!GetFeatureCap(networkId, &local, &remote)) {
221 LNN_LOGE(LNN_LANE, "get feature cap error");
222 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
223 }
224 if (((local & (1 << BIT_WIFI_DIRECT_TLV_NEGOTIATION)) == 0) ||
225 ((remote & (1 << BIT_WIFI_DIRECT_TLV_NEGOTIATION)) == 0)) {
226 LNN_LOGE(LNN_LANE, "hml capa disable, local=%{public}" PRIu64 ", remote=%{public}" PRIu64, local, remote);
227 return ((local & (1 << BIT_WIFI_DIRECT_TLV_NEGOTIATION)) == 0) ?
228 SOFTBUS_LANE_LOCAL_NO_WIFI_DIRECT_CAP : SOFTBUS_LANE_REMOTE_NO_WIFI_DIRECT_CAP;
229 }
230 return SOFTBUS_OK;
231 }
232
P2pReuseCapCheck(const char * networkId)233 static int32_t P2pReuseCapCheck(const char *networkId)
234 {
235 int32_t ret = P2pCapCheck(networkId);
236 if (ret != SOFTBUS_OK) {
237 LNN_LOGE(LNN_LANE, "p2p cap check error");
238 return ret;
239 }
240 uint64_t local;
241 uint64_t remote;
242 if (!GetFeatureCap(networkId, &local, &remote)) {
243 LNN_LOGE(LNN_LANE, "get feature cap error");
244 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
245 }
246 if (((local & (1 << BIT_WIFI_P2P_REUSE)) == 0) || ((remote & (1 << BIT_WIFI_P2P_REUSE)) == 0)) {
247 LNN_LOGE(LNN_LANE, "p2p reuse capa disable, local=%{public}" PRIu64 ", remote=%{public}" PRIu64,
248 local, remote);
249 return ((local & (1 << BIT_WIFI_P2P_REUSE)) == 0) ?
250 SOFTBUS_LANE_LOCAL_NO_WIFI_DIRECT_CAP : SOFTBUS_LANE_REMOTE_NO_WIFI_DIRECT_CAP;
251 }
252 return SOFTBUS_OK;
253 }
254
BleCapCheck(const char * networkId)255 static int32_t BleCapCheck(const char *networkId)
256 {
257 uint32_t local;
258 uint32_t remote;
259 if (!GetNetCap(networkId, &local, &remote)) {
260 LNN_LOGE(LNN_LANE, "GetNetCap error");
261 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
262 }
263 if (((local & (1 << BIT_BLE)) == 0) || ((remote & (1 << BIT_BLE)) == 0)) {
264 LNN_LOGE(LNN_LANE, "ble capa disable, local=%{public}u, remote=%{public}u", local, remote);
265 return ((local & (1 << BIT_BLE)) == 0) ? SOFTBUS_LANE_LOCAL_NO_BLE_CAP : SOFTBUS_LANE_REMOTE_NO_BLE_CAP;
266 }
267 return SOFTBUS_OK;
268 }
269
BleDirectCapCheck(const char * networkId)270 static int32_t BleDirectCapCheck(const char *networkId)
271 {
272 int32_t ret = BleCapCheck(networkId);
273 if (ret != SOFTBUS_OK) {
274 LNN_LOGE(LNN_LANE, "ble is not enable");
275 return ret;
276 }
277
278 uint64_t local;
279 uint64_t remote;
280 if (!GetFeatureCap(networkId, &local, &remote)) {
281 LNN_LOGE(LNN_LANE, "GetFeatureCap error");
282 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
283 }
284 if (((local & (1 << BIT_BLE_DIRECT_CONNECT_CAPABILITY)) == 0) ||
285 ((remote & (1 << BIT_BLE_DIRECT_CONNECT_CAPABILITY)) == 0)) {
286 LNN_LOGE(LNN_LANE, "ble direct capa disable, local=%{public}" PRIu64 ", remote=%{public}" PRIu64,
287 local, remote);
288 return ((local & (1 << BIT_BLE_DIRECT_CONNECT_CAPABILITY)) == 0) ?
289 SOFTBUS_LANE_LOCAL_NO_BLE_DIRECT_CAP : SOFTBUS_LANE_REMOTE_NO_BLE_DIRECT_CAP;
290 }
291 return SOFTBUS_OK;
292 }
293
CocCapCheck(const char * networkId)294 static int32_t CocCapCheck(const char *networkId)
295 {
296 int32_t ret = BleCapCheck(networkId);
297 if (ret != SOFTBUS_OK) {
298 LNN_LOGE(LNN_LANE, "ble is not enable");
299 return ret;
300 }
301 uint64_t local;
302 uint64_t remote;
303 if (!GetFeatureCap(networkId, &local, &remote)) {
304 LNN_LOGE(LNN_LANE, "GetFeatureCap error");
305 return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
306 }
307 if (((local & (1 << BIT_COC_CONNECT_CAPABILITY)) == 0) || ((remote & (1 << BIT_COC_CONNECT_CAPABILITY)) == 0)) {
308 LNN_LOGE(LNN_LANE, "coc capa disable, local=%{public}" PRIu64 ", remote=%{public}" PRIu64,
309 local, remote);
310 return ((local & (1 << BIT_COC_CONNECT_CAPABILITY)) == 0) ?
311 SOFTBUS_LANE_LOCAL_NO_COC_CAP : SOFTBUS_LANE_REMOTE_NO_COC_CAP;
312 }
313 return SOFTBUS_OK;
314 }
315
CocDirectCapCheck(const char * networkId)316 static int32_t CocDirectCapCheck(const char *networkId)
317 {
318 int32_t ret = CocCapCheck(networkId);
319 if (ret != SOFTBUS_OK) {
320 LNN_LOGE(LNN_LANE, "coc is not enable");
321 return ret;
322 }
323 ret = BleDirectCapCheck(networkId);
324 if (ret != SOFTBUS_OK) {
325 LNN_LOGE(LNN_LANE, "ble direct is not enable");
326 return ret;
327 }
328 return SOFTBUS_OK;
329 }
330
GetBrScore(const char * networkId,uint32_t expectedBw)331 static int32_t GetBrScore(const char *networkId, uint32_t expectedBw)
332 {
333 (void)networkId;
334 (void)expectedBw;
335 return LNN_LINK_DEFAULT_SCORE;
336 }
337
GetBleScore(const char * networkId,uint32_t expectedBw)338 static int32_t GetBleScore(const char *networkId, uint32_t expectedBw)
339 {
340 (void)networkId;
341 (void)expectedBw;
342 return LNN_LINK_DEFAULT_SCORE;
343 }
344
GetP2pScore(const char * networkId,uint32_t expectedBw)345 static int32_t GetP2pScore(const char *networkId, uint32_t expectedBw)
346 {
347 (void)networkId;
348 (void)expectedBw;
349 return LNN_LINK_DEFAULT_SCORE;
350 }
351
GetHmlScore(const char * networkId,uint32_t expectedBw)352 static int32_t GetHmlScore(const char *networkId, uint32_t expectedBw)
353 {
354 (void)networkId;
355 (void)expectedBw;
356 return LNN_LINK_DEFAULT_SCORE;
357 }
358
359
GetLinkedChannelScore(void)360 static int32_t GetLinkedChannelScore(void)
361 {
362 int32_t frequency = GetWlanLinkedFrequency();
363 if (frequency <= 0) {
364 return LNN_LINK_DEFAULT_SCORE;
365 }
366 int32_t channel = SoftBusFrequencyToChannel(frequency);
367 if (channel < 0) {
368 LNN_LOGE(LNN_LANE, "get curr channel fail");
369 return LNN_LINK_DEFAULT_SCORE;
370 }
371 int32_t score = LnnGetCurrChannelScore(channel);
372 LNN_LOGI(LNN_LANE, "current channel=%{public}d, score=%{public}d", channel, score);
373 if (score <= 0) {
374 score = LNN_LINK_DEFAULT_SCORE;
375 }
376 return score;
377 }
378
GetWlan2P4GScore(const char * networkId,uint32_t expectedBw)379 static int32_t GetWlan2P4GScore(const char *networkId, uint32_t expectedBw)
380 {
381 (void)networkId;
382 (void)expectedBw;
383 return GetLinkedChannelScore();
384 }
385
GetWlan5GScore(const char * networkId,uint32_t expectedBw)386 static int32_t GetWlan5GScore(const char *networkId, uint32_t expectedBw)
387 {
388 (void)networkId;
389 (void)expectedBw;
390 return GetLinkedChannelScore();
391 }
392
GetCocScore(const char * networkId,uint32_t expectedBw)393 static int32_t GetCocScore(const char *networkId, uint32_t expectedBw)
394 {
395 (void)networkId;
396 (void)expectedBw;
397 return LNN_LINK_DEFAULT_SCORE;
398 }
399
400 static LinkAttribute g_linkAttr[LANE_LINK_TYPE_BUTT] = {
401 [LANE_BR] = {true, BrCapCheck, GetBrScore },
402 [LANE_BLE] = { true, BleCapCheck, GetBleScore },
403 [LANE_P2P] = { true, P2pCapCheck, GetP2pScore },
404 [LANE_HML] = { true, HmlCapCheck, GetHmlScore },
405 [LANE_WLAN_2P4G] = { true, Wlan2P4GCapCheck, GetWlan2P4GScore},
406 [LANE_WLAN_5G] = { true, Wlan5GCapCheck, GetWlan5GScore },
407 [LANE_ETH] = { false, NULL, NULL },
408 [LANE_P2P_REUSE] = { true, P2pReuseCapCheck, GetP2pScore },
409 [LANE_BLE_DIRECT] = { true, BleDirectCapCheck, GetBleScore },
410 [LANE_BLE_REUSE] = { false, NULL, NULL },
411 [LANE_COC] = { true, CocCapCheck, GetCocScore },
412 [LANE_COC_DIRECT] = { true, CocDirectCapCheck, GetCocScore },
413 };
414
GetLinkAttrByLinkType(LaneLinkType linkType)415 LinkAttribute *GetLinkAttrByLinkType(LaneLinkType linkType)
416 {
417 if ((linkType < 0) || (linkType >= LANE_LINK_TYPE_BUTT)) {
418 return NULL;
419 }
420 return &g_linkAttr[linkType];
421 }
422
423 static uint32_t g_laneBandWidth[BW_TYPE_BUTT][LANE_LINK_TYPE_BUTT + 1] = {
424 [HIGH_BAND_WIDTH] = {LANE_HML, LANE_P2P, LANE_LINK_TYPE_BUTT},
425 [MIDDLE_HIGH_BAND_WIDTH] = {LANE_HML, LANE_WLAN_5G, LANE_LINK_TYPE_BUTT},
426 [MIDDLE_LOW_BAND_WIDTH] = {LANE_WLAN_5G, LANE_HML, LANE_WLAN_2P4G, LANE_LINK_TYPE_BUTT},
427 [LOW_BAND_WIDTH] = {LANE_WLAN_5G, LANE_WLAN_2P4G, LANE_HML, LANE_LINK_TYPE_BUTT},
428 };
429
430 static uint32_t g_retryLaneList[BW_TYPE_BUTT][LANE_LINK_TYPE_BUTT + 1] = {
431 [HIGH_BAND_WIDTH] = {LANE_HML, LANE_P2P, LANE_WLAN_5G, LANE_WLAN_2P4G, LANE_LINK_TYPE_BUTT},
432 [MIDDLE_HIGH_BAND_WIDTH] = {LANE_HML, LANE_WLAN_5G, LANE_WLAN_2P4G, LANE_P2P,
433 LANE_LINK_TYPE_BUTT},
434 [MIDDLE_LOW_BAND_WIDTH] = {LANE_WLAN_5G, LANE_HML, LANE_WLAN_2P4G, LANE_P2P,
435 LANE_LINK_TYPE_BUTT},
436 [LOW_BAND_WIDTH] = {LANE_WLAN_5G, LANE_WLAN_2P4G, LANE_HML, LANE_BR, LANE_P2P,
437 LANE_COC_DIRECT, LANE_BLE, LANE_LINK_TYPE_BUTT},
438 };
439
IsLinkTypeValid(LaneLinkType type)440 static bool IsLinkTypeValid(LaneLinkType type)
441 {
442 if ((type < 0) || (type >= LANE_LINK_TYPE_BUTT)) {
443 return false;
444 }
445 return true;
446 }
447
CheckLaneValid(const char * networkId,LaneLinkType linkType,LaneTransType transType)448 static int32_t CheckLaneValid(const char *networkId, LaneLinkType linkType, LaneTransType transType)
449 {
450 if (!IsLinkTypeValid(linkType)) {
451 return SOFTBUS_INVALID_PARAM;
452 }
453 LinkAttribute *linkAttr = GetLinkAttrByLinkType(linkType);
454 if ((linkAttr == NULL) || (!linkAttr->available)) {
455 return SOFTBUS_INVALID_PARAM;
456 }
457 int32_t ret = linkAttr->linkCapCheck(networkId);
458 if (ret != SOFTBUS_OK) {
459 LNN_LOGE(LNN_LANE, "link capacity is not support. linkType=%{public}d", linkType);
460 return ret;
461 }
462 bool isStream = (transType == LANE_T_RAW_STREAM || transType == LANE_T_COMMON_VIDEO ||
463 transType == LANE_T_COMMON_VOICE);
464 bool isBt = (linkType == LANE_BR || linkType == LANE_BLE || linkType == LANE_BLE_DIRECT ||
465 linkType == LANE_BLE_REUSE || linkType == LANE_COC || linkType == LANE_COC_DIRECT);
466 if (isStream && isBt) {
467 LNN_LOGE(LNN_LANE, "Bt not support stream datatype, link=%{public}d", linkType);
468 return SOFTBUS_INVALID_PARAM;
469 }
470 return SOFTBUS_OK;
471 }
472
GetBwType(uint32_t bandWidth)473 static int32_t GetBwType(uint32_t bandWidth)
474 {
475 int32_t bandWidthType;
476 if (bandWidth >= HIGH_BW) {
477 bandWidthType = HIGH_BAND_WIDTH;
478 } else if (bandWidth > MID_BW) {
479 bandWidthType = MIDDLE_HIGH_BAND_WIDTH;
480 } else if (bandWidth > LOW_BW) {
481 bandWidthType = MIDDLE_LOW_BAND_WIDTH;
482 } else {
483 bandWidthType = LOW_BAND_WIDTH;
484 }
485 return bandWidthType;
486 }
487
DecideOptimalLinks(const char * networkId,const LaneSelectParam * request,LaneLinkType * linkList,uint32_t * linksNum)488 static void DecideOptimalLinks(const char *networkId, const LaneSelectParam *request,
489 LaneLinkType *linkList, uint32_t *linksNum)
490 {
491 uint32_t minBandWidth = request->qosRequire.minBW;
492 uint32_t minLaneLatency = request->qosRequire.minLaneLatency;
493 if (minLaneLatency == 0) {
494 LNN_LOGI(LNN_LANE, "minLaneLatency is zero, cancel decide optimal link");
495 return;
496 }
497 int32_t bandWidthType = GetBwType(minBandWidth);
498 LNN_LOGI(LNN_LANE,
499 "decide optimal link, bandWidthType=%{public}d, minLaneLatency=%{public}d", bandWidthType, minLaneLatency);
500 for (uint32_t i = 0; i < (LANE_LINK_TYPE_BUTT + 1); i++) {
501 if (g_laneBandWidth[bandWidthType][i] == LANE_LINK_TYPE_BUTT) {
502 break;
503 }
504 if ((CheckLaneValid(networkId, g_laneBandWidth[bandWidthType][i], request->transType) == SOFTBUS_OK)) {
505 linkList[(*linksNum)++] = g_laneBandWidth[bandWidthType][i];
506 LNN_LOGI(LNN_LANE, "decide optimal linkType=%{public}d", g_laneBandWidth[bandWidthType][i]);
507 continue;
508 }
509 }
510 LNN_LOGI(LNN_LANE, "decide optimal links num=%{public}d", *linksNum);
511 }
512
IsLaneExist(LaneLinkType * linkList,LaneLinkType linkType)513 static bool IsLaneExist(LaneLinkType *linkList, LaneLinkType linkType)
514 {
515 for (int i = 0; i < LANE_LINK_TYPE_BUTT; i++) {
516 if (linkList[i] == linkType) {
517 return true;
518 }
519 }
520 return false;
521 }
522
DecideRetryLinks(const char * networkId,const LaneSelectParam * request,LaneLinkType * linkList,uint32_t * linksNum)523 static void DecideRetryLinks(const char *networkId, const LaneSelectParam *request,
524 LaneLinkType *linkList, uint32_t *linksNum)
525 {
526 uint32_t minBandWidth = request->qosRequire.minBW;
527 int32_t bandWidthType = GetBwType(minBandWidth);
528 for (uint32_t i = 0; i < (LANE_LINK_TYPE_BUTT + 1); i++) {
529 if (g_retryLaneList[bandWidthType][i] == LANE_LINK_TYPE_BUTT) {
530 break;
531 }
532 if ((CheckLaneValid(networkId, g_retryLaneList[bandWidthType][i], request->transType) == SOFTBUS_OK) &&
533 !IsLaneExist(linkList, g_retryLaneList[bandWidthType][i])) {
534 linkList[(*linksNum)++] = g_retryLaneList[bandWidthType][i];
535 LNN_LOGI(LNN_LANE, "decide retry linkType=%{public}d", g_retryLaneList[bandWidthType][i]);
536 }
537 }
538 }
539
IsSupportWifiDirect(const char * networkId)540 static bool IsSupportWifiDirect(const char *networkId)
541 {
542 uint64_t localFeature = 0;
543 uint64_t remoteFeature = 0;
544 bool isFound = GetFeatureCap(networkId, &localFeature, &remoteFeature);
545 if (!isFound) {
546 LNN_LOGE(LNN_LANE, "getFeature fail");
547 return false;
548 }
549 if (((localFeature & (1 << BIT_BLE_TRIGGER_CONNECTION)) == 0) ||
550 ((remoteFeature & (1 << BIT_BLE_TRIGGER_CONNECTION)) == 0)) {
551 LNN_LOGE(LNN_LANE, "local=%{public}" PRIu64 ", remote=%{public}" PRIu64, localFeature, remoteFeature);
552 return false;
553 }
554 return true;
555 }
556
FilterWifiDirectLink(const char * peerNetWorkId,uint32_t bandWidth,LaneLinkType * linkList,uint32_t * linksNum)557 static void FilterWifiDirectLink(const char *peerNetWorkId, uint32_t bandWidth,
558 LaneLinkType *linkList, uint32_t *linksNum)
559 {
560 if (GetBwType(bandWidth) != LOW_BAND_WIDTH) {
561 return;
562 }
563 int32_t osType = 0;
564 if (LnnGetOsTypeByNetworkId(peerNetWorkId, &osType) != SOFTBUS_OK) {
565 LNN_LOGE(LNN_LANE, "get remote osType fail");
566 return;
567 }
568 if (osType == OH_OS_TYPE || IsSupportWifiDirect(peerNetWorkId)) {
569 LNN_LOGI(LNN_LANE, "valid wifiDirect, no need filter link");
570 return;
571 }
572 LNN_LOGI(LNN_LANE, "low bandWidth and not support wifiDirect, filter wifiDirect link");
573 LaneLinkType tmpList[LANE_LINK_TYPE_BUTT] = {0};
574 uint32_t num = 0;
575 for (uint32_t i = 0; i < *linksNum; i++) {
576 if (linkList[i] != LANE_HML) {
577 tmpList[num++] = linkList[i];
578 }
579 }
580 uint32_t size = sizeof(LaneLinkType) * LANE_LINK_TYPE_BUTT;
581 (void)memset_s(linkList, size, -1, size);
582 *linksNum = num;
583 for (uint32_t i = 0; i < *linksNum; i++) {
584 linkList[i] = tmpList[i];
585 }
586 }
587
UpdateHmlPriority(const char * peerNetWorkId,const LaneSelectParam * request,LaneLinkType * linkList,uint32_t * linksNum)588 static void UpdateHmlPriority(const char *peerNetWorkId, const LaneSelectParam *request,
589 LaneLinkType *linkList, uint32_t *linksNum)
590 {
591 if (*linksNum > LANE_LINK_TYPE_BUTT) {
592 LNN_LOGE(LNN_LANE, "link num exceed lisk list");
593 return;
594 }
595 char peerUdid[UDID_BUF_LEN] = {0};
596 if (LnnGetRemoteStrInfo(peerNetWorkId, STRING_KEY_DEV_UDID, peerUdid, UDID_BUF_LEN) != SOFTBUS_OK) {
597 LNN_LOGE(LNN_LANE, "get udid error");
598 return;
599 }
600 FilterWifiDirectLink(peerNetWorkId, request->qosRequire.minBW, linkList, linksNum);
601 LaneResource resourceItem;
602 (void)memset_s(&resourceItem, sizeof(LaneResource), 0, sizeof(LaneResource));
603 if (FindLaneResourceByLinkType(peerUdid, LANE_HML, &resourceItem) != SOFTBUS_OK ||
604 (CheckLaneValid(peerNetWorkId, LANE_HML, request->transType) != SOFTBUS_OK)) {
605 LNN_LOGE(LNN_LANE, "hml not support reuse");
606 return;
607 }
608 LNN_LOGI(LNN_LANE, "hml exist reuse laneId=%{public}" PRIu64 ", update priority", resourceItem.laneId);
609 LaneLinkType tmpList[LANE_LINK_TYPE_BUTT] = {0};
610 uint32_t num = 0;
611 tmpList[num++] = LANE_HML;
612 for (uint32_t i = 0; i < *linksNum; i++) {
613 if (linkList[i] != LANE_HML) {
614 tmpList[num++] = linkList[i];
615 }
616 }
617 uint32_t size = sizeof(LaneLinkType) * LANE_LINK_TYPE_BUTT;
618 (void)memset_s(linkList, size, -1, size);
619 *linksNum = num;
620 for (uint32_t i = 0; i < *linksNum; i++) {
621 linkList[i] = tmpList[i];
622 }
623 }
624
DelHasAllocedLink(uint64_t allocedLaneId,LaneLinkType * linkList,uint32_t * linksNum)625 static void DelHasAllocedLink(uint64_t allocedLaneId, LaneLinkType *linkList, uint32_t *linksNum)
626 {
627 LaneResource resourceItem;
628 (void)memset_s(&resourceItem, sizeof(LaneResource), 0, sizeof(LaneResource));
629 if (FindLaneResourceByLaneId(allocedLaneId, &resourceItem) != SOFTBUS_OK) {
630 LNN_LOGE(LNN_LANE, "invalid allocedLaneId=%{public}" PRIu64 "", allocedLaneId);
631 return;
632 }
633 uint32_t num = 0;
634 LaneLinkType tmpList[LANE_LINK_TYPE_BUTT] = {0};
635 if (*linksNum > LANE_LINK_TYPE_BUTT) {
636 LNN_LOGE(LNN_LANE, "link num exceed lisk list");
637 return;
638 }
639 for (uint32_t i = 0; i < *linksNum; i++) {
640 if (linkList[i] != resourceItem.link.type) {
641 tmpList[num++] = linkList[i];
642 }
643 }
644 uint32_t size = sizeof(LaneLinkType) * LANE_LINK_TYPE_BUTT;
645 (void)memset_s(linkList, size, -1, size);
646 *linksNum = num;
647 for (uint32_t i = 0; i < *linksNum; i++) {
648 linkList[i] = tmpList[i];
649 }
650 }
651
FinalDecideLinkType(const char * networkId,LaneLinkType * linkList,uint32_t listNum,LanePreferredLinkList * recommendList)652 int32_t FinalDecideLinkType(const char *networkId, LaneLinkType *linkList,
653 uint32_t listNum, LanePreferredLinkList *recommendList)
654 {
655 if (networkId == NULL || linkList == NULL || recommendList == NULL) {
656 LNN_LOGE(LNN_LANE, "invalid param");
657 return SOFTBUS_INVALID_PARAM;
658 }
659 if (listNum >= LANE_LINK_TYPE_BUTT) {
660 LNN_LOGE(LNN_LANE, "linkList size exceed limit, size=%{public}d", listNum);
661 return SOFTBUS_INVALID_PARAM;
662 }
663 bool isFilterP2p = IsSupportWifiDirect(networkId);
664 uint32_t availableLinkNums = 0;
665 for (uint32_t i = 0; i < listNum; i++) {
666 if (isFilterP2p && linkList[i] == LANE_P2P) {
667 LNN_LOGI(LNN_LANE, "p2pLink is filtered");
668 continue;
669 }
670 recommendList->linkType[availableLinkNums++] = linkList[i];
671 }
672 recommendList->linkTypeNum = availableLinkNums;
673 if (availableLinkNums == 0) {
674 LNN_LOGE(LNN_LANE, "not available link");
675 return SOFTBUS_LANE_NO_AVAILABLE_LINK;
676 }
677 return SOFTBUS_OK;
678 }
679
GetErrCodeOfRequest(const char * networkId,const LaneSelectParam * request)680 static int32_t GetErrCodeOfRequest(const char *networkId, const LaneSelectParam *request)
681 {
682 SoftBusWifiDetailState wifiState = SoftBusGetWifiState();
683 if (wifiState == SOFTBUS_WIFI_STATE_INACTIVE || wifiState == SOFTBUS_WIFI_STATE_DEACTIVATING) {
684 return SOFTBUS_LANE_WIFI_OFF;
685 }
686 int32_t bandWidthType = GetBwType(request->qosRequire.minBW);
687 return CheckLaneValid(networkId, g_laneBandWidth[bandWidthType][0], request->transType);
688 }
689
DecideAvailableLane(const char * networkId,const LaneSelectParam * request,LanePreferredLinkList * recommendList)690 int32_t DecideAvailableLane(const char *networkId, const LaneSelectParam *request, LanePreferredLinkList *recommendList)
691 {
692 if (request == NULL || recommendList == NULL) {
693 return SOFTBUS_INVALID_PARAM;
694 }
695 LaneLinkType linkList[LANE_LINK_TYPE_BUTT];
696 (void)memset_s(linkList, sizeof(linkList), -1, sizeof(linkList));
697 uint32_t linksNum = 0;
698 DecideOptimalLinks(networkId, request, linkList, &linksNum);
699 DecideRetryLinks(networkId, request, linkList, &linksNum);
700 UpdateHmlPriority(networkId, request, linkList, &linksNum);
701 if (request->allocedLaneId != INVALID_LANE_ID) {
702 DelHasAllocedLink(request->allocedLaneId, linkList, &linksNum);
703 }
704 int32_t ret = FinalDecideLinkType(networkId, linkList, linksNum, recommendList);
705 if (recommendList->linkTypeNum == 0) {
706 LNN_LOGE(LNN_LANE, "there is none linkResource can be used");
707 return GetErrCodeOfRequest(networkId, request);
708 }
709 return ret;
710 }
711