Feat:add user notify

Signed-off-by: s00442234 <susha@huawei.com>
This commit is contained in:
s00442234
2022-06-01 16:11:06 +08:00
parent 130c1dc758
commit 089ad2babf
6 changed files with 387 additions and 20 deletions
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef PLATFORM_LISTENER_COMMON_H
#define PLATFORM_LISTENER_COMMON_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
enum PlatformListenerEventID {
PLATFORM_LISTENER_EVENT_GPIO_INT_NOTIFY,
};
#define LISTENER_MATCH_INFO_LEN 256
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PLATFORM_LISTENER_COMMON_H */
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef PLATFORM_LISTENER_U_H
#define PLATFORM_LISTENER_U_H
#include "gpio_if.h"
#include "hdf_base.h"
#include "hdf_dlist.h"
#include "hdf_service_status.h"
#include "osal_mutex.h"
#include "platform_core.h"
#include "platform_listener_common.h"
#include "rtc_if.h"
#include "svcmgr_ioservice.h"
#include "timer_if.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct PlatformUserListener {
enum PlatformModuleType moudle;
uint32_t num;
struct HdfDevEventlistener *listener;
void *data;
struct DListHead node;
};
struct PlatformUserListenerManager {
struct HdfIoService *service;
enum PlatformModuleType moudle;
struct DListHead listeners;
struct OsalMutex lock;
};
struct PlatformUserListenerGpioParam {
uint16_t gpio;
void *data;
GpioIrqFunc func;
};
struct PlatformUserListenerRtcParam {
enum RtcAlarmIndex index;
RtcAlarmCallback func;
};
struct PlatformUserListenerTimerParam {
uint32_t handle;
bool isOnce;
TimerHandleCb func;
struct PlatformUserListenerManager *manager;
};
struct PlatformUserListenerManager *PlatformUserListenerManagerGet(enum PlatformModuleType moudle);
int32_t PlatformUserListenerReg(struct PlatformUserListenerManager *manager, uint32_t num, void *data);
void PlatformUserListenerDestory(struct PlatformUserListenerManager *manager, uint32_t num);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PLATFORM_LISTENER_U_H */
@@ -0,0 +1,189 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "platform_listener_u.h"
#include "hdf_io_service_if.h"
#include "hdf_log.h"
#include "ioservstat_listener.h"
#include "osal_mem.h"
#include "securec.h"
struct ModuleOnDevEventReceived {
enum PlatformModuleType moudle;
OnEventReceived callback;
};
static int GpioOnDevEventReceive(void *priv, uint32_t id, struct HdfSBuf *data)
{
struct PlatformUserListenerGpioParam *gpio = NULL;
struct PlatformUserListener *userListener = NULL;
uint16_t gpioId;
if (priv == NULL || data == NULL) {
HDF_LOGE("GpioOnDevEventReceive param error");
return HDF_FAILURE;
}
userListener = (struct PlatformUserListener *)priv;
gpio = (struct PlatformUserListenerGpioParam *)userListener->data;
if (gpio == NULL || gpio->data == NULL || gpio->func == NULL) {
HDF_LOGE("GpioOnDevEventReceive gpio error");
return HDF_FAILURE;
}
if (!HdfSbufReadUint16(data, &gpioId)) {
HDF_LOGE("GpioOnDevEventReceive read sbuf fail");
return HDF_ERR_IO;
}
HDF_LOGD("GpioOnDevEventReceive event %d gpioId:%d == gpio:%d", id, gpioId, gpio->gpio);
if ((id == PLATFORM_LISTENER_EVENT_GPIO_INT_NOTIFY) && (gpioId == gpio->gpio)) {
gpio->func(gpioId, gpio->data);
}
return HDF_SUCCESS;
}
static struct ModuleOnDevEventReceived g_Receives[] = {
{PLATFORM_MODULE_GPIO, GpioOnDevEventReceive},
};
static OnEventReceived PlatformUserListenerCbGet(enum PlatformModuleType moudle)
{
unsigned int i;
for (i = 0; i < sizeof(g_Receives) / sizeof(g_Receives[0]); i++) {
if (moudle == g_Receives[i].moudle) {
return g_Receives[i].callback;
}
}
HDF_LOGD("PlatformUserListenerCbGet module callback[%d]not find", moudle);
return NULL;
}
static struct PlatformUserListener *PlatformUserListenerInit(
struct PlatformUserListenerManager *manager, uint32_t num, void *data)
{
struct PlatformUserListener *userListener = NULL;
struct HdfDevEventlistener *listener = NULL;
userListener = OsalMemCalloc(sizeof(struct PlatformUserListener));
if (userListener == NULL) {
HDF_LOGE("PlatformUserListenerInit userListener get failed");
return NULL;
}
listener = OsalMemCalloc(sizeof(struct HdfDevEventlistener));
if (listener == NULL) {
HDF_LOGE("PlatformUserListenerInit hdf listener get failed");
OsalMemFree(userListener);
return NULL;
}
userListener->listener = listener;
userListener->moudle = manager->moudle;
userListener->num = num;
userListener->data = data;
listener->callBack = PlatformUserListenerCbGet(manager->moudle);
if (listener->callBack == NULL) {
HDF_LOGE("PlatformUserListenerInit hdf listener cb get failed");
OsalMemFree(userListener);
OsalMemFree(listener);
return NULL;
}
listener->priv = userListener;
if (HdfDeviceRegisterEventListener(manager->service, listener) != HDF_SUCCESS) {
HDF_LOGE("PlatformUserListenerInit HdfDeviceRegisterEventListener failed");
OsalMemFree(userListener);
OsalMemFree(listener);
return NULL;
}
HDF_LOGD("PlatformUserListenerInit get listener for %d %d success", manager->moudle, num);
return userListener;
}
int32_t PlatformUserListenerReg(struct PlatformUserListenerManager *manager, uint32_t num, void *data)
{
struct PlatformUserListener *pos = NULL;
struct PlatformUserListener *node = NULL;
if (manager == NULL) {
HDF_LOGE("PlatformUserListenerReg manager null");
return HDF_FAILURE;
}
if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
HDF_LOGE("PlatformUserListenerReg: OsalMutexLock failed");
return HDF_FAILURE;
};
DLIST_FOR_EACH_ENTRY(pos, &manager->listeners, struct PlatformUserListener, node) {
if (pos->num == num) {
(void)OsalMutexUnlock(&manager->lock);
return HDF_SUCCESS;
}
}
node = PlatformUserListenerInit(manager, num, data);
if (node == NULL) {
HDF_LOGE("PlatformUserListenerReg PlatformUserListenerInit fail");
(void)OsalMutexUnlock(&manager->lock);
return HDF_FAILURE;
}
DListInsertTail(&node->node, &manager->listeners);
(void)OsalMutexUnlock(&manager->lock);
return HDF_SUCCESS;
}
void PlatformUserListenerDestory(struct PlatformUserListenerManager *manager, uint32_t num)
{
struct PlatformUserListener *pos = NULL;
struct PlatformUserListener *tmp = NULL;
if (manager == NULL) {
HDF_LOGE("PlatformUserListenerDestory manager null");
return;
}
if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
HDF_LOGE("%s: OsalMutexLock failed", __func__);
return;
}
DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->listeners, struct PlatformUserListener, node) {
if (pos->num == num) {
HDF_LOGD("PlatformUserListenerDestory: node [%d][%d] find, then del", manager->moudle, num);
if (HdfDeviceUnregisterEventListener(manager->service, pos->listener) != HDF_SUCCESS) {
HDF_LOGE("PlatformUserListenerDestory unregister fail");
(void)OsalMutexUnlock(&manager->lock);
return;
}
OsalMemFree(pos->listener);
OsalMemFree(pos->data);
DListRemove(&pos->node);
OsalMemFree(pos);
(void)OsalMutexUnlock(&manager->lock);
return;
}
}
(void)OsalMutexUnlock(&manager->lock);
}
struct PlatformUserListenerManager *PlatformUserListenerManagerGet(enum PlatformModuleType moudle)
{
struct PlatformUserListenerManager *manager = OsalMemCalloc(sizeof(struct PlatformUserListenerManager));
if (manager == NULL) {
HDF_LOGE("PlatformUserListenerManagerGet manager get failed");
return NULL;
}
manager->moudle = moudle;
DListHeadInit(&manager->listeners);
if (OsalMutexInit(&manager->lock) != HDF_SUCCESS) {
HDF_LOGE("PlatformUserListenerManagerGet moudle %d OsalSpinInit fail", moudle);
OsalMemFree(manager);
return NULL;
}
HDF_LOGD("PlatformUserListenerManagerGet moudle %d success", moudle);
return manager;
}
+50 -4
View File
@@ -10,7 +10,9 @@
#include "gpio/gpio_service.h"
#include "hdf_base.h"
#include "hdf_io_service_if.h"
#include "osal_mem.h"
#include "platform_core.h"
#include "platform_listener_u.h"
#define PLAT_LOG_TAG gpio_if_u
@@ -25,6 +27,15 @@ static struct HdfIoService *GpioManagerServiceGet(void)
if (service == NULL) {
HDF_LOGE("%s: fail to get gpio manager service!", __func__);
}
if (service->priv == NULL) {
struct PlatformUserListenerManager *manager = PlatformUserListenerManagerGet(PLATFORM_MODULE_GPIO);
if (manager == NULL) {
HDF_LOGE("%s: PlatformUserListenerManagerGet fail!", __func__);
}
service->priv = manager;
manager->service = service;
}
return service;
}
@@ -220,14 +231,39 @@ int32_t GpioSetDir(uint16_t gpio, uint16_t dir)
HdfSbufRecycle(data);
return HDF_SUCCESS;
}
static int32_t GpioRegListener(struct HdfIoService *service, uint16_t gpio, GpioIrqFunc func, void *arg)
{
struct PlatformUserListenerGpioParam *param = NULL;
param = OsalMemCalloc(sizeof(struct PlatformUserListenerGpioParam));
if (param == NULL) {
HDF_LOGE("%s: OsalMemCalloc param fail", __func__);
return HDF_ERR_IO;
}
param->gpio = gpio;
param->func = func;
param->data = arg;
if (PlatformUserListenerReg((struct PlatformUserListenerManager *)service->priv, gpio, (void *)param) !=
HDF_SUCCESS) {
HDF_LOGE("%s: PlatformUserListenerReg fail", __func__);
OsalMemFree(param);
return HDF_ERR_IO;
}
return HDF_SUCCESS;
}
int32_t GpioSetIrq(uint16_t gpio, uint16_t mode, GpioIrqFunc func, void *arg)
{
int32_t ret;
struct HdfIoService *service = NULL;
struct HdfSBuf *data = NULL;
(void) func;
(void) arg;
if (func == NULL) {
HDF_LOGE("%s: func null!", __func__);
return HDF_ERR_INVALID_PARAM;
}
service = GpioManagerServiceGet();
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
@@ -235,27 +271,36 @@ int32_t GpioSetIrq(uint16_t gpio, uint16_t mode, GpioIrqFunc func, void *arg)
return HDF_PLT_ERR_DEV_GET;
}
if (GpioRegListener(service, gpio, func, arg) != HDF_SUCCESS) {
HDF_LOGE("%s: GpioGetListener fail!", __func__);
return HDF_FAILURE;
}
data = HdfSbufObtainDefaultSize();
if (data == NULL) {
HDF_LOGE("%s: fail to obtain data", __func__);
PlatformUserListenerDestory((struct PlatformUserListenerManager *)service->priv, gpio);
return HDF_ERR_MALLOC_FAIL;
}
if (!HdfSbufWriteUint16(data, gpio)) {
HDF_LOGE("%s: write gpio number fail!", __func__);
PlatformUserListenerDestory((struct PlatformUserListenerManager *)service->priv, gpio);
HdfSbufRecycle(data);
return HDF_ERR_IO;
}
if (!HdfSbufWriteUint16(data, mode)) {
HDF_LOGE("%s: write gpio mode fail!", __func__);
PlatformUserListenerDestory((struct PlatformUserListenerManager *)service->priv, gpio);
HdfSbufRecycle(data);
return HDF_ERR_IO;
}
ret = service->dispatcher->Dispatch(&service->object, GPIO_IO_SETIRQ, data, NULL);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: service call fail:%d", __func__, ret);
HDF_LOGE("%s: service call fail:%d %d", __func__, ret, gpio);
PlatformUserListenerDestory((struct PlatformUserListenerManager *)service->priv, gpio);
HdfSbufRecycle(data);
return ret;
}
@@ -270,7 +315,7 @@ int32_t GpioUnsetIrq(uint16_t gpio, void *arg)
struct HdfIoService *service = NULL;
struct HdfSBuf *data = NULL;
(void) arg;
(void)arg;
service = GpioManagerServiceGet();
if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
@@ -298,6 +343,7 @@ int32_t GpioUnsetIrq(uint16_t gpio, void *arg)
}
HdfSbufRecycle(data);
PlatformUserListenerDestory((struct PlatformUserListenerManager *)service->priv, gpio);
return HDF_SUCCESS;
}
+56 -7
View File
@@ -6,11 +6,14 @@
* See the LICENSE file in the root of this repository for complete details.
*/
#include "hdf_device_desc.h"
#include "platform_core.h"
#include "gpio_if.h"
#include "gpio/gpio_core.h"
#include "gpio/gpio_service.h"
#include "gpio/gpio_core.h"
#include "gpio_if.h"
#include "hdf_device_desc.h"
#include "hdf_device_object.h"
#include "platform_core.h"
#include "platform_listener_common.h"
#include "securec.h"
#define HDF_LOG_TAG gpio_service
@@ -135,10 +138,47 @@ static int32_t GpioServiceIoSetDir(struct HdfSBuf *data, struct HdfSBuf *reply)
return ret;
}
static void GpioServiceUpdate(uint16_t gpio)
{
int32_t ret;
uint32_t id;
struct HdfSBuf *data = NULL;
struct PlatformManager *gpioMgr = NULL;
gpioMgr = GpioManagerGet();
if (gpioMgr == NULL || gpioMgr->device.hdfDev == NULL) {
HDF_LOGE("%s: get gpio manager fail", __func__);
return;
}
id = PLATFORM_LISTENER_EVENT_GPIO_INT_NOTIFY;
data = HdfSbufObtainDefaultSize();
if (data == NULL) {
HDF_LOGE("GpioServiceUpdate HdfSbufObtainDefaultSize failed");
return;
}
if (!HdfSbufWriteUint16(data, gpio)) {
HDF_LOGE("GpioServiceUpdate: write gpio fail!");
HdfSbufRecycle(data);
return;
}
ret = HdfDeviceSendEvent(gpioMgr->device.hdfDev, id, data);
HdfSbufRecycle(data);
HDF_LOGE("%s:set service info done, ret = %d, id = %d", __func__, ret, id);
}
static int32_t GpioServiceIrqFunc(uint16_t gpio, void *data)
{
HDF_LOGD("%s:%d", __func__, gpio);
GpioServiceUpdate(gpio);
return HDF_SUCCESS;
}
static int32_t GpioServiceIoSetIrq(struct HdfSBuf *data, struct HdfSBuf *reply)
{
uint16_t gpio;
uint16_t mode;
int32_t ret;
(void)reply;
if (data == NULL) {
@@ -156,6 +196,11 @@ static int32_t GpioServiceIoSetIrq(struct HdfSBuf *data, struct HdfSBuf *reply)
return HDF_ERR_IO;
}
ret = GpioSetIrq(gpio, mode, GpioServiceIrqFunc, NULL);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: set gpio irq fail:%d", __func__, ret);
return ret;
}
return HDF_SUCCESS;
}
@@ -174,6 +219,11 @@ static int32_t GpioServiceIoUnsetIrq(struct HdfSBuf *data, struct HdfSBuf *reply
return HDF_ERR_IO;
}
if (GpioUnsetIrq(gpio, NULL) != HDF_SUCCESS) {
HDF_LOGE("%s: GpioUnsetIrq fail", __func__);
return HDF_ERR_IO;
}
return HDF_SUCCESS;
}
@@ -227,9 +277,8 @@ static int32_t GpioServiceIoDisableIrq(struct HdfSBuf *data, struct HdfSBuf *rep
return ret;
}
static int32_t GpioServiceDispatch(struct HdfDeviceIoClient *client, int cmd,
struct HdfSBuf *data, struct HdfSBuf *reply)
static int32_t GpioServiceDispatch(
struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
{
int32_t ret;
@@ -327,10 +327,6 @@ static int32_t GpioTestIrqLevel(void)
static int32_t GpioTestIrqEdge(void)
{
#if defined(_LINUX_USER_) || defined(__USER__)
(void)GpioTestIrqSharedFunc;
return HDF_SUCCESS;
#else
uint16_t mode;
struct GpioTester *tester = NULL;
@@ -348,14 +344,10 @@ static int32_t GpioTestIrqEdge(void)
#endif
mode = GPIO_IRQ_TRIGGER_FALLING | GPIO_IRQ_TRIGGER_RISING;
return GpioTestIrqSharedFunc(tester, mode, true);
#endif
}
int32_t GpioTestIrqThread(void)
{
#if defined(_LINUX_USER_) || defined(__USER__)
return HDF_SUCCESS;
#else
uint16_t mode;
struct GpioTester *tester = NULL;
@@ -373,7 +365,6 @@ int32_t GpioTestIrqThread(void)
#endif
mode = GPIO_IRQ_TRIGGER_FALLING | GPIO_IRQ_TRIGGER_RISING | GPIO_IRQ_USING_THREAD;
return GpioTestIrqSharedFunc(tester, mode, true);
#endif
}
static int32_t GpioTestReliability(void)