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