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 "pool.h"
17
18 #include "securec.h"
19
20 #include "adaptor_algorithm.h"
21 #include "adaptor_log.h"
22 #include "adaptor_memory.h"
23
24 #define MAX_DUPLICATE_CHECK 100
25
26 // Resource pool list, which caches registered executor information.
27 static LinkedList *g_poolList = NULL;
28
DestroyExecutorInfo(void * data)29 static void DestroyExecutorInfo(void *data)
30 {
31 if (data == NULL) {
32 LOG_ERROR("data is null");
33 return;
34 }
35 Free(data);
36 }
37
IsExecutorIdMatchById(const void * data,const void * condition)38 static bool IsExecutorIdMatchById(const void *data, const void *condition)
39 {
40 if ((condition == NULL) || (data == NULL)) {
41 LOG_ERROR("input para is null");
42 return false;
43 }
44 uint64_t executorIndex = *(uint64_t *)condition;
45 ExecutorInfoHal *executorInfo = (ExecutorInfoHal *)data;
46 return (executorInfo->executorIndex == executorIndex);
47 }
48
IsExecutorNodeMatch(const void * data,const void * condition)49 static bool IsExecutorNodeMatch(const void *data, const void *condition)
50 {
51 if ((condition == NULL) || (data == NULL)) {
52 LOG_ERROR("get null data");
53 return false;
54 }
55 ExecutorInfoHal *executorIndex = (ExecutorInfoHal *)condition;
56 ExecutorInfoHal *executorInfo = (ExecutorInfoHal *)data;
57 return (executorInfo->executorRole == executorIndex->executorRole &&
58 executorInfo->authType == executorIndex->authType &&
59 executorInfo->executorSensorHint == executorIndex->executorSensorHint);
60 }
61
IsInit()62 static bool IsInit()
63 {
64 return g_poolList != NULL;
65 }
66
InitResourcePool(void)67 ResultCode InitResourcePool(void)
68 {
69 if (!IsInit()) {
70 g_poolList = CreateLinkedList(DestroyExecutorInfo);
71 }
72 if (g_poolList == NULL) {
73 return RESULT_GENERAL_ERROR;
74 }
75 return RESULT_SUCCESS;
76 }
77
DestroyResourcePool(void)78 void DestroyResourcePool(void)
79 {
80 DestroyLinkedList(g_poolList);
81 g_poolList = NULL;
82 }
83
IsExecutorValid(const ExecutorInfoHal * executorInfo)84 static bool IsExecutorValid(const ExecutorInfoHal *executorInfo)
85 {
86 if (executorInfo == NULL) {
87 LOG_ERROR("get null data");
88 return false;
89 }
90 return true;
91 }
92
IsExecutorIdDuplicate(uint64_t executorIndex)93 static bool IsExecutorIdDuplicate(uint64_t executorIndex)
94 {
95 LinkedListNode *temp = g_poolList->head;
96 ExecutorInfoHal *executorInfo = NULL;
97 while (temp != NULL) {
98 executorInfo = (ExecutorInfoHal *)temp->data;
99 if (executorInfo != NULL && executorInfo->executorIndex == executorIndex) {
100 return true;
101 }
102 temp = temp->next;
103 }
104
105 return false;
106 }
107
GenerateValidExecutorId(uint64_t * executorIndex)108 static ResultCode GenerateValidExecutorId(uint64_t *executorIndex)
109 {
110 if (g_poolList == NULL) {
111 LOG_ERROR("g_poolList is null");
112 return RESULT_BAD_PARAM;
113 }
114
115 for (uint32_t i = 0; i < MAX_DUPLICATE_CHECK; ++i) {
116 uint64_t tempRandom;
117 if (SecureRandom((uint8_t *)&tempRandom, sizeof(uint64_t)) != RESULT_SUCCESS) {
118 LOG_ERROR("get random failed");
119 return RESULT_GENERAL_ERROR;
120 }
121 if (!IsExecutorIdDuplicate(tempRandom)) {
122 *executorIndex = tempRandom;
123 return RESULT_SUCCESS;
124 }
125 }
126
127 LOG_ERROR("a rare failure");
128 return RESULT_GENERAL_ERROR;
129 }
130
QueryRepeatExecutor(const ExecutorInfoHal * executorInfo)131 static LinkedList *QueryRepeatExecutor(const ExecutorInfoHal *executorInfo)
132 {
133 ExecutorCondition condition = {};
134 SetExecutorConditionAuthType(&condition, executorInfo->authType);
135 SetExecutorConditionSensorHint(&condition, executorInfo->executorSensorHint);
136 SetExecutorConditionExecutorRole(&condition, executorInfo->executorRole);
137 return QueryExecutor(&condition);
138 }
139
RegisterExecutorToPool(ExecutorInfoHal * executorInfo)140 ResultCode RegisterExecutorToPool(ExecutorInfoHal *executorInfo)
141 {
142 if (!IsInit()) {
143 LOG_ERROR("pool not init");
144 return RESULT_NEED_INIT;
145 }
146 if (!IsExecutorValid(executorInfo)) {
147 LOG_ERROR("get invalid executorInfo");
148 return RESULT_BAD_PARAM;
149 }
150 LinkedList *executors = QueryRepeatExecutor(executorInfo);
151 if (executors == NULL) {
152 LOG_ERROR("query executor failed");
153 return RESULT_NO_MEMORY;
154 }
155 ResultCode result = RESULT_UNKNOWN;
156 if (executors->getSize(executors) != 0) {
157 if (executors->head == NULL || executors->head->data == NULL) {
158 LOG_ERROR("list node is invalid");
159 goto EXIT;
160 }
161 executorInfo->executorIndex = ((ExecutorInfoHal *)(executors->head->data))->executorIndex;
162 if (g_poolList->remove(g_poolList, (void *)executorInfo, IsExecutorNodeMatch, true) != RESULT_SUCCESS) {
163 LOG_INFO("remove executor failed");
164 goto EXIT;
165 }
166 } else {
167 result = GenerateValidExecutorId(&executorInfo->executorIndex);
168 if (result != RESULT_SUCCESS) {
169 LOG_ERROR("get executorId failed");
170 goto EXIT;
171 }
172 }
173 ExecutorInfoHal *executorCopy = CopyExecutorInfo(executorInfo);
174 if (executorCopy == NULL) {
175 LOG_ERROR("copy executor failed");
176 result = RESULT_BAD_COPY;
177 goto EXIT;
178 }
179 result = g_poolList->insert(g_poolList, (void *)executorCopy);
180 if (result != RESULT_SUCCESS) {
181 LOG_ERROR("insert failed");
182 DestroyExecutorInfo(executorCopy);
183 }
184
185 EXIT:
186 DestroyLinkedList(executors);
187 return result;
188 }
189
UnregisterExecutorToPool(uint64_t executorIndex)190 ResultCode UnregisterExecutorToPool(uint64_t executorIndex)
191 {
192 if (!IsInit()) {
193 LOG_ERROR("pool not init");
194 return RESULT_NEED_INIT;
195 }
196 return g_poolList->remove(g_poolList, (void *)&executorIndex, IsExecutorIdMatchById, true);
197 }
198
CopyExecutorInfo(ExecutorInfoHal * src)199 ExecutorInfoHal *CopyExecutorInfo(ExecutorInfoHal *src)
200 {
201 if (src == NULL) {
202 LOG_ERROR("get null data");
203 return NULL;
204 }
205 ExecutorInfoHal *dest = (ExecutorInfoHal *)Malloc(sizeof(ExecutorInfoHal));
206 if (dest == NULL) {
207 LOG_ERROR("no memory");
208 return NULL;
209 }
210 if (memcpy_s(dest, sizeof(ExecutorInfoHal), src, sizeof(ExecutorInfoHal)) != EOK) {
211 LOG_ERROR("copy executor info failed");
212 Free(dest);
213 return NULL;
214 }
215 return dest;
216 }
217
IsExecutorMatch(const ExecutorCondition * condition,const ExecutorInfoHal * credentialInfo)218 static bool IsExecutorMatch(const ExecutorCondition *condition, const ExecutorInfoHal *credentialInfo)
219 {
220 if ((condition->conditonFactor & EXECUTOR_CONDITION_INDEX) != 0 &&
221 condition->executorIndex != credentialInfo->executorIndex) {
222 return false;
223 }
224 if ((condition->conditonFactor & EXECUTOR_CONDITION_AUTH_TYPE) != 0 &&
225 condition->authType != credentialInfo->authType) {
226 return false;
227 }
228 if ((condition->conditonFactor & EXECUTOR_CONDITION_SENSOR_HINT) != 0 &&
229 condition->executorSensorHint != INVALID_SENSOR_HINT &&
230 condition->executorSensorHint != credentialInfo->executorSensorHint) {
231 return false;
232 }
233 if ((condition->conditonFactor & EXECUTOR_CONDITION_ROLE) != 0 &&
234 condition->executorRole != credentialInfo->executorRole) {
235 return false;
236 }
237 if ((condition->conditonFactor & EXECUTOR_CONDITION_MATCHER) != 0 &&
238 condition->executorMatcher != credentialInfo->executorMatcher) {
239 return false;
240 }
241 return true;
242 }
243
QueryExecutor(const ExecutorCondition * limit)244 LinkedList *QueryExecutor(const ExecutorCondition *limit)
245 {
246 if (!IsInit()) {
247 LOG_ERROR("pool not init");
248 return NULL;
249 }
250 LinkedList *result = CreateLinkedList(DestroyExecutorInfo);
251 if (result == NULL) {
252 LOG_ERROR("create result list failed");
253 return NULL;
254 }
255 LinkedListIterator *iterator = g_poolList->createIterator(g_poolList);
256 if (iterator == NULL) {
257 LOG_ERROR("create iterator failed");
258 DestroyLinkedList(result);
259 return NULL;
260 }
261
262 while (iterator->hasNext(iterator)) {
263 ExecutorInfoHal *executorInfo = (ExecutorInfoHal *)iterator->next(iterator);
264 if (!IsExecutorValid(executorInfo)) {
265 LOG_ERROR("get invalid executor info");
266 continue;
267 }
268 if (!IsExecutorMatch(limit, executorInfo)) {
269 continue;
270 }
271 ExecutorInfoHal *copy = CopyExecutorInfo(executorInfo);
272 if (copy == NULL) {
273 LOG_ERROR("copy executor info failed");
274 continue;
275 }
276 if (result->insert(result, copy) != RESULT_SUCCESS) {
277 LOG_ERROR("insert executor info failed");
278 DestroyExecutorInfo(copy);
279 continue;
280 }
281 }
282 g_poolList->destroyIterator(iterator);
283 return result;
284 }
285
QueryCollecterMatcher(uint32_t authType,uint32_t executorSensorHint,uint32_t * matcher)286 ResultCode QueryCollecterMatcher(uint32_t authType, uint32_t executorSensorHint, uint32_t *matcher)
287 {
288 if (!IsInit()) {
289 LOG_ERROR("pool not init");
290 return RESULT_NEED_INIT;
291 }
292 if (matcher == NULL) {
293 LOG_ERROR("matcher is null");
294 return RESULT_BAD_PARAM;
295 }
296 LinkedListIterator *iterator = g_poolList->createIterator(g_poolList);
297 if (iterator == NULL) {
298 LOG_ERROR("create iterator failed");
299 return RESULT_NO_MEMORY;
300 }
301
302 while (iterator->hasNext(iterator)) {
303 ExecutorInfoHal *executorInfo = (ExecutorInfoHal *)(iterator->next(iterator));
304 if (!IsExecutorValid(executorInfo)) {
305 LOG_ERROR("get invalid executor info");
306 continue;
307 }
308 if (executorInfo->authType == authType && executorInfo->executorSensorHint == executorSensorHint &&
309 (executorInfo->executorRole == COLLECTOR || executorInfo->executorRole == ALL_IN_ONE)) {
310 *matcher = executorInfo->executorMatcher;
311 g_poolList->destroyIterator(iterator);
312 return RESULT_SUCCESS;
313 }
314 }
315 LOG_ERROR("can't found executor, sensor hint is %{public}u", executorSensorHint);
316 g_poolList->destroyIterator(iterator);
317 return RESULT_NOT_FOUND;
318 }
319
320
QueryCredentialExecutorIndex(uint32_t authType,uint32_t executorSensorHint)321 uint64_t QueryCredentialExecutorIndex(uint32_t authType, uint32_t executorSensorHint)
322 {
323 if (!IsInit()) {
324 LOG_ERROR("pool not init");
325 return INVALID_EXECUTOR_INDEX;
326 }
327 LinkedListIterator *iterator = g_poolList->createIterator(g_poolList);
328 if (iterator == NULL) {
329 LOG_ERROR("create iterator failed");
330 return INVALID_EXECUTOR_INDEX;
331 }
332
333 while (iterator->hasNext(iterator)) {
334 ExecutorInfoHal *executorInfo = (ExecutorInfoHal *)(iterator->next(iterator));
335 if (!IsExecutorValid(executorInfo)) {
336 LOG_ERROR("get invalid executor info");
337 continue;
338 }
339 if (executorInfo->authType == authType && executorInfo->executorSensorHint == executorSensorHint &&
340 (executorInfo->executorRole == VERIFIER || executorInfo->executorRole == ALL_IN_ONE)) {
341 g_poolList->destroyIterator(iterator);
342 return executorInfo->executorIndex;
343 }
344 }
345 LOG_ERROR("can't found executor, sensor hint is %{public}u", executorSensorHint);
346 g_poolList->destroyIterator(iterator);
347 return INVALID_EXECUTOR_INDEX;
348 }
349
350
SetExecutorConditionExecutorIndex(ExecutorCondition * condition,uint64_t executorIndex)351 void SetExecutorConditionExecutorIndex(ExecutorCondition *condition, uint64_t executorIndex)
352 {
353 if (condition == NULL) {
354 LOG_ERROR("condition is null");
355 return;
356 }
357 condition->executorIndex = executorIndex;
358 condition->conditonFactor |= EXECUTOR_CONDITION_INDEX;
359 }
360
SetExecutorConditionAuthType(ExecutorCondition * condition,uint32_t authType)361 void SetExecutorConditionAuthType(ExecutorCondition *condition, uint32_t authType)
362 {
363 if (condition == NULL) {
364 LOG_ERROR("condition is null");
365 return;
366 }
367 condition->authType = authType;
368 condition->conditonFactor |= EXECUTOR_CONDITION_AUTH_TYPE;
369 }
370
SetExecutorConditionSensorHint(ExecutorCondition * condition,uint32_t executorSensorHint)371 void SetExecutorConditionSensorHint(ExecutorCondition *condition, uint32_t executorSensorHint)
372 {
373 if (condition == NULL) {
374 LOG_ERROR("condition is null");
375 return;
376 }
377 condition->executorSensorHint = executorSensorHint;
378 condition->conditonFactor |= EXECUTOR_CONDITION_SENSOR_HINT;
379 }
380
SetExecutorConditionExecutorRole(ExecutorCondition * condition,uint32_t executorRole)381 void SetExecutorConditionExecutorRole(ExecutorCondition *condition, uint32_t executorRole)
382 {
383 if (condition == NULL) {
384 LOG_ERROR("condition is null");
385 return;
386 }
387 condition->executorRole = executorRole;
388 condition->conditonFactor |= EXECUTOR_CONDITION_ROLE;
389 }
390
SetExecutorConditionExecutorMatcher(ExecutorCondition * condition,uint32_t executorMatcher)391 void SetExecutorConditionExecutorMatcher(ExecutorCondition *condition, uint32_t executorMatcher)
392 {
393 if (condition == NULL) {
394 LOG_ERROR("condition is null");
395 return;
396 }
397 condition->executorMatcher = executorMatcher;
398 condition->conditonFactor |= EXECUTOR_CONDITION_MATCHER;
399 }