1 /*
2 * Copyright (c) 2020-2021 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_wlan_priority_queue.h"
11 #include "utils/hdf_log.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 }
51
HandleResponseMessage(const RemoteService * service,MessageContext * context)52 static void HandleResponseMessage(const RemoteService *service, MessageContext *context)
53 {
54 HDF_STATUS status;
55 (void)service;
56 if (context->requestType < MESSAGE_RSP_START) {
57 return;
58 }
59
60 if (context->requestType == MESSAGE_TYPE_SYNC_RSP) {
61 status = OsalSemPost(&context->rspSemaphore);
62 if (status != HDF_SUCCESS) {
63 ReleaseMessageContext(context);
64 }
65 } else if (context->requestType == MESSAGE_TYPE_ASYNC_RSP) {
66 if (context->callback != NULL) {
67 context->callback((const RequestContext *)context, context->reqData, context->rspData,
68 context->responseStatus);
69 }
70 ReleaseMessageContext(context);
71 } else {
72 HDF_LOGE("%s:Response type not supported!type=%u", __func__, context->requestType);
73 }
74 }
75
SendMessageLocalNode(const RemoteService * service,MessageContext * context)76 ErrorCode SendMessageLocalNode(const RemoteService *service, MessageContext *context)
77 {
78 LocalNodeService *localService = NULL;
79 uint8_t pri = HIGHEST_PRIORITY;
80 if (service == NULL || context == NULL) {
81 HDF_LOGE("%s:Input is NULL!", __func__);
82 return ME_ERROR_NULL_PTR;
83 }
84
85 if (!context->crossNode && context->requestType == MESSAGE_TYPE_SYNC_REQ) {
86 HandleRequestMessage(service, context);
87 SetToResponse(context);
88 return context->responseStatus;
89 } else if (context->requestType == MESSAGE_TYPE_SYNC_RSP) {
90 (void)OsalSemPost(&context->rspSemaphore);
91 return ME_SUCCESS;
92 } else {
93 localService = (LocalNodeService *)service;
94 if (localService->dispatcher == NULL || localService->dispatcher->AppendMessage == NULL) {
95 HDF_LOGE("This service has no dispatcher!");
96 return ME_ERROR_NOT_SUPPORTED;
97 }
98 if (context->requestType < MESSAGE_RSP_START) {
99 if (localService->mapper == NULL || localService->mapper->messages == NULL) {
100 HDF_LOGE("%s:Bad message mapper!", __func__);
101 return ME_ERROR_NULL_PTR;
102 }
103
104 if (context->commandId >= localService->mapper->messagesLength ||
105 localService->mapper->messages[context->commandId].handler == NULL) {
106 HDF_LOGE("%s:Request command not found!", __func__);
107 return ME_ERROR_NO_SUCH_COMMAND;
108 }
109
110 pri = localService->mapper->messages[context->commandId].pri;
111 }
112 return localService->dispatcher->AppendMessage(localService->dispatcher, pri, context);
113 }
114 }
115
ShutdownLocalService(RemoteService * service)116 static void ShutdownLocalService(RemoteService *service)
117 {
118 service->status = ME_STATUS_TODESTROY;
119 }
120
DestroyLocalNodeRemoteService(RemoteService * service)121 static void DestroyLocalNodeRemoteService(RemoteService *service)
122 {
123 LocalNodeService *localService = NULL;
124 if (service == NULL) {
125 return;
126 }
127 localService = (LocalNodeService *)service;
128 if (localService->dispatcher != NULL && localService->dispatcher->Disref != NULL) {
129 localService->dispatcher->Disref(localService->dispatcher);
130 }
131 localService->mapper = NULL;
132 localService->dispatcher = NULL;
133 DEINIT_SHARED_OBJ(RemoteService, service);
134 }
135
CreateLocalNodeService(MessageNode * node,MessageDispatcher * dispatcher,struct ServiceDef * mapper)136 RemoteService *CreateLocalNodeService(MessageNode *node, MessageDispatcher *dispatcher, struct ServiceDef *mapper)
137 {
138 LocalNodeService *service = NULL;
139 ErrorCode errCode;
140 (void)node;
141 if (mapper == NULL) {
142 return NULL;
143 }
144 if (dispatcher == NULL || dispatcher->Ref == NULL) {
145 HDF_LOGE("%s:Bad dispatcher found!", __func__);
146 return NULL;
147 }
148 service = (LocalNodeService *)OsalMemCalloc(sizeof(LocalNodeService));
149 if (service == NULL) {
150 return NULL;
151 }
152 do {
153 service->status = ME_STATUS_RUNNING;
154 service->ExecRequestMsg = HandleRequestMessage;
155 service->ExecResponseMsg = HandleResponseMessage;
156 service->SendMessage = SendMessageLocalNode;
157 service->Shutdown = ShutdownLocalService;
158 service->serviceId = mapper->serviceId;
159 service->mapper = mapper;
160 service->dispatcher = dispatcher->Ref(dispatcher);
161 if (service->dispatcher == NULL) {
162 errCode = ME_ERROR_NO_SUCH_DISPATCHER;
163 break;
164 }
165
166 errCode = INIT_SHARED_OBJ(RemoteService, (RemoteService *)service, DestroyLocalNodeRemoteService);
167 if (errCode != ME_SUCCESS) {
168 break;
169 }
170 } while (false);
171
172 if (errCode != ME_SUCCESS) {
173 DestroyLocalNodeRemoteService((RemoteService *)service);
174 OsalMemFree(service);
175 return NULL;
176 }
177 return (RemoteService *)service;
178 }
179
InitLocalNode(MessageNode * node)180 static ErrorCode InitLocalNode(MessageNode *node)
181 {
182 HDF_STATUS status;
183 ErrorCode errCode;
184 if (node == NULL) {
185 return ME_ERROR_NULL_PTR;
186 }
187
188 status = OsalMutexTimedLock(&node->mutex, HDF_WAIT_FOREVER);
189 if (status != HDF_SUCCESS) {
190 return ME_ERROR_OPER_MUTEX_FAILED;
191 }
192 errCode = ME_SUCCESS;
193 do {
194 if (node->status != ME_STATUS_STOPPED) {
195 HDF_LOGE("%s:unexpected status %d", __func__, node->status);
196 errCode = ME_ERROR_MUTI_INIT_NOT_ALLOWED;
197 break;
198 }
199
200 node->status = ME_STATUS_STARTTING;
201 } while (false);
202
203 status = OsalMutexUnlock(&node->mutex);
204 if (status != HDF_SUCCESS) {
205 HDF_LOGE("%s:unlock mutex failed!", __func__);
206 }
207
208 if (errCode != ME_SUCCESS) {
209 return errCode;
210 }
211
212 status = OsalMutexTimedLock(&node->mutex, HDF_WAIT_FOREVER);
213 if (status != HDF_SUCCESS) {
214 HDF_LOGE("%s:lock mutex failed!", __func__);
215 }
216 if (errCode == ME_SUCCESS) {
217 node->status = ME_STATUS_RUNNING;
218 } else {
219 node->status = ME_STATUS_STOPPED;
220 }
221
222 status = OsalMutexUnlock(&node->mutex);
223 if (status != HDF_SUCCESS) {
224 HDF_LOGE("%s:unlock mutex failed!", __func__);
225 }
226 return errCode;
227 }
228
DestroyLocalNode(MessageNode * node)229 static void DestroyLocalNode(MessageNode *node)
230 {
231 int32_t ret;
232 if (node == NULL) {
233 return;
234 }
235 ret = OsalMutexDestroy(&node->mutex);
236 if (ret != HDF_SUCCESS) {
237 HDF_LOGE("%s:Release mutex failed!ret=%d", __func__, ret);
238 }
239 DEINIT_SHARED_OBJ(MessageNode, node);
240 }
241
CreateLocalNode(MessageNode ** node)242 ErrorCode CreateLocalNode(MessageNode **node)
243 {
244 int32_t ret;
245 LocalMessageNode *newNode = NULL;
246 ErrorCode errCode;
247 if (node == NULL) {
248 return ME_ERROR_NULL_PTR;
249 }
250 HDF_LOGI("Creating local node...");
251 newNode = (LocalMessageNode *)OsalMemCalloc(sizeof(LocalMessageNode));
252 if (newNode == NULL) {
253 return ME_ERROR_RES_LAKE;
254 }
255 do {
256 newNode->status = ME_STATUS_STOPPED;
257 newNode->Init = InitLocalNode;
258 newNode->CreateRemoteService = CreateLocalNodeService;
259 newNode->SyncService = NULL;
260 newNode->NotifyServiceAdd = NULL;
261 newNode->NotifyServiceDel = NULL;
262
263 ret = OsalMutexInit(&newNode->mutex);
264 if (ret != HDF_SUCCESS) {
265 HDF_LOGE("%s:Init mutex failed!err=%d", __func__, ret);
266 errCode = ME_ERROR_OPER_MUTEX_FAILED;
267 break;
268 }
269
270 errCode = INIT_SHARED_OBJ(MessageNode, (MessageNode *)newNode, DestroyLocalNode);
271 if (errCode != ME_SUCCESS) {
272 break;
273 }
274 } while (false);
275
276 if (errCode != ME_SUCCESS) {
277 DestroyLocalNode((MessageNode *)newNode);
278 OsalMemFree(newNode);
279 } else {
280 *node = (MessageNode *)newNode;
281 }
282 return errCode;
283 }