• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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