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
16 #include "dslm_device_list.h"
17
18 #include <stddef.h>
19 #include <stdint.h>
20 #include <string.h>
21
22 #include "securec.h"
23
24 #include "device_security_defines.h"
25 #include "dslm_core_defines.h"
26 #include "dslm_fsm_process.h"
27 #include "dslm_notify_node.h"
28 #include "utils_dslm_list.h"
29 #include "utils_log.h"
30 #include "utils_mem.h"
31 #include "utils_mutex.h"
32 #include "utils_state_machine.h"
33
34 #define MAX_DEVICE_CNT 128
35 #define DEFAULT_TYPE 10
36
GetDeviceListMutex(void)37 static inline Mutex *GetDeviceListMutex(void)
38 {
39 static Mutex mutex = INITED_MUTEX;
40 return &mutex;
41 }
42
GetDeviceList(void)43 static ListHead *GetDeviceList(void)
44 {
45 static ListHead list = INIT_LIST(list);
46 return &list;
47 }
48
GetDeviceListSize(void)49 int32_t GetDeviceListSize(void)
50 {
51 int32_t size = 0;
52 ListNode *node = NULL;
53
54 LockMutex(GetDeviceListMutex());
55 FOREACH_LIST_NODE (node, GetDeviceList()) {
56 size++;
57 }
58 UnlockMutex(GetDeviceListMutex());
59 return size;
60 }
61
GetDslmDeviceInfo(const DeviceIdentify * device)62 DslmDeviceInfo *GetDslmDeviceInfo(const DeviceIdentify *device)
63 {
64 if (device == NULL) {
65 return NULL;
66 }
67
68 DslmDeviceInfo *result = NULL;
69 ListNode *node = NULL;
70
71 LockMutex(GetDeviceListMutex());
72 FOREACH_LIST_NODE (node, GetDeviceList()) {
73 DslmDeviceInfo *info = LIST_ENTRY(node, DslmDeviceInfo, linkNode);
74 if (IsSameDevice(&info->identity, device)) {
75 result = info;
76 break;
77 }
78 }
79 UnlockMutex(GetDeviceListMutex());
80 return result;
81 }
82
CreatOrGetDslmDeviceInfo(const DeviceIdentify * device)83 DslmDeviceInfo *CreatOrGetDslmDeviceInfo(const DeviceIdentify *device)
84 {
85 if (device == NULL) {
86 return NULL;
87 }
88
89 if (device->length != DEVICE_ID_MAX_LEN) {
90 return NULL;
91 }
92
93 DslmDeviceInfo *info = GetDslmDeviceInfo(device);
94 if (info != NULL) {
95 return info;
96 }
97
98 if (GetDeviceListSize() > MAX_DEVICE_CNT) {
99 return NULL;
100 }
101
102 info = MALLOC(sizeof(DslmDeviceInfo));
103 if (info == NULL) {
104 return NULL;
105 }
106 (void)memset_s(info, sizeof(DslmDeviceInfo), 0, sizeof(DslmDeviceInfo));
107
108 if (memcpy_s(&info->identity, sizeof(DeviceIdentify), device, sizeof(DeviceIdentify)) != EOK) {
109 FREE(info);
110 return NULL;
111 }
112
113 info->result = UINT32_MAX;
114 info->notifyListSize = 0;
115 info->historyListSize = 0;
116
117 InitDslmStateMachine(info);
118 LockMutex(GetDeviceListMutex());
119 AddListNodeBefore(&info->linkNode, GetDeviceList());
120 InitListHead(&info->notifyList);
121 InitListHead(&info->historyList);
122 UnlockMutex(GetDeviceListMutex());
123 SECURITY_LOG_INFO("create new DslmDeviceInfo %{public}x", info->machine.machineId);
124 return info;
125 }
126
IsSameDevice(const DeviceIdentify * first,const DeviceIdentify * second)127 bool IsSameDevice(const DeviceIdentify *first, const DeviceIdentify *second)
128 {
129 if ((first == NULL) || (second == NULL)) {
130 return false;
131 }
132 if (first->length != second->length) {
133 return false;
134 }
135 if (memcmp(first->identity, second->identity, first->length) != 0) {
136 return false;
137 }
138 return true;
139 }
140
ForEachDeviceDump(const ProcessDumpFunction dumper,int32_t dumpHandle)141 void ForEachDeviceDump(const ProcessDumpFunction dumper, int32_t dumpHandle)
142 {
143 ListNode *node = NULL;
144 if (dumper == NULL) {
145 return;
146 }
147
148 LockMutex(GetDeviceListMutex());
149 FOREACH_LIST_NODE (node, GetDeviceList()) {
150 const DslmDeviceInfo *info = LIST_ENTRY(node, DslmDeviceInfo, linkNode);
151 dumper(info, dumpHandle);
152 }
153 UnlockMutex(GetDeviceListMutex());
154 }
155
JudgeListDeviceType(void)156 bool JudgeListDeviceType(void)
157 {
158 bool result = true;
159 ListNode *node = NULL;
160
161 LockMutex(GetDeviceListMutex());
162 FOREACH_LIST_NODE (node, GetDeviceList()) {
163 DslmDeviceInfo *info = LIST_ENTRY(node, DslmDeviceInfo, linkNode);
164 if (info->osType != DEFAULT_TYPE) {
165 result = false;
166 break;
167 }
168 }
169 UnlockMutex(GetDeviceListMutex());
170
171 return result;
172 }
173
DestroyNotifyAndHistoryInfo(DslmDeviceInfo * info)174 static void DestroyNotifyAndHistoryInfo(DslmDeviceInfo *info)
175 {
176 ListNode *node = NULL;
177 ListNode *temp = NULL;
178
179 FOREACH_LIST_NODE_SAFE (node, &info->notifyList, temp) {
180 DslmNotifyListNode *notifyNode = LIST_ENTRY(node, DslmNotifyListNode, linkNode);
181 RemoveListNode(node);
182 FREE(notifyNode);
183 }
184
185 FOREACH_LIST_NODE_SAFE (node, &info->historyList, temp) {
186 DslmNotifyListNode *historyNode = LIST_ENTRY(node, DslmNotifyListNode, linkNode);
187 RemoveListNode(node);
188 FREE(historyNode);
189 }
190 }
191
DestroyAllDslmDeviceInfo(void)192 void DestroyAllDslmDeviceInfo(void)
193 {
194 ListNode *node = NULL;
195 ListNode *temp = NULL;
196
197 LockMutex(GetDeviceListMutex());
198 FOREACH_LIST_NODE_SAFE (node, GetDeviceList(), temp) {
199 DslmDeviceInfo *info = LIST_ENTRY(node, DslmDeviceInfo, linkNode);
200 DestroyNotifyAndHistoryInfo(info);
201 RemoveListNode(node);
202 FREE(info);
203 }
204 UnlockMutex(GetDeviceListMutex());
205 }