• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #include "svcmgr_ioservice.h"
10 #include "hdf_base.h"
11 #include "hdf_dlist.h"
12 #include "hdf_io_service_if.h"
13 #include "hdf_log.h"
14 #include "hdf_sbuf.h"
15 #include "ioservstat_listener.h"
16 #include "osal_mem.h"
17 
18 struct SvcMgrIoservice {
19     struct ISvcMgrIoservice svcmgr;
20     struct HdfIoService *iosvc;
21     struct DListHead listeners;
22 };
23 
ProcessListenClass(struct SvcMgrIoservice * svcmgrInst,uint16_t devClass,int cmdId)24 static int32_t ProcessListenClass(struct SvcMgrIoservice *svcmgrInst, uint16_t devClass, int cmdId)
25 {
26     struct HdfSBuf *data = HdfSbufObtainDefaultSize();
27     if (data == NULL) {
28         return HDF_ERR_MALLOC_FAIL;
29     }
30 
31     (void)HdfSbufWriteUint16(data, devClass);
32     if (svcmgrInst->iosvc == NULL || svcmgrInst->iosvc->dispatcher == NULL ||
33         svcmgrInst->iosvc->dispatcher->Dispatch == NULL) {
34         HdfSbufRecycle(data);
35         return HDF_ERR_INVALID_OBJECT;
36     }
37     int32_t ret = svcmgrInst->iosvc->dispatcher->Dispatch(
38         (struct HdfObject *)svcmgrInst->iosvc, cmdId, data, NULL);
39     HdfSbufRecycle(data);
40     return ret;
41 }
42 
SetListenClass(struct SvcMgrIoservice * svcmgrInst,uint16_t devClass)43 static int32_t SetListenClass(struct SvcMgrIoservice *svcmgrInst, uint16_t devClass)
44 {
45     return ProcessListenClass(svcmgrInst, devClass, SVCMGR_REGISTER_LISTENER);
46 }
47 
UnSetListenClass(struct SvcMgrIoservice * svcmgrInst,uint16_t devClass)48 static int32_t UnSetListenClass(struct SvcMgrIoservice *svcmgrInst, uint16_t devClass)
49 {
50     return ProcessListenClass(svcmgrInst, devClass, SVCMGR_UNREGISTER_LISTENER);
51 }
52 
SvcMgrIoserviceRegSvcStatListener(struct ISvcMgrIoservice * self,struct ServiceStatusListener * listener,uint16_t deviceClass)53 int32_t SvcMgrIoserviceRegSvcStatListener(
54     struct ISvcMgrIoservice *self, struct ServiceStatusListener *listener, uint16_t deviceClass)
55 {
56     if (self == NULL || listener == NULL || deviceClass >= DEVICE_CLASS_MAX) {
57         return HDF_ERR_INVALID_PARAM;
58     }
59 
60     struct SvcMgrIoservice *svcmgrInst = CONTAINER_OF(self, struct SvcMgrIoservice, svcmgr);
61     struct IoServiceStatusListener *listenerInst
62         = CONTAINER_OF(listener, struct IoServiceStatusListener, svcstatListener);
63 
64     listenerInst->deviceClass = deviceClass;
65     int ret = SetListenClass(svcmgrInst, deviceClass);
66     if (ret != HDF_SUCCESS) {
67         HDF_LOGE("failed to set listen class");
68         return ret;
69     }
70 
71     return HdfDeviceRegisterEventListener(svcmgrInst->iosvc, &listenerInst->ioservListener);
72 }
73 
SvcMgrIoserviceUnRegSvcStatListener(struct ISvcMgrIoservice * self,struct ServiceStatusListener * listener)74 int32_t SvcMgrIoserviceUnRegSvcStatListener(struct ISvcMgrIoservice *self, struct ServiceStatusListener *listener)
75 {
76     if (self == NULL || listener == NULL) {
77         return HDF_ERR_INVALID_PARAM;
78     }
79 
80     struct SvcMgrIoservice *svcmgrInst = CONTAINER_OF(self, struct SvcMgrIoservice, svcmgr);
81     struct IoServiceStatusListener *listenerInst
82         = CONTAINER_OF(listener, struct IoServiceStatusListener, svcstatListener);
83 
84     int ret = HdfDeviceUnregisterEventListener(svcmgrInst->iosvc, &listenerInst->ioservListener);
85     if (ret != HDF_SUCCESS) {
86         return ret;
87     }
88 
89     if (HdfIoserviceGetListenerCount(svcmgrInst->iosvc) == 0) {
90         ret = UnSetListenClass(svcmgrInst, listenerInst->deviceClass);
91     }
92 
93     return ret;
94 }
95 
SvcMgrIoserviceConstruct(struct ISvcMgrIoservice * svcmgrInst)96 static void SvcMgrIoserviceConstruct(struct ISvcMgrIoservice *svcmgrInst)
97 {
98     svcmgrInst->RegisterServiceStatusListener = SvcMgrIoserviceRegSvcStatListener;
99     svcmgrInst->UnregisterServiceStatusListener = SvcMgrIoserviceUnRegSvcStatListener;
100 }
101 
SvcMgrIoserviceGet(void)102 struct ISvcMgrIoservice *SvcMgrIoserviceGet(void)
103 {
104     struct SvcMgrIoservice *svcmgrInst = OsalMemCalloc(sizeof(struct SvcMgrIoservice));
105     if (svcmgrInst == NULL) {
106         return NULL;
107     }
108 
109     svcmgrInst->iosvc = HdfIoServiceBind(DEV_SVCMGR_NODE);
110     if (svcmgrInst->iosvc == NULL) {
111         HDF_LOGE("ioserivce %s not exist", DEV_SVCMGR_NODE);
112         OsalMemFree(svcmgrInst);
113         return NULL;
114     }
115     SvcMgrIoserviceConstruct(&svcmgrInst->svcmgr);
116     return &svcmgrInst->svcmgr;
117 }
118 
SvcMgrIoserviceRelease(struct ISvcMgrIoservice * svcmgr)119 void SvcMgrIoserviceRelease(struct ISvcMgrIoservice *svcmgr)
120 {
121     if (svcmgr == NULL) {
122         return;
123     }
124     struct SvcMgrIoservice *svcmgrInst = CONTAINER_OF(svcmgr, struct SvcMgrIoservice, svcmgr);
125     HdfIoServiceRecycle(svcmgrInst->iosvc);
126     OsalMemFree(svcmgrInst);
127 }