1 /*
2  * Copyright (c) 2020-2022 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 #ifndef SIDECAR_H
10 #define SIDECAR_H
11 
12 #include "hdf_base.h"
13 #include "hdf_device_desc.h"
14 #include "hdf_sbuf.h"
15 #include "message_types.h"
16 #include "osal_sem.h"
17 
18 enum MessageType {
19     MESSAGE_REQ_START = 0,
20     MESSAGE_TYPE_SYNC_REQ,
21     MESSAGE_TYPE_ASYNC_REQ,
22 
23     MESSAGE_RSP_START,
24     MESSAGE_TYPE_SYNC_RSP,
25     MESSAGE_TYPE_ASYNC_RSP,
26 };
27 
28 #define INHERT_REQUEST_CONTEXT \
29     uint32_t commandId;        \
30     uint8_t senderId;          \
31     uint8_t receiverId;        \
32     uint8_t requestType;       \
33     bool crossNode;            \
34     struct HdfDeviceIoClient *client
35 
36 #define RESERVED_SERVICE_ID 0
37 #define BAD_SERVICE_ID 254
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 int32_t DispatchToMessage(struct HdfDeviceIoClient *client, int id, struct HdfSBuf *reqData, struct HdfSBuf *rspData);
44 
45 typedef struct {
46     INHERT_REQUEST_CONTEXT;
47 } RequestContext;
48 
49 typedef void (*MessageCallBack)(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData,
50     ErrorCode responseStatus);
51 
52 typedef ErrorCode (*MessageHandler)(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData);
53 
54 struct MessageContext {
55     INHERT_REQUEST_CONTEXT;
56 #if defined(KERNEL_SERVER_SUPPORT) || defined(USERSPACE_CLIENT_SUPPORT)
57     uint16_t messageID;
58 #endif
59     ErrorCode responseStatus;
60     struct HdfSBuf *reqData;
61     struct HdfSBuf *rspData;
62     union {
63         MessageCallBack callback;
64         OSAL_DECLARE_SEMAPHORE(rspSemaphore);
65     };
66 };
67 typedef struct MessageContext MessageContext;
68 
69 typedef struct SideCar_ {
70     ErrorCode (*SendOneWayMessage)(const struct SideCar_ *sideCar, ServiceId receiver, uint32_t commandId,
71         struct HdfSBuf *reqData);
72 
73     ErrorCode (*SendSyncMessage)(const struct SideCar_ *sideCar, ServiceId receiver, uint32_t commandId,
74         struct HdfSBuf *sendData, struct HdfSBuf *recvData);
75 
76     ErrorCode (*SendAsyncMessage)(const struct SideCar_ *sideCar, ServiceId receiver, uint32_t commandId,
77         struct HdfSBuf *reqData, MessageCallBack callback);
78 
79     ErrorCode (*Destroy)(struct SideCar_ *sideCar);
80 
81     void *privateData;
82 } Service;
83 
84 typedef struct {
85     DispatcherId dispatcherId;
86 } ServiceCfg;
87 
88 struct MessageDef {
89     MessageHandler handler;
90     uint8_t pri;
91 };
92 
93 struct ServiceDef {
94     ServiceId serviceId;
95     uint8_t messagesLength;
96     struct MessageDef *messages;
97 };
98 
99 Service *InitService(struct ServiceDef *def, const ServiceCfg *cfg);
100 
101 #define DUEMessage(CMDID, HANDLER, PRI) \
102     [(CMDID)] = {                         \
103         .handler = (HANDLER),             \
104         .pri = (PRI)                      \
105     }
106 
107 #define ServiceDefine(ServiceName, SERVICE_ID, ServiceMap)                    \
108     Service *CreateService##ServiceName(const ServiceCfg *cfg)                \
109     {                                                                         \
110         static struct ServiceDef serviceDef = {                               \
111             .serviceId = (SERVICE_ID),                                          \
112             .messagesLength = sizeof(ServiceMap) / sizeof(struct MessageDef), \
113             .messages = (ServiceMap)                                            \
114         };                                                                    \
115         return InitService(&serviceDef, cfg);                                 \
116     }
117 
118 #define CreateService(ServiceName, cfg) CreateService##ServiceName(cfg)
119 
120 
121 #ifdef __cplusplus
122 }
123 #endif
124 
125 #endif
126