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