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