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