• 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 
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 }