• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 <securec.h>
17 #include <stdint.h>
18 #include <stdio.h>
19 #include <string.h>
20 
21 #include "anonymizer.h"
22 #include "auth_interface.h"
23 #include "bus_center_adapter.h"
24 #include "bus_center_event.h"
25 #include "bus_center_info_key.h"
26 #include "bus_center_manager.h"
27 #include "disc_interface.h"
28 #include "lnn_async_callback_utils.h"
29 #include "lnn_common_utils.h"
30 #include "lnn_connection_fsm.h"
31 #include "lnn_discovery_manager.h"
32 #include "lnn_ip_utils_adapter.h"
33 #include "lnn_linkwatch.h"
34 #include "lnn_log.h"
35 #include "lnn_net_builder.h"
36 #include "lnn_network_manager.h"
37 #include "lnn_physical_subnet_manager.h"
38 #include "message_handler.h"
39 #include "softbus_adapter_mem.h"
40 #include "softbus_common.h"
41 #include "softbus_def.h"
42 #include "softbus_protocol_def.h"
43 #include "trans_tcp_direct_listener.h"
44 
45 #define IP_DEFAULT_PORT 0
46 #define LNN_LOOPBACK_IPV6 "::1"
47 
48 #define GET_IP_RETRY_TIMES 1
49 #define GET_IP_INTERVAL_TIME 500 // uint:ms
50 
IsValidUsbIfname(const char * ifname)51 static bool IsValidUsbIfname(const char* ifname)
52 {
53     if (ifname != NULL &&
54         ((strstr(ifname, "ncm") != NULL) || (strstr(ifname, "wwan") != NULL))) {
55         return true;
56     }
57     return false;
58 }
59 
UpdateUsbNetCap(bool isSet)60 static void UpdateUsbNetCap(bool isSet)
61 {
62     uint32_t netCapability = 0;
63     if (LnnGetLocalNumU32Info(NUM_KEY_NET_CAP, &netCapability) != SOFTBUS_OK) {
64         LNN_LOGE(LNN_BUILDER, "get netcap fail");
65         return;
66     }
67     if (isSet) {
68         (void)LnnSetNetCapability(&netCapability, BIT_USB);
69     } else {
70         (void)LnnClearNetCapability(&netCapability, BIT_USB);
71     }
72     if (LnnSetLocalNumInfo(NUM_KEY_NET_CAP, (int32_t)netCapability) != SOFTBUS_OK) {
73         LNN_LOGE(LNN_BUILDER, "set cap to local ledger fail");
74         return;
75     }
76 }
77 
GetIpAddrFromNetlink(const char * ifName,char * ip,uint32_t size)78 static int32_t GetIpAddrFromNetlink(const char *ifName, char *ip, uint32_t size)
79 {
80     if (GetNetworkIpv6ByIfName(ifName, ip, size) != SOFTBUS_OK) {
81         LNN_LOGE(LNN_BUILDER, "get ip by ifname fail");
82         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
83     }
84 
85     if (strcmp(ip, LNN_LOOPBACK_IPV6) == 0 || strcmp(ip, "") == 0) {
86         LNN_LOGE(LNN_BUILDER, "invalid ip addr");
87         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
88     }
89     return SOFTBUS_OK;
90 }
91 
GetIpProcess(const char * ifName,char * ip,uint32_t size)92 static bool GetIpProcess(const char *ifName, char *ip, uint32_t size)
93 {
94     if (GetIpAddrFromNetlink(ifName, ip, size) != SOFTBUS_OK) {
95         LNN_LOGD(LNN_BUILDER, "get network IP by ifName fail");
96         return false;
97     }
98     return true;
99 }
100 
NotifyUsbAddressChanged(const LnnNetIfMgr * netifManager,void * data)101 static VisitNextChoice NotifyUsbAddressChanged(const LnnNetIfMgr *netifManager, void *data)
102 {
103     if (netifManager != NULL && netifManager->type == LNN_NETIF_TYPE_USB) {
104         LNN_LOGI(LNN_BUILDER, "notify usb changed at %{public}" PRIu64, SoftBusGetSysTimeMs());
105         LnnNotifyPhysicalSubnetStatusChanged(netifManager->ifName, LNN_PROTOCOL_USB, data);
106     }
107     return CHOICE_VISIT_NEXT;
108 }
109 
RetryGetAvailableIpAddr(void * para)110 static void RetryGetAvailableIpAddr(void *para)
111 {
112     (void)para;
113     (void)LnnVisitNetif(NotifyUsbAddressChanged, NULL);
114 }
115 
GetAvailableIpAddr(const char * ifName,char * ip,uint32_t size)116 static int32_t GetAvailableIpAddr(const char *ifName, char *ip, uint32_t size)
117 {
118     static int32_t retryTime = GET_IP_RETRY_TIMES;
119     if (!IsValidUsbIfname(ifName)) {
120         retryTime = 0;
121     }
122     if (GetIpProcess(ifName, ip, size)) {
123         retryTime = GET_IP_RETRY_TIMES;
124         return SOFTBUS_OK;
125     }
126     LNN_LOGD(LNN_BUILDER, "get ip retry time=%{public}d", retryTime);
127     if (--retryTime > 0 && LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), RetryGetAvailableIpAddr,
128         NULL, GET_IP_INTERVAL_TIME) != SOFTBUS_OK) {
129         LNN_LOGE(LNN_BUILDER, "LnnAsyncCallbackDelayHelper get available ip fail");
130         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
131     }
132     if (retryTime <= 0) {
133         retryTime = GET_IP_RETRY_TIMES;
134     }
135     return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
136 }
137 
OpenAuthPort(void)138 static int32_t OpenAuthPort(void)
139 {
140     char localIp[MAX_ADDR_LEN] = {0};
141 
142     int32_t authPort;
143     if (LnnGetLocalNumInfoByIfnameIdx(NUM_KEY_AUTH_PORT, &authPort, USB_IF) != SOFTBUS_OK) {
144         LNN_LOGE(LNN_BUILDER, "get port failed");
145         authPort = 0;
146     }
147 
148     if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_IP6_WITH_IF, localIp, MAX_ADDR_LEN, USB_IF) != SOFTBUS_OK) {
149         LNN_LOGE(LNN_BUILDER, "get local ip failed");
150         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
151     }
152     int32_t port = AuthStartListening(AUTH_LINK_TYPE_USB, localIp, authPort);
153     if (port < 0) {
154         LNN_LOGE(LNN_BUILDER, "AuthStartListening failed");
155         return SOFTBUS_INVALID_PORT;
156     }
157     char *anonyIp = NULL;
158     Anonymize(localIp, &anonyIp);
159     LNN_LOGI(LNN_BUILDER, "open auth port listening on ip=%{public}s", AnonymizeWrapper(anonyIp));
160     AnonymizeFree(anonyIp);
161     if (authPort == 0) {
162         return LnnSetLocalNumInfoByIfnameIdx(NUM_KEY_AUTH_PORT, port, USB_IF);
163     }
164     return SOFTBUS_OK;
165 }
166 
CloseAuthPort(void)167 static void CloseAuthPort(void)
168 {
169     AuthStopListening(AUTH_LINK_TYPE_USB);
170     (void)LnnSetLocalNumInfoByIfnameIdx(NUM_KEY_AUTH_PORT, IP_DEFAULT_PORT, USB_IF);
171 }
172 
OpenSessionPort(void)173 static int32_t OpenSessionPort(void)
174 {
175     int32_t sessionPort = 0;
176     if (LnnGetLocalNumInfoByIfnameIdx(NUM_KEY_SESSION_PORT, &sessionPort, USB_IF) != SOFTBUS_OK) {
177         LNN_LOGE(LNN_BUILDER, "get port failed, use default value.");
178     }
179 
180     LocalListenerInfo info = {
181         .type = CONNECT_TCP,
182         .socketOption = {
183             .addr = "",
184             .port = sessionPort,
185             .moduleId = DIRECT_CHANNEL_SERVER_USB,
186             .protocol = LNN_PROTOCOL_USB,
187         }
188     };
189     if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_IP6_WITH_IF, info.socketOption.addr,
190         sizeof(info.socketOption.addr), USB_IF) != SOFTBUS_OK) {
191         LNN_LOGE(LNN_BUILDER, "get local ip failed");
192         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
193     }
194     int32_t port = TransTdcStartSessionListener(DIRECT_CHANNEL_SERVER_WIFI, &info);
195     if (port < 0) {
196         LNN_LOGE(LNN_BUILDER, "open session server failed");
197         return SOFTBUS_INVALID_PORT;
198     }
199     if (sessionPort == 0) {
200         return LnnSetLocalNumInfoByIfnameIdx(NUM_KEY_SESSION_PORT, port, USB_IF);
201     }
202 
203     return SOFTBUS_OK;
204 }
205 
CloseSessionPort(void)206 static void CloseSessionPort(void)
207 {
208     TransTdcStopSessionListener(DIRECT_CHANNEL_SERVER_USB);
209     (void)LnnSetLocalNumInfoByIfnameIdx(NUM_KEY_SESSION_PORT, IP_DEFAULT_PORT, USB_IF);
210 }
211 
OpenIpLink(void)212 static int32_t OpenIpLink(void)
213 {
214     int32_t ret = OpenAuthPort();
215     if (ret != SOFTBUS_OK) {
216         LNN_LOGE(LNN_BUILDER, "OpenAuthPort fail");
217         return SOFTBUS_NETWORK_PORT_PROCESS_FAILED;
218     }
219     ret = OpenSessionPort();
220     if (ret != SOFTBUS_OK) {
221         LNN_LOGE(LNN_BUILDER, "OpenSessionPort fail");
222         CloseAuthPort();
223         return SOFTBUS_NETWORK_PORT_PROCESS_FAILED;
224     }
225     return SOFTBUS_OK;
226 }
227 
CloseIpLink(void)228 static void CloseIpLink(void)
229 {
230     CloseAuthPort();
231     CloseSessionPort();
232     LNN_LOGI(LNN_BUILDER, "close port success");
233 }
234 
GetLocalIpInfo(char * ipAddr,uint32_t ipAddrLen,char * ifName,uint32_t ifNameLen)235 static int32_t GetLocalIpInfo(char *ipAddr, uint32_t ipAddrLen, char *ifName, uint32_t ifNameLen)
236 {
237     if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_IP, ipAddr, ipAddrLen, USB_IF) != SOFTBUS_OK) {
238         LNN_LOGE(LNN_BUILDER, "get local ip error");
239         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
240     }
241     if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_NET_IF_NAME, ifName, ifNameLen, USB_IF) != SOFTBUS_OK) {
242         LNN_LOGE(LNN_BUILDER, "get local ifName error");
243         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
244     }
245     return SOFTBUS_OK;
246 }
247 
SetLocalIpInfo(const char * ipAddr,const char * ifName)248 static int32_t SetLocalIpInfo(const char *ipAddr, const char *ifName)
249 {
250     if (LnnSetLocalStrInfoByIfnameIdx(STRING_KEY_IP, ipAddr, USB_IF) != SOFTBUS_OK) {
251         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
252     }
253     if (LnnSetLocalStrInfoByIfnameIdx(STRING_KEY_NET_IF_NAME, ifName, USB_IF) != SOFTBUS_OK) {
254         LNN_LOGE(LNN_BUILDER, "set local ifName error");
255         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
256     }
257     return SOFTBUS_OK;
258 }
259 
LeaveOldIpNetwork(const char * ifCurrentName)260 static void LeaveOldIpNetwork(const char *ifCurrentName)
261 {
262     ConnectionAddrType type = CONNECTION_ADDR_MAX;
263     bool addrType[CONNECTION_ADDR_MAX] = { false };
264 
265     if (LnnGetAddrTypeByIfName(ifCurrentName, &type) != SOFTBUS_OK) {
266         LNN_LOGE(LNN_BUILDER, "LnnGetAddrTypeByIfName failed ifName=%{public}s", ifCurrentName);
267         return;
268     }
269     if (type == CONNECTION_ADDR_MAX) {
270         addrType[CONNECTION_ADDR_WLAN] = true;
271         addrType[CONNECTION_ADDR_ETH] = true;
272     } else {
273         addrType[type] = true;
274     }
275     LNN_LOGI(LNN_BUILDER, "LNN start leave ip network");
276     if (LnnRequestLeaveByAddrType(addrType, CONNECTION_ADDR_MAX) != SOFTBUS_OK) {
277         LNN_LOGE(LNN_BUILDER, "LNN leave ip network fail");
278     }
279 }
280 
ReleaseMainPort(const char * ifName)281 static int32_t ReleaseMainPort(const char *ifName)
282 {
283     char oldMainIf[NET_IF_NAME_LEN] = {0};
284     do {
285         if (LnnGetLocalStrInfoByIfnameIdx(
286             STRING_KEY_NET_IF_NAME, oldMainIf, sizeof(oldMainIf), USB_IF) != SOFTBUS_OK) {
287             LNN_LOGE(LNN_BUILDER, "get local ifName error!");
288             break;
289         }
290         if (strcmp(ifName, oldMainIf) != 0) {
291             LNN_LOGE(LNN_BUILDER, "if is not main port! ifName=%{public}s", ifName);
292             return SOFTBUS_CMP_FAIL;
293         }
294     } while (false);
295     if (SetLocalIpInfo(LNN_LOOPBACK_IPV6, LNN_LOOPBACK_IFNAME) != SOFTBUS_OK) {
296         LNN_LOGE(LNN_BUILDER, "set local ip info failed");
297         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
298     }
299     return SOFTBUS_OK;
300 }
301 
RequestMainPort(const char * ifName,const char * address)302 static int32_t RequestMainPort(const char *ifName, const char *address)
303 {
304     if (strcmp(ifName, LNN_LOOPBACK_IFNAME) == 0) {
305         LNN_LOGE(LNN_BUILDER, "loopback ifName not allowed");
306         return SOFTBUS_CMP_FAIL;
307     }
308     if (strcmp(address, LNN_LOOPBACK_IPV6) == 0) {
309         LNN_LOGE(LNN_BUILDER, "loopback ip not allowed");
310         return SOFTBUS_CMP_FAIL;
311     }
312     LNN_LOGI(LNN_BUILDER, "get local ifName begin");
313     char oldMainIf[NET_IF_NAME_LEN] = {0};
314     if (LnnGetLocalStrInfoByIfnameIdx(STRING_KEY_NET_IF_NAME, oldMainIf, sizeof(oldMainIf), USB_IF) != SOFTBUS_OK) {
315         LNN_LOGE(LNN_BUILDER, "get local ifName error");
316         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
317     }
318     LNN_LOGD(LNN_BUILDER, "get local ifName end");
319     if (strcmp(oldMainIf, ifName) != 0 && strcmp(oldMainIf, LNN_LOOPBACK_IFNAME) != 0) {
320         LNN_LOGE(LNN_BUILDER, "Only 1 local subnet is allowed");
321         return SOFTBUS_CMP_FAIL;
322     }
323     if (SetLocalIpInfo(address, ifName) != SOFTBUS_OK) {
324         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
325     }
326     return SOFTBUS_OK;
327 }
328 
EnableIpSubnet(LnnPhysicalSubnet * subnet)329 static int32_t EnableIpSubnet(LnnPhysicalSubnet *subnet)
330 {
331     char address[IP_LEN] = {0};
332 
333     int32_t ret = GetAvailableIpAddr(subnet->ifName, address, sizeof(address));
334     if (ret != SOFTBUS_OK) {
335         LNN_LOGE(LNN_BUILDER, "get available Ip failed! ifName=%{public}s, ret=%{public}d", subnet->ifName, ret);
336         return ret;
337     }
338     if (RequestMainPort(subnet->ifName, address)) {
339         LNN_LOGE(LNN_BUILDER, "request main port failed! ifName=%{public}s", subnet->ifName);
340         return SOFTBUS_NETWORK_PORT_PROCESS_FAILED;
341     }
342     if (OpenIpLink() != SOFTBUS_OK) {
343         LNN_LOGE(LNN_BUILDER, "open ip link failed");
344         return SOFTBUS_CONN_AUTH_START_LISTEN_FAIL;
345     }
346     UpdateUsbNetCap(true);
347     DiscLinkStatusChanged(LINK_STATUS_UP, COAP, USB_IF);
348     LNN_LOGI(LNN_BUILDER, "notify ip ready");
349     LnnNotifyNetlinkStateChangeEvent(SOFTBUS_NETMANAGER_IFNAME_LINK_CHANGED, subnet->ifName);
350     return SOFTBUS_OK;
351 }
352 
DisableIpSubnet(LnnPhysicalSubnet * subnet)353 static int32_t DisableIpSubnet(LnnPhysicalSubnet *subnet)
354 {
355     if (subnet->status == LNN_SUBNET_RUNNING) {
356         CloseIpLink();
357         UpdateUsbNetCap(false);
358         LeaveOldIpNetwork(subnet->ifName);
359         ReleaseMainPort(subnet->ifName);
360         DiscLinkStatusChanged(LINK_STATUS_DOWN, COAP, USB_IF);
361     }
362     return SOFTBUS_OK;
363 }
364 
ChangeIpSubnetAddress(LnnPhysicalSubnet * subnet)365 static int32_t ChangeIpSubnetAddress(LnnPhysicalSubnet *subnet)
366 {
367     CloseIpLink();
368     UpdateUsbNetCap(false);
369     LeaveOldIpNetwork(subnet->ifName);
370     ReleaseMainPort(subnet->ifName);
371     DiscLinkStatusChanged(LINK_STATUS_DOWN, COAP, USB_IF);
372     return SOFTBUS_OK;
373 }
374 
DestroyUsbSubnetManager(LnnPhysicalSubnet * subnet)375 static void DestroyUsbSubnetManager(LnnPhysicalSubnet *subnet)
376 {
377     if (subnet == NULL) {
378         LNN_LOGE(LNN_BUILDER, "invalid subnet");
379         return;
380     }
381     if (subnet->status == LNN_SUBNET_RUNNING) {
382         DisableIpSubnet(subnet);
383     }
384     SoftBusFree(subnet);
385 }
386 
387 typedef enum {
388     USB_SUBNET_MANAGER_EVENT_IF_READY,
389     USB_SUBNET_MANAGER_EVENT_IF_DOWN,    // addr change from available to
390     USB_SUBNET_MANAGER_EVENT_IF_CHANGED, // addr changed
391     USB_SUBNET_MANAGER_EVENT_MAX
392 } IpSubnetManagerEvent;
393 
394 typedef enum {
395     IP_EVENT_RESULT_ACCEPTED = 0,
396     IP_EVENT_RESULT_REJECTED,
397     IP_EVENT_RESULT_OPTION_COUNT
398 } IpSubnetManagerEventResultOptions;
399 
TransactIpSubnetState(LnnPhysicalSubnet * subnet,IpSubnetManagerEvent event,bool isAccepted)400 static void TransactIpSubnetState(LnnPhysicalSubnet *subnet, IpSubnetManagerEvent event, bool isAccepted)
401 {
402     LnnPhysicalSubnetStatus transactMap[][IP_EVENT_RESULT_OPTION_COUNT] = {
403         [USB_SUBNET_MANAGER_EVENT_IF_READY] = {LNN_SUBNET_RUNNING, LNN_SUBNET_IDLE},
404         [USB_SUBNET_MANAGER_EVENT_IF_DOWN] = {LNN_SUBNET_SHUTDOWN, subnet->status},
405         [USB_SUBNET_MANAGER_EVENT_IF_CHANGED] = {LNN_SUBNET_RESETTING, subnet->status}
406     };
407     subnet->status = transactMap[event][isAccepted ? IP_EVENT_RESULT_ACCEPTED : IP_EVENT_RESULT_REJECTED];
408     LNN_LOGI(LNN_BUILDER, "subnet state change. ifName=%{public}s, protocolId=%{public}u, new status=%{public}d",
409         subnet->ifName, subnet->protocol->id, subnet->status);
410 }
411 
GetIpEventInOther(LnnPhysicalSubnet * subnet)412 static IpSubnetManagerEvent GetIpEventInOther(LnnPhysicalSubnet *subnet)
413 {
414     char currentIfAddress[IP_LEN] = {0};
415     int32_t ret = GetAvailableIpAddr(subnet->ifName, currentIfAddress, sizeof(currentIfAddress));
416     if (ret == SOFTBUS_OK) {
417         return USB_SUBNET_MANAGER_EVENT_IF_READY;
418     }
419     return subnet->status == LNN_SUBNET_SHUTDOWN ? USB_SUBNET_MANAGER_EVENT_IF_DOWN : USB_SUBNET_MANAGER_EVENT_MAX;
420 }
421 
GetIpEventInRunning(LnnPhysicalSubnet * subnet)422 static IpSubnetManagerEvent GetIpEventInRunning(LnnPhysicalSubnet *subnet)
423 {
424     char currentIfAddress[IP_LEN] = {0};
425     int32_t ret = GetAvailableIpAddr(subnet->ifName, currentIfAddress, sizeof(currentIfAddress));
426     if (ret != SOFTBUS_OK) {
427         LNN_LOGE(LNN_BUILDER, "GetAvailableIpAddr fail");
428         return USB_SUBNET_MANAGER_EVENT_IF_DOWN;
429     }
430 
431     char localIpAddr[IP_LEN] = {0};
432     char localNetifName[NET_IF_NAME_LEN] = {0};
433     if (GetLocalIpInfo(localIpAddr, sizeof(localIpAddr), localNetifName, sizeof(localNetifName)) != SOFTBUS_OK) {
434         LNN_LOGE(LNN_BUILDER, "get main ip info failed");
435         return USB_SUBNET_MANAGER_EVENT_IF_READY;
436     }
437     if (strcmp(localNetifName, subnet->ifName) != 0) {
438         return USB_SUBNET_MANAGER_EVENT_IF_READY;
439     }
440     if (strcmp(localIpAddr, currentIfAddress) == 0) {
441         return USB_SUBNET_MANAGER_EVENT_MAX;
442     } else {
443         return USB_SUBNET_MANAGER_EVENT_IF_CHANGED;
444     }
445 }
446 
OnSoftbusIpNetworkDisconnected(LnnPhysicalSubnet * subnet)447 static void OnSoftbusIpNetworkDisconnected(LnnPhysicalSubnet *subnet)
448 {
449     if (subnet != NULL && (subnet->status == LNN_SUBNET_RESETTING || subnet->status == LNN_SUBNET_IDLE)) {
450         int32_t ret = EnableIpSubnet(subnet);
451         TransactIpSubnetState(subnet, USB_SUBNET_MANAGER_EVENT_IF_READY, (ret == SOFTBUS_OK));
452     }
453 }
454 
OnIpNetifStatusChanged(LnnPhysicalSubnet * subnet,void * status)455 static void OnIpNetifStatusChanged(LnnPhysicalSubnet *subnet, void *status)
456 {
457     if (subnet == NULL) {
458         LNN_LOGE(LNN_BUILDER, "invaild subnet paramter");
459         if (status != NULL) {
460             SoftBusFree(status);
461         }
462         return;
463     }
464     LNN_LOGI(LNN_BUILDER, "subnet now status=%{public}d", subnet->status);
465     IpSubnetManagerEvent event = USB_SUBNET_MANAGER_EVENT_MAX;
466     if (status == NULL) {
467         if (subnet->status == LNN_SUBNET_RUNNING) {
468             event = GetIpEventInRunning(subnet);
469         } else {
470             event = GetIpEventInOther(subnet);
471         }
472     } else {
473         event = *(IpSubnetManagerEvent *)status;
474         SoftBusFree(status);
475         if (event < USB_SUBNET_MANAGER_EVENT_IF_READY || event > USB_SUBNET_MANAGER_EVENT_MAX) {
476             LNN_LOGW(LNN_BUILDER, "is not right event=%{public}d", event);
477             return;
478         }
479     }
480 
481     int32_t ret = SOFTBUS_NETWORK_NETIF_STATUS_CHANGED;
482     switch (event) {
483         case USB_SUBNET_MANAGER_EVENT_IF_READY: {
484             ret = EnableIpSubnet(subnet);
485             break;
486         }
487         case USB_SUBNET_MANAGER_EVENT_IF_DOWN: {
488             ret = DisableIpSubnet(subnet);
489             break;
490         }
491         case USB_SUBNET_MANAGER_EVENT_IF_CHANGED: {
492             ret = ChangeIpSubnetAddress(subnet);
493             break;
494         }
495         default:
496             return;
497     }
498 
499     TransactIpSubnetState(subnet, event, (ret == SOFTBUS_OK));
500 }
501 
CreateUsbSubnetManager(const struct LnnProtocolManager * self,const char * ifName)502 static LnnPhysicalSubnet *CreateUsbSubnetManager(const struct LnnProtocolManager *self, const char *ifName)
503 {
504     LnnPhysicalSubnet *subnet = (LnnPhysicalSubnet *)SoftBusCalloc(sizeof(LnnPhysicalSubnet));
505     if (subnet == NULL) {
506         LNN_LOGE(LNN_BUILDER, "malloc subnet fail");
507         return NULL;
508     }
509 
510     do {
511         subnet->destroy = DestroyUsbSubnetManager;
512         subnet->protocol = self;
513         subnet->status = LNN_SUBNET_IDLE;
514         subnet->onNetifStatusChanged = OnIpNetifStatusChanged;
515         subnet->onSoftbusNetworkDisconnected = OnSoftbusIpNetworkDisconnected;
516 
517         int32_t ret = strcpy_s(subnet->ifName, sizeof(subnet->ifName), ifName);
518         if (ret != EOK) {
519             LNN_LOGE(LNN_BUILDER, "copy ifName failed ret=%{public}d", ret);
520             break;
521         }
522         return subnet;
523     } while (false);
524 
525     subnet->destroy((LnnPhysicalSubnet *)subnet);
526     return NULL;
527 }
528 
IpAddrChangeEventHandler(const LnnEventBasicInfo * info)529 static void IpAddrChangeEventHandler(const LnnEventBasicInfo *info)
530 {
531     if (info == NULL || info->event != LNN_EVENT_IP_ADDR_CHANGED) {
532         LNN_LOGE(LNN_BUILDER, "not interest event");
533         return;
534     }
535     const LnnMonitorAddressChangedEvent *event = (const LnnMonitorAddressChangedEvent *)info;
536     if (IsValidUsbIfname(event->ifName)) {
537         LNN_LOGI(LNN_BUILDER, "if name is %{public}s", event->ifName);
538         LnnNotifyPhysicalSubnetStatusChanged(event->ifName, LNN_PROTOCOL_USB, NULL);
539     }
540 }
541 
UsbNcmChangeHandler(const LnnEventBasicInfo * info)542 static void UsbNcmChangeHandler(const LnnEventBasicInfo *info)
543 {
544     if (info == NULL || info->event != LNN_EVENT_NET_LINK_STATE_CHANGE) {
545         LNN_LOGE(LNN_BUILDER, "get invalid param");
546         return;
547     }
548     const LnnMonitorNetlinkStateInfo *event = (const LnnMonitorNetlinkStateInfo *)info;
549     if (!IsValidUsbIfname(event->ifName)) {
550         LNN_LOGD(LNN_BUILDER, "not interest event");
551         return;
552     }
553     NetManagerIfNameState status = (NetManagerIfNameState)event->status;
554     switch (status) {
555         case SOFTBUS_NETMANAGER_IFNAME_REMOVED:
556             LNN_LOGI(LNN_BUILDER, "%{public}s removed", event->ifName);
557             LnnNotifyPhysicalSubnetStatusChanged(event->ifName, LNN_PROTOCOL_USB, NULL);
558             break;
559         default:
560             LNN_LOGD(LNN_BUILDER, "status %{public}d skip", status);
561     }
562 }
563 
LnnInitUsbProtocol(struct LnnProtocolManager * self)564 int32_t LnnInitUsbProtocol(struct LnnProtocolManager *self)
565 {
566     LNN_LOGI(LNN_INIT, "LnnInitUsbProtocol");
567     (void)self;
568     int32_t ret = SOFTBUS_OK;
569     if (LnnRegisterEventHandler(LNN_EVENT_IP_ADDR_CHANGED, IpAddrChangeEventHandler) != SOFTBUS_OK) {
570         LNN_LOGE(LNN_INIT, "register ip addr change event handler failed");
571         return SOFTBUS_NETWORK_REG_EVENT_HANDLER_ERR;
572     }
573 
574     if (LnnRegisterEventHandler(LNN_EVENT_NET_LINK_STATE_CHANGE, UsbNcmChangeHandler) != SOFTBUS_OK) {
575         LNN_LOGE(LNN_INIT, "usb regist evt handle faild");
576         return SOFTBUS_NETWORK_USB_REG_EVENT_FAILED;
577     }
578 
579     if (SetLocalIpInfo(LNN_LOOPBACK_IPV6, LNN_LOOPBACK_IFNAME) != SOFTBUS_OK) {
580         LNN_LOGE(LNN_INIT, "init local ip as loopback failed!");
581         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
582     }
583     UpdateUsbNetCap(false);
584     DiscLinkStatusChanged(LINK_STATUS_DOWN, COAP, USB_IF);
585     return ret;
586 }
587 
LnnEnableUsbProtocol(struct LnnProtocolManager * self,LnnNetIfMgr * netifMgr)588 int32_t LnnEnableUsbProtocol(struct LnnProtocolManager *self, LnnNetIfMgr *netifMgr)
589 {
590     (void)self;
591     if (netifMgr == NULL) {
592         LNN_LOGE(LNN_BUILDER, "netif mgr is null");
593         return SOFTBUS_INVALID_PARAM;
594     }
595     LnnPhysicalSubnet *manager = CreateUsbSubnetManager(self, netifMgr->ifName);
596     if (manager == NULL) {
597         LNN_LOGE(LNN_BUILDER, "malloc subnet mgr fail");
598         return SOFTBUS_MALLOC_ERR;
599     }
600     int ret = LnnRegistPhysicalSubnet(manager);
601     if (ret != SOFTBUS_OK) {
602         LNN_LOGE(LNN_BUILDER, "regist subnet manager failed! ret=%{public}d", ret);
603         manager->destroy(manager);
604         return ret;
605     }
606     return SOFTBUS_OK;
607 }
608 
LnnGetUsbListenerModule(ListenerMode mode)609 static ListenerModule LnnGetUsbListenerModule(ListenerMode mode)
610 {
611     if (mode == LNN_LISTENER_MODE_PROXY ||
612         mode == LNN_LISTENER_MODE_DIRECT) {
613         return DIRECT_CHANNEL_SERVER_USB;
614     } else {
615         return UNUSE_BUTT;
616     }
617 }
618 
LnnDeinitUsbNetwork(struct LnnProtocolManager * self)619 void LnnDeinitUsbNetwork(struct LnnProtocolManager *self)
620 {
621     (void)self;
622     LnnUnregisterEventHandler(LNN_EVENT_IP_ADDR_CHANGED, IpAddrChangeEventHandler);
623     LnnUnregisterEventHandler(LNN_EVENT_NET_LINK_STATE_CHANGE, UsbNcmChangeHandler);
624     LnnUnregistPhysicalSubnetByType(LNN_PROTOCOL_USB);
625     LNN_LOGW(LNN_INIT, "usb network deinited");
626 }
627 
628 static LnnProtocolManager g_usbProtocol = {
629     .init = LnnInitUsbProtocol,
630     .deinit = LnnDeinitUsbNetwork,
631     .enable = LnnEnableUsbProtocol,
632     .disable = NULL,
633     .getListenerModule = LnnGetUsbListenerModule,
634     .id = LNN_PROTOCOL_USB,
635     .supportedNetif = LNN_NETIF_TYPE_USB,
636     .pri = 10,
637 };
638 
RegistUsbProtocolManager(void)639 int32_t RegistUsbProtocolManager(void)
640 {
641     return LnnRegistProtocol(&g_usbProtocol);
642 }
643