1 /*
2 * Copyright (c) 2022-2023 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 #include "platform_listener_u.h"
10 #include "hdf_core_log.h"
11 #include "osal_mem.h"
12 #include "platform_listener_common.h"
13 #include "securec.h"
14
15 #define IRQ_CB_NUM 0
16 #define DMA_CB_NUM 1
17
RtcOnDevEventReceive(void * priv,uint32_t id,struct HdfSBuf * data)18 int RtcOnDevEventReceive(void *priv, uint32_t id, struct HdfSBuf *data)
19 {
20 struct PlatformUserListenerRtcParam *rtc = NULL;
21 struct PlatformUserListener *userListener = NULL;
22 uint8_t index;
23
24 if (priv == NULL || data == NULL) {
25 HDF_LOGE("RtcOnDevEventReceive: id %d param error!", id);
26 return HDF_FAILURE;
27 }
28
29 userListener = (struct PlatformUserListener *)priv;
30 rtc = (struct PlatformUserListenerRtcParam *)userListener->data;
31 if (rtc == NULL || rtc->func == NULL) {
32 HDF_LOGE("RtcOnDevEventReceive: rtc id %d error!", id);
33 return HDF_FAILURE;
34 }
35
36 if (!HdfSbufReadUint8(data, &index)) {
37 HDF_LOGE("RtcOnDevEventReceive: id %d read sbuf fail!", id);
38 return HDF_ERR_IO;
39 }
40
41 HDF_LOGD("RtcOnDevEventReceive: event %d index:%d == index:%d!", id, index, rtc->index);
42 if ((id == PLATFORM_LISTENER_EVENT_RTC_ALARM_NOTIFY) && (index == rtc->index)) {
43 rtc->func(index);
44 }
45 return HDF_SUCCESS;
46 }
47
PcieOnDevEventReceive(void * priv,uint32_t id,struct HdfSBuf * data)48 int PcieOnDevEventReceive(void *priv, uint32_t id, struct HdfSBuf *data)
49 {
50 struct PlatformUserListenerPcieParam *pcie = NULL;
51 struct PlatformUserListener *userListener = NULL;
52 uint8_t *buf = NULL;
53 uint32_t num;
54 uint32_t len;
55
56 if (priv == NULL || data == NULL || id != PLATFORM_LISTENER_EVENT_PCIE_NOTIFY) {
57 HDF_LOGE("PcieOnDevEventReceive: id %d param error!", id);
58 return HDF_FAILURE;
59 }
60
61 userListener = (struct PlatformUserListener *)priv;
62 pcie = (struct PlatformUserListenerPcieParam *)userListener->data;
63 if (pcie == NULL || pcie->func == NULL) {
64 HDF_LOGE("PcieOnDevEventReceive: pcie id %d error!", id);
65 return HDF_FAILURE;
66 }
67
68 if (!HdfSbufReadUint32(data, &num)) {
69 HDF_LOGE("PcieOnDevEventReceive: read num fail!");
70 return HDF_ERR_IO;
71 }
72 if (num == DMA_CB_NUM) {
73 if (pcie->dmaData == 0 || pcie->len == 0) {
74 HDF_LOGE("PcieOnDevEventReceive: invalid DMA data!");
75 return HDF_ERR_INVALID_PARAM;
76 }
77 if (pcie->dir == PCIE_DMA_FROM_DEVICE) {
78 if (!HdfSbufReadBuffer(data, (const void **)&buf, &len)) {
79 HDF_LOGE("PcieOnDevEventReceive: sbuf read buffer fail!");
80 return HDF_ERR_IO;
81 }
82 if (memcpy_s((void *)pcie->dmaData, pcie->len, buf, len) != EOK) {
83 HDF_LOGE("PcieOnDevEventReceive: memory copy fail!");
84 return HDF_ERR_IO;
85 }
86 }
87 }
88 return pcie->func(pcie->handle);
89 }
90
TimerOnDevEventReceive(void * priv,uint32_t id,struct HdfSBuf * data)91 int TimerOnDevEventReceive(void *priv, uint32_t id, struct HdfSBuf *data)
92 {
93 struct PlatformUserListenerTimerParam *timer = NULL;
94 struct PlatformUserListener *userListener = NULL;
95 uint32_t handle;
96
97 if (priv == NULL || data == NULL) {
98 HDF_LOGE("TimerOnDevEventReceive: id %d param error!", id);
99 return HDF_FAILURE;
100 }
101
102 userListener = (struct PlatformUserListener *)priv;
103 timer = (struct PlatformUserListenerTimerParam *)userListener->data;
104 if (timer == NULL || timer->func == NULL) {
105 HDF_LOGE("TimerOnDevEventReceive: timer id %d error!", id);
106 return HDF_FAILURE;
107 }
108
109 if (!HdfSbufReadUint32(data, &handle)) {
110 HDF_LOGE("TimerOnDevEventReceive: id %d read sbuf fail", id);
111 return HDF_ERR_IO;
112 }
113
114 HDF_LOGD("TimerOnDevEventReceive: event %d handle:%d == handle:%d!", id, handle, timer->handle);
115 if ((id == PLATFORM_LISTENER_EVENT_TIMER_NOTIFY) && (handle == timer->handle)) {
116 timer->func(handle);
117 }
118 return HDF_SUCCESS;
119 }
120
GpioOnDevEventReceive(void * priv,uint32_t id,struct HdfSBuf * data)121 int GpioOnDevEventReceive(void *priv, uint32_t id, struct HdfSBuf *data)
122 {
123 struct PlatformUserListenerGpioParam *gpio = NULL;
124 struct PlatformUserListener *userListener = NULL;
125 uint16_t gpioId;
126
127 if (priv == NULL || data == NULL) {
128 HDF_LOGE("GpioOnDevEventReceive: id %d param error!", id);
129 return HDF_FAILURE;
130 }
131
132 userListener = (struct PlatformUserListener *)priv;
133 gpio = (struct PlatformUserListenerGpioParam *)userListener->data;
134 if (gpio == NULL || gpio->data == NULL || gpio->func == NULL) {
135 HDF_LOGE("GpioOnDevEventReceive: id %d gpio error!", id);
136 return HDF_FAILURE;
137 }
138
139 if (!HdfSbufReadUint16(data, &gpioId)) {
140 HDF_LOGE("GpioOnDevEventReceive: id %d read sbuf fail!", id);
141 return HDF_ERR_IO;
142 }
143
144 HDF_LOGD("GpioOnDevEventReceive: event %d gpioId:%d == gpio:%d!", id, gpioId, gpio->gpio);
145 if ((id == PLATFORM_LISTENER_EVENT_GPIO_INT_NOTIFY) && (gpioId == gpio->gpio)) {
146 gpio->func(gpioId, gpio->data);
147 }
148 return HDF_SUCCESS;
149 }
150
PlatformUserListenerInit(const struct PlatformUserListenerManager * manager,uint32_t num,void * data,OnEventReceived callback)151 static struct PlatformUserListener *PlatformUserListenerInit(
152 const struct PlatformUserListenerManager *manager, uint32_t num, void *data, OnEventReceived callback)
153 {
154 struct PlatformUserListener *userListener = NULL;
155 struct HdfDevEventlistener *listener = NULL;
156
157 userListener = OsalMemCalloc(sizeof(struct PlatformUserListener));
158 if (userListener == NULL) {
159 HDF_LOGE("PlatformUserListenerInit: userListener get fail!");
160 return NULL;
161 }
162
163 listener = OsalMemCalloc(sizeof(struct HdfDevEventlistener));
164 if (listener == NULL) {
165 HDF_LOGE("PlatformUserListenerInit: memcalloc hdf listener fail!");
166 OsalMemFree(userListener);
167 return NULL;
168 }
169
170 userListener->listener = listener;
171 userListener->moudle = manager->moudle;
172 userListener->num = num;
173 userListener->data = data;
174
175 listener->callBack = callback;
176 listener->priv = userListener;
177 if (HdfDeviceRegisterEventListener(manager->service, listener) != HDF_SUCCESS) {
178 HDF_LOGE("PlatformUserListenerInit: HdfDeviceRegisterEventListener fail!");
179 OsalMemFree(userListener);
180 OsalMemFree(listener);
181 return NULL;
182 }
183
184 HDF_LOGD("PlatformUserListenerInit: get listener for %d %d success!", manager->moudle, num);
185 return userListener;
186 }
187
PlatformUserListenerReg(struct PlatformUserListenerManager * manager,uint32_t num,void * data,OnEventReceived callback)188 int32_t PlatformUserListenerReg(
189 struct PlatformUserListenerManager *manager, uint32_t num, void *data, OnEventReceived callback)
190 {
191 struct PlatformUserListener *pos = NULL;
192 struct PlatformUserListener *node = NULL;
193
194 if (manager == NULL || callback == NULL) {
195 HDF_LOGE("PlatformUserListenerReg: manager or callback is null!");
196 return HDF_FAILURE;
197 }
198
199 if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
200 HDF_LOGE("PlatformUserListenerReg: OsalMutexLock fail!");
201 return HDF_FAILURE;
202 };
203 DLIST_FOR_EACH_ENTRY(pos, &manager->listeners, struct PlatformUserListener, node) {
204 if (pos->num == num) {
205 (void)OsalMutexUnlock(&manager->lock);
206 return HDF_SUCCESS;
207 }
208 }
209
210 node = PlatformUserListenerInit(manager, num, data, callback);
211 if (node == NULL) {
212 HDF_LOGE("PlatformUserListenerReg: PlatformUserListenerInit fail!");
213 (void)OsalMutexUnlock(&manager->lock);
214 return HDF_FAILURE;
215 }
216
217 DListInsertTail(&node->node, &manager->listeners);
218 (void)OsalMutexUnlock(&manager->lock);
219 return HDF_SUCCESS;
220 }
221
PlatformUserListenerDestory(struct PlatformUserListenerManager * manager,uint32_t num)222 void PlatformUserListenerDestory(struct PlatformUserListenerManager *manager, uint32_t num)
223 {
224 struct PlatformUserListener *pos = NULL;
225 struct PlatformUserListener *tmp = NULL;
226
227 if (manager == NULL) {
228 HDF_LOGE("PlatformUserListenerDestory: manager is null!");
229 return;
230 }
231 if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
232 HDF_LOGE("PlatformUserListenerDestory: OsalMutexLock fail!");
233 return;
234 }
235 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->listeners, struct PlatformUserListener, node) {
236 if (pos->num == num) {
237 HDF_LOGD("PlatformUserListenerDestory: node [%d][%d] find, then del!", manager->moudle, num);
238 if (HdfDeviceUnregisterEventListener(manager->service, pos->listener) != HDF_SUCCESS) {
239 HDF_LOGE("PlatformUserListenerDestory: unregister fail!");
240 (void)OsalMutexUnlock(&manager->lock);
241 return;
242 }
243 OsalMemFree(pos->listener);
244 OsalMemFree(pos->data);
245 DListRemove(&pos->node);
246 OsalMemFree(pos);
247 (void)OsalMutexUnlock(&manager->lock);
248 return;
249 }
250 }
251 (void)OsalMutexUnlock(&manager->lock);
252 }
253
PlatformUserListenerManagerGet(enum PlatformModuleType moudle)254 struct PlatformUserListenerManager *PlatformUserListenerManagerGet(enum PlatformModuleType moudle)
255 {
256 struct PlatformUserListenerManager *manager = OsalMemCalloc(sizeof(struct PlatformUserListenerManager));
257
258 if (manager == NULL) {
259 HDF_LOGE("PlatformUserListenerManagerGet: manager get fail!");
260 return NULL;
261 }
262
263 manager->moudle = moudle;
264 DListHeadInit(&manager->listeners);
265 if (OsalMutexInit(&manager->lock) != HDF_SUCCESS) {
266 HDF_LOGE("PlatformUserListenerManagerGet: moudle %d OsalSpinInit fail!", moudle);
267 OsalMemFree(manager);
268 return NULL;
269 }
270
271 HDF_LOGD("PlatformUserListenerManagerGet: moudle %d success!", moudle);
272 return manager;
273 }
274
PlatformUserListenerManagerDestory(struct PlatformUserListenerManager * manager)275 void PlatformUserListenerManagerDestory(struct PlatformUserListenerManager *manager)
276 {
277 struct PlatformUserListener *pos = NULL;
278 struct PlatformUserListener *tmp = NULL;
279
280 if (manager == NULL) {
281 HDF_LOGE("PlatformUserListenerDestory manager is null!");
282 return;
283 }
284 if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
285 HDF_LOGE("PlatformUserListenerManagerDestory: OsalMutexLock fail!");
286 return;
287 }
288 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->listeners, struct PlatformUserListener, node) {
289 (void)HdfDeviceUnregisterEventListener(manager->service, pos->listener);
290 OsalMemFree(pos->listener);
291 OsalMemFree(pos->data);
292 DListRemove(&pos->node);
293 OsalMemFree(pos);
294 }
295 (void)OsalMutexUnlock(&manager->lock);
296 (void)OsalMutexDestroy(&manager->lock);
297 OsalMemFree(manager);
298 }
299