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