1 /*
2 * Copyright (c) 2022 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 #include "lnn_physical_subnet_manager.h"
16
17 #include <stddef.h>
18 #include <string.h>
19
20 #include "lnn_log.h"
21 #include "lnn_network_manager.h"
22 #include "softbus_adapter_thread.h"
23 #include "softbus_def.h"
24 #include "softbus_errcode.h"
25
26 #define MAX_SUPPORTED_PHYSICAL_SUBNET 6
27
28 static SoftBusMutex g_physicalSubnetsLock;
29 static LnnPhysicalSubnet *g_physicalSubnets[MAX_SUPPORTED_PHYSICAL_SUBNET];
30
31 #define CALL_WITH_LOCK(RET, LOCK, ACTION) \
32 do { \
33 ret = SoftBusMutexLock(LOCK); \
34 if (ret != SOFTBUS_OK) { \
35 LNN_LOGE(LNN_BUILDER, "lock mutex failed"); \
36 break; \
37 } \
38 (RET) = (ACTION); \
39 SoftBusMutexUnlock(LOCK); \
40 } while (false)
41
42 #define CALL_VOID_FUNC_WITH_LOCK(LOCK, ACTION) \
43 do { \
44 if (SoftBusMutexLock(LOCK) != 0) { \
45 LNN_LOGE(LNN_BUILDER, "lock mutex failed"); \
46 break; \
47 } \
48 (ACTION); \
49 SoftBusMutexUnlock(LOCK); \
50 } while (false)
51
LnnInitPhysicalSubnetManager(void)52 int32_t LnnInitPhysicalSubnetManager(void)
53 {
54 LNN_LOGI(LNN_BUILDER, "g_physicalSubnetsLock init");
55 int32_t ret = SoftBusMutexInit(&g_physicalSubnetsLock, NULL);
56 LNN_LOGI(LNN_BUILDER, "g_physicalSubnetsLock init succ");
57 return ret;
58 }
59
ClearSubnetManager(void)60 static void ClearSubnetManager(void)
61 {
62 for (uint8_t i = 0; i < MAX_SUPPORTED_PHYSICAL_SUBNET; i++) {
63 if (g_physicalSubnets[i] != NULL) {
64 if (g_physicalSubnets[i]->destroy != NULL) {
65 g_physicalSubnets[i]->destroy(g_physicalSubnets[i]);
66 }
67 g_physicalSubnets[i] = NULL;
68 }
69 }
70 }
71
LnnDeinitPhysicalSubnetManager(void)72 void LnnDeinitPhysicalSubnetManager(void)
73 {
74 LNN_LOGI(LNN_BUILDER, "g_physicalSubnetsLock deinit");
75 CALL_VOID_FUNC_WITH_LOCK(&g_physicalSubnetsLock, ClearSubnetManager());
76 LNN_LOGI(LNN_BUILDER, "g_physicalSubnetsLock deinit succ");
77 if (SoftBusMutexDestroy(&g_physicalSubnetsLock) != SOFTBUS_OK) {
78 LNN_LOGE(LNN_BUILDER, "destroy mutex failed");
79 }
80 }
81
DoRegistSubnet(LnnPhysicalSubnet * subnet)82 static int32_t DoRegistSubnet(LnnPhysicalSubnet *subnet)
83 {
84 for (uint8_t i = 0; i < MAX_SUPPORTED_PHYSICAL_SUBNET; i++) {
85 if (g_physicalSubnets[i] != NULL) {
86 continue;
87 }
88 g_physicalSubnets[i] = subnet;
89 if (g_physicalSubnets[i]->onNetifStatusChanged != NULL) {
90 g_physicalSubnets[i]->onNetifStatusChanged(g_physicalSubnets[i], NULL);
91 }
92 return SOFTBUS_OK;
93 }
94 LNN_LOGE(LNN_BUILDER, "subnet list is full");
95 return SOFTBUS_ERR;
96 }
97
LnnRegistPhysicalSubnet(LnnPhysicalSubnet * subnet)98 int32_t LnnRegistPhysicalSubnet(LnnPhysicalSubnet *subnet)
99 {
100 if (subnet == NULL || subnet->protocol == NULL) {
101 LNN_LOGE(LNN_BUILDER, "protocol of subnet is required");
102 return SOFTBUS_ERR;
103 }
104 int32_t ret = SOFTBUS_OK;
105 LNN_LOGI(LNN_BUILDER, "get g_physicalSubnetsLock start, currTime=%{public}" PRIu64, SoftBusGetSysTimeMs());
106 CALL_WITH_LOCK(ret, &g_physicalSubnetsLock, DoRegistSubnet(subnet));
107 LNN_LOGI(LNN_BUILDER, "get g_physicalSubnetsLock end, currTime=%{public}" PRIu64, SoftBusGetSysTimeMs());
108 return ret;
109 }
110
DoUnregistSubnetByType(ProtocolType type)111 static int32_t DoUnregistSubnetByType(ProtocolType type)
112 {
113 for (uint8_t i = 0; i < MAX_SUPPORTED_PHYSICAL_SUBNET; i++) {
114 if (g_physicalSubnets[i] != NULL && g_physicalSubnets[i]->protocol->id == type) {
115 if (g_physicalSubnets[i]->destroy != NULL) {
116 g_physicalSubnets[i]->destroy(g_physicalSubnets[i]);
117 }
118 g_physicalSubnets[i] = NULL;
119 }
120 }
121 return SOFTBUS_OK;
122 }
123
LnnUnregistPhysicalSubnetByType(ProtocolType type)124 int32_t LnnUnregistPhysicalSubnetByType(ProtocolType type)
125 {
126 int32_t ret = SOFTBUS_OK;
127 LNN_LOGI(LNN_BUILDER, "get g_physicalSubnetsLock start, currTime=%{public}" PRIu64, SoftBusGetSysTimeMs());
128 CALL_WITH_LOCK(ret, &g_physicalSubnetsLock, DoUnregistSubnetByType(type));
129 LNN_LOGI(LNN_BUILDER, "get g_physicalSubnetsLock end, currTime=%{public}" PRIu64, SoftBusGetSysTimeMs());
130 return ret;
131 }
132
DoNotifyStatusChange(const char * ifName,ProtocolType protocolType,void * status)133 void DoNotifyStatusChange(const char *ifName, ProtocolType protocolType, void *status)
134 {
135 for (uint16_t i = 0; i < MAX_SUPPORTED_PHYSICAL_SUBNET; i++) {
136 if (g_physicalSubnets[i] == NULL || g_physicalSubnets[i]->protocol->id != protocolType) {
137 continue;
138 }
139
140 if (strcmp(g_physicalSubnets[i]->ifName, LNN_PHYSICAL_SUBNET_ALL_NETIF) != 0 &&
141 strcmp(g_physicalSubnets[i]->ifName, ifName) != 0) {
142 continue;
143 }
144
145 if (g_physicalSubnets[i]->onNetifStatusChanged != NULL) {
146 g_physicalSubnets[i]->onNetifStatusChanged(g_physicalSubnets[i], status);
147 }
148 }
149 }
150
LnnNotifyPhysicalSubnetStatusChanged(const char * ifName,ProtocolType protocolType,void * status)151 void LnnNotifyPhysicalSubnetStatusChanged(const char *ifName, ProtocolType protocolType, void *status)
152 {
153 CALL_VOID_FUNC_WITH_LOCK(&g_physicalSubnetsLock, DoNotifyStatusChange(ifName, protocolType, status));
154 LNN_LOGI(LNN_BUILDER, "success");
155 }
156
EnableResetingSubnetByType(ProtocolType protocolType)157 static void EnableResetingSubnetByType(ProtocolType protocolType)
158 {
159 for (uint16_t i = 0; i < MAX_SUPPORTED_PHYSICAL_SUBNET; i++) {
160 if (g_physicalSubnets[i] == NULL || g_physicalSubnets[i]->protocol->id != protocolType) {
161 continue;
162 }
163 if (g_physicalSubnets[i]->onSoftbusNetworkDisconnected != NULL) {
164 g_physicalSubnets[i]->onSoftbusNetworkDisconnected(g_physicalSubnets[i]);
165 }
166 }
167 }
168
LnnNotifyAllTypeOffline(ConnectionAddrType type)169 void LnnNotifyAllTypeOffline(ConnectionAddrType type)
170 {
171 if (type == CONNECTION_ADDR_ETH || type == CONNECTION_ADDR_WLAN || type == CONNECTION_ADDR_MAX) {
172 CALL_VOID_FUNC_WITH_LOCK(&g_physicalSubnetsLock, EnableResetingSubnetByType(LNN_PROTOCOL_IP));
173 LNN_LOGI(LNN_BUILDER, "success");
174 }
175 }
176
DoVisitSubnet(LnnVisitPhysicalSubnetCallback callback,void * data)177 static bool DoVisitSubnet(LnnVisitPhysicalSubnetCallback callback, void *data)
178 {
179 VisitNextChoice result = CHOICE_VISIT_NEXT;
180 for (uint16_t i = 0; i < MAX_SUPPORTED_PHYSICAL_SUBNET; i++) {
181 if (g_physicalSubnets[i] == NULL) {
182 continue;
183 }
184 result = callback(g_physicalSubnets[i], data);
185 if (result == CHOICE_FINISH_VISITING) {
186 return false;
187 }
188 }
189 return true;
190 }
191
LnnVisitPhysicalSubnet(LnnVisitPhysicalSubnetCallback callback,void * data)192 bool LnnVisitPhysicalSubnet(LnnVisitPhysicalSubnetCallback callback, void *data)
193 {
194 bool ret = false;
195 LNN_LOGI(LNN_BUILDER, "get g_physicalSubnetsLock start, currTime=%{public}" PRIu64, SoftBusGetSysTimeMs());
196 CALL_WITH_LOCK(ret, &g_physicalSubnetsLock, DoVisitSubnet(callback, data));
197 LNN_LOGI(LNN_BUILDER, "get g_physicalSubnetsLock end, currTime=%{public}" PRIu64, SoftBusGetSysTimeMs());
198 return ret;
199 }
200