• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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_discovery_manager.h"
31 #include "lnn_fast_offline.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_adapter_thread.h"
41 #include "softbus_adapter_timer.h"
42 #include "softbus_common.h"
43 #include "softbus_def.h"
44 #include "softbus_error_code.h"
45 #include "softbus_feature_config.h"
46 #include "softbus_protocol_def.h"
47 #include "trans_tcp_direct_listener.h"
48 #include "conn_coap.h"
49 #include "lnn_connection_fsm.h"
50 
51 #define IP_DEFAULT_PORT 0
52 #define LNN_LOOPBACK_IP "127.0.0.1"
53 #define WLAN_IFNAME "wlan0"
54 
55 static bool g_wifiConnected = false;
56 static bool g_apEnabled = false;
57 static bool g_heartbeatEnable = false;
58 
59 #define GET_IP_RETRY_TIMES 10
60 #define GET_IP_INTERVAL_TIME 500 // uint:ms
61 
GetWifiServiceIpAddr(const char * ifName,char * ip,uint32_t size)62 static int32_t GetWifiServiceIpAddr(const char *ifName, char *ip, uint32_t size)
63 {
64     if (ifName == NULL || ip == NULL || size == 0) {
65         LNN_LOGE(LNN_BUILDER, "invalid parameter");
66         return SOFTBUS_INVALID_PARAM;
67     }
68     if (strcmp(ifName, WLAN_IFNAME) != 0) {
69         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
70     }
71     if (GetWlanIpv4Addr(ip, size) != SOFTBUS_OK) {
72         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
73     }
74     if (strnlen(ip, size) == 0 || strnlen(ip, size) == size) {
75         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
76     }
77     if (strcmp(ip, LNN_LOOPBACK_IP) == 0 || strcmp(ip, "") == 0 || strcmp(ip, "0.0.0.0") == 0) {
78         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
79     }
80     return SOFTBUS_OK;
81 }
82 
GetIpAddrFromNetlink(const char * ifName,char * ip,uint32_t size)83 static int32_t GetIpAddrFromNetlink(const char *ifName, char *ip, uint32_t size)
84 {
85     if (GetNetworkIpByIfName(ifName, ip, NULL, size) != SOFTBUS_OK) {
86         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
87     }
88 
89     if (strcmp(ip, LNN_LOOPBACK_IP) == 0 || strcmp(ip, "") == 0 || strcmp(ip, "0.0.0.0") == 0) {
90         LNN_LOGE(LNN_BUILDER, "invalid ip addr");
91         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
92     }
93     return SOFTBUS_OK;
94 }
95 
GetIpProcess(const char * ifName,char * ip,uint32_t size)96 static bool GetIpProcess(const char *ifName, char *ip, uint32_t size)
97 {
98     if (GetIpAddrFromNetlink(ifName, ip, size) != SOFTBUS_OK &&
99         GetWifiServiceIpAddr(ifName, ip, size) != SOFTBUS_OK) {
100         LNN_LOGD(LNN_BUILDER, "get network IP by ifName fail");
101         return false;
102     }
103     return true;
104 }
105 
NotifyWlanAddressChanged(const LnnNetIfMgr * netifManager,void * data)106 static VisitNextChoice NotifyWlanAddressChanged(const LnnNetIfMgr *netifManager, void *data)
107 {
108     if (netifManager->type == LNN_NETIF_TYPE_WLAN) {
109         LNN_LOGI(LNN_BUILDER, "notify wlan changed at %{public}" PRIu64, SoftBusGetSysTimeMs());
110         LnnNotifyPhysicalSubnetStatusChanged(netifManager->ifName, LNN_PROTOCOL_IP, data);
111     }
112     return CHOICE_VISIT_NEXT;
113 }
114 
RetryGetAvailableIpAddr(void * para)115 static void RetryGetAvailableIpAddr(void *para)
116 {
117     (void)para;
118     (void)LnnVisitNetif(NotifyWlanAddressChanged, NULL);
119 }
120 
GetAvailableIpAddr(const char * ifName,char * ip,uint32_t size)121 static int32_t GetAvailableIpAddr(const char *ifName, char *ip, uint32_t size)
122 {
123     static int32_t retryTime = GET_IP_RETRY_TIMES;
124     if (strcmp(ifName, WLAN_IFNAME) != 0) {
125         retryTime = 0;
126     }
127     if (GetIpProcess(ifName, ip, size)) {
128         retryTime = GET_IP_RETRY_TIMES;
129         return SOFTBUS_OK;
130     }
131     LNN_LOGD(LNN_BUILDER, "get ip retry time=%{public}d", retryTime);
132     if (--retryTime > 0 && LnnAsyncCallbackDelayHelper(GetLooper(LOOP_TYPE_DEFAULT), RetryGetAvailableIpAddr,
133         NULL, GET_IP_INTERVAL_TIME) != SOFTBUS_OK) {
134         LNN_LOGE(LNN_BUILDER, "LnnAsyncCallbackDelayHelper get available ip fail");
135         return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
136     }
137     if (retryTime <= 0) {
138         retryTime = GET_IP_RETRY_TIMES;
139     }
140     return SOFTBUS_NETWORK_GET_IP_ADDR_FAILED;
141 }
142 
OpenAuthPort(void)143 static int32_t OpenAuthPort(void)
144 {
145     char localIp[MAX_ADDR_LEN] = {0};
146 
147     int32_t authPort;
148     if (LnnGetLocalNumInfo(NUM_KEY_AUTH_PORT, &authPort) != SOFTBUS_OK) {
149         LNN_LOGE(LNN_BUILDER, "get port failed");
150         authPort = 0;
151     }
152 
153     if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, localIp, MAX_ADDR_LEN) != SOFTBUS_OK) {
154         LNN_LOGE(LNN_BUILDER, "get local ip failed");
155         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
156     }
157     int32_t port = AuthStartListening(AUTH_LINK_TYPE_WIFI, localIp, authPort);
158     if (port < 0) {
159         LNN_LOGE(LNN_BUILDER, "AuthStartListening failed");
160         return SOFTBUS_INVALID_PORT;
161     }
162     char *anonyIp = NULL;
163     Anonymize(localIp, &anonyIp);
164     LNN_LOGI(LNN_BUILDER, "open auth port listening on ip=%{public}s", AnonymizeWrapper(anonyIp));
165     AnonymizeFree(anonyIp);
166     if (authPort == 0) {
167         return LnnSetLocalNumInfo(NUM_KEY_AUTH_PORT, port);
168     }
169     return SOFTBUS_OK;
170 }
171 
CloseAuthPort(void)172 static void CloseAuthPort(void)
173 {
174     AuthStopListening(AUTH_LINK_TYPE_WIFI);
175     (void)LnnSetLocalNumInfo(NUM_KEY_AUTH_PORT, IP_DEFAULT_PORT);
176 }
177 
OpenSessionPort(void)178 static int32_t OpenSessionPort(void)
179 {
180     int32_t sessionPort;
181     if (LnnGetLocalNumInfo(NUM_KEY_SESSION_PORT, &sessionPort) != SOFTBUS_OK) {
182         LNN_LOGE(LNN_BUILDER, "get port failed");
183         sessionPort = 0;
184     }
185 
186     int32_t port;
187     LocalListenerInfo info = {
188         .type = CONNECT_TCP,
189         .socketOption = {
190             .addr = "",
191             .port = sessionPort,
192             .moduleId = DIRECT_CHANNEL_SERVER_WIFI,
193             .protocol = LNN_PROTOCOL_IP,
194         }
195     };
196     if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, info.socketOption.addr, sizeof(info.socketOption.addr)) != SOFTBUS_OK) {
197         LNN_LOGE(LNN_BUILDER, "get local ip failed");
198         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
199     }
200     port = TransTdcStartSessionListener(DIRECT_CHANNEL_SERVER_WIFI, &info);
201     if (port < 0) {
202         LNN_LOGE(LNN_BUILDER, "open session server failed");
203         return SOFTBUS_INVALID_PORT;
204     }
205     if (sessionPort == 0) {
206         return LnnSetLocalNumInfo(NUM_KEY_SESSION_PORT, port);
207     }
208 
209     return SOFTBUS_OK;
210 }
211 
CloseSessionPort(void)212 static void CloseSessionPort(void)
213 {
214     TransTdcStopSessionListener(DIRECT_CHANNEL_SERVER_WIFI);
215     (void)LnnSetLocalNumInfo(NUM_KEY_SESSION_PORT, IP_DEFAULT_PORT);
216 }
217 
OpenProxyPort(void)218 static void OpenProxyPort(void)
219 {
220     int32_t proxyPort;
221     if (LnnGetLocalNumInfo(NUM_KEY_PROXY_PORT, &proxyPort) != SOFTBUS_OK) {
222         LNN_LOGE(LNN_BUILDER, "get port failed");
223         proxyPort = 0;
224     }
225 
226     LocalListenerInfo listenerInfo = {
227         .type = CONNECT_TCP,
228         .socketOption = {
229             .addr = "",
230             .port = proxyPort,
231             .moduleId = PROXY,
232             .protocol = LNN_PROTOCOL_IP,
233         }
234     };
235     int32_t ret = LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, listenerInfo.socketOption.addr,
236         sizeof(listenerInfo.socketOption.addr));
237     if (ret != SOFTBUS_OK) {
238         LNN_LOGE(LNN_BUILDER, "get local ip failed");
239         return;
240     }
241     int32_t port = ConnStartLocalListening(&listenerInfo);
242     if (port < 0) {
243         LNN_LOGE(LNN_BUILDER, "open proxy server failed");
244         return;
245     }
246     if (proxyPort == 0) {
247         (void)LnnSetLocalNumInfo(NUM_KEY_PROXY_PORT, port);
248     }
249 }
250 
CloseProxyPort(void)251 static void CloseProxyPort(void)
252 {
253     LocalListenerInfo listenerInfo = {
254         .type = CONNECT_TCP,
255         .socketOption = {
256             .addr = "",
257             .port = 0,
258             .moduleId = PROXY,
259             .protocol = LNN_PROTOCOL_IP,
260         }
261     };
262     if (ConnStopLocalListening(&listenerInfo) != SOFTBUS_OK) {
263         LNN_LOGE(LNN_BUILDER, "ConnStopLocalListening fail");
264     }
265     (void)LnnSetLocalNumInfo(NUM_KEY_PROXY_PORT, IP_DEFAULT_PORT);
266 }
267 
OpenIpLink(void)268 static int32_t OpenIpLink(void)
269 {
270     int32_t ret = OpenAuthPort();
271     if (ret != SOFTBUS_OK) {
272         LNN_LOGE(LNN_BUILDER, "OpenAuthPort fail");
273         return SOFTBUS_NETWORK_PORT_PROCESS_FAILED;
274     }
275     ret = OpenSessionPort();
276     if (ret != SOFTBUS_OK) {
277         LNN_LOGE(LNN_BUILDER, "OpenSessionPort fail");
278         CloseAuthPort();
279         return SOFTBUS_NETWORK_PORT_PROCESS_FAILED;
280     }
281     OpenProxyPort();
282     return SOFTBUS_OK;
283 }
284 
CloseIpLink(void)285 static void CloseIpLink(void)
286 {
287     CloseAuthPort();
288     CloseSessionPort();
289     CloseProxyPort();
290     LNN_LOGI(LNN_BUILDER, "close port success");
291 }
292 
GetLocalIpInfo(char * ipAddr,uint32_t ipAddrLen,char * ifName,uint32_t ifNameLen)293 static int32_t GetLocalIpInfo(char *ipAddr, uint32_t ipAddrLen, char *ifName, uint32_t ifNameLen)
294 {
295     if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, ipAddr, ipAddrLen) != SOFTBUS_OK) {
296         LNN_LOGE(LNN_BUILDER, "get local ip error");
297         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
298     }
299     if (LnnGetLocalStrInfo(STRING_KEY_NET_IF_NAME, ifName, ifNameLen) != SOFTBUS_OK) {
300         LNN_LOGE(LNN_BUILDER, "get local ifName error");
301         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
302     }
303     return SOFTBUS_OK;
304 }
305 
SetLocalIpInfo(const char * ipAddr,const char * ifName)306 static int32_t SetLocalIpInfo(const char *ipAddr, const char *ifName)
307 {
308     if (LnnSetLocalStrInfo(STRING_KEY_WLAN_IP, ipAddr) != SOFTBUS_OK) {
309         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
310     }
311     if (LnnSetLocalStrInfo(STRING_KEY_NET_IF_NAME, ifName) != SOFTBUS_OK) {
312         LNN_LOGE(LNN_BUILDER, "set local ifName error");
313         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
314     }
315     return SOFTBUS_OK;
316 }
317 
LeaveOldIpNetwork(const char * ifCurrentName)318 static void LeaveOldIpNetwork(const char *ifCurrentName)
319 {
320     ConnectionAddrType type = CONNECTION_ADDR_MAX;
321     bool addrType[CONNECTION_ADDR_MAX] = {false};
322 
323     if (LnnGetAddrTypeByIfName(ifCurrentName, &type) != SOFTBUS_OK) {
324         LNN_LOGE(LNN_BUILDER, "LnnGetAddrTypeByIfName failed ifName=%{public}s", ifCurrentName);
325         return;
326     }
327     if (type == CONNECTION_ADDR_MAX) {
328         addrType[CONNECTION_ADDR_WLAN] = true;
329         addrType[CONNECTION_ADDR_ETH] = true;
330     } else {
331         addrType[type] = true;
332     }
333     LNN_LOGI(LNN_BUILDER, "LNN start leave ip network");
334     if (LnnRequestLeaveByAddrType(addrType, CONNECTION_ADDR_MAX) != SOFTBUS_OK) {
335         LNN_LOGE(LNN_BUILDER, "LNN leave ip network fail");
336     }
337 }
338 
ReleaseMainPort(const char * ifName)339 static int32_t ReleaseMainPort(const char *ifName)
340 {
341     char oldMainIf[NET_IF_NAME_LEN] = {0};
342     do {
343         if (LnnGetLocalStrInfo(STRING_KEY_NET_IF_NAME, oldMainIf, sizeof(oldMainIf)) != SOFTBUS_OK) {
344             LNN_LOGE(LNN_BUILDER, "get local ifName error!");
345             break;
346         }
347         if (strcmp(ifName, oldMainIf) != 0) {
348             LNN_LOGE(LNN_BUILDER, "if is not main port! ifName=%{public}s", ifName);
349             return SOFTBUS_CMP_FAIL;
350         }
351     } while (false);
352     if (SetLocalIpInfo(LNN_LOOPBACK_IP, LNN_LOOPBACK_IFNAME) != SOFTBUS_OK) {
353         LNN_LOGE(LNN_BUILDER, "set local ip info failed");
354         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
355     }
356     return SOFTBUS_OK;
357 }
358 
RequestMainPort(const char * ifName,const char * address)359 static int32_t RequestMainPort(const char *ifName, const char *address)
360 {
361     if (strcmp(ifName, LNN_LOOPBACK_IFNAME) == 0) {
362         LNN_LOGE(LNN_BUILDER, "loopback ifName not allowed");
363         return SOFTBUS_CMP_FAIL;
364     }
365     if (strcmp(address, LNN_LOOPBACK_IP) == 0) {
366         LNN_LOGE(LNN_BUILDER, "loopback ip not allowed");
367         return SOFTBUS_CMP_FAIL;
368     }
369     LNN_LOGI(LNN_BUILDER, "get local ifName begin");
370     char oldMainIf[NET_IF_NAME_LEN] = {0};
371     if (LnnGetLocalStrInfo(STRING_KEY_NET_IF_NAME, oldMainIf, sizeof(oldMainIf)) != SOFTBUS_OK) {
372         LNN_LOGE(LNN_BUILDER, "get local ifName error");
373         return SOFTBUS_NETWORK_GET_NODE_INFO_ERR;
374     }
375     LNN_LOGD(LNN_BUILDER, "get local ifName end");
376     if (strcmp(oldMainIf, ifName) != 0 && strcmp(oldMainIf, LNN_LOOPBACK_IFNAME) != 0) {
377         LNN_LOGE(LNN_BUILDER, "Only 1 local subnet is allowed");
378         return SOFTBUS_CMP_FAIL;
379     }
380     if (SetLocalIpInfo(address, ifName) != SOFTBUS_OK) {
381         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
382     }
383     return SOFTBUS_OK;
384 }
385 
EnableIpSubnet(LnnPhysicalSubnet * subnet)386 static int32_t EnableIpSubnet(LnnPhysicalSubnet *subnet)
387 {
388     char address[IP_LEN] = {0};
389 
390     int32_t ret = GetAvailableIpAddr(subnet->ifName, address, sizeof(address));
391     if (ret != SOFTBUS_OK) {
392         LNN_LOGE(LNN_BUILDER, "get available Ip failed! ifName=%{public}s, ret=%{public}d", subnet->ifName, ret);
393         return ret;
394     }
395     if (RequestMainPort(subnet->ifName, address)) {
396         LNN_LOGE(LNN_BUILDER, "request main port failed! ifName=%{public}s", subnet->ifName);
397         return SOFTBUS_NETWORK_PORT_PROCESS_FAILED;
398     }
399     LNN_LOGI(LNN_BUILDER, "open ip link and start discovery");
400     if (OpenIpLink() != SOFTBUS_OK) {
401         LNN_LOGE(LNN_BUILDER, "open ip link failed");
402         return SOFTBUS_CONN_AUTH_START_LISTEN_FAIL;
403     }
404     if (ConnCoapStartServerListen() != SOFTBUS_OK) {
405         LNN_LOGE(LNN_BUILDER, "start coap conn server failed");
406     }
407     if (!LnnIsAutoNetWorkingEnabled()) {
408         LNN_LOGI(LNN_BUILDER, "auto network disable");
409         return SOFTBUS_OK;
410     }
411     DiscLinkStatusChanged(LINK_STATUS_UP, COAP);
412     if (LnnStartPublish() != SOFTBUS_OK) {
413         LNN_LOGE(LNN_BUILDER, "start publish failed");
414     }
415     if (LnnStartDiscovery() != SOFTBUS_OK) {
416         LNN_LOGE(LNN_BUILDER, "start discovery failed");
417     }
418     return SOFTBUS_OK;
419 }
420 
DisableIpSubnet(LnnPhysicalSubnet * subnet)421 static int32_t DisableIpSubnet(LnnPhysicalSubnet *subnet)
422 {
423     if (subnet->status == LNN_SUBNET_RUNNING) {
424         LnnIpAddrChangeEventHandler();
425         CloseIpLink();
426         LnnStopPublish();
427         LnnStopDiscovery();
428         ConnCoapStopServerListen();
429         DiscLinkStatusChanged(LINK_STATUS_DOWN, COAP);
430         LeaveOldIpNetwork(subnet->ifName);
431         ReleaseMainPort(subnet->ifName);
432     }
433     return SOFTBUS_OK;
434 }
435 
ChangeIpSubnetAddress(LnnPhysicalSubnet * subnet)436 static int32_t ChangeIpSubnetAddress(LnnPhysicalSubnet *subnet)
437 {
438     CloseIpLink();
439     LnnStopPublish();
440     LnnStopDiscovery();
441     ConnCoapStopServerListen();
442     DiscLinkStatusChanged(LINK_STATUS_DOWN, COAP);
443     LeaveOldIpNetwork(subnet->ifName);
444     return SOFTBUS_OK;
445 }
446 
DestroyIpSubnetManager(LnnPhysicalSubnet * subnet)447 static void DestroyIpSubnetManager(LnnPhysicalSubnet *subnet)
448 {
449     if (subnet->status == LNN_SUBNET_RUNNING) {
450         DisableIpSubnet(subnet);
451     }
452     SoftBusFree(subnet);
453 }
454 
455 typedef enum {
456     IP_SUBNET_MANAGER_EVENT_IF_READY,
457     IP_SUBNET_MANAGER_EVENT_IF_DOWN,    // addr change from available to
458     IP_SUBNET_MANAGER_EVENT_IF_CHANGED, // addr changed
459     IP_SUBNET_MANAGER_EVENT_MAX
460 } IpSubnetManagerEvent;
461 
462 typedef enum {
463     IP_EVENT_RESULT_ACCEPTED = 0,
464     IP_EVENT_RESULT_REJECTED,
465     IP_EVENT_RESULT_OPTION_COUNT
466 } IpSubnetManagerEventResultOptions;
467 
TransactIpSubnetState(LnnPhysicalSubnet * subnet,IpSubnetManagerEvent event,bool isAccepted)468 static void TransactIpSubnetState(LnnPhysicalSubnet *subnet, IpSubnetManagerEvent event, bool isAccepted)
469 {
470     LnnPhysicalSubnetStatus transactMap[][IP_EVENT_RESULT_OPTION_COUNT] = {
471         [IP_SUBNET_MANAGER_EVENT_IF_READY] = {LNN_SUBNET_RUNNING, LNN_SUBNET_IDLE},
472         [IP_SUBNET_MANAGER_EVENT_IF_DOWN] = {LNN_SUBNET_SHUTDOWN, subnet->status},
473         [IP_SUBNET_MANAGER_EVENT_IF_CHANGED] = {LNN_SUBNET_RESETTING, subnet->status}
474     };
475     subnet->status = transactMap[event][isAccepted ? IP_EVENT_RESULT_ACCEPTED : IP_EVENT_RESULT_REJECTED];
476     LNN_LOGD(LNN_BUILDER, "subnet state change. ifName=%{public}s, protocolId=%{public}u, status=%{public}d",
477         subnet->ifName, subnet->protocol->id, subnet->status);
478 }
479 
GetIpEventInOther(LnnPhysicalSubnet * subnet)480 static IpSubnetManagerEvent GetIpEventInOther(LnnPhysicalSubnet *subnet)
481 {
482     char currentIfAddress[IP_LEN] = {0};
483     int32_t ret = GetAvailableIpAddr(subnet->ifName, currentIfAddress, sizeof(currentIfAddress));
484     if (ret == SOFTBUS_OK) {
485         return IP_SUBNET_MANAGER_EVENT_IF_READY;
486     }
487     return subnet->status == LNN_SUBNET_SHUTDOWN ? IP_SUBNET_MANAGER_EVENT_IF_DOWN : IP_SUBNET_MANAGER_EVENT_MAX;
488 }
489 
GetIpEventInRunning(LnnPhysicalSubnet * subnet)490 static IpSubnetManagerEvent GetIpEventInRunning(LnnPhysicalSubnet *subnet)
491 {
492     char currentIfAddress[IP_LEN] = {0};
493     int32_t ret = GetAvailableIpAddr(subnet->ifName, currentIfAddress, sizeof(currentIfAddress));
494     if (ret != SOFTBUS_OK) {
495         return IP_SUBNET_MANAGER_EVENT_IF_DOWN;
496     }
497 
498     char localIpAddr[IP_LEN] = {0};
499     char localNetifName[NET_IF_NAME_LEN] = {0};
500     if (GetLocalIpInfo(localIpAddr, sizeof(localIpAddr), localNetifName, sizeof(localNetifName)) != SOFTBUS_OK) {
501         LNN_LOGE(LNN_BUILDER, "get main ip info failed");
502         return IP_SUBNET_MANAGER_EVENT_IF_READY;
503     }
504     if (strcmp(localNetifName, subnet->ifName) != 0) {
505         return IP_SUBNET_MANAGER_EVENT_IF_READY;
506     }
507     if (strcmp(localIpAddr, currentIfAddress) == 0) {
508         return IP_SUBNET_MANAGER_EVENT_MAX;
509     } else {
510         return IP_SUBNET_MANAGER_EVENT_IF_CHANGED;
511     }
512 }
513 
OnSoftbusIpNetworkDisconnected(LnnPhysicalSubnet * subnet)514 static void OnSoftbusIpNetworkDisconnected(LnnPhysicalSubnet *subnet)
515 {
516     if (subnet->status == LNN_SUBNET_RESETTING || subnet->status == LNN_SUBNET_IDLE) {
517         int32_t ret = EnableIpSubnet(subnet);
518         TransactIpSubnetState(subnet, IP_SUBNET_MANAGER_EVENT_IF_READY, (ret == SOFTBUS_OK));
519     }
520 }
521 
OnIpNetifStatusChanged(LnnPhysicalSubnet * subnet,void * status)522 static void OnIpNetifStatusChanged(LnnPhysicalSubnet *subnet, void *status)
523 {
524     IpSubnetManagerEvent event = IP_SUBNET_MANAGER_EVENT_MAX;
525     if (status == NULL) {
526         if (subnet->status == LNN_SUBNET_RUNNING) {
527             event = GetIpEventInRunning(subnet);
528         } else {
529             event = GetIpEventInOther(subnet);
530         }
531     } else {
532         event = *(IpSubnetManagerEvent *)status;
533         LNN_LOGI(LNN_BUILDER, "want to enter event=%{public}d", event);
534         SoftBusFree(status);
535         if (event < IP_SUBNET_MANAGER_EVENT_IF_READY || event > IP_SUBNET_MANAGER_EVENT_MAX) {
536             LNN_LOGW(LNN_BUILDER, "is not right event=%{public}d", event);
537             return;
538         }
539     }
540 
541     int32_t ret = SOFTBUS_NETWORK_NETIF_STATUS_CHANGED;
542     switch (event) {
543         case IP_SUBNET_MANAGER_EVENT_IF_READY: {
544             ret = EnableIpSubnet(subnet);
545             break;
546         }
547         case IP_SUBNET_MANAGER_EVENT_IF_DOWN: {
548             ret = DisableIpSubnet(subnet);
549             break;
550         }
551         case IP_SUBNET_MANAGER_EVENT_IF_CHANGED: {
552             ret = ChangeIpSubnetAddress(subnet);
553             break;
554         }
555         default:
556             return;
557     }
558 
559     TransactIpSubnetState(subnet, event, (ret == SOFTBUS_OK));
560 }
561 
CreateIpSubnetManager(const struct LnnProtocolManager * self,const char * ifName)562 static LnnPhysicalSubnet *CreateIpSubnetManager(const struct LnnProtocolManager *self, const char *ifName)
563 {
564     LnnPhysicalSubnet *subnet = (LnnPhysicalSubnet *)SoftBusCalloc(sizeof(LnnPhysicalSubnet));
565     if (subnet == NULL) {
566         LNN_LOGE(LNN_BUILDER, "malloc subnet fail");
567         return NULL;
568     }
569 
570     do {
571         subnet->destroy = DestroyIpSubnetManager;
572         subnet->protocol = self;
573         subnet->status = LNN_SUBNET_IDLE;
574         subnet->onNetifStatusChanged = OnIpNetifStatusChanged;
575         subnet->onSoftbusNetworkDisconnected = OnSoftbusIpNetworkDisconnected;
576 
577         int32_t ret = strcpy_s(subnet->ifName, sizeof(subnet->ifName), ifName);
578         if (ret != EOK) {
579             LNN_LOGE(LNN_BUILDER, "copy ifName failed ret=%{public}d", ret);
580             break;
581         }
582         return subnet;
583     } while (false);
584 
585     subnet->destroy((LnnPhysicalSubnet *)subnet);
586     return NULL;
587 }
588 
IpAddrChangeEventHandler(const LnnEventBasicInfo * info)589 static void IpAddrChangeEventHandler(const LnnEventBasicInfo *info)
590 {
591     if (info == NULL || info->event != LNN_EVENT_IP_ADDR_CHANGED) {
592         LNN_LOGE(LNN_BUILDER, "not interest event");
593         return;
594     }
595     const LnnMonitorAddressChangedEvent *event = (const LnnMonitorAddressChangedEvent *)info;
596     if (strlen(event->ifName) != 0) {
597         LnnNotifyPhysicalSubnetStatusChanged(event->ifName, LNN_PROTOCOL_IP, NULL);
598         DfxRecordTriggerTime(WIFI_IP_ADDR_CHANGED, EVENT_STAGE_LNN_WIFI_TRIGGER);
599     }
600 }
601 
WifiStateChangeWifiOrAp(const SoftBusWifiState wifiState)602 static bool WifiStateChangeWifiOrAp(const SoftBusWifiState wifiState)
603 {
604     switch (wifiState) {
605         case SOFTBUS_WIFI_CONNECTED:
606             g_wifiConnected = true;
607             return true;
608         case SOFTBUS_WIFI_DISCONNECTED:
609             g_wifiConnected = false;
610             return true;
611         case SOFTBUS_AP_ENABLED:
612             g_apEnabled = true;
613             return true;
614         case SOFTBUS_AP_DISABLED:
615             g_apEnabled = false;
616             return true;
617         default:
618             return false;
619     }
620 }
621 
IsValidLocalIp(void)622 static bool IsValidLocalIp(void)
623 {
624     char localIp[MAX_ADDR_LEN] = {0};
625     if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, localIp, MAX_ADDR_LEN) != SOFTBUS_OK) {
626         LNN_LOGE(LNN_BUILDER, "get local ip failed");
627         return false;
628     }
629     if (strcmp(localIp, LNN_LOOPBACK_IP) == 0 || strcmp(localIp, "") == 0 || strcmp(localIp, "0.0.0.0") == 0) {
630         return false;
631     }
632     return true;
633 }
634 
WifiStateChangeEventHandler(const LnnEventBasicInfo * info)635 static void WifiStateChangeEventHandler(const LnnEventBasicInfo *info)
636 {
637     if (info == NULL || info->event != LNN_EVENT_WIFI_STATE_CHANGED) {
638         LNN_LOGE(LNN_BUILDER, "not interest event");
639         return;
640     }
641     if (!g_heartbeatEnable) {
642         LNN_LOGI(LNN_BUILDER, "g_heartbeatEnable not enable");
643         return;
644     }
645     const LnnMonitorWlanStateChangedEvent *event = (const LnnMonitorWlanStateChangedEvent *)info;
646     SoftBusWifiState wifiState = (SoftBusWifiState)event->status;
647     LNN_LOGI(LNN_BUILDER, "wifi state change. wifiState=%{public}d", wifiState);
648     bool beforeConnected = g_apEnabled || g_wifiConnected;
649     if (!WifiStateChangeWifiOrAp(wifiState)) {
650         LNN_LOGI(LNN_BUILDER, "not interest wifi event");
651         return;
652     }
653     bool currentConnected = g_apEnabled || g_wifiConnected;
654     bool isValidIp = IsValidLocalIp();
655     LNN_LOGI(LNN_BUILDER,
656         "wifi or ap wifiConnected=%{public}d, apEnabled=%{public}d, beforeConnected=%{public}d, "
657         "currentConnected=%{public}d, isValidIp=%{public}d",
658         g_wifiConnected, g_apEnabled, beforeConnected, currentConnected, isValidIp);
659     IpSubnetManagerEvent *status = (IpSubnetManagerEvent *)SoftBusCalloc(sizeof(IpSubnetManagerEvent));
660     if (status == NULL) {
661         LNN_LOGE(LNN_BUILDER, "wifi start calloc fail");
662         return;
663     }
664     if ((beforeConnected != currentConnected) || (currentConnected && !isValidIp)) {
665         LNN_LOGI(LNN_BUILDER, "wifi start to subnet change!");
666         if (currentConnected) {
667             SoftBusFree(status);
668             (void)LnnVisitNetif(NotifyWlanAddressChanged, NULL);
669         } else {
670             *status = IP_SUBNET_MANAGER_EVENT_IF_DOWN;
671             (void)LnnVisitNetif(NotifyWlanAddressChanged, status);
672         }
673         return;
674     }
675     SoftBusFree(status);
676 }
677 
LnnInitIpProtocol(struct LnnProtocolManager * self)678 int32_t LnnInitIpProtocol(struct LnnProtocolManager *self)
679 {
680     (void)self;
681     int32_t ret = SOFTBUS_OK;
682     if (LnnRegisterEventHandler(LNN_EVENT_IP_ADDR_CHANGED, IpAddrChangeEventHandler) != SOFTBUS_OK) {
683         LNN_LOGE(LNN_INIT, "register ip addr change event handler failed");
684         return SOFTBUS_NETWORK_REG_EVENT_HANDLER_ERR;
685     }
686     if (SetLocalIpInfo(LNN_LOOPBACK_IP, LNN_LOOPBACK_IFNAME) != SOFTBUS_OK) {
687         LNN_LOGE(LNN_INIT, "init local ip as loopback failed!");
688         return SOFTBUS_NETWORK_SET_NODE_INFO_ERR;
689     }
690     DiscLinkStatusChanged(LINK_STATUS_DOWN, COAP);
691     g_heartbeatEnable = IsEnableSoftBusHeartbeat();
692     LNN_LOGI(LNN_INIT, "init IP protocol g_heartbeatEnable=%{public}d", g_heartbeatEnable);
693     return ret;
694 }
695 
LnnEnableIpProtocol(struct LnnProtocolManager * self,LnnNetIfMgr * netifMgr)696 int32_t LnnEnableIpProtocol(struct LnnProtocolManager *self, LnnNetIfMgr *netifMgr)
697 {
698     (void)self;
699     if (netifMgr == NULL) {
700         LNN_LOGE(LNN_BUILDER, "netif mgr is null");
701         return SOFTBUS_INVALID_PARAM;
702     }
703     LnnPhysicalSubnet *manager = CreateIpSubnetManager(self, netifMgr->ifName);
704     if (manager == NULL) {
705         LNN_LOGE(LNN_BUILDER, "malloc subnet mgr fail");
706         return SOFTBUS_MALLOC_ERR;
707     }
708     int ret = LnnRegistPhysicalSubnet(manager);
709     if (ret != SOFTBUS_OK) {
710         LNN_LOGE(LNN_BUILDER, "regist subnet manager failed! ret=%{public}d", ret);
711         manager->destroy(manager);
712         return ret;
713     }
714     return SOFTBUS_OK;
715 }
716 
LnnGetIpListenerModule(ListenerMode mode)717 static ListenerModule LnnGetIpListenerModule(ListenerMode mode)
718 {
719     if (mode == LNN_LISTENER_MODE_PROXY) {
720         return PROXY;
721     } else if (mode == LNN_LISTENER_MODE_DIRECT) {
722         return DIRECT_CHANNEL_SERVER_WIFI;
723     } else {
724         return UNUSE_BUTT;
725     }
726 }
727 
LnnDeinitIpNetwork(struct LnnProtocolManager * self)728 void LnnDeinitIpNetwork(struct LnnProtocolManager *self)
729 {
730     (void)self;
731     LnnUnregisterEventHandler(LNN_EVENT_IP_ADDR_CHANGED, IpAddrChangeEventHandler);
732     LnnUnregisterEventHandler(LNN_EVENT_WIFI_STATE_CHANGED, WifiStateChangeEventHandler);
733     LnnUnregistPhysicalSubnetByType(LNN_PROTOCOL_IP);
734     LNN_LOGW(LNN_INIT, "ip network deinited");
735 }
736 
737 static LnnProtocolManager g_ipProtocol = {
738     .init = LnnInitIpProtocol,
739     .deinit = LnnDeinitIpNetwork,
740     .enable = LnnEnableIpProtocol,
741     .disable = NULL,
742     .getListenerModule = LnnGetIpListenerModule,
743     .id = LNN_PROTOCOL_IP,
744     .supportedNetif = LNN_NETIF_TYPE_ETH | LNN_NETIF_TYPE_WLAN,
745     .pri = 10,
746 };
747 
RegistIPProtocolManager(void)748 int32_t RegistIPProtocolManager(void)
749 {
750     return LnnRegistProtocol(&g_ipProtocol);
751 }
752