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 "securec.h"
10 #include "hdf_log.h"
11 #include "hdf_wlan_priority_queue.h"
12 #include "message/message_types.h"
13 #include "message_router_inner.h"
14 #include "sidecar.h"
15 
16 #ifdef USERSPACE_CLIENT_SUPPORT
17 #define HDF_LOG_TAG UMsgEngine
18 #else
19 #define HDF_LOG_TAG KMsgEngine
20 #endif
21 
22 typedef struct LocalMessageNode {
23     INHERT_MESSAGE_NODE;
24 } LocalMessageNode;
25 
26 typedef struct LocalNodeService {
27     INHERT_REMOTE_SERVICE;
28     MessageDispatcher *dispatcher;
29     struct ServiceDef *mapper;
30 } LocalNodeService;
31 
HandleRequestMessage(const RemoteService * service,MessageContext * context)32 static void HandleRequestMessage(const RemoteService *service, MessageContext *context)
33 {
34     LocalNodeService *localNodeService = NULL;
35     localNodeService = (LocalNodeService *)service;
36     struct MessageDef messageDef = { NULL, 0 };
37 
38     if (context == NULL || service == NULL) {
39         HDF_LOGE("%s:Input is NULL", __func__);
40         return;
41     }
42     if (localNodeService->mapper != NULL && context->commandId < localNodeService->mapper->messagesLength) {
43         messageDef = localNodeService->mapper->messages[context->commandId];
44     }
45     if (messageDef.handler == NULL) {
46         context->responseStatus = ME_ERROR_NO_SUCH_COMMAND;
47     } else {
48         context->responseStatus = messageDef.handler((RequestContext *)context, context->reqData, context->rspData);
49     }
50     HDF_LOGD("%s:HandleRequestMessage finished!", __func__);
51 }
52 
HandleResponseMessage(const RemoteService * service,MessageContext * context)53 static void HandleResponseMessage(const RemoteService *service, MessageContext *context)
54 {
55     HDF_STATUS status;
56     (void)service;
57     if (context->requestType < MESSAGE_RSP_START) {
58         HDF_LOGD("%s: Not expected requestType!", __func__);
59         return;
60     }
61 
62     if (context->requestType == MESSAGE_TYPE_SYNC_RSP) {
63         status = OsalSemPost(&context->rspSemaphore);
64         if (status != HDF_SUCCESS) {
65             HDF_LOGE("%s: OsalSemPost failed! status=%d", __func__, status);
66             ReleaseMessageContext(context);
67         }
68     } else if (context->requestType == MESSAGE_TYPE_ASYNC_RSP) {
69         if (context->callback != NULL) {
70             context->callback((const RequestContext *)context, context->reqData, context->rspData,
71                 context->responseStatus);
72         }
73         ReleaseMessageContext(context);
74     } else {
75         HDF_LOGE("%s:Response type not supported!type=%u", __func__, context->requestType);
76     }
77     HDF_LOGD("%s: HandleResponseMessage  finished!", __func__);
78 }
79 
SendMessageLocalNode(const RemoteService * service,MessageContext * context)80 ErrorCode SendMessageLocalNode(const RemoteService *service, MessageContext *context)
81 {
82     LocalNodeService *localService = NULL;
83     uint8_t pri = HIGHEST_PRIORITY;
84     if (service == NULL || context == NULL) {
85         HDF_LOGE("%s:Input is NULL!", __func__);
86         return ME_ERROR_NULL_PTR;
87     }
88 
89     if (!context->crossNode && context->requestType == MESSAGE_TYPE_SYNC_REQ) {
90         HandleRequestMessage(service, context);
91         SetToResponse(context);
92         return context->responseStatus;
93     } else if (context->requestType == MESSAGE_TYPE_SYNC_RSP) {
94         (void)OsalSemPost(&context->rspSemaphore);
95         return ME_SUCCESS;
96     } else {
97         localService = (LocalNodeService *)service;
98         if (localService->dispatcher == NULL || localService->dispatcher->AppendMessage == NULL) {
99             HDF_LOGE("This service has no dispatcher!");
100             return ME_ERROR_NOT_SUPPORTED;
101         }
102         if (context->requestType < MESSAGE_RSP_START) {
103             if (localService->mapper == NULL || localService->mapper->messages == NULL) {
104                 HDF_LOGE("%s:Bad message mapper!", __func__);
105                 return ME_ERROR_NULL_PTR;
106             }
107 
108             if (context->commandId >= localService->mapper->messagesLength ||
109                 localService->mapper->messages[context->commandId].handler == NULL) {
110                 HDF_LOGE("%s:Request command not found!", __func__);
111                 return ME_ERROR_NO_SUCH_COMMAND;
112             }
113 
114             pri = localService->mapper->messages[context->commandId].pri;
115         }
116         return localService->dispatcher->AppendMessage(localService->dispatcher, pri, context);
117     }
118 }
119 
ShutdownLocalService(RemoteService * service)120 static void ShutdownLocalService(RemoteService *service)
121 {
122     service->status = ME_STATUS_TODESTROY;
123 }
124 
DestroyLocalNodeRemoteService(RemoteService * service)125 static void DestroyLocalNodeRemoteService(RemoteService *service)
126 {
127     LocalNodeService *localService = NULL;
128     if (service == NULL) {
129         HDF_LOGE("%s: Input param is null!", __func__);
130         return;
131     }
132     localService = (LocalNodeService *)service;
133     if (localService->dispatcher != NULL && localService->dispatcher->Disref != NULL) {
134         localService->dispatcher->Disref(localService->dispatcher);
135     }
136     localService->mapper = NULL;
137     localService->dispatcher = NULL;
138     DEINIT_SHARED_OBJ(RemoteService, service);
139     HDF_LOGD("%s:DestroyLocalNodeRemoteService finished!", __func__);
140 }
141 
CreateLocalNodeService(MessageNode * node,MessageDispatcher * dispatcher,struct ServiceDef * mapper)142 RemoteService *CreateLocalNodeService(MessageNode *node, MessageDispatcher *dispatcher, struct ServiceDef *mapper)
143 {
144     LocalNodeService *service = NULL;
145     ErrorCode errCode;
146     (void)node;
147     if (mapper == NULL) {
148         HDF_LOGE("%s: Input param is null!", __func__);
149         return NULL;
150     }
151     if (dispatcher == NULL || dispatcher->Ref == NULL) {
152         HDF_LOGE("%s:Bad dispatcher found!", __func__);
153         return NULL;
154     }
155     service = (LocalNodeService *)OsalMemCalloc(sizeof(LocalNodeService));
156     if (service == NULL) {
157         HDF_LOGE("%s: Request memory failed!", __func__);
158         return NULL;
159     }
160     do {
161         HDF_LOGD("%s: Create local node service...!", __func__);
162         service->status = ME_STATUS_RUNNING;
163         service->ExecRequestMsg = HandleRequestMessage;
164         service->ExecResponseMsg = HandleResponseMessage;
165         service->SendMessage = SendMessageLocalNode;
166         service->Shutdown = ShutdownLocalService;
167         service->serviceId = mapper->serviceId;
168         service->mapper = mapper;
169         service->dispatcher = dispatcher->Ref(dispatcher);
170         if (service->dispatcher == NULL) {
171             HDF_LOGD("%s: Service->dispatcher is null!", __func__);
172             errCode = ME_ERROR_NO_SUCH_DISPATCHER;
173             break;
174         }
175 
176         errCode = INIT_SHARED_OBJ(RemoteService, (RemoteService *)service, DestroyLocalNodeRemoteService);
177         if (errCode != ME_SUCCESS) {
178             HDF_LOGE("%s: Init shared obj failed! errCode=%d", __func__, errCode);
179             break;
180         }
181     } while (false);
182 
183     if (errCode != ME_SUCCESS) {
184         DestroyLocalNodeRemoteService((RemoteService *)service);
185         OsalMemFree(service);
186         return NULL;
187     }
188     HDF_LOGD("%s: CreateLocalNodeService finished!", __func__);
189     return (RemoteService *)service;
190 }
191 
InitLocalNode(MessageNode * node)192 static ErrorCode InitLocalNode(MessageNode *node)
193 {
194     HDF_STATUS status;
195     ErrorCode errCode;
196     if (node == NULL) {
197         HDF_LOGE("%s: Input param is null!", __func__);
198         return ME_ERROR_NULL_PTR;
199     }
200     HDF_LOGD("%s:Init local node...", __func__);
201     status = OsalMutexTimedLock(&node->mutex, HDF_WAIT_FOREVER);
202     if (status != HDF_SUCCESS) {
203         HDF_LOGE("%s: Lock mutexTime failed!", __func__);
204         return ME_ERROR_OPER_MUTEX_FAILED;
205     }
206     errCode = ME_SUCCESS;
207     do {
208         if (node->status != ME_STATUS_STOPPED) {
209             HDF_LOGE("%s:unexpected status %d", __func__, node->status);
210             errCode = ME_ERROR_MUTI_INIT_NOT_ALLOWED;
211             break;
212         }
213 
214         node->status = ME_STATUS_STARTTING;
215     } while (false);
216 
217     status = OsalMutexUnlock(&node->mutex);
218     if (status != HDF_SUCCESS) {
219         HDF_LOGE("%s:Unlock mutex failed! status=%d", __func__, status);
220     }
221 
222     if (errCode != ME_SUCCESS) {
223         HDF_LOGE("%s:Unexpected errCode! errCode=%d", __func__, errCode);
224         return errCode;
225     }
226 
227     status = OsalMutexTimedLock(&node->mutex, HDF_WAIT_FOREVER);
228     if (status != HDF_SUCCESS) {
229         HDF_LOGE("%s:Lock mutex failed! status=%d", __func__, status);
230     }
231     if (errCode == ME_SUCCESS) {
232         node->status = ME_STATUS_RUNNING;
233     } else {
234         node->status = ME_STATUS_STOPPED;
235     }
236 
237     status = OsalMutexUnlock(&node->mutex);
238     if (status != HDF_SUCCESS) {
239         HDF_LOGE("%s:Unlock mutex failed! status=%d", __func__, status);
240     }
241     HDF_LOGD("%s: InitLocalNode finished! errCode=%d", __func__, errCode);
242     return errCode;
243 }
244 
DestroyLocalNode(MessageNode * node)245 static void DestroyLocalNode(MessageNode *node)
246 {
247     int32_t ret;
248     if (node == NULL) {
249         HDF_LOGE("%s: Input param is null!", __func__);
250         return;
251     }
252     ret = OsalMutexDestroy(&node->mutex);
253     if (ret != HDF_SUCCESS) {
254         HDF_LOGE("%s:Release mutex failed!ret=%d", __func__, ret);
255     }
256     DEINIT_SHARED_OBJ(MessageNode, node);
257     HDF_LOGD("%s: DestroyLocalNode finished!", __func__);
258 }
259 
CreateLocalNode(MessageNode ** node)260 ErrorCode CreateLocalNode(MessageNode **node)
261 {
262     int32_t ret;
263     LocalMessageNode *newNode = NULL;
264     ErrorCode errCode;
265     if (node == NULL) {
266         HDF_LOGE("%s: Input param is null!", __func__);
267         return ME_ERROR_NULL_PTR;
268     }
269     HDF_LOGI("%s: Creating local node...!", __func__);
270     newNode = (LocalMessageNode *)OsalMemCalloc(sizeof(LocalMessageNode));
271     if (newNode == NULL) {
272         HDF_LOGE("%s: Failed to request memory!", __func__);
273         return ME_ERROR_RES_LAKE;
274     }
275     do {
276         newNode->status = ME_STATUS_STOPPED;
277         newNode->Init = InitLocalNode;
278         newNode->CreateRemoteService = CreateLocalNodeService;
279         newNode->SyncService = NULL;
280         newNode->NotifyServiceAdd = NULL;
281         newNode->NotifyServiceDel = NULL;
282 
283         ret = OsalMutexInit(&newNode->mutex);
284         if (ret != HDF_SUCCESS) {
285             HDF_LOGE("%s:Init mutex failed!err=%d", __func__, ret);
286             errCode = ME_ERROR_OPER_MUTEX_FAILED;
287             break;
288         }
289 
290         errCode = INIT_SHARED_OBJ(MessageNode, (MessageNode *)newNode, DestroyLocalNode);
291         if (errCode != ME_SUCCESS) {
292             HDF_LOGE("%s: Init shared obj failed! errCode=%d", __func__, errCode);
293             break;
294         }
295     } while (false);
296 
297     if (errCode != ME_SUCCESS) {
298         DestroyLocalNode((MessageNode *)newNode);
299         OsalMemFree(newNode);
300     } else {
301         *node = (MessageNode *)newNode;
302     }
303     return errCode;
304 }