1 /*
2 * Copyright (c) 2020-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_manager.h"
10 #include "devmgr_service.h"
11 #include "hdf_base.h"
12 #include "hdf_cstring.h"
13 #include "hdf_log.h"
14 #include "hdf_object_manager.h"
15 #include "hdf_service_record.h"
16
17 #define HDF_LOG_TAG devsvc_manager
18
DevSvcManagerSearchService(struct IDevSvcManager * inst,uint32_t serviceKey)19 static struct DevSvcRecord *DevSvcManagerSearchService(struct IDevSvcManager *inst, uint32_t serviceKey)
20 {
21 struct HdfSListIterator it;
22 struct DevSvcRecord *record = NULL;
23 struct DevSvcRecord *searchResult = NULL;
24 struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst;
25 if (devSvcManager == NULL) {
26 HDF_LOGE("failed to search service, devSvcManager is null");
27 return NULL;
28 }
29
30 OsalMutexLock(&devSvcManager->mutex);
31 HdfSListIteratorInit(&it, &devSvcManager->services);
32 while (HdfSListIteratorHasNext(&it)) {
33 record = (struct DevSvcRecord *)HdfSListIteratorNext(&it);
34 if ((record != NULL) && (record->key == serviceKey)) {
35 searchResult = record;
36 break;
37 }
38 }
39 OsalMutexUnlock(&devSvcManager->mutex);
40 return searchResult;
41 }
42
DevSvcManagerAddService(struct IDevSvcManager * inst,const char * svcName,struct HdfDeviceObject * service)43 int DevSvcManagerAddService(struct IDevSvcManager *inst, const char *svcName, struct HdfDeviceObject *service)
44 {
45 struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst;
46 if ((devSvcManager == NULL) || (service == NULL) || (svcName == NULL)) {
47 HDF_LOGE("failed to add service, input param is null");
48 return HDF_FAILURE;
49 }
50
51 struct DevSvcRecord *record = DevSvcRecordNewInstance();
52 if (record == NULL) {
53 HDF_LOGE("failed to add service , record is null");
54 return HDF_FAILURE;
55 }
56
57 record->key = HdfStringMakeHashKey(svcName, 0);
58 record->value = service;
59 OsalMutexLock(&devSvcManager->mutex);
60 HdfSListAdd(&devSvcManager->services, &record->entry);
61 OsalMutexUnlock(&devSvcManager->mutex);
62 return HDF_SUCCESS;
63 }
64
DevSvcManagerSubscribeService(struct IDevSvcManager * inst,const char * svcName,struct SubscriberCallback callBack)65 int DevSvcManagerSubscribeService(struct IDevSvcManager *inst, const char *svcName, struct SubscriberCallback callBack)
66 {
67 int ret = HDF_FAILURE;
68 struct DevSvcManager *devSvcMgr = (struct DevSvcManager *)inst;
69 if (svcName == NULL || devSvcMgr == NULL) {
70 return ret;
71 }
72
73 struct HdfObject *deviceService = DevSvcManagerGetService(inst, svcName);
74 if (deviceService != NULL) {
75 if (callBack.OnServiceConnected != NULL) {
76 callBack.OnServiceConnected(callBack.deviceObject, deviceService);
77 }
78 return HDF_SUCCESS;
79 }
80
81 return DevmgrServiceLoadDevice(svcName);
82 }
83
DevSvcManagerRemoveService(struct IDevSvcManager * inst,const char * svcName)84 void DevSvcManagerRemoveService(struct IDevSvcManager *inst, const char *svcName)
85 {
86 struct DevSvcManager *devSvcManager = (struct DevSvcManager *)inst;
87 uint32_t serviceKey = HdfStringMakeHashKey(svcName, 0);
88 if (svcName == NULL || devSvcManager == NULL) {
89 return;
90 }
91 struct DevSvcRecord *serviceRecord = DevSvcManagerSearchService(inst, serviceKey);
92 if (serviceRecord != NULL) {
93 OsalMutexLock(&devSvcManager->mutex);
94 HdfSListRemove(&devSvcManager->services, &serviceRecord->entry);
95 OsalMutexUnlock(&devSvcManager->mutex);
96 }
97 DevSvcRecordFreeInstance(serviceRecord);
98 }
99
DevSvcManagerGetObject(struct IDevSvcManager * inst,const char * svcName)100 struct HdfDeviceObject *DevSvcManagerGetObject(struct IDevSvcManager *inst, const char *svcName)
101 {
102 uint32_t serviceKey = HdfStringMakeHashKey(svcName, 0);
103 if (svcName == NULL) {
104 HDF_LOGE("Get service failed, svcName is null");
105 return NULL;
106 }
107 struct DevSvcRecord *serviceRecord = DevSvcManagerSearchService(inst, serviceKey);
108 if (serviceRecord != NULL) {
109 return serviceRecord->value;
110 }
111 return NULL;
112 }
113
DevSvcManagerGetService(struct IDevSvcManager * inst,const char * svcName)114 struct HdfObject *DevSvcManagerGetService(struct IDevSvcManager *inst, const char *svcName)
115 {
116 struct HdfDeviceObject *deviceObject = DevSvcManagerGetObject(inst, svcName);
117 if (deviceObject == NULL) {
118 return NULL;
119 }
120 return (struct HdfObject *)deviceObject->service;
121 }
122
DevSvcManagerConstruct(struct DevSvcManager * inst)123 bool DevSvcManagerConstruct(struct DevSvcManager *inst)
124 {
125 if (inst == NULL) {
126 HDF_LOGE("%s: inst is null!", __func__);
127 return false;
128 }
129 struct IDevSvcManager *devSvcMgrIf = &inst->super;
130 devSvcMgrIf->AddService = DevSvcManagerAddService;
131 devSvcMgrIf->SubscribeService = DevSvcManagerSubscribeService;
132 devSvcMgrIf->UnsubscribeService = NULL;
133 devSvcMgrIf->RemoveService = DevSvcManagerRemoveService;
134 devSvcMgrIf->GetService = DevSvcManagerGetService;
135 devSvcMgrIf->GetObject = DevSvcManagerGetObject;
136 HdfSListInit(&inst->services);
137 if (OsalMutexInit(&inst->mutex) != HDF_SUCCESS) {
138 HDF_LOGE("failed to create device service manager mutex");
139 return false;
140 }
141 return true;
142 }
143
DevSvcManagerCreate()144 struct HdfObject *DevSvcManagerCreate()
145 {
146 static bool isDevSvcManagerInit = false;
147 static struct DevSvcManager devSvcManagerInstance;
148 if (!isDevSvcManagerInit) {
149 if (!DevSvcManagerConstruct(&devSvcManagerInstance)) {
150 return NULL;
151 }
152 isDevSvcManagerInit = true;
153 }
154 return (struct HdfObject *)&devSvcManagerInstance;
155 }
156
DevSvcManagerRelease(struct HdfObject * object)157 void DevSvcManagerRelease(struct HdfObject *object)
158 {
159 struct DevSvcManager *devSvcManager = (struct DevSvcManager *)object;
160 if (object == NULL) {
161 return;
162 }
163 HdfSListFlush(&devSvcManager->services, DevSvcRecordDelete);
164 OsalMutexDestroy(&devSvcManager->mutex);
165 }
166
DevSvcManagerGetInstance()167 struct IDevSvcManager *DevSvcManagerGetInstance()
168 {
169 static struct IDevSvcManager *instance = NULL;
170 if (instance == NULL) {
171 instance = (struct IDevSvcManager *)HdfObjectManagerGetObject(HDF_OBJECT_ID_DEVSVC_MANAGER);
172 }
173 return instance;
174 }
175