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 "lnn_meta_node_ledger.h"
17 
18 #include <securec.h>
19 #include <string.h>
20 
21 #include "lnn_deviceinfo_to_profile.h"
22 #include "lnn_log.h"
23 #include "lnn_network_id.h"
24 #include "softbus_adapter_mem.h"
25 #include "softbus_def.h"
26 #include "softbus_errcode.h"
27 #include "softbus_utils.h"
28 
29 typedef struct {
30     ListNode node;
31     MetaNodeInfo info;
32 } MetaNodeStorageInfo;
33 
34 static SoftBusList *g_metaNodeList = NULL;
35 
CheckMetaNodeConfigInfo(const MetaNodeConfigInfo * info)36 static bool CheckMetaNodeConfigInfo(const MetaNodeConfigInfo *info)
37 {
38     if (info == NULL) {
39         return false;
40     }
41     if (info->addrNum > CONNECTION_ADDR_MAX) {
42         return false;
43     }
44     return true;
45 }
46 
FindMetaNodeStorageInfo(const char * id,bool isUdid)47 static MetaNodeStorageInfo *FindMetaNodeStorageInfo(const char *id, bool isUdid)
48 {
49     MetaNodeStorageInfo *item = NULL;
50     MetaNodeStorageInfo *next = NULL;
51     const char *itemId = NULL;
52 
53     LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_metaNodeList->list, MetaNodeStorageInfo, node) {
54         itemId = isUdid ? item->info.configInfo.udid : item->info.metaNodeId;
55         if (strlen(id) > strlen(itemId)) {
56             LNN_LOGE(LNN_LEDGER, "id is invalid");
57             continue;
58         }
59         if (strncmp(itemId, id, strlen(id)) == 0) {
60             return item;
61         }
62     }
63     return NULL;
64 }
65 
CreateMetaNodeStorageInfo(const MetaNodeConfigInfo * info,const char * networkId)66 static MetaNodeStorageInfo *CreateMetaNodeStorageInfo(const MetaNodeConfigInfo *info, const char *networkId)
67 {
68     MetaNodeStorageInfo *storageInfo = SoftBusCalloc(sizeof(MetaNodeStorageInfo));
69     if (storageInfo == NULL) {
70         LNN_LOGE(LNN_LEDGER, "create meta node storage info fail");
71         return NULL;
72     }
73     ListInit(&storageInfo->node);
74     storageInfo->info.configInfo = *info;
75     storageInfo->info.isOnline = false;
76     if (strncpy_s(storageInfo->info.metaNodeId, NETWORK_ID_BUF_LEN, networkId, strlen(networkId)) != SOFTBUS_OK) {
77         LNN_LOGE(LNN_LEDGER, "copy meta node id fail");
78         SoftBusFree(storageInfo);
79         return NULL;
80     }
81     return storageInfo;
82 }
83 
LnnActiveMetaNode(const MetaNodeConfigInfo * info,char * metaNodeId)84 int32_t LnnActiveMetaNode(const MetaNodeConfigInfo *info, char *metaNodeId)
85 {
86     MetaNodeStorageInfo *storageInfo = NULL;
87     int32_t rc = SOFTBUS_ERR;
88 
89     if (!CheckMetaNodeConfigInfo(info) || metaNodeId == NULL) {
90         LNN_LOGE(LNN_LEDGER, "LnnActiveMetaNode: para is invalid");
91         return SOFTBUS_INVALID_PARAM;
92     }
93     if (SoftBusMutexLock(&g_metaNodeList->lock) != SOFTBUS_OK) {
94         LNN_LOGE(LNN_LEDGER, "LnnActiveMetaNode: lock failed");
95         return SOFTBUS_LOCK_ERR;
96     }
97     do {
98         storageInfo = FindMetaNodeStorageInfo(info->udid, true);
99         if (storageInfo == NULL) {
100             if (g_metaNodeList->cnt >= MAX_META_NODE_NUM) {
101                 LNN_LOGE(LNN_LEDGER, "meta node exceed maximum");
102                 break;
103             }
104             if (LnnGenLocalNetworkId(metaNodeId, NETWORK_ID_BUF_LEN) != SOFTBUS_OK) {
105                 LNN_LOGE(LNN_LEDGER, "generate meta node id fail");
106                 break;
107             }
108             storageInfo = CreateMetaNodeStorageInfo(info, metaNodeId);
109             if (storageInfo == NULL) {
110                 break;
111             }
112             ListAdd(&g_metaNodeList->list, &storageInfo->node);
113             g_metaNodeList->cnt++;
114             InsertMetaNodeInfoToProfile(&storageInfo->info);
115             LNN_LOGI(LNN_LEDGER, "active a mete node");
116         } else {
117             if (strncpy_s(metaNodeId, NETWORK_ID_BUF_LEN, storageInfo->info.metaNodeId,
118                 strlen(storageInfo->info.metaNodeId)) != EOK) {
119                 LNN_LOGE(LNN_LEDGER, "copy meta node id fail");
120                 break;
121             }
122             storageInfo->info.configInfo = *info;
123             UpdateMetaNodeProfile(&storageInfo->info);
124             LNN_LOGI(LNN_LEDGER, "update a mete node");
125         }
126         rc = SOFTBUS_OK;
127     } while (false);
128     if (SoftBusMutexUnlock(&g_metaNodeList->lock) != 0) {
129         LNN_LOGE(LNN_LEDGER, "LnnActiveMetaNode: unlock failed");
130     }
131     return rc;
132 }
133 
LnnDeactiveMetaNode(const char * metaNodeId)134 int32_t LnnDeactiveMetaNode(const char *metaNodeId)
135 {
136     MetaNodeStorageInfo *storageInfo = NULL;
137     int32_t rc = SOFTBUS_OK;
138 
139     if (metaNodeId == NULL) {
140         LNN_LOGE(LNN_LEDGER, "LnnDeactiveMetaNode: para is invalid");
141         return SOFTBUS_INVALID_PARAM;
142     }
143     if (SoftBusMutexLock(&g_metaNodeList->lock) != SOFTBUS_OK) {
144         LNN_LOGE(LNN_LEDGER, "LnnDeactiveMetaNode: lock failed");
145         return SOFTBUS_LOCK_ERR;
146     }
147     storageInfo = FindMetaNodeStorageInfo(metaNodeId, false);
148     if (storageInfo != NULL) {
149         ListDelete(&storageInfo->node);
150         g_metaNodeList->cnt--;
151         DeleteFromProfile(storageInfo->info.configInfo.udid);
152         SoftBusFree(storageInfo);
153         LNN_LOGI(LNN_LEDGER, "deactive a mete node");
154     } else {
155         LNN_LOGE(LNN_LEDGER, "meta node not exist");
156         rc = SOFTBUS_ERR;
157     }
158     if (SoftBusMutexUnlock(&g_metaNodeList->lock) != SOFTBUS_OK) {
159         LNN_LOGE(LNN_LEDGER, "LnnDeactiveMetaNode: unlock failed");
160     }
161     return rc;
162 }
163 
LnnGetAllMetaNodeInfo(MetaNodeInfo * infos,int32_t * infoNum)164 int32_t LnnGetAllMetaNodeInfo(MetaNodeInfo *infos, int32_t *infoNum)
165 {
166     MetaNodeStorageInfo *item = NULL;
167     int32_t i = 0;
168 
169     if (infos == NULL || infoNum == NULL) {
170         LNN_LOGE(LNN_LEDGER, "LnnGetAllMetaNodeInfo: para is invalid");
171         return SOFTBUS_INVALID_PARAM;
172     }
173     if (SoftBusMutexLock(&g_metaNodeList->lock) != SOFTBUS_OK) {
174         LNN_LOGE(LNN_LEDGER, "LnnGetAllMetaNodeInfo: lock failed");
175         return SOFTBUS_LOCK_ERR;
176     }
177     if (*infoNum < (int32_t)g_metaNodeList->cnt) {
178         LNN_LOGE(LNN_LEDGER, "meta node info num too small");
179         (void)SoftBusMutexUnlock(&g_metaNodeList->lock);
180         return SOFTBUS_INVALID_PARAM;
181     }
182     LIST_FOR_EACH_ENTRY(item, &g_metaNodeList->list, MetaNodeStorageInfo, node) {
183         infos[i] = item->info;
184         i += 1;
185     }
186     *infoNum = i;
187     if (SoftBusMutexUnlock(&g_metaNodeList->lock) != SOFTBUS_OK) {
188         LNN_LOGE(LNN_LEDGER, "LnnGetAllMetaNodeInfo: unlock failed");
189     }
190     return SOFTBUS_OK;
191 }
192 
LnnGetMetaNodeUdidByNetworkId(const char * networkId,char * udid)193 int32_t LnnGetMetaNodeUdidByNetworkId(const char *networkId, char *udid)
194 {
195     MetaNodeStorageInfo *item = NULL;
196     int32_t ret = SOFTBUS_ERR;
197     if (networkId == NULL) {
198         LNN_LOGE(LNN_LEDGER, "LnnGetMetaNodeInfoByNetworkId: para is invalid");
199         return SOFTBUS_INVALID_PARAM;
200     }
201     if (SoftBusMutexLock(&g_metaNodeList->lock) != SOFTBUS_OK) {
202         LNN_LOGE(LNN_LEDGER, "LnnGetMetaNodeInfoByNetworkId: lock failed");
203         return SOFTBUS_LOCK_ERR;
204     }
205     LIST_FOR_EACH_ENTRY(item, &g_metaNodeList->list, MetaNodeStorageInfo, node) {
206         if (strcmp(item->info.metaNodeId, networkId) != 0) {
207             continue;
208         }
209         if (strcpy_s(udid, UDID_BUF_LEN, item->info.configInfo.udid) != EOK) {
210             LNN_LOGE(LNN_LEDGER, "meta node udid copy error");
211             ret = SOFTBUS_STRCPY_ERR;
212             break;
213         }
214         ret = SOFTBUS_OK;
215         break;
216     }
217     if (SoftBusMutexUnlock(&g_metaNodeList->lock) != SOFTBUS_OK) {
218         LNN_LOGE(LNN_LEDGER, "LnnGetMetaNodeInfoByNetworkId: unlock failed");
219     }
220     return ret;
221 }
222 
223 
LnnGetMetaNodeInfoByNetworkId(const char * networkId,MetaNodeInfo * nodeInfo)224 int32_t LnnGetMetaNodeInfoByNetworkId(const char *networkId, MetaNodeInfo *nodeInfo)
225 {
226     MetaNodeStorageInfo *item = NULL;
227     int32_t ret = SOFTBUS_ERR;
228     if (networkId == NULL) {
229         LNN_LOGE(LNN_LEDGER, "LnnGetMetaNodeInfoByNetworkId: para is invalid");
230         return SOFTBUS_INVALID_PARAM;
231     }
232     if (SoftBusMutexLock(&g_metaNodeList->lock) != SOFTBUS_OK) {
233         LNN_LOGE(LNN_LEDGER, "LnnGetMetaNodeInfoByNetworkId: lock failed");
234         return SOFTBUS_LOCK_ERR;
235     }
236     LIST_FOR_EACH_ENTRY(item, &g_metaNodeList->list, MetaNodeStorageInfo, node) {
237         if (strcmp(item->info.metaNodeId, networkId) != 0) {
238             continue;
239         }
240         if (memcpy_s(nodeInfo, sizeof(MetaNodeInfo), &item->info, sizeof(MetaNodeInfo)) != EOK) {
241             LNN_LOGE(LNN_LEDGER, "memcpy reply fail");
242             ret = SOFTBUS_MEM_ERR;
243             break;
244         }
245         ret = SOFTBUS_OK;
246         break;
247     }
248     if (SoftBusMutexUnlock(&g_metaNodeList->lock) != SOFTBUS_OK) {
249         LNN_LOGE(LNN_LEDGER, "LnnGetMetaNodeInfoByNetworkId: unlock failed");
250     }
251     return ret;
252 }
253 
LnnInitMetaNodeLedger(void)254 int32_t LnnInitMetaNodeLedger(void)
255 {
256     if (g_metaNodeList == NULL) {
257         g_metaNodeList = CreateSoftBusList();
258     }
259     if (g_metaNodeList == NULL) {
260         LNN_LOGE(LNN_LEDGER, "create meta node list failed");
261         return SOFTBUS_ERR;
262     }
263     LNN_LOGI(LNN_LEDGER, "meta node init success");
264     return SOFTBUS_OK;
265 }
266 
LnnDeinitMetaNodeLedger(void)267 void LnnDeinitMetaNodeLedger(void)
268 {
269     if (g_metaNodeList == NULL) {
270         return;
271     }
272 
273     MetaNodeStorageInfo *item = NULL;
274     MetaNodeStorageInfo *next = NULL;
275     if (SoftBusMutexLock(&g_metaNodeList->lock) != SOFTBUS_OK) {
276         LNN_LOGE(LNN_LEDGER, "lock failed");
277         return;
278     }
279     LIST_FOR_EACH_ENTRY_SAFE(item, next, &g_metaNodeList->list, MetaNodeStorageInfo, node) {
280         ListDelete(&item->node);
281         g_metaNodeList->cnt--;
282         SoftBusFree(item);
283     }
284     (void)SoftBusMutexUnlock(&g_metaNodeList->lock);
285     DestroySoftBusList(g_metaNodeList);
286     g_metaNodeList = NULL;
287 }