• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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_query.h"
17 
18 #include <securec.h>
19 #include "bus_center_info_key.h"
20 #include "bus_center_manager.h"
21 #include "lnn_distributed_net_ledger.h"
22 #include "lnn_feature_capability.h"
23 #include "lnn_lane_communication_capability.h"
24 #include "lnn_local_net_ledger.h"
25 #include "lnn_log.h"
26 #include "lnn_lane_link.h"
27 #include "softbus_bus_center.h"
28 #include "softbus_error_code.h"
29 #include "softbus_wifi_api_adapter.h"
30 #include "wifi_direct_manager.h"
31 
32 #define QOS_MIN_BANDWIDTH (384 * 1024)
33 #define QOS_P2P_ONLY_BANDWIDTH (160 * 1024 * 1024)
34 
35 typedef struct {
36     bool available;
37     int32_t (*QueryLink)(const char *networkId);
38 } LinkState;
39 
GetFileLaneLink(LaneLinkType * linkList,uint32_t * listNum,bool isHighBand)40 static void GetFileLaneLink(LaneLinkType *linkList, uint32_t *listNum, bool isHighBand)
41 {
42     linkList[(*listNum)++] = LANE_HML;
43     linkList[(*listNum)++] = LANE_WLAN_5G;
44     linkList[(*listNum)++] = LANE_WLAN_2P4G;
45     linkList[(*listNum)++] = LANE_P2P;
46     if (!isHighBand) {
47         linkList[(*listNum)++] = LANE_BR;
48     }
49 }
50 
GetStreamLaneLink(LaneLinkType * linkList,uint32_t * listNum,bool isHighBand)51 static void GetStreamLaneLink(LaneLinkType *linkList, uint32_t *listNum, bool isHighBand)
52 {
53     linkList[(*listNum)++] = LANE_HML;
54     linkList[(*listNum)++] = LANE_WLAN_5G;
55     linkList[(*listNum)++] = LANE_WLAN_2P4G;
56     linkList[(*listNum)++] = LANE_P2P;
57 }
58 
GetMsgLaneLink(LaneLinkType * linkList,uint32_t * listNum,bool isHighBand)59 static void GetMsgLaneLink(LaneLinkType *linkList, uint32_t *listNum, bool isHighBand)
60 {
61     linkList[(*listNum)++] = LANE_HML;
62     linkList[(*listNum)++] = LANE_WLAN_5G;
63     linkList[(*listNum)++] = LANE_WLAN_2P4G;
64     linkList[(*listNum)++] = LANE_P2P;
65     if (!isHighBand) {
66         linkList[(*listNum)++] = LANE_BLE;
67         linkList[(*listNum)++] = LANE_BR;
68     }
69 }
70 
GetBytesLaneLink(LaneLinkType * linkList,uint32_t * listNum,bool isHighBand)71 static void GetBytesLaneLink(LaneLinkType *linkList, uint32_t *listNum, bool isHighBand)
72 {
73     linkList[(*listNum)++] = LANE_HML;
74     linkList[(*listNum)++] = LANE_WLAN_5G;
75     linkList[(*listNum)++] = LANE_WLAN_2P4G;
76     linkList[(*listNum)++] = LANE_P2P;
77     if (!isHighBand) {
78         linkList[(*listNum)++] = LANE_BLE;
79         linkList[(*listNum)++] = LANE_BR;
80     }
81 }
82 
GetLaneResource(LaneTransType transType,LaneLinkType * optLink,uint32_t * linkNum,bool isHighBand)83 static int32_t GetLaneResource(LaneTransType transType, LaneLinkType *optLink, uint32_t *linkNum,
84     bool isHighBand)
85 {
86     LaneLinkType defaultLink[LANE_LINK_TYPE_BUTT];
87     (void)memset_s(defaultLink, sizeof(defaultLink), -1, sizeof(defaultLink));
88     uint32_t optLinkMaxNum = *linkNum;
89     uint32_t index = 0;
90     switch (transType) {
91         case LANE_T_MSG:
92             GetMsgLaneLink(defaultLink, &index, isHighBand);
93             break;
94         case LANE_T_BYTE:
95             GetBytesLaneLink(defaultLink, &index, isHighBand);
96             break;
97         case LANE_T_FILE:
98             GetFileLaneLink(defaultLink, &index, isHighBand);
99             break;
100         case LANE_T_RAW_STREAM:
101         case LANE_T_COMMON_VIDEO:
102         case LANE_T_COMMON_VOICE:
103             GetStreamLaneLink(defaultLink, &index, isHighBand);
104             break;
105         default:
106             LNN_LOGE(LNN_LANE, "lane type is not supported, transType=%{public}d", transType);
107             return SOFTBUS_INVALID_PARAM;
108     }
109     *linkNum = 0;
110     if (memcpy_s(optLink, optLinkMaxNum * sizeof(LaneLinkType), defaultLink, sizeof(defaultLink)) != EOK) {
111         LNN_LOGE(LNN_LANE, "memcpy default linkList to optinal fail");
112         return SOFTBUS_MEM_ERR;
113     }
114     *linkNum = index;
115     return SOFTBUS_OK;
116 }
117 
GetNetCap(const char * networkId,uint32_t * local,uint32_t * remote)118 static bool GetNetCap(const char *networkId, uint32_t *local, uint32_t *remote)
119 {
120     int32_t ret = LnnGetLocalNumU32Info(NUM_KEY_NET_CAP, local);
121     if (ret != SOFTBUS_OK) {
122         LNN_LOGE(LNN_LANE, "LnnGetLocalNumInfo err, ret=%{public}d", ret);
123         return false;
124     }
125     ret = LnnGetRemoteNumU32Info(networkId, NUM_KEY_NET_CAP, remote);
126     if (ret != SOFTBUS_OK) {
127         LNN_LOGE(LNN_LANE, "LnnGetRemoteNumInfo err, ret=%{public}d", ret);
128         return false;
129     }
130     return true;
131 }
132 
BrLinkState(const char * networkId)133 static int32_t BrLinkState(const char *networkId)
134 {
135     uint32_t local = 0;
136     uint32_t remote = 0;
137     if (!GetNetCap(networkId, &local, &remote)) {
138         LNN_LOGE(LNN_LANE, "GetNetCap error");
139         return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
140     }
141     if (!(local & (1 << BIT_BR))) {
142         LNN_LOGE(LNN_LANE, "local bluetooth close, local=%{public}u", local);
143         return SOFTBUS_BLUETOOTH_OFF;
144     }
145     if (!(remote & (1 << BIT_BR))) {
146         LNN_LOGE(LNN_LANE, "remote bluetooth close, remote=%{public}u", remote);
147         return SOFTBUS_BLUETOOTH_OFF;
148     }
149     LNN_LOGI(LNN_LANE, "br link ok, local=%{public}u, remote=%{public}u", local, remote);
150     return SOFTBUS_OK;
151 }
152 
BleLinkState(const char * networkId)153 static int32_t BleLinkState(const char *networkId)
154 {
155     uint32_t local = 0;
156     uint32_t remote = 0;
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_BLE))) {
162         LNN_LOGE(LNN_LANE, "local bluetooth close, local=%{public}u", local);
163         return SOFTBUS_BLUETOOTH_OFF;
164     }
165     if (!(remote & (1 << BIT_BLE))) {
166         LNN_LOGE(LNN_LANE, "remote bluetooth close, remote=%{public}u", remote);
167         return SOFTBUS_BLUETOOTH_OFF;
168     }
169     LNN_LOGI(LNN_LANE, "ble link ok, local=%{public}u, remote=%{public}u", local, remote);
170     return SOFTBUS_OK;
171 }
172 
WlanLinkState(const char * networkId)173 static int32_t WlanLinkState(const char *networkId)
174 {
175     if (!SoftBusIsWifiActive()) {
176         return SOFTBUS_WIFI_OFF;
177     }
178     NodeInfo node;
179     (void)memset_s(&node, sizeof(NodeInfo), 0, sizeof(NodeInfo));
180     if (LnnGetRemoteNodeInfoById(networkId, CATEGORY_NETWORK_ID, &node) != SOFTBUS_OK) {
181         LNN_LOGE(LNN_LANE, "get remote node info fail");
182         return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
183     }
184     if (!LnnHasDiscoveryType(&node, DISCOVERY_TYPE_WIFI) && !LnnHasDiscoveryType(&node, DISCOVERY_TYPE_LSA)) {
185         LNN_LOGE(LNN_LANE, "peer node not wifi online");
186         return SOFTBUS_NETWORK_NODE_OFFLINE;
187     }
188     uint32_t local = 0;
189     uint32_t remote = 0;
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))) {
195         LNN_LOGE(LNN_LANE, "local wifi close, local=%{public}u", local);
196         return SOFTBUS_WIFI_DISCONNECT;
197     }
198     if (!(remote & (1 << BIT_WIFI))) {
199         LNN_LOGE(LNN_LANE, "remote wifi close, remote=%{public}u", remote);
200         return SOFTBUS_WIFI_DISCONNECT;
201     }
202     LNN_LOGI(LNN_LANE, "wifi link ok, local=%{public}u, remote=%{public}u", local, remote);
203     return SOFTBUS_OK;
204 }
205 
P2pLinkState(const char * networkId)206 static int32_t P2pLinkState(const char *networkId)
207 {
208     struct WifiDirectManager *pManager = GetWifiDirectManager();
209     if (pManager == NULL) {
210         LNN_LOGE(LNN_LANE, "not support wifi direct");
211         return SOFTBUS_P2P_NOT_SUPPORT;
212     }
213     SoftBusWifiDetailState wifiState = SoftBusGetWifiState();
214     if (wifiState == SOFTBUS_WIFI_STATE_INACTIVE || wifiState == SOFTBUS_WIFI_STATE_DEACTIVATING) {
215         return SOFTBUS_WIFI_OFF;
216     }
217     uint32_t local = 0;
218     uint32_t remote = 0;
219     if (!GetNetCap(networkId, &local, &remote)) {
220         LNN_LOGE(LNN_LANE, "GetNetCap error");
221         return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
222     }
223     if (((local & (1 << BIT_WIFI_P2P)) == 0) || ((remote & (1 << BIT_WIFI_P2P)) == 0)) {
224         LNN_LOGE(LNN_LANE, "p2p capa disable, local=%{public}u, remote=%{public}u", local, remote);
225         return SOFTBUS_P2P_NOT_SUPPORT;
226     }
227     int32_t ret = pManager->prejudgeAvailability(networkId, WIFI_DIRECT_LINK_TYPE_P2P);
228     if (ret == V1_ERROR_GC_CONNECTED_TO_ANOTHER_DEVICE) {
229         return SOFTBUS_P2P_ROLE_CONFLICT;
230     }
231     return ret;
232 }
233 
HmlLinkState(const char * networkId)234 static int32_t HmlLinkState(const char *networkId)
235 {
236     struct WifiDirectManager *pManager = GetWifiDirectManager();
237     if (pManager == NULL) {
238         LNN_LOGE(LNN_LANE, "not support wifi direct");
239         return SOFTBUS_HML_NOT_SUPPORT;
240     }
241     SoftBusWifiDetailState wifiState = SoftBusGetWifiState();
242     if (wifiState == SOFTBUS_WIFI_STATE_INACTIVE || wifiState == SOFTBUS_WIFI_STATE_DEACTIVATING) {
243         return SOFTBUS_WIFI_OFF;
244     }
245     uint64_t feature = LnnGetFeatureCapabilty();
246     if (!IsFeatureSupport(feature, BIT_WIFI_DIRECT_TLV_NEGOTIATION)) {
247         LNN_LOGE(LNN_LANE, "local feature not supported");
248         return SOFTBUS_HML_NOT_SUPPORT;
249     }
250     bool result = false;
251     if (LnnGetRemoteBoolInfo(networkId, BOOL_KEY_TLV_NEGOTIATION, &result) != SOFTBUS_OK) {
252         LNN_LOGE(LNN_LANE, "get remote feature failed");
253         return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
254     }
255     if (!result) {
256         LNN_LOGE(LNN_LANE, "remote feature not supported");
257         return SOFTBUS_HML_NOT_SUPPORT;
258     }
259     int32_t ret = pManager->prejudgeAvailability(networkId, WIFI_DIRECT_LINK_TYPE_HML);
260     if (ret == ERROR_LOCAL_THREE_VAP_CONFLICT) {
261         return SOFTBUS_HML_THREE_VAP_CONFLIC;
262     }
263     return ret;
264 }
265 
UsbLinkState(const char * networkId)266 static int32_t UsbLinkState(const char *networkId)
267 {
268     NodeInfo node;
269     (void)memset_s(&node, sizeof(NodeInfo), 0, sizeof(NodeInfo));
270     if (LnnGetRemoteNodeInfoById(networkId, CATEGORY_NETWORK_ID, &node) != SOFTBUS_OK) {
271         LNN_LOGE(LNN_LANE, "get remote node info fail");
272         return SOFTBUS_LANE_GET_LEDGER_INFO_ERR;
273     }
274     if (!LnnHasDiscoveryType(&node, DISCOVERY_TYPE_USB)) {
275         LNN_LOGE(LNN_LANE, "peer node not USB online");
276         return SOFTBUS_NETWORK_NODE_OFFLINE;
277     }
278 
279     int32_t ret = CheckStaticNetCap(networkId, LANE_USB);
280     if (ret != SOFTBUS_OK) {
281         LNN_LOGE(LNN_LANE, "check static capability fail, errorCode: %{public}d", ret);
282         return ret;
283     }
284 
285     ret = CheckDynamicNetCap(networkId, LANE_USB);
286     if (ret != SOFTBUS_OK) {
287         LNN_LOGE(LNN_LANE, "check dynamic capability fail, errorCode: %{public}d", ret);
288         return ret;
289     }
290     LNN_LOGI(LNN_LANE, "usb link ok");
291     return SOFTBUS_OK;
292 }
293 
294 static LinkState g_linkState[LANE_LINK_TYPE_BUTT] = {
295     [LANE_BR] = {true,   BrLinkState},
296     [LANE_BLE] = { true,   BleLinkState},
297     [LANE_WLAN_2P4G] = { true,   WlanLinkState},
298     [LANE_WLAN_5G] = { true,   WlanLinkState},
299     [LANE_P2P] = { true,   P2pLinkState},
300     [LANE_HML] = { true,   HmlLinkState},
301     [LANE_USB] = { true,   UsbLinkState},
302 };
303 
IsValidLaneLink(const char * networkId,LaneLinkType linkType)304 static int32_t IsValidLaneLink(const char *networkId, LaneLinkType linkType)
305 {
306     if ((linkType < 0) || (linkType >= LANE_LINK_TYPE_BUTT)) {
307         LNN_LOGE(LNN_LANE, "invalid linkType=%{public}d", linkType);
308         return SOFTBUS_INVALID_PARAM;
309     }
310     if (!g_linkState[linkType].available) {
311         LNN_LOGE(LNN_LANE, "invalid QueryLink, linkType=%{public}d", linkType);
312         return SOFTBUS_INVALID_PARAM;
313     }
314     if (g_linkState[linkType].QueryLink == NULL) {
315         LNN_LOGE(LNN_LANE, "invalid QueryLink, linkType=%{public}d", linkType);
316         return SOFTBUS_INVALID_PARAM;
317     }
318     return g_linkState[linkType].QueryLink(networkId);
319 }
320 
isHighRequire(const QosInfo * qosInfo,bool * isHighBand)321 static bool isHighRequire(const QosInfo *qosInfo, bool *isHighBand)
322 {
323     if (qosInfo->minBW > QOS_MIN_BANDWIDTH) {
324         *isHighBand = true;
325         return true;
326     } else {
327         *isHighBand = false;
328         return true;
329     }
330     return false;
331 }
332 
QueryByRequireLink(const LaneQueryInfo * queryInfo,const QosInfo * qosInfo)333 static int32_t QueryByRequireLink(const LaneQueryInfo *queryInfo, const QosInfo *qosInfo)
334 {
335     if (qosInfo->minBW == QOS_P2P_ONLY_BANDWIDTH) {
336         return IsValidLaneLink(queryInfo->networkId, LANE_P2P);
337     }
338     bool isHighBand = false;
339     if (!isHighRequire(qosInfo, &isHighBand)) {
340         LNN_LOGE(LNN_LANE, "set param failed");
341         return SOFTBUS_INVALID_PARAM;
342     }
343     LaneLinkType optLink[LANE_LINK_TYPE_BUTT];
344     (void)memset_s(optLink, sizeof(optLink), 0, sizeof(optLink));
345     uint32_t linkNum = LANE_LINK_TYPE_BUTT;
346     int32_t ret = GetLaneResource(queryInfo->transType, optLink, &linkNum, isHighBand);
347     if (ret != SOFTBUS_OK) {
348         LNN_LOGE(LNN_LANE, "get defaultLinkList fail");
349         return ret;
350     }
351     for (uint32_t i = 0; i < linkNum; i++) {
352         ret = IsValidLaneLink(queryInfo->networkId, optLink[i]);
353         if (ret == SOFTBUS_OK) {
354             LNN_LOGI(LNN_LANE, "high require get enable Link, linktype=%{public}d", optLink[i]);
355             return ret;
356         }
357     }
358     return ret;
359 }
360 
QueryByDefaultLink(const LaneQueryInfo * queryInfo)361 static int32_t QueryByDefaultLink(const LaneQueryInfo *queryInfo)
362 {
363     LaneLinkType optLink[LANE_LINK_TYPE_BUTT];
364     (void)memset_s(optLink, sizeof(optLink), 0, sizeof(optLink));
365     uint32_t linkNum = LANE_LINK_TYPE_BUTT;
366     int32_t ret = GetLaneResource(queryInfo->transType, optLink, &linkNum, false);
367     if (ret != SOFTBUS_OK) {
368         LNN_LOGE(LNN_LANE, "get defaultLinkList fail");
369         return ret;
370     }
371     for (uint32_t i = 0; i < linkNum; i++) {
372         ret = IsValidLaneLink(queryInfo->networkId, optLink[i]);
373         if (ret == SOFTBUS_OK) {
374             LNN_LOGI(LNN_LANE, "default get enable Link, linktype=%{public}d", optLink[i]);
375             return ret;
376         }
377     }
378     return ret;
379 }
380 
QueryLaneResource(const LaneQueryInfo * queryInfo,const QosInfo * qosInfo)381 int32_t QueryLaneResource(const LaneQueryInfo *queryInfo, const QosInfo *qosInfo)
382 {
383     if (queryInfo == NULL || qosInfo == NULL) {
384         LNN_LOGE(LNN_LANE, "invalid param");
385         return SOFTBUS_INVALID_PARAM;
386     }
387     if (qosInfo->minBW > 0) {
388         LNN_LOGI(LNN_LANE, "Query lane by prefer linklist, transType=%{public}d, minBW=%{public}d",
389             queryInfo->transType, qosInfo->minBW);
390         return QueryByRequireLink(queryInfo, qosInfo);
391     } else {
392         LNN_LOGI(LNN_LANE, "Query lane by default linklist, transType=%{public}d", queryInfo->transType);
393         return QueryByDefaultLink(queryInfo);
394     }
395 }