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 #include "hdf_base.h"
9 #include "securec.h"
10 #include "utils/hdf_log.h"
11 #include "sidecar.h"
12 #include "message_router.h"
13 #include "message_router_inner.h"
14
15 #ifdef USERSPACE_CLIENT_SUPPORT
16 #define HDF_LOG_TAG UMsgEngine
17 #else
18 #define HDF_LOG_TAG KMsgEngine
19 #endif
20
21 // Service has only one private data.The service ID of current service
22 typedef struct {
23 DispatcherId dispatcherId;
24 ServiceId serviceId;
25 } SideCarPrivateData;
26
MessageInputCheck(const Service * sideCar,ServiceId receiver,struct HdfSBuf * sendData)27 static ErrorCode MessageInputCheck(const Service *sideCar, ServiceId receiver, struct HdfSBuf *sendData)
28 {
29 if (sideCar == NULL || sideCar->privateData == NULL) {
30 HDF_LOGE("%s:sideCar or sideCar.privateData is NULL", __func__);
31 return ME_ERROR_NULL_PTR;
32 }
33
34 SideCarPrivateData *privateData = (SideCarPrivateData *)sideCar->privateData;
35 if (receiver >= MESSAGE_ENGINE_MAX_SERVICE || privateData->serviceId >= MESSAGE_ENGINE_MAX_SERVICE) {
36 return ME_ERROR_NO_SUCH_SERVICE;
37 }
38 return ME_SUCCESS;
39 }
40
CreateMessageContext(ServiceId sender,ServiceId receiver,uint32_t commandId,struct HdfSBuf * sendData)41 static MessageContext *CreateMessageContext(ServiceId sender, ServiceId receiver, uint32_t commandId,
42 struct HdfSBuf *sendData)
43 {
44 MessageContext *context = (MessageContext *)OsalMemCalloc(sizeof(MessageContext));
45 if (context == NULL) {
46 return NULL;
47 }
48
49 context->commandId = commandId;
50 context->senderId = sender;
51 context->receiverId = receiver;
52 context->reqData = sendData;
53 context->crossNode = false;
54
55 return context;
56 }
57
58 #define MESSAGE_CMD_BITS 16
59 #define MESSAGE_CMD_MASK 0xffff
60
GetServiceID(uint32_t id)61 inline static uint32_t GetServiceID(uint32_t id)
62 {
63 return (id & ~((uint32_t)(MESSAGE_CMD_MASK))) >> MESSAGE_CMD_BITS;
64 }
65
GetCmd(uint32_t id)66 inline static uint32_t GetCmd(uint32_t id)
67 {
68 return id & MESSAGE_CMD_MASK;
69 }
70
DispatchToMessage(struct HdfDeviceIoClient * client,int id,struct HdfSBuf * reqData,struct HdfSBuf * rspData)71 int32_t DispatchToMessage(struct HdfDeviceIoClient *client, int id, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
72 {
73 ErrorCode errCode;
74 ServiceId serviceId = GetServiceID(id);
75 uint32_t cmd = GetCmd(id);
76 MessageContext *context = NULL;
77
78 if (client == NULL) {
79 return HDF_ERR_INVALID_PARAM;
80 }
81 if (serviceId >= MESSAGE_ENGINE_MAX_SERVICE) {
82 return ME_ERROR_NO_SUCH_SERVICE;
83 }
84 context = CreateMessageContext(RESERVED_SERVICE_ID, serviceId, cmd, reqData);
85 if (context == NULL) {
86 return ME_ERROR_NULL_PTR;
87 }
88 context->rspData = rspData;
89 context->requestType = MESSAGE_TYPE_SYNC_REQ;
90 context->client = client;
91 RemoteService *targetService = NULL;
92 do {
93 targetService = RefRemoteService(serviceId);
94 if (targetService == NULL || targetService->SendMessage == NULL) {
95 HDF_LOGE("%s:Target service is NULL or has no SendMessage!", __func__);
96 errCode = ME_ERROR_NO_SUCH_SERVICE;
97 break;
98 }
99
100 errCode = targetService->SendMessage(targetService, context);
101 } while (false);
102 if (targetService != NULL && targetService->Disref != NULL) {
103 targetService->Disref(targetService);
104 }
105 OsalMemFree(context);
106 return errCode;
107 }
108
SideCarSendSyncMessage(const Service * sideCar,ServiceId receiver,uint32_t commandId,struct HdfSBuf * sendData,struct HdfSBuf * recvData)109 static ErrorCode SideCarSendSyncMessage(const Service *sideCar, ServiceId receiver, uint32_t commandId,
110 struct HdfSBuf *sendData, struct HdfSBuf *recvData)
111 {
112 ErrorCode errCode = MessageInputCheck(sideCar, receiver, sendData);
113 if (errCode != ME_SUCCESS) {
114 return errCode;
115 }
116 SideCarPrivateData *privateData = (SideCarPrivateData *)sideCar->privateData;
117 MessageContext *context = CreateMessageContext(privateData->serviceId, receiver, commandId, sendData);
118 if (context == NULL) {
119 return ME_ERROR_NULL_PTR;
120 }
121 context->rspData = recvData;
122 context->requestType = MESSAGE_TYPE_SYNC_REQ;
123 RemoteService *targetService = NULL;
124 do {
125 targetService = RefRemoteService(receiver);
126 if (targetService == NULL || targetService->SendMessage == NULL) {
127 HDF_LOGE("Target service is NULL or has no SendMessage!");
128 errCode = ME_ERROR_NO_SUCH_SERVICE;
129 break;
130 }
131
132 errCode = targetService->SendMessage(targetService, context);
133 } while (false);
134 if (targetService != NULL && targetService->Disref != NULL) {
135 targetService->Disref(targetService);
136 }
137 OsalMemFree(context);
138 return errCode;
139 }
140
SideCarSendAsyncMessageInner(const Service * sideCar,ServiceId receiver,uint32_t commandId,struct HdfSBuf * reqData,MessageCallBack callback)141 static ErrorCode SideCarSendAsyncMessageInner(const Service *sideCar, ServiceId receiver, uint32_t commandId,
142 struct HdfSBuf *reqData, MessageCallBack callback)
143 {
144 ErrorCode errCode = MessageInputCheck(sideCar, receiver, reqData);
145 if (errCode != ME_SUCCESS) {
146 return errCode;
147 }
148
149 SideCarPrivateData *privateData = (SideCarPrivateData *)sideCar->privateData;
150 MessageContext *context = CreateMessageContext(privateData->serviceId, receiver, commandId, reqData);
151 if (context == NULL) {
152 return ME_ERROR_NULL_PTR;
153 }
154 struct HdfSBuf *rspData = HdfSBufObtainDefaultSize();
155 if (rspData == NULL) {
156 OsalMemFree(context);
157 return HDF_FAILURE;
158 }
159 context->requestType = MESSAGE_TYPE_ASYNC_REQ;
160 context->callback = callback;
161 context->rspData = rspData;
162
163 RemoteService *targetService = NULL;
164 do {
165 targetService = RefRemoteService(receiver);
166 if (targetService == NULL || targetService->SendMessage == NULL) {
167 HDF_LOGE("Target service is NULL or has no SendMessage!");
168 errCode = ME_ERROR_NO_SUCH_SERVICE;
169 break;
170 }
171
172 errCode = targetService->SendMessage(targetService, context);
173 } while (false);
174 if (targetService != NULL && targetService->Disref != NULL) {
175 targetService->Disref(targetService);
176 }
177 if (errCode != ME_SUCCESS) {
178 HdfSBufRecycle(rspData);
179 OsalMemFree(context);
180 }
181 return errCode;
182 }
183
SideCarSendAsyncMessage(const Service * sideCar,ServiceId receiver,uint32_t commandId,struct HdfSBuf * reqData,MessageCallBack callback)184 static ErrorCode SideCarSendAsyncMessage(const Service *sideCar, ServiceId receiver, uint32_t commandId,
185 struct HdfSBuf *reqData, MessageCallBack callback)
186 {
187 if (callback == NULL) {
188 HDF_LOGE("%s:Callback function can not be NULL.Did you mean SendOnewayMessage?", __func__);
189 return ME_ERROR_PARA_WRONG;
190 }
191 return SideCarSendAsyncMessageInner(sideCar, receiver, commandId, reqData, callback);
192 }
193
SideCarSendOneWayMessage(const struct SideCar_ * sideCar,ServiceId receiver,uint32_t commandId,struct HdfSBuf * reqData)194 static ErrorCode SideCarSendOneWayMessage(const struct SideCar_ *sideCar, ServiceId receiver, uint32_t commandId,
195 struct HdfSBuf *reqData)
196 {
197 return SideCarSendAsyncMessageInner(sideCar, receiver, commandId, reqData, NULL);
198 }
199
DestroyService(Service * service)200 static ErrorCode DestroyService(Service *service)
201 {
202 if (service == NULL) {
203 return ME_ERROR_NULL_PTR;
204 }
205
206 if (service->privateData == NULL) {
207 HDF_LOGE("%s:privateData is NULL!", __func__);
208 return ME_ERROR_PARA_WRONG;
209 }
210 SideCarPrivateData *data = (SideCarPrivateData *)service->privateData;
211 HDF_LOGE("Destroy service! id=%d", data->serviceId);
212
213 ErrorCode errCode = UnregistLocalService(data->dispatcherId, data->serviceId);
214 if (errCode != ME_SUCCESS) {
215 HDF_LOGE("Unregist service failed!ret=%d", errCode);
216 return errCode;
217 }
218
219 OsalMemFree(data);
220 service->privateData = NULL;
221 OsalMemFree(service);
222 return ME_SUCCESS;
223 }
224
InitService(struct ServiceDef * def,const ServiceCfg * cfg)225 Service *InitService(struct ServiceDef *def, const ServiceCfg *cfg)
226 {
227 if (cfg == NULL || def == NULL) {
228 return NULL;
229 }
230
231 if (def->serviceId == RESERVED_SERVICE_ID) {
232 HDF_LOGE("%s:Init service with ID 0 is not allowed!", __func__);
233 return NULL;
234 }
235
236 Service *service = (Service *)OsalMemCalloc(sizeof(Service));
237 if (service == NULL) {
238 HDF_LOGE("%s:OsalMemAlloc return NULL!", __func__);
239 return NULL;
240 }
241 service->SendAsyncMessage = SideCarSendAsyncMessage;
242 service->SendSyncMessage = SideCarSendSyncMessage;
243 service->SendOneWayMessage = SideCarSendOneWayMessage;
244 service->Destroy = DestroyService;
245
246 SideCarPrivateData *privateData = (SideCarPrivateData *)OsalMemCalloc(sizeof(SideCarPrivateData));
247 if (privateData == NULL) {
248 OsalMemFree(service);
249 HDF_LOGE("%s:OsalMemAlloc return NULL!", __func__);
250 return NULL;
251 }
252 privateData->serviceId = def->serviceId;
253 privateData->dispatcherId = cfg->dispatcherId;
254 service->privateData = (void *)privateData;
255 privateData = NULL;
256
257 ErrorCode errCode = RegistLocalService(cfg->dispatcherId, def);
258 if (errCode != ME_SUCCESS) {
259 OsalMemFree(service->privateData);
260 service->privateData = NULL;
261 OsalMemFree(service);
262 service = NULL;
263 HDF_LOGE("Register service failed!serviceId=%d,ret=%d", def->serviceId, errCode);
264 return NULL;
265 }
266 return service;
267 }
268