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 }