• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_network_manager.h"
21 #include "softbus_adapter_thread.h"
22 #include "softbus_def.h"
23 #include "softbus_errcode.h"
24 #include "softbus_log.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             HILOG_ERROR(SOFTBUS_HILOG_ID, "%s:lock mutex failed", __func__); \
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             HILOG_ERROR(SOFTBUS_HILOG_ID, "%s:lock mutex failed", __func__); \
46             break;                                                           \
47         }                                                                    \
48         (ACTION);                                                            \
49         SoftBusMutexUnlock(LOCK);                                            \
50     } while (false)
51 
LnnInitPhysicalSubnetManager(void)52 NO_SANITIZE("cfi") int32_t LnnInitPhysicalSubnetManager(void)
53 {
54     return SoftBusMutexInit(&g_physicalSubnetsLock, NULL);
55 }
56 
ClearSubnetManager(void)57 static void ClearSubnetManager(void)
58 {
59     for (uint8_t i = 0; i < MAX_SUPPORTED_PHYSICAL_SUBNET; i++) {
60         if (g_physicalSubnets[i] != NULL) {
61             if (g_physicalSubnets[i]->destroy != NULL) {
62                 g_physicalSubnets[i]->destroy(g_physicalSubnets[i]);
63             }
64             g_physicalSubnets[i] = NULL;
65         }
66     }
67 }
68 
LnnDeinitPhysicalSubnetManager(void)69 NO_SANITIZE("cfi") void LnnDeinitPhysicalSubnetManager(void)
70 {
71     CALL_VOID_FUNC_WITH_LOCK(&g_physicalSubnetsLock, ClearSubnetManager());
72     if (SoftBusMutexDestroy(&g_physicalSubnetsLock) != SOFTBUS_OK) {
73         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "%s: destroy mutex failed!", __func__);
74     }
75 }
76 
DoRegistSubnet(LnnPhysicalSubnet * subnet)77 static int32_t DoRegistSubnet(LnnPhysicalSubnet *subnet)
78 {
79     for (uint8_t i = 0; i < MAX_SUPPORTED_PHYSICAL_SUBNET; i++) {
80         if (g_physicalSubnets[i] != NULL) {
81             continue;
82         }
83         g_physicalSubnets[i] = subnet;
84         if (g_physicalSubnets[i]->onNetifStatusChanged != NULL) {
85             g_physicalSubnets[i]->onNetifStatusChanged(g_physicalSubnets[i], NULL);
86         }
87         return SOFTBUS_OK;
88     }
89     SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "%s: subnet list is full", __func__);
90     return SOFTBUS_ERR;
91 }
92 
LnnRegistPhysicalSubnet(LnnPhysicalSubnet * subnet)93 NO_SANITIZE("cfi") int32_t LnnRegistPhysicalSubnet(LnnPhysicalSubnet *subnet)
94 {
95     if (subnet == NULL || subnet->protocol == NULL) {
96         SoftBusLog(SOFTBUS_LOG_LNN, SOFTBUS_LOG_ERROR, "%s: protocol of subnet is required!", __func__);
97         return SOFTBUS_ERR;
98     }
99     int32_t ret = SOFTBUS_OK;
100     CALL_WITH_LOCK(ret, &g_physicalSubnetsLock, DoRegistSubnet(subnet));
101     return ret;
102 }
103 
DoUnregistSubnetByType(ProtocolType type)104 static int32_t DoUnregistSubnetByType(ProtocolType type)
105 {
106     for (uint8_t i = 0; i < MAX_SUPPORTED_PHYSICAL_SUBNET; i++) {
107         if (g_physicalSubnets[i] != NULL && g_physicalSubnets[i]->protocol->id == type) {
108             if (g_physicalSubnets[i]->destroy != NULL) {
109                 g_physicalSubnets[i]->destroy(g_physicalSubnets[i]);
110             }
111             g_physicalSubnets[i] = NULL;
112         }
113     }
114     return SOFTBUS_OK;
115 }
116 
LnnUnregistPhysicalSubnetByType(ProtocolType type)117 NO_SANITIZE("cfi") int32_t LnnUnregistPhysicalSubnetByType(ProtocolType type)
118 {
119     int32_t ret = SOFTBUS_OK;
120     CALL_WITH_LOCK(ret, &g_physicalSubnetsLock, DoUnregistSubnetByType(type));
121     return ret;
122 }
123 
DoNotifyStatusChange(const char * ifName,ProtocolType protocolType,void * status)124 void DoNotifyStatusChange(const char *ifName, ProtocolType protocolType, void *status)
125 {
126     for (uint16_t i = 0; i < MAX_SUPPORTED_PHYSICAL_SUBNET; i++) {
127         if (g_physicalSubnets[i] == NULL || g_physicalSubnets[i]->protocol->id != protocolType) {
128             continue;
129         }
130 
131         if (strcmp(g_physicalSubnets[i]->ifName, LNN_PHYSICAL_SUBNET_ALL_NETIF) != 0 &&
132             strcmp(g_physicalSubnets[i]->ifName, ifName) != 0) {
133             continue;
134         }
135 
136         if (g_physicalSubnets[i]->onNetifStatusChanged != NULL) {
137             g_physicalSubnets[i]->onNetifStatusChanged(g_physicalSubnets[i], status);
138         }
139     }
140 }
141 
LnnNotifyPhysicalSubnetStatusChanged(const char * ifName,ProtocolType protocolType,void * status)142 void LnnNotifyPhysicalSubnetStatusChanged(const char *ifName, ProtocolType protocolType, void *status)
143 {
144     CALL_VOID_FUNC_WITH_LOCK(&g_physicalSubnetsLock, DoNotifyStatusChange(ifName, protocolType, status));
145 }
146 
EnableResetingSubnetByType(ProtocolType protocolType)147 NO_SANITIZE("cfi") static void EnableResetingSubnetByType(ProtocolType protocolType)
148 {
149     for (uint16_t i = 0; i < MAX_SUPPORTED_PHYSICAL_SUBNET; i++) {
150         if (g_physicalSubnets[i] == NULL || g_physicalSubnets[i]->protocol->id != protocolType) {
151             continue;
152         }
153         if (g_physicalSubnets[i]->onSoftbusNetworkDisconnected != NULL) {
154             g_physicalSubnets[i]->onSoftbusNetworkDisconnected(g_physicalSubnets[i]);
155         }
156     }
157 }
158 
LnnNotifyAllTypeOffline(ConnectionAddrType type)159 NO_SANITIZE("cfi") void LnnNotifyAllTypeOffline(ConnectionAddrType type)
160 {
161     if (type == CONNECTION_ADDR_ETH || type == CONNECTION_ADDR_WLAN || type == CONNECTION_ADDR_MAX) {
162         CALL_VOID_FUNC_WITH_LOCK(&g_physicalSubnetsLock, EnableResetingSubnetByType(LNN_PROTOCOL_IP));
163     }
164 }
165 
DoVisitSubnet(LnnVisitPhysicalSubnetCallback callback,void * data)166 static bool DoVisitSubnet(LnnVisitPhysicalSubnetCallback callback, void *data)
167 {
168     VisitNextChoice result = CHOICE_VISIT_NEXT;
169     for (uint16_t i = 0; i < MAX_SUPPORTED_PHYSICAL_SUBNET; i++) {
170         if (g_physicalSubnets[i] == NULL) {
171             continue;
172         }
173         result = callback(g_physicalSubnets[i], data);
174         if (result == CHOICE_FINISH_VISITING) {
175             return false;
176         }
177     }
178     return true;
179 }
180 
LnnVisitPhysicalSubnet(LnnVisitPhysicalSubnetCallback callback,void * data)181 NO_SANITIZE("cfi") bool LnnVisitPhysicalSubnet(LnnVisitPhysicalSubnetCallback callback, void *data)
182 {
183     bool ret = false;
184     CALL_WITH_LOCK(ret, &g_physicalSubnetsLock, DoVisitSubnet(callback, data));
185     return ret;
186 }
187