1 /*
2 * Copyright (c) 2020 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 #include "samgr_lite_inner.h"
16 #include <string.h>
17 #include <securec.h>
18 #include <ohos_errno.h>
19 #include <log.h>
20 #include "memory_adapter.h"
21 #include "time_adapter.h"
22 #include "thread_adapter.h"
23 #include "service_impl.h"
24 #include "feature_impl.h"
25 #include "service_registry.h"
26
27 #undef LOG_TAG
28 #undef LOG_DOMAIN
29 #define LOG_TAG "Samgr"
30 #define LOG_DOMAIN 0xD001800
31
32 /* **************************************************************************************************
33 * Samgr Lite public interfaces
34 * ************************************************************************************************* */
35 static BOOL RegisterService(Service *service);
36 static Service *UnregisterService(const char *name);
37 static BOOL RegisterFeature(const char *serviceName, Feature *feature);
38 static Feature *UnregisterFeature(const char *serviceName, const char *featureName);
39 static BOOL RegisterFeatureApi(const char *serviceName, const char *feature, IUnknown *publicApi);
40 static IUnknown *UnregisterFeatureApi(const char *serviceName, const char *feature);
41 static BOOL RegisterDefaultFeatureApi(const char *serviceName, IUnknown *publicApi);
42 static IUnknown *UnregisterDefaultFeatureApi(const char *serviceName);
43 static IUnknown *GetDefaultFeatureApi(const char *serviceName);
44 static IUnknown *GetFeatureApi(const char *serviceName, const char *feature);
45 static int32 AddSystemCapability(const char *sysCap);
46 static BOOL HasSystemCapability(const char *sysCap);
47 static int32 GetSystemAvailableCapabilities(char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *sysCapNum);
48 #ifdef MINI_SAMGR_LITE_RPC
49 static IUnknown *GetRemoteDefaultFeatureApi(char *deviceId, const char *serviceName);
50 #endif
51 /* **************************************************************************************************
52 * Samgr Lite location functions
53 * ************************************************************************************************* */
54 static void InitializeAllServices(Vector *services);
55 static void InitializeSingleService(ServiceImpl *service);
56 static int32 SendBootRequest(int msgId, uint32 msgValue);
57 static const char *GetServiceName(const ServiceImpl *serviceImpl);
58 static short GetUninitializedPos(void);
59 static void AddTaskPool(ServiceImpl *service, TaskConfig *cfg, const char *name);
60 static int32 InitCompleted(void);
61 static void HandleInitRequest(const Request *request, const Response *response);
62 static SamgrLiteImpl *GetImplement(void);
63 static ServiceImpl *GetService(const char *name);
64 static TaskPool *GetSpecifiedTaskPool(TaskConfig *config);
65 static void Init(void);
66 /* **************************************************************************************************
67 * Samgr Lite location structure and local variable
68 * ************************************************************************************************* */
69 static SamgrLiteImpl g_samgrImpl;
70
71 #define TO_NEXT_STATUS(status) (BootStatus)((uint8)(status) | 0x1)
72
SAMGR_GetInstance(void)73 SamgrLite *SAMGR_GetInstance(void)
74 {
75 if (g_samgrImpl.mutex == NULL) {
76 Init();
77 }
78 return &(GetImplement()->vtbl);
79 }
80
GetImplement(void)81 static SamgrLiteImpl *GetImplement(void)
82 {
83 return &g_samgrImpl;
84 }
85
Init(void)86 static void Init(void)
87 {
88 WDT_Start(WDG_SAMGR_INIT_TIME);
89 g_samgrImpl.vtbl.RegisterService = RegisterService;
90 g_samgrImpl.vtbl.UnregisterService = UnregisterService;
91 g_samgrImpl.vtbl.RegisterFeature = RegisterFeature;
92 g_samgrImpl.vtbl.UnregisterFeature = UnregisterFeature;
93 g_samgrImpl.vtbl.RegisterFeatureApi = RegisterFeatureApi;
94 g_samgrImpl.vtbl.UnregisterFeatureApi = UnregisterFeatureApi;
95 g_samgrImpl.vtbl.RegisterDefaultFeatureApi = RegisterDefaultFeatureApi;
96 g_samgrImpl.vtbl.UnregisterDefaultFeatureApi = UnregisterDefaultFeatureApi;
97 g_samgrImpl.vtbl.GetDefaultFeatureApi = GetDefaultFeatureApi;
98 g_samgrImpl.vtbl.GetFeatureApi = GetFeatureApi;
99 #ifdef MINI_SAMGR_LITE_RPC
100 g_samgrImpl.vtbl.GetRemoteDefaultFeatureApi = GetRemoteDefaultFeatureApi;
101 #endif
102 g_samgrImpl.vtbl.AddSystemCapability = AddSystemCapability;
103 g_samgrImpl.vtbl.HasSystemCapability = HasSystemCapability;
104 g_samgrImpl.vtbl.GetSystemAvailableCapabilities = GetSystemAvailableCapabilities;
105 g_samgrImpl.status = BOOT_SYS;
106 g_samgrImpl.services = VECTOR_Make((VECTOR_Key)GetServiceName, (VECTOR_Compare)strcmp);
107 g_samgrImpl.mutex = MUTEX_InitValue();
108 (void)memset_s(g_samgrImpl.sharedPool, sizeof(TaskPool *) * MAX_POOL_NUM, 0,
109 sizeof(TaskPool *) * MAX_POOL_NUM);
110 WDT_Reset(WDG_SVC_REG_TIME);
111 }
112
SAMGR_Bootstrap(void)113 void SAMGR_Bootstrap(void)
114 {
115 SamgrLiteImpl *samgr = GetImplement();
116 if (samgr->mutex == NULL) {
117 HILOG_INFO(HILOG_MODULE_SAMGR, "Samgr is not init, no service!");
118 return;
119 }
120 WDT_Reset(WDG_SVC_BOOT_TIME);
121 Vector initServices = VECTOR_Make(NULL, NULL);
122 MUTEX_Lock(samgr->mutex);
123 samgr->status = TO_NEXT_STATUS(samgr->status);
124 int16 size = VECTOR_Size(&(samgr->services));
125 int16 i;
126 for (i = 0; i < size; ++i) {
127 ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(&(samgr->services), i);
128 if (serviceImpl == NULL || serviceImpl->inited != SVC_INIT) {
129 continue;
130 }
131 VECTOR_Add(&initServices, serviceImpl);
132 }
133 MUTEX_Unlock(samgr->mutex);
134 HILOG_INFO(HILOG_MODULE_SAMGR, BOOT_FMT(samgr->status), VECTOR_Size(&initServices));
135 InitializeAllServices(&initServices);
136 VECTOR_Clear(&initServices);
137 int32 err = InitCompleted();
138 if (err != EC_SUCCESS) {
139 HILOG_INFO(HILOG_MODULE_SAMGR, "Goto next boot step return code:%d", err);
140 }
141 }
142
SAMGR_GetServiceByID(int16 serviceId)143 ServiceImpl *SAMGR_GetServiceByID(int16 serviceId)
144 {
145 SamgrLiteImpl *manager = GetImplement();
146 MUTEX_Lock(manager->mutex);
147 int16 size = VECTOR_Size(&(manager->services));
148 if (serviceId < 0 || serviceId > size) {
149 MUTEX_Unlock(manager->mutex);
150 return NULL;
151 }
152 ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(&(manager->services), serviceId);
153 MUTEX_Unlock(manager->mutex);
154 return serviceImpl;
155 }
156
InitCompleted(void)157 static int32 InitCompleted(void)
158 {
159 // Did all services be inited?
160 SamgrLiteImpl *manager = GetImplement();
161 int16 pos = GetUninitializedPos();
162 int16 size = VECTOR_Size(&(manager->services));
163 if (pos < size) {
164 return EC_SUCCESS;
165 }
166
167 MUTEX_Lock(manager->mutex);
168 if (manager->status == BOOT_SYS_WAIT) {
169 manager->status = BOOT_APP;
170 MUTEX_Unlock(manager->mutex);
171 HILOG_INFO(HILOG_MODULE_SAMGR, "Initialized all core system services!");
172 WDT_Reset(WDG_SVC_REG_TIME);
173 return SendBootRequest(BOOT_SYS_COMPLETED, pos);
174 }
175
176 if (manager->status == BOOT_APP_WAIT) {
177 manager->status = BOOT_DYNAMIC;
178 MUTEX_Unlock(manager->mutex);
179 HILOG_INFO(HILOG_MODULE_SAMGR, "Initialized all system and application services!");
180 WDT_Reset(WDG_SVC_TEST_TIME);
181 return SendBootRequest(BOOT_APP_COMPLETED, pos);
182 }
183 MUTEX_Unlock(manager->mutex);
184 WDT_Stop();
185 return EC_SUCCESS;
186 }
187
InitializeAllServices(Vector * services)188 static void InitializeAllServices(Vector *services)
189 {
190 int16 size = VECTOR_Size(services);
191 int16 i;
192 for (i = 0; i < size; ++i) {
193 ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, i);
194 if (serviceImpl == NULL) {
195 continue;
196 }
197
198 TaskConfig config = serviceImpl->service->GetTaskConfig(serviceImpl->service);
199 const char *name = serviceImpl->service->GetName(serviceImpl->service);
200 AddTaskPool(serviceImpl, &config, name);
201
202 HILOG_INFO(HILOG_MODULE_SAMGR, "Init service:%s", name);
203 InitializeSingleService(serviceImpl);
204 }
205 SamgrLiteImpl *samgr = GetImplement();
206 MUTEX_Lock(samgr->mutex);
207 for (i = 0; i < size; ++i) {
208 ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, i);
209 if (serviceImpl == NULL) {
210 continue;
211 }
212 const char *name = serviceImpl->service->GetName(serviceImpl->service);
213 SAMGR_StartTaskPool(serviceImpl->taskPool, name);
214 }
215 MUTEX_Unlock(samgr->mutex);
216 }
217
RegisterService(Service * service)218 static BOOL RegisterService(Service *service)
219 {
220 if (IsInvalidService(service)) {
221 return FALSE;
222 }
223
224 SamgrLiteImpl *samgr = GetImplement();
225 MUTEX_Lock(samgr->mutex);
226 int16 pos = VECTOR_FindByKey(&(samgr->services), (void *)service->GetName(service));
227 if (pos >= 0) {
228 MUTEX_Unlock(samgr->mutex);
229 return FALSE;
230 }
231
232 if (VECTOR_Num(&(samgr->services)) >= MAX_SERVICE_NUM) {
233 MUTEX_Unlock(samgr->mutex);
234 return FALSE;
235 }
236
237 ServiceImpl *serviceImpl = SAMGR_CreateServiceImpl(service, samgr->status);
238 if (serviceImpl == NULL) {
239 MUTEX_Unlock(samgr->mutex);
240 return FALSE;
241 }
242 serviceImpl->serviceId = VECTOR_Add(&(samgr->services), serviceImpl);
243 MUTEX_Unlock(samgr->mutex);
244 if (serviceImpl->serviceId == INVALID_INDEX) {
245 SAMGR_Free(serviceImpl);
246 return FALSE;
247 }
248 return TRUE;
249 }
250
UnregisterService(const char * name)251 static Service *UnregisterService(const char *name)
252 {
253 if (name == NULL) {
254 return NULL;
255 }
256
257 SamgrLiteImpl *samgr = GetImplement();
258 MUTEX_Lock(samgr->mutex);
259 Vector *services = &(samgr->services);
260 int16 pos = VECTOR_FindByKey(services, (void *)name);
261 ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, pos);
262 if (serviceImpl == NULL || serviceImpl->defaultApi != NULL || VECTOR_Num(&serviceImpl->features) > 0) {
263 MUTEX_Unlock(samgr->mutex);
264 return NULL;
265 }
266
267 VECTOR_Swap(services, pos, NULL);
268 // release task pool must be in the lock to keep atomicity of the reference
269 SAMGR_ReleaseTaskPool(serviceImpl->taskPool);
270 MUTEX_Unlock(samgr->mutex);
271
272 Service *service = serviceImpl->service;
273 VECTOR_Clear(&serviceImpl->features);
274 SAMGR_Free(serviceImpl);
275 return service;
276 }
277
RegisterFeature(const char * serviceName,Feature * feature)278 static BOOL RegisterFeature(const char *serviceName, Feature *feature)
279 {
280 if (IsInvalidFeature(feature)) {
281 return FALSE;
282 }
283
284 ServiceImpl *serviceImpl = GetService(serviceName);
285 if (serviceImpl == NULL || serviceImpl->inited != SVC_INIT) {
286 return FALSE;
287 }
288
289 if (DEFAULT_GetFeature(serviceImpl, feature->GetName(feature)) != NULL) {
290 return FALSE;
291 }
292
293 int16 featureId = DEFAULT_AddFeature(serviceImpl, feature);
294 if (featureId < 0) {
295 return FALSE;
296 }
297 return TRUE;
298 }
299
UnregisterFeature(const char * serviceName,const char * featureName)300 static Feature *UnregisterFeature(const char *serviceName, const char *featureName)
301 {
302 ServiceImpl *serviceImpl = GetService(serviceName);
303 if (serviceImpl == NULL) {
304 return NULL;
305 }
306 return DEFAULT_DeleteFeature(serviceImpl, featureName);
307 }
308
RegisterFeatureApi(const char * serviceName,const char * feature,IUnknown * publicApi)309 static BOOL RegisterFeatureApi(const char *serviceName, const char *feature, IUnknown *publicApi)
310 {
311 if (IsInvalidIUnknown(publicApi)) {
312 return FALSE;
313 }
314
315 ServiceImpl *serviceImpl = GetService(serviceName);
316 if (serviceImpl == NULL) {
317 return FALSE;
318 }
319
320 if (feature == NULL) {
321 if (serviceImpl->defaultApi != NULL) {
322 return FALSE;
323 }
324 serviceImpl->defaultApi = publicApi;
325 return TRUE;
326 }
327
328 FeatureImpl *featureImpl = DEFAULT_GetFeature(serviceImpl, feature);
329 if (featureImpl == NULL) {
330 return FALSE;
331 }
332 return SAMGR_AddInterface(featureImpl, publicApi);
333 }
334
UnregisterFeatureApi(const char * serviceName,const char * feature)335 static IUnknown *UnregisterFeatureApi(const char *serviceName, const char *feature)
336 {
337 ServiceImpl *serviceImpl = GetService(serviceName);
338 if (serviceImpl == NULL) {
339 return NULL;
340 }
341
342 if (feature == NULL) {
343 IUnknown *iUnknown = serviceImpl->defaultApi;
344 serviceImpl->defaultApi = NULL;
345 return iUnknown;
346 }
347
348 return SAMGR_DelInterface(DEFAULT_GetFeature(serviceImpl, feature));
349 }
350
RegisterDefaultFeatureApi(const char * serviceName,IUnknown * publicApi)351 static BOOL RegisterDefaultFeatureApi(const char *serviceName, IUnknown *publicApi)
352 {
353 return RegisterFeatureApi(serviceName, NULL, publicApi);
354 }
355
UnregisterDefaultFeatureApi(const char * serviceName)356 static IUnknown *UnregisterDefaultFeatureApi(const char *serviceName)
357 {
358 return UnregisterFeatureApi(serviceName, NULL);
359 }
360
GetDefaultFeatureApi(const char * serviceName)361 static IUnknown *GetDefaultFeatureApi(const char *serviceName)
362 {
363 return GetFeatureApi(serviceName, NULL);
364 }
365
AddSystemCapability(const char * sysCap)366 static int32 AddSystemCapability(const char *sysCap)
367 {
368 if (sysCap == NULL || strlen(sysCap) == 0 || strlen(sysCap) > MAX_SYSCAP_NAME_LEN) {
369 return EC_INVALID;
370 }
371 return SAMGR_RegisterSystemCapabilityApi(sysCap, TRUE);
372 }
373
HasSystemCapability(const char * sysCap)374 static BOOL HasSystemCapability(const char *sysCap)
375 {
376 if (sysCap == NULL || strlen(sysCap) == 0 || strlen(sysCap) > MAX_SYSCAP_NAME_LEN) {
377 return FALSE;
378 }
379 return SAMGR_QuerySystemCapabilityApi(sysCap);
380 }
381
GetSystemAvailableCapabilities(char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN],int32 * sysCapNum)382 static int32 GetSystemAvailableCapabilities(char sysCaps[MAX_SYSCAP_NUM][MAX_SYSCAP_NAME_LEN], int32 *sysCapNum)
383 {
384 if (sysCaps == NULL || sysCapNum == NULL) {
385 return EC_INVALID;
386 }
387 return SAMGR_GetSystemCapabilitiesApi(sysCaps, sysCapNum);
388 }
389
GetFeatureApi(const char * serviceName,const char * feature)390 static IUnknown *GetFeatureApi(const char *serviceName, const char *feature)
391 {
392 ServiceImpl *serviceImpl = GetService(serviceName);
393 if (serviceImpl == NULL) {
394 return SAMGR_FindServiceApi(serviceName, feature);
395 }
396
397 FeatureImpl *featureImpl = DEFAULT_GetFeature(serviceImpl, feature);
398 if (featureImpl == NULL && feature == NULL) {
399 return serviceImpl->defaultApi;
400 }
401
402 return SAMGR_GetInterface(featureImpl);
403 }
404
GetUninitializedPos()405 static short GetUninitializedPos()
406 {
407 SamgrLiteImpl *manager = GetImplement();
408 MUTEX_Lock(manager->mutex);
409 int16 size = VECTOR_Size(&(manager->services));
410 int16 i;
411 for (i = 0; i < size; ++i) {
412 ServiceImpl *service = (ServiceImpl *)VECTOR_At(&(manager->services), i);
413 if (service == NULL) {
414 continue;
415 }
416
417 if (service->inited == SVC_INIT) {
418 MUTEX_Unlock(manager->mutex);
419 return i;
420 }
421 }
422 MUTEX_Unlock(manager->mutex);
423 return size;
424 }
425
GetServiceName(const ServiceImpl * serviceImpl)426 static const char *GetServiceName(const ServiceImpl *serviceImpl)
427 {
428 if (serviceImpl == NULL) {
429 return NULL;
430 }
431 return serviceImpl->service->GetName(serviceImpl->service);
432 }
433
AddTaskPool(ServiceImpl * service,TaskConfig * cfg,const char * name)434 static void AddTaskPool(ServiceImpl *service, TaskConfig *cfg, const char *name)
435 {
436 if (service->taskPool != NULL) {
437 return;
438 }
439
440 if (cfg->priority < PRI_LOW || cfg->priority >= PRI_BUTT) {
441 HILOG_ERROR(HILOG_MODULE_SAMGR, "The %s service pri(%d) is out of range!", name, cfg->priority);
442 cfg->priority = PRI_LOW;
443 }
444
445 switch (cfg->taskFlags) {
446 case SHARED_TASK: {
447 int pos = (int)cfg->priority / PROPERTY_STEP;
448 SamgrLiteImpl *samgr = GetImplement();
449 if (samgr->sharedPool[pos] == NULL) {
450 TaskConfig shareCfg = {LEVEL_HIGH, (int16) ((pos) * PROPERTY_STEP + 1),
451 SHARED_TASK_STACK_SIZE, 25, SHARED_TASK};
452 samgr->sharedPool[pos] = SAMGR_CreateFixedTaskPool(&shareCfg, name, DEFAULT_SIZE);
453 }
454 service->taskPool = samgr->sharedPool[pos];
455 if (SAMGR_ReferenceTaskPool(service->taskPool) == NULL) {
456 HILOG_ERROR(HILOG_MODULE_SAMGR, "pri:%d ref is full", cfg->priority);
457 samgr->sharedPool[pos] = NULL;
458 }
459 }
460 break;
461
462 case SPECIFIED_TASK:
463 service->taskPool = GetSpecifiedTaskPool(cfg);
464 if (service->taskPool != NULL) {
465 break;
466 }
467 // fallthrough
468 case SINGLE_TASK:
469 service->taskPool = SAMGR_CreateFixedTaskPool(cfg, name, SINGLE_SIZE);
470 break;
471 default:
472 break;
473 }
474
475 if (service->taskPool == NULL) {
476 HILOG_ERROR(HILOG_MODULE_SAMGR, "Service<name:%s, flag:%hhu> create taskPool failed!", name, cfg->taskFlags);
477 }
478 }
479
GetService(const char * name)480 static ServiceImpl *GetService(const char *name)
481 {
482 if (name == NULL) {
483 return NULL;
484 }
485
486 SamgrLiteImpl *manager = GetImplement();
487 MUTEX_Lock(manager->mutex);
488 Vector *services = &(manager->services);
489 short pos = VECTOR_FindByKey(services, (void *)name);
490 if (pos < 0) {
491 MUTEX_Unlock(manager->mutex);
492 return NULL;
493 }
494 ServiceImpl *serviceImpl = (ServiceImpl *)VECTOR_At(services, pos);
495 MUTEX_Unlock(manager->mutex);
496 return serviceImpl;
497 }
498
SendBootRequest(int msgId,uint32 msgValue)499 static int32 SendBootRequest(int msgId, uint32 msgValue)
500 {
501 Identity id = DEFAULT_GetFeatureId(GetService(BOOTSTRAP_SERVICE), NULL);
502 Request request = {msgId, 0, NULL, msgValue};
503 return SAMGR_SendRequest(&id, &request, (Handler)SAMGR_Bootstrap);
504 }
505
HandleInitRequest(const Request * request,const Response * response)506 static void HandleInitRequest(const Request *request, const Response *response)
507 {
508 ServiceImpl *serviceImpl = (ServiceImpl *)request->data;
509 if (serviceImpl == NULL) {
510 HILOG_ERROR(HILOG_MODULE_SAMGR, "Init service Request:<%d,%u>, Response:<%d>!",
511 request->msgId, request->msgValue, response->len);
512 return;
513 }
514 uint32 lastTime = serviceImpl->ops.timestamp;
515
516 DEFAULT_Initialize(serviceImpl);
517 serviceImpl->ops.timestamp = SAMGR_GetProcessTime();
518 serviceImpl->inited = SVC_IDLE;
519 HILOG_INFO(HILOG_MODULE_SAMGR, "Init service %s <time: %ums> success!",
520 serviceImpl->service->GetName(serviceImpl->service), serviceImpl->ops.timestamp - lastTime);
521 int32 err = InitCompleted();
522 if (err != EC_SUCCESS) {
523 HILOG_INFO(HILOG_MODULE_SAMGR, "Goto next boot step return code:%d", err);
524 }
525 }
526
InitializeSingleService(ServiceImpl * service)527 static void InitializeSingleService(ServiceImpl *service)
528 {
529 // service is guaranteed not to be NULL by the caller; and it's a static function, won't have external call.
530 if (service->taskPool == NULL) {
531 DEFAULT_Initialize(service);
532 return;
533 }
534
535 Identity identity = {service->serviceId, INVALID_INDEX, service->taskPool->queueId};
536 Request request = {0, 0, service, 0};
537 uint32 *ref = NULL;
538 (void)SAMGR_SendSharedDirectRequest(&identity, &request, NULL, &ref, HandleInitRequest);
539 }
540
GetSpecifiedTaskPool(TaskConfig * config)541 static TaskPool *GetSpecifiedTaskPool(TaskConfig *config)
542 {
543 SamgrLiteImpl *samgr = GetImplement();
544 Vector *services = &(samgr->services);
545 MUTEX_Lock(samgr->mutex);
546 int16 serviceNum = VECTOR_Size(services);
547 int i;
548 for (i = 0; i < serviceNum; ++i) {
549 ServiceImpl *impl = VECTOR_At(services, i);
550 if (impl == NULL) {
551 continue;
552 }
553
554 TaskConfig cfg = impl->service->GetTaskConfig(impl->service);
555 if (memcmp(&cfg, config, sizeof(TaskConfig)) != 0) {
556 continue;
557 }
558
559 if (impl->taskPool == NULL) {
560 break;
561 }
562
563 TaskPool *taskPool = SAMGR_ReferenceTaskPool(impl->taskPool);
564 if (taskPool != NULL) {
565 MUTEX_Unlock(samgr->mutex);
566 return taskPool;
567 }
568 }
569 MUTEX_Unlock(samgr->mutex);
570 return NULL;
571 }
572
573 #ifdef MINI_SAMGR_LITE_RPC
GetRemoteDefaultFeatureApi(char * deviceId,const char * serviceName)574 static IUnknown *GetRemoteDefaultFeatureApi(char *deviceId, const char *serviceName)
575 {
576 return SAMGR_CreateIRemoteProxy(deviceId, serviceName, NULL);
577 }
578 #endif
579