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