• 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 "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