1 /*
2  * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "message_router.h"
10 #ifdef USERSPACE_CLIENT_SUPPORT
11 #include <signal.h>
12 #include <unistd.h>
13 #endif
14 #include "hdf_base.h"
15 #include "hdf_log.h"
16 #include "message_dispatcher.h"
17 #include "message_router_inner.h"
18 #include "osal_mutex.h"
19 #include "securec.h"
20 
21 #ifdef USERSPACE_CLIENT_SUPPORT
22 #define HDF_LOG_TAG UMsgEngine
23 #else
24 #define HDF_LOG_TAG KMsgEngine
25 #endif
26 
27 #ifndef UINT8_MAX
28 #define UINT8_MAX 255
29 #endif
30 
31 #if MESSAGE_ENGINE_MAX_DISPATCHER > UINT8_MAX
32 #error Max MESSAGE_ENGINE_MAX_DISPATCHER is UINT8_MAX
33 #endif
34 
35 IMPLEMENT_SHARED_OBJ(MessageNode);
36 IMPLEMENT_SHARED_OBJ(RemoteService);
37 
38 typedef struct {
39     uint8_t nodeIndex;
40     DispatcherId dispatcherId;
41     RemoteService *remoteService;
42 } ServiceInfo;
43 
44 #define MAX_NODE_COUNT 2
45 
46 OSAL_DECLARE_MUTEX(g_routerMutex) = {
47     .realMutex = NULL
48 };
49 
50 static ServiceInfo g_servicesIndex[MESSAGE_ENGINE_MAX_SERVICE] = {0};
51 
52 static MessageNode *g_messageNodes[MAX_NODE_COUNT] = { 0, 0};
53 
54 MessageDispatcher *g_dispatchers[MESSAGE_ENGINE_MAX_DISPATCHER] = {0};
55 
56 static uint8_t g_routerStatus = ME_STATUS_STOPPED;
57 
ReleaseRemoteService(RemoteService * service)58 static void ReleaseRemoteService(RemoteService *service)
59 {
60     if (service == NULL) {
61         HDF_LOGE("%s: Input param is null!", __func__);
62         return;
63     }
64     if (service->Shutdown != NULL) {
65         service->Shutdown(service);
66     }
67     if (service->Disref != NULL) {
68         service->Disref(service);
69     }
70     HDF_LOGD("%s:ReleaseRemoteService finished!", __func__);
71 }
72 
RefDispatcherInner(const DispatcherId dispatcherId,bool requireLock)73 static MessageDispatcher *RefDispatcherInner(const DispatcherId dispatcherId, bool requireLock)
74 {
75     MessageDispatcher *result = NULL;
76     if (dispatcherId >= MESSAGE_ENGINE_MAX_DISPATCHER) {
77         HDF_LOGE("%s:Input ID is too big.input=%u", __func__, dispatcherId);
78         return NULL;
79     }
80 
81     if (requireLock) {
82         HDF_STATUS status = OsalMutexTimedLock(&g_routerMutex, HDF_WAIT_FOREVER);
83         if (status != HDF_SUCCESS) {
84             HDF_LOGE("Unable to get lock!status=%d", status);
85             return NULL;
86         }
87     }
88 
89     do {
90         if (g_dispatchers[dispatcherId] == NULL) {
91             break;
92         }
93 
94         if (g_dispatchers[dispatcherId]->Ref == NULL) {
95             break;
96         }
97         result = g_dispatchers[dispatcherId]->Ref(g_dispatchers[dispatcherId]);
98     } while (false);
99 
100     if (requireLock) {
101         HDF_STATUS status = OsalMutexUnlock(&g_routerMutex);
102         if (status != HDF_SUCCESS) {
103             HDF_LOGE("Unable to unlock!status=%d", status);
104         }
105     }
106     return result;
107 }
108 
RegDispatcher(DispatcherId dispatcherId,MessageDispatcher * dispatcher)109 static ErrorCode RegDispatcher(DispatcherId dispatcherId, MessageDispatcher *dispatcher)
110 {
111     HDF_STATUS status;
112     ErrorCode errCode;
113     if (dispatcherId >= MESSAGE_ENGINE_MAX_DISPATCHER) {
114         HDF_LOGE("%s:dispatcher id is too big!id=%u", __func__, dispatcherId);
115         return ME_ERROR_PARA_WRONG;
116     }
117 
118     status = OsalMutexTimedLock(&g_routerMutex, HDF_WAIT_FOREVER);
119     if (status != HDF_SUCCESS) {
120         HDF_LOGE("Unable to get lock!status=%d", status);
121         return ME_ERROR_OPER_MUTEX_FAILED;
122     }
123     errCode = ME_SUCCESS;
124     do {
125         if (g_routerStatus != ME_STATUS_RUNNING) {
126             HDF_LOGE("%s: Unexpected g_routerStatus!", __func__);
127             errCode = ME_ERROR_WRONG_STATUS;
128             break;
129         }
130         if (g_dispatchers[dispatcherId] != NULL) {
131             HDF_LOGE("%s:DispatcherId conflict!ID=%u", __func__, dispatcherId);
132             errCode = ME_ERROR_DISPATCHERID_CONFLICT;
133         } else {
134             g_dispatchers[dispatcherId] = dispatcher;
135         }
136     } while (false);
137 
138     status = OsalMutexUnlock(&g_routerMutex);
139     if (status != HDF_SUCCESS) {
140         HDF_LOGE("Unable to unlock!status=%d", status);
141     }
142     HDF_LOGD("%s: RegDispatcher finished! errCode = %d", __func__, errCode);
143     return errCode;
144 }
145 
AddDispatcher(DispatcherConfig * config)146 ErrorCode AddDispatcher(DispatcherConfig *config)
147 {
148     ErrorCode errCode;
149     MessageDispatcher *dispatcher = NULL;
150     if (config == NULL) {
151         HDF_LOGE("%s: Input param is null!", __func__);
152         return ME_ERROR_NULL_PTR;
153     }
154     errCode = CreateLocalDispatcher(&dispatcher, config);
155     if (errCode != ME_SUCCESS) {
156         HDF_LOGE("%s: Create local dispatcher failed! errCode=%d", __func__, errCode);
157         return errCode;
158     }
159     if (dispatcher == NULL) {
160         HDF_LOGE("%s:CreateDispatcher return NULL!", __func__);
161         return ME_ERROR_NULL_PTR;
162     }
163     do {
164         if (dispatcher->Start != NULL) {
165             errCode = dispatcher->Start(dispatcher);
166             if (errCode != ME_SUCCESS) {
167                 HDF_LOGE("%s:Start dispatcher %u failed!errCode=%d", __func__, config->dispatcherId, errCode);
168                 break;
169             }
170         }
171         errCode = RegDispatcher(config->dispatcherId, dispatcher);
172     } while (false);
173 
174     if (errCode != ME_SUCCESS && dispatcher->Shutdown != NULL) {
175         dispatcher->Shutdown(dispatcher);
176     }
177     if (errCode != ME_SUCCESS && dispatcher->Disref != NULL) {
178         dispatcher->Disref(dispatcher);
179     }
180     HDF_LOGD("%s: AddDispatcher finished! errCode = %d", __func__, errCode);
181     return errCode;
182 }
183 
NotifyAllNodesServiceDel(const NodeId nodeId,ServiceId serviceId)184 static void NotifyAllNodesServiceDel(const NodeId nodeId, ServiceId serviceId)
185 {
186     uint8_t i;
187     for (i = 0; i < MAX_NODE_COUNT; i++) {
188         if (i == nodeId) {
189             continue;
190         }
191         if (g_messageNodes[i] != NULL && g_messageNodes[i]->NotifyServiceDel != NULL) {
192             ErrorCode subErrCode = g_messageNodes[i]->NotifyServiceDel(g_messageNodes[i], serviceId);
193             if (subErrCode != ME_SUCCESS) {
194                 HDF_LOGE("%s:Rollback service add to node failed!nodeId=%hhu,serviceId=%d,errCode=%d", __func__, i,
195                     serviceId, subErrCode);
196             }
197         }
198     }
199 }
200 
NotifyAllNodesServiceAdd(const NodeId nodeId,struct ServiceDef * mapper)201 static ErrorCode NotifyAllNodesServiceAdd(const NodeId nodeId, struct ServiceDef *mapper)
202 {
203     uint8_t i;
204     uint8_t notifyNodeIndex;
205     ErrorCode errCode;
206     if (mapper == NULL) {
207         return ME_ERROR_NULL_PTR;
208     }
209 
210     errCode = ME_SUCCESS;
211     for (notifyNodeIndex = 0; notifyNodeIndex < MAX_NODE_COUNT; notifyNodeIndex++) {
212         if (notifyNodeIndex == nodeId) {
213             continue;
214         }
215         if (g_messageNodes[notifyNodeIndex] != NULL && g_messageNodes[notifyNodeIndex]->NotifyServiceAdd != NULL) {
216             errCode = g_messageNodes[notifyNodeIndex]->NotifyServiceAdd(g_messageNodes[notifyNodeIndex], mapper);
217             if (errCode != ME_SUCCESS) {
218                 HDF_LOGE("%s:Notify service add to node failed!nodeId=%d,serviceId=%d,errCode=%d", __func__,
219                     notifyNodeIndex, mapper->serviceId, errCode);
220                 break;
221             }
222         }
223     }
224 
225     if (errCode == ME_SUCCESS) {
226         return ME_SUCCESS;
227     }
228     for (i = 0; i < MAX_NODE_COUNT && i < notifyNodeIndex; i++) {
229         if (i == nodeId) {
230             continue;
231         }
232         if (g_messageNodes[i] != NULL && g_messageNodes[i]->NotifyServiceDel != NULL) {
233             ErrorCode subErrCode = g_messageNodes[i]->NotifyServiceDel(g_messageNodes[i], mapper->serviceId);
234             if (subErrCode != ME_SUCCESS) {
235                 HDF_LOGE("%s:Rollback service add to node failed!nodeId=%d,serviceId=%d,errCode=%d", __func__, i,
236                     mapper->serviceId, subErrCode);
237             }
238         }
239     }
240     return errCode;
241 }
242 
DoRegistService(const NodeId nodeId,const DispatcherId dispatcherId,RemoteService * remoteService)243 static ErrorCode DoRegistService(const NodeId nodeId, const DispatcherId dispatcherId, RemoteService *remoteService)
244 {
245     if (remoteService == NULL) {
246         return ME_ERROR_NULL_PTR;
247     }
248 
249     if (remoteService->serviceId >= MESSAGE_ENGINE_MAX_SERVICE) {
250         return ME_ERROR_PARA_WRONG;
251     }
252 
253     if (g_routerStatus != ME_STATUS_RUNNING) {
254         return ME_ERROR_WRONG_STATUS;
255     }
256 
257     HDF_LOGW("%s:Register service Node:%d;Dispatcher:%u;Service:%u", __func__, nodeId, dispatcherId,
258         remoteService->serviceId);
259 
260     if (g_servicesIndex[remoteService->serviceId].remoteService != NULL) {
261         HDF_LOGE("%s:Router index find conflict serviceId!", __func__);
262         return ME_ERROR_SERVICEID_CONFLICT;
263     }
264 
265     g_servicesIndex[remoteService->serviceId].remoteService = remoteService;
266     g_servicesIndex[remoteService->serviceId].nodeIndex = nodeId;
267     g_servicesIndex[remoteService->serviceId].dispatcherId = dispatcherId;
268 
269     return ME_SUCCESS;
270 }
271 
RegistServiceInner(const NodeId nodeId,const DispatcherId dispatcherId,struct ServiceDef * mapper)272 static ErrorCode RegistServiceInner(const NodeId nodeId, const DispatcherId dispatcherId, struct ServiceDef *mapper)
273 {
274     MessageNode *node = NULL;
275     RemoteService *remoteService = NULL;
276     MessageDispatcher *dispatcher = NULL;
277     ErrorCode errCode = ME_ERROR_NOT_SUPPORTED;
278     if (mapper == NULL || mapper->serviceId >= MESSAGE_ENGINE_MAX_SERVICE) {
279         return ME_ERROR_NULL_PTR;
280     }
281 
282     if (OsalMutexTimedLock(&g_routerMutex, HDF_WAIT_FOREVER) != HDF_SUCCESS) {
283         HDF_LOGE("Unable to get lock!");
284         return ME_ERROR_OPER_MUTEX_FAILED;
285     }
286 
287     node = RefMessageNode(nodeId, false);
288     if (node == NULL) {
289         OsalMutexUnlock(&g_routerMutex);
290         return ME_ERROR_NO_SUCH_NODE;
291     }
292     do {
293         if (node->CreateRemoteService == NULL) {
294             HDF_LOGE("%s:Can not reg service to node %d", __func__, nodeId);
295             break;
296         }
297         dispatcher = RefDispatcherInner(dispatcherId, false);
298 
299         remoteService = node->CreateRemoteService(node, dispatcher, mapper);
300         if (remoteService == NULL) {
301             HDF_LOGE("%s:Node create service failed!node=%d", __func__, nodeId);
302             break;
303         }
304 
305         errCode = NotifyAllNodesServiceAdd(nodeId, mapper);
306         if (errCode != ME_SUCCESS) {
307             HDF_LOGE("%s:NotifyAllNodesServiceAdd failed!err=%d", __func__, errCode);
308             break;
309         }
310 
311         errCode = DoRegistService(nodeId, dispatcherId, remoteService);
312         if (errCode != ME_SUCCESS) {
313             HDF_LOGE("%s:DoRegistService failed!err=%d.", __func__, errCode);
314             NotifyAllNodesServiceDel(nodeId, mapper->serviceId);
315             break;
316         }
317     } while (false);
318 
319     OsalMutexUnlock(&g_routerMutex);
320     if (dispatcher != NULL && dispatcher->Disref != NULL) {
321         dispatcher->Disref(dispatcher);
322     }
323     if (node != NULL && node->Disref != NULL) {
324         node->Disref(node);
325     }
326 
327     if (errCode != ME_SUCCESS) {
328         ReleaseRemoteService(remoteService);
329     }
330 
331     return errCode;
332 }
333 
RegistLocalService(const DispatcherId dispatcherId,struct ServiceDef * mapper)334 ErrorCode RegistLocalService(const DispatcherId dispatcherId, struct ServiceDef *mapper)
335 {
336     return RegistServiceInner(LOCAL_NODE_INDEX, dispatcherId, mapper);
337 }
338 
RegistRemoteService(NodeId nodeId,RemoteService * service)339 ErrorCode RegistRemoteService(NodeId nodeId, RemoteService *service)
340 {
341     HDF_STATUS status;
342     ErrorCode errCode;
343     if (service == NULL) {
344         return ME_ERROR_NULL_PTR;
345     }
346     if (service->serviceId >= MESSAGE_ENGINE_MAX_SERVICE) {
347         HDF_LOGE("%s:serviceId exceed max value! ServiceId=%d", __func__, service->serviceId);
348         return ME_ERROR_PARA_WRONG;
349     }
350     if (nodeId >= MAX_NODE_COUNT) {
351         HDF_LOGE("%s:NodeId exceed max value! NodeId=%d", __func__, nodeId);
352         return ME_ERROR_PARA_WRONG;
353     }
354     status = OsalMutexTimedLock(&g_routerMutex, HDF_WAIT_FOREVER);
355     if (status != HDF_SUCCESS) {
356         HDF_LOGE("Unable to get lock!status=%d", status);
357         return ME_ERROR_OPER_MUTEX_FAILED;
358     }
359 
360     errCode = DoRegistService(nodeId, BAD_DISPATCHER_ID, service);
361     if (errCode != ME_SUCCESS) {
362         HDF_LOGE("%s:RegService failed! errCode=%d", __func__, errCode);
363     }
364 
365     status = OsalMutexUnlock(&g_routerMutex);
366     if (status != HDF_SUCCESS) {
367         HDF_LOGE("Unable to unlock!status=%d", status);
368     }
369     return errCode;
370 }
UnregistServiceInner(const NodeId nodeId,const DispatcherId dispatcherId,const ServiceId serviceId)371 static ErrorCode UnregistServiceInner(const NodeId nodeId, const DispatcherId dispatcherId, const ServiceId serviceId)
372 {
373     RemoteService *service = NULL;
374     HDF_STATUS status;
375     ErrorCode errCode;
376     if (serviceId >= MESSAGE_ENGINE_MAX_SERVICE) {
377         return ME_ERROR_PARA_WRONG;
378     }
379 
380     status = OsalMutexTimedLock(&g_routerMutex, HDF_WAIT_FOREVER);
381     if (status != HDF_SUCCESS) {
382         HDF_LOGE("Unable to get lock!status=%d", status);
383         return ME_ERROR_OPER_MUTEX_FAILED;
384     }
385     errCode = ME_SUCCESS;
386     do {
387         if (g_servicesIndex[serviceId].nodeIndex != nodeId || g_servicesIndex[serviceId].dispatcherId != dispatcherId) {
388             errCode = ME_ERROR_NO_SUCH_SERVICE;
389             break;
390         }
391         if (g_servicesIndex[serviceId].remoteService == NULL) {
392             errCode = ME_ERROR_NO_SUCH_SERVICE;
393             break;
394         }
395         service = g_servicesIndex[serviceId].remoteService;
396         ReleaseRemoteService(service);
397         g_servicesIndex[serviceId].remoteService = NULL;
398         g_servicesIndex[serviceId].nodeIndex = NO_SUCH_NODE_INDEX;
399         g_servicesIndex[serviceId].dispatcherId = BAD_DISPATCHER_ID;
400         NotifyAllNodesServiceDel(nodeId, serviceId);
401     } while (false);
402     status = OsalMutexUnlock(&g_routerMutex);
403     if (status != HDF_SUCCESS) {
404         HDF_LOGE("Unable to unlock!status=%d", status);
405     }
406     return errCode;
407 }
408 
UnregistLocalService(const DispatcherId dispatcherId,ServiceId serviceId)409 ErrorCode UnregistLocalService(const DispatcherId dispatcherId, ServiceId serviceId)
410 {
411     return UnregistServiceInner(LOCAL_NODE_INDEX, dispatcherId, serviceId);
412 }
413 
UnregistRemoteService(NodeId nodeId,ServiceId serviceId)414 ErrorCode UnregistRemoteService(NodeId nodeId, ServiceId serviceId)
415 {
416     (void)nodeId;
417     return UnregistServiceInner(REMOTE_NODE_INDEX, BAD_DISPATCHER_ID, serviceId);
418 }
CheckServiceID(ServiceId serviceId,bool allowSync)419 static bool CheckServiceID(ServiceId serviceId, bool allowSync)
420 {
421     if (serviceId >= MESSAGE_ENGINE_MAX_SERVICE) {
422         HDF_LOGE("receiverId exceed MaxServiceID.Route failed!");
423         return false;
424     }
425     (void)allowSync;
426 
427     if (g_servicesIndex[serviceId].remoteService != NULL) {
428         return true;
429     }
430 #ifdef USERSPACE_CLIENT_SUPPORT
431     if (!allowSync) {
432         return false;
433     }
434     for (uint8_t i = 0; i < MAX_NODE_COUNT; i++) {
435         if (g_messageNodes[i] != NULL && g_messageNodes[i]->SyncService != NULL) {
436             (void)g_messageNodes[i]->SyncService(g_messageNodes[i]);
437         }
438     }
439     return CheckServiceID(serviceId, false);
440 #else
441     return false;
442 #endif
443 }
444 
RefRemoteService(ServiceId serviceId)445 RemoteService *RefRemoteService(ServiceId serviceId)
446 {
447     HDF_STATUS status;
448     RemoteService *remoteService = NULL;
449     RemoteService *service = NULL;
450     if (serviceId >= MESSAGE_ENGINE_MAX_SERVICE) {
451         return NULL;
452     }
453 
454     if (!CheckServiceID(serviceId, true)) {
455         return NULL;
456     }
457     status = OsalMutexTimedLock(&g_routerMutex, HDF_WAIT_FOREVER);
458     if (status != HDF_SUCCESS) {
459         HDF_LOGE("Unable to get lock!status=%d", status);
460         return NULL;
461     }
462 
463     do {
464         remoteService = g_servicesIndex[serviceId].remoteService;
465         if (remoteService != NULL && remoteService->Ref != NULL) {
466             service = remoteService->Ref(remoteService);
467         }
468     } while (false);
469 
470     status = OsalMutexUnlock(&g_routerMutex);
471     if (status != HDF_SUCCESS) {
472         HDF_LOGE("Unable to get lock!status=%d", status);
473     }
474     return service;
475 }
476 
SendMessage(MessageContext * context)477 ErrorCode SendMessage(MessageContext *context)
478 {
479     RemoteService *service = NULL;
480     ErrorCode errCode;
481     service = RefRemoteService(context->receiverId);
482     if (service == NULL) {
483         return ME_ERROR_NO_SUCH_SERVICE;
484     }
485     do {
486         if (service->SendMessage == NULL) {
487             errCode = ME_ERROR_NOT_SUPPORTED;
488             break;
489         }
490         errCode = service->SendMessage(service, context);
491     } while (false);
492 
493     if (service->Disref != NULL) {
494         service->Disref(service);
495     }
496     return errCode;
497 }
498 
499 #if defined(KERNEL_SERVER_SUPPORT) || defined(USERSPACE_CLIENT_SUPPORT)
500 #error("define both KERNEL_SERVER_SUPPORT and USERSPACE_CLIENT_SUPPORT is not allowed!")
501 #endif
502 
503 #if defined(KERNEL_SERVER_SUPPORT) || defined(USERSPACE_CLIENT_SUPPORT)
CreateRemoteMessageNode(uint8_t nodesConfig)504 static ErrorCode CreateRemoteMessageNode(uint8_t nodesConfig)
505 {
506     ErrorCode errCode = ME_SUCCESS;
507     (void)nodesConfig;
508 
509 #ifdef KERNEL_SERVER_SUPPORT
510     if ((nodesConfig & MESSAGE_NODE_REMOTE_KERNEL_SERVER) != 0) {
511         HDF_LOGI("Creating kernel server node...");
512         errCode = CreateKernelServerNode(&g_messageNodes[REMOTE_NODE_INDEX]);
513     }
514 #endif
515 
516 #ifdef USERSPACE_CLIENT_SUPPORT
517     if ((nodesConfig & MESSAGE_NODE_REMOTE_USERSPACE_CLIENT) != 0) {
518         HDF_LOGI("Creating UserspaceClient server node...");
519         errCode = CreateUserspaceClientNode(&g_messageNodes[REMOTE_NODE_INDEX]);
520     }
521 #endif
522     return errCode;
523 }
524 #endif
525 
InitNodes(void)526 static ErrorCode InitNodes(void)
527 {
528     ErrorCode errCode = ME_SUCCESS;
529     uint8_t i;
530     for (i = 0; i < MAX_NODE_COUNT; i++) {
531         MessageNode *node = g_messageNodes[i];
532         if (node != NULL) {
533             if (node->Init != NULL) {
534                 errCode = node->Init(node);
535             }
536             if (errCode != ME_SUCCESS) {
537                 HDF_LOGE("%s: init node failed!id=%d,ret=%d", __func__, i, errCode);
538                 return errCode;
539             }
540         }
541     }
542     HDF_LOGI("%s: InitNodes successful!", __func__);
543     return ME_SUCCESS;
544 }
545 
ReleaseNodes(void)546 static void ReleaseNodes(void)
547 {
548     uint8_t i;
549     for (i = 0; i < MAX_NODE_COUNT; i++) {
550         MessageNode *node = g_messageNodes[i];
551         if (node == NULL) {
552             continue;
553         }
554         if (node->Disref != NULL) {
555             node->Disref(node);
556         }
557         g_messageNodes[i] = NULL;
558     }
559     HDF_LOGD("%s: ReleaseNodes finished!", __func__);
560 }
561 
DoStartMessageRouter(uint8_t nodesConfig)562 static ErrorCode DoStartMessageRouter(uint8_t nodesConfig)
563 {
564     uint8_t i;
565     ErrorCode errCode = ME_SUCCESS;
566     if (g_routerStatus != ME_STATUS_STOPPED) {
567         HDF_LOGE("Router have already started!");
568         return ME_ERROR_MUTI_INIT_NOT_ALLOWED;
569     }
570 
571     for (i = 0; i < MESSAGE_ENGINE_MAX_SERVICE; i++) {
572         g_servicesIndex[i].remoteService = NULL;
573         g_servicesIndex[i].nodeIndex = NO_SUCH_NODE_INDEX;
574         g_servicesIndex[i].dispatcherId = BAD_DISPATCHER_ID;
575     }
576     do {
577         HDF_LOGD("%s:Create local node ...", __func__);
578         errCode = CreateLocalNode(&g_messageNodes[LOCAL_NODE_INDEX]);
579         if (errCode != ME_SUCCESS) {
580             HDF_LOGE("%s:Create local node failed!ret=%d", __func__, errCode);
581             break;
582         }
583 #if defined(KERNEL_SERVER_SUPPORT) || defined(USERSPACE_CLIENT_SUPPORT)
584         HDF_LOGI("%s:Create remote node ...", __func__);
585         errCode = CreateRemoteMessageNode(nodesConfig);
586         if (errCode != ME_SUCCESS) {
587             HDF_LOGE("%s:Create remote node failed!ret=%d", __func__, errCode);
588             break;
589         }
590 #else
591         (void)nodesConfig;
592 #endif
593         errCode = InitNodes();
594     } while (false);
595 
596     if (errCode == ME_SUCCESS) {
597         g_routerStatus = ME_STATUS_RUNNING;
598         return ME_SUCCESS;
599     }
600 
601     ReleaseNodes();
602     HDF_LOGD("%s: DoStartMessageRouter successful!", __func__);
603     return ME_SUCCESS;
604 }
605 
EnableDefaultDispatcher(void)606 ErrorCode EnableDefaultDispatcher(void)
607 {
608     ErrorCode errCode;
609     DispatcherConfig config = {
610         .dispatcherId = DEFAULT_DISPATCHER_ID,
611         .queueSize = DEFAULT_DISPATCHER_QUEUE_SIZE,
612         .priorityLevelCount = DEFAULT_DISPATCHER_PRIORITY_COUNT
613     };
614     HDF_LOGI("Register default dispatcher...");
615     errCode = AddDispatcher(&config);
616     if (errCode != ME_SUCCESS) {
617         HDF_LOGE("Register default dispatcher failed!ret=%d", errCode);
618     }
619     return errCode;
620 }
621 
StartMessageRouter(uint8_t nodesConfig)622 ErrorCode StartMessageRouter(uint8_t nodesConfig)
623 {
624     HDF_STATUS status;
625     ErrorCode errCode;
626     if (g_routerMutex.realMutex == NULL) {
627         status = OsalMutexInit(&g_routerMutex);
628         if (status != HDF_SUCCESS) {
629             HDF_LOGE("%s: Init mutex failed! status=%d", __func__, status);
630             return ME_ERROR_OPER_MUTEX_FAILED;
631         }
632     }
633     status = OsalMutexTimedLock(&g_routerMutex, HDF_WAIT_FOREVER);
634     if (status != HDF_SUCCESS) {
635         HDF_LOGE("%s: Unable to get lock!status=%d", __func__, status);
636         return ME_ERROR_OPER_MUTEX_FAILED;
637     }
638     errCode = DoStartMessageRouter(nodesConfig);
639     status = OsalMutexUnlock(&g_routerMutex);
640     if (status != HDF_SUCCESS) {
641         HDF_LOGE("%s: Unable to get lock!status=%d", __func__, status);
642     }
643     HDF_LOGD("%s: StartMessageRouter finished! errCode=%d", __func__, errCode);
644     return errCode;
645 }
646 
DoShutdownMessageRouter(void)647 static ErrorCode DoShutdownMessageRouter(void)
648 {
649     uint8_t i;
650     RemoteService *service = NULL;
651     if (g_routerStatus == ME_STATUS_STOPPED) {
652         HDF_LOGD("%s: Router Status is stoped!", __func__);
653         return ME_SUCCESS;
654     }
655 
656     g_routerStatus = ME_STATUS_STOPPING;
657     for (i = 0; i < MESSAGE_ENGINE_MAX_SERVICE; i++) {
658         if (g_servicesIndex[i].remoteService == NULL) {
659             continue;
660         }
661         service = g_servicesIndex[i].remoteService;
662         g_servicesIndex[i].remoteService = NULL;
663         g_servicesIndex[i].nodeIndex = NO_SUCH_NODE_INDEX;
664         g_servicesIndex[i].dispatcherId = BAD_DISPATCHER_ID;
665 
666         ReleaseRemoteService(service);
667     }
668 
669     for (i = 0; i < MESSAGE_ENGINE_MAX_DISPATCHER; i++) {
670         if (g_dispatchers[i] != NULL && g_dispatchers[i]->Shutdown != NULL) {
671             g_dispatchers[i]->Shutdown(g_dispatchers[i]);
672         }
673         if (g_dispatchers[i] != NULL && g_dispatchers[i]->Disref != NULL) {
674             g_dispatchers[i]->Disref(g_dispatchers[i]);
675         }
676         g_dispatchers[i] = NULL;
677     }
678 
679     ReleaseNodes();
680     g_routerStatus = ME_STATUS_STOPPED;
681     HDF_LOGD("%s: DoShutdownMessageRouter successful!", __func__);
682     return ME_SUCCESS;
683 }
684 
ShutdownMessageRouter(void)685 ErrorCode ShutdownMessageRouter(void)
686 {
687     HDF_STATUS status;
688     ErrorCode errCode;
689     HDF_LOGW("%s:Shutdown router...", __func__);
690     status = OsalMutexTimedLock(&g_routerMutex, HDF_WAIT_FOREVER);
691     if (status != HDF_SUCCESS) {
692         HDF_LOGE("Unable to get lock!status=%d", status);
693         return ME_ERROR_OPER_MUTEX_FAILED;
694     }
695     errCode = DoShutdownMessageRouter();
696     status = OsalMutexUnlock(&g_routerMutex);
697     if (status != HDF_SUCCESS) {
698         HDF_LOGE("Unable to get lock!status=%d", status);
699     }
700     if (errCode == ME_SUCCESS) {
701         HDF_LOGW("%s:Router down.", __func__);
702     }
703     return errCode;
704 }
705 
RefMessageNode(const NodeId nodeId,bool isRequireLock)706 MessageNode *RefMessageNode(const NodeId nodeId, bool isRequireLock)
707 {
708     MessageNode *node = NULL;
709     HDF_STATUS status;
710     if (nodeId >= MAX_NODE_COUNT) {
711         HDF_LOGE("Input nodeId >= MAX_NODE_COUNT");
712         return NULL;
713     }
714     if (isRequireLock) {
715         status = OsalMutexTimedLock(&g_routerMutex, HDF_WAIT_FOREVER);
716         if (status != HDF_SUCCESS) {
717             HDF_LOGE("%s:require lock failed!", __func__);
718             return NULL;
719         }
720     }
721 
722     if (g_messageNodes[nodeId] != NULL && g_messageNodes[nodeId]->Ref != NULL) {
723         node = g_messageNodes[nodeId]->Ref(g_messageNodes[nodeId]);
724     }
725 
726     if (isRequireLock) {
727         status = OsalMutexUnlock(&g_routerMutex);
728         if (status != HDF_SUCCESS) {
729             HDF_LOGE("%s:Unlock mutex failed!", __func__);
730         }
731     }
732     return node;
733 }
734