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