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