• 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 "devsvc_listener_holder.h"
10 #include "devsvc_manager.h"
11 #include "hdf_base.h"
12 #include "hdf_device_node.h"
13 #include "hdf_io_service.h"
14 #include "hdf_log.h"
15 #include "hdf_object_manager.h"
16 #include "osal_mem.h"
17 #include "svcmgr_ioservice.h"
18 #include "osal_mutex.h"
19 
20 #define HDF_LOG_TAG devsvc_mger
21 #define SVC_MGR_NODE_PERM 0660
22 
23 struct DevSvcManagerExt {
24     struct DevSvcManager super;
25     struct IDeviceIoService ioService;
26     struct HdfIoService *serv;
27     struct OsalMutex mutex;
28     bool started;
29 };
30 
DeviceSvcMgrOpen(struct HdfDeviceIoClient * client)31 int32_t DeviceSvcMgrOpen(struct HdfDeviceIoClient *client)
32 {
33     (void)client;
34     return HDF_SUCCESS;
35 }
36 
DevSvcManagerExtRegisterListener(struct HdfDeviceIoClient * client,struct HdfSBuf * data)37 static int32_t DevSvcManagerExtRegisterListener(struct HdfDeviceIoClient *client, struct HdfSBuf *data)
38 {
39     struct ServStatListenerHolder *holder = NULL;
40     uint16_t devClass = DEVICE_CLASS_MAX;
41     struct DevSvcManagerExt *svcmgrInst = NULL;
42     if (client->device == NULL || client->device->priv == NULL) {
43         return HDF_ERR_INVALID_PARAM;
44     }
45     svcmgrInst = (struct DevSvcManagerExt *)DevSvcManagerGetInstance();
46 
47     if (!HdfSbufReadUint16(data, &devClass)) {
48         return HDF_ERR_INVALID_PARAM;
49     }
50 
51     holder = ServStatListenerHolderGet((uintptr_t)client);
52     if (holder != NULL) {
53         HDF_LOGE("%s:register listener exist, update and return", __func__);
54         holder->listenClass = devClass;
55         return HDF_SUCCESS;
56     }
57 
58     holder = ServStatListenerHolderCreate((uintptr_t)client, devClass);
59     if (holder == NULL) {
60         return HDF_ERR_MALLOC_FAIL;
61     }
62 
63     return svcmgrInst->super.super.RegsterServListener(&svcmgrInst->super.super, holder);
64 }
65 
DevSvcManagerExtUnRegisterListener(struct HdfDeviceIoClient * client)66 static int32_t DevSvcManagerExtUnRegisterListener(struct HdfDeviceIoClient *client)
67 {
68     struct ServStatListenerHolder *holder = NULL;
69     struct DevSvcManagerExt *svcmgrInst = NULL;
70 
71     if (client->device == NULL || client->device->priv == NULL) {
72         return HDF_ERR_INVALID_PARAM;
73     }
74 
75     svcmgrInst = (struct DevSvcManagerExt *)client->device->priv;
76     OsalMutexLock(&svcmgrInst->mutex);
77     holder = ServStatListenerHolderGet((uintptr_t)client);
78     if (holder == NULL) {
79         OsalMutexUnlock(&svcmgrInst->mutex);
80         return HDF_DEV_ERR_NO_DEVICE_SERVICE;
81     }
82     if (holder->node.next != NULL) {
83         svcmgrInst->super.super.UnregsterServListener(&svcmgrInst->super.super, holder);
84     }
85     ServStatListenerHolderRelease(holder);
86     OsalMutexUnlock(&svcmgrInst->mutex);
87 
88     return HDF_SUCCESS;
89 }
90 
DeviceSvcMgrDispatch(struct HdfObject * service,int cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)91 int32_t DeviceSvcMgrDispatch(struct HdfObject *service, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
92 {
93     uint64_t ioClientPtr = 0;
94     struct HdfDeviceIoClient *client = NULL;
95     if (service == NULL || data == NULL || reply == NULL) {
96         return HDF_ERR_INVALID_PARAM;
97     }
98 
99     if (!HdfSbufReadUint64(reply, &ioClientPtr) || ioClientPtr == 0) {
100         HDF_LOGE("device svc dispatch: ioClient is null");
101         return HDF_FAILURE;
102     }
103     HdfSbufFlush(reply);
104     client = (struct HdfDeviceIoClient *)(uintptr_t)ioClientPtr;
105     switch (cmdId) {
106         case SVCMGR_REGISTER_LISTENER:
107             return DevSvcManagerExtRegisterListener(client, data);
108         case SVCMGR_UNREGISTER_LISTENER:
109             return DevSvcManagerExtUnRegisterListener(client);
110         default:
111             break;
112     }
113 
114     return HDF_ERR_NOT_SUPPORT;
115 }
116 
DeviceSvcMgrRelease(struct HdfDeviceIoClient * client)117 void DeviceSvcMgrRelease(struct HdfDeviceIoClient *client)
118 {
119     if (client == NULL) {
120         return;
121     }
122     DevSvcManagerExtUnRegisterListener(client);
123 }
124 
DevSvcManagerExtStart(struct IDevSvcManager * svcmgr)125 int DevSvcManagerExtStart(struct IDevSvcManager *svcmgr)
126 {
127     struct DevSvcManagerExt *inst = (struct DevSvcManagerExt *)svcmgr;
128     static struct HdfDeviceObject svcmgrDevObj = { 0 };
129     static struct IDeviceIoService svcmgrIoService = {
130         .Open = DeviceSvcMgrOpen,
131         .Dispatch = NULL,
132         .Release = DeviceSvcMgrRelease,
133     };
134     if (inst == NULL) {
135         return HDF_ERR_INVALID_PARAM;
136     }
137 
138     if (inst->started) {
139         return HDF_SUCCESS;
140     }
141 
142     svcmgrDevObj.service = &svcmgrIoService;
143     svcmgrDevObj.property = NULL;
144     svcmgrDevObj.deviceClass = DEVICE_CLASS_DEFAULT;
145     svcmgrDevObj.priv = (void *)svcmgr;
146 
147     inst->serv = HdfIoServicePublish(DEV_SVCMGR_NODE, SVC_MGR_NODE_PERM);
148     if (inst->serv == NULL) {
149         HDF_LOGE("failed to pushlish svcmgr ioservice");
150     } else {
151         static struct HdfIoDispatcher dispatcher = {
152             .Dispatch = DeviceSvcMgrDispatch,
153         };
154         inst->serv->dispatcher = &dispatcher;
155         inst->serv->target = (struct HdfObject *)&svcmgrDevObj;
156     }
157 
158     ServStatListenerHolderinit();
159     inst->started = true;
160     return HDF_SUCCESS;
161 }
162 
DevSvcManagerExtConstruct(struct DevSvcManagerExt * inst)163 static bool DevSvcManagerExtConstruct(struct DevSvcManagerExt *inst)
164 {
165     if (inst == NULL) {
166         return false;
167     }
168     if (!DevSvcManagerConstruct(&inst->super)) {
169         HDF_LOGE("failed to construct device service manager");
170         return false;
171     }
172     if (OsalMutexInit(&inst->mutex) != HDF_SUCCESS) {
173         HDF_LOGE("failed to create devsvcmgrext mutex");
174         return false;
175     }
176     inst->super.super.StartService = DevSvcManagerExtStart;
177 
178     return true;
179 }
180 
DevSvcManagerExtCreate(void)181 struct HdfObject *DevSvcManagerExtCreate(void)
182 {
183     static struct DevSvcManagerExt *instance;
184     if (instance != NULL) {
185         return (struct HdfObject *)instance;
186     }
187 
188     instance = OsalMemCalloc(sizeof(struct DevSvcManagerExt));
189     if (!DevSvcManagerExtConstruct(instance)) {
190         OsalMemFree(instance);
191         instance = NULL;
192     }
193 
194     return (struct HdfObject *)instance;
195 }
196 
DevSvcManagerExtRelease(struct IDevSvcManager * inst)197 void DevSvcManagerExtRelease(struct IDevSvcManager *inst)
198 {
199     struct DevSvcManagerExt *instance = (struct DevSvcManagerExt *)inst;
200     if (instance == NULL) {
201         return;
202     }
203     if (instance->serv != NULL) {
204         HdfIoServiceRemove(instance->serv);
205         instance->serv = NULL;
206     }
207     DevSvcManagerRelease(inst);
208     instance->started = false;
209 }
210