• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <securec.h>
17 /*
18  * The "devmgr_service_stub.h" header file should be used. Actually, only the interface ID definition and service name
19  * are required here. This dependency can be removed when interface proxy impl is automatically generated from IDL.
20  */
21 #include <devmgr_service_stub.h>
22 #include <hdf_base.h>
23 #include <hdf_log.h>
24 #include <hdf_remote_service.h>
25 #include <osal_mem.h>
26 #include <servmgr_hdi.h>
27 #include "devmgr_hdi.h"
28 
29 #define HDF_LOG_TAG devmgr_interface
30 
31 static void DevmgrFreeQueryDeviceListImpl(struct DeviceInfoList *list);
32 
DeviceManagerHdiCall(struct HDIDeviceManager * iDevMgr,int32_t id,struct HdfSBuf * data,struct HdfSBuf * reply)33 static int32_t DeviceManagerHdiCall(struct HDIDeviceManager *iDevMgr, int32_t id,
34     struct HdfSBuf *data, struct HdfSBuf *reply)
35 {
36     if (iDevMgr->remote == NULL || iDevMgr->remote->dispatcher == NULL ||
37         iDevMgr->remote->dispatcher->Dispatch == NULL) {
38         return HDF_ERR_INVALID_OBJECT;
39     }
40 
41     return iDevMgr->remote->dispatcher->Dispatch(iDevMgr->remote, id, data, reply);
42 }
43 
HdfObtainDeviceInfo(struct DeviceInfoList * list,struct HdfSBuf * reply)44 static int32_t HdfObtainDeviceInfo(struct DeviceInfoList *list, struct HdfSBuf *reply)
45 {
46     struct DeviceInfoNode *node = NULL;
47     const char *svrName = NULL;
48     int32_t svrNameLen;
49     char *base = NULL;
50     int32_t deviceType;
51 
52     while ((svrName = HdfSbufReadString(reply))) {
53         svrNameLen = strlen(svrName) + 1;
54         base = (char *)OsalMemCalloc(sizeof(*node) + svrNameLen);
55         if (base == NULL) {
56             DevmgrFreeQueryDeviceListImpl(list);
57             return HDF_FAILURE;
58         }
59         node = (struct DeviceInfoNode *)base;
60         node->svcName = base + sizeof(*node);
61         if (strcpy_s(node->svcName, svrNameLen, svrName) != EOK) {
62             HDF_LOGE("strcpy service name %{public}s failed", svrName);
63             OsalMemFree(base);
64             continue;
65         }
66         HDF_LOGD("%{public}s %{public}s", __func__, svrName);
67         HdfSbufReadInt32(reply, &deviceType);
68         if (deviceType != HDF_LOCAL_SERVICE && deviceType != HDF_REMOTE_SERVICE) {
69             HDF_LOGE("device type error %{public}d ", deviceType);
70             OsalMemFree(base);
71             continue;
72         }
73         node->deviceType = deviceType;
74         DListInsertTail(&node->node, &list->list);
75         list->deviceCnt++;
76     }
77 
78     return HDF_SUCCESS;
79 }
80 
DevmgrQueryDeviceInfo(struct HDIDeviceManager * iDevMgr,struct DeviceInfoList * list,int32_t type)81 static int32_t DevmgrQueryDeviceInfo(struct HDIDeviceManager *iDevMgr, struct DeviceInfoList *list, int32_t type)
82 {
83     struct HdfSBuf *reply = NULL;
84     struct HdfSBuf *data = NULL;
85     int32_t ret;
86 
87     reply = HdfSbufTypedObtain(SBUF_IPC);
88     if (reply == NULL) {
89         return HDF_ERR_MALLOC_FAIL;
90     }
91 
92     data = HdfSbufTypedObtain(SBUF_IPC);
93     if (data == NULL) {
94         HdfSbufRecycle(reply);
95         return HDF_ERR_MALLOC_FAIL;
96     }
97     do {
98         if (!HdfRemoteServiceWriteInterfaceToken(iDevMgr->remote, data)) {
99             ret = HDF_FAILURE;
100             break;
101         }
102         list->deviceCnt = 0;
103         DListHeadInit(&list->list);
104 
105         HdfSbufWriteInt32(data, type);
106         ret = DeviceManagerHdiCall(iDevMgr, DEVMGR_SERVICE_QUERY_DEVICE, data, reply);
107         if (ret != HDF_SUCCESS) {
108             HDF_LOGE("DevmgrProxyQueryDevice failed");
109             break;
110         }
111 
112         ret = HdfObtainDeviceInfo(list, reply);
113     } while (0);
114 
115     HdfSbufRecycle(reply);
116     HdfSbufRecycle(data);
117     return ret;
118 }
119 
DevmgrQueryUsableDeviceInfo(struct HDIDeviceManager * self,struct DeviceInfoList * list)120 static int32_t DevmgrQueryUsableDeviceInfo(struct HDIDeviceManager *self, struct DeviceInfoList *list)
121 {
122     if (self == NULL || list == NULL) {
123         return HDF_ERR_INVALID_PARAM;
124     }
125     return DevmgrQueryDeviceInfo(self, list, HDF_SERVICE_USABLE);
126 }
127 
DevmgrQueryUnusableDeviceInfo(struct HDIDeviceManager * self,struct DeviceInfoList * list)128 static int32_t DevmgrQueryUnusableDeviceInfo(struct HDIDeviceManager *self, struct DeviceInfoList *list)
129 {
130     if (self == NULL || list == NULL) {
131         return HDF_ERR_INVALID_PARAM;
132     }
133 
134     return DevmgrQueryDeviceInfo(self, list, HDF_SERVICE_UNUSABLE);
135 }
136 
DevmgrFreeQueryDeviceListImpl(struct DeviceInfoList * list)137 static void DevmgrFreeQueryDeviceListImpl(struct DeviceInfoList *list)
138 {
139     if (list == NULL) {
140         return;
141     }
142 
143     struct DeviceInfoNode *devNode = NULL;
144     struct DeviceInfoNode *tmp = NULL;
145     DLIST_FOR_EACH_ENTRY_SAFE(devNode, tmp, &list->list, struct DeviceInfoNode, node) {
146         DListRemove(&devNode->node);
147         OsalMemFree(devNode);
148     }
149     list->deviceCnt = 0;
150 }
151 
DevmgrFreeQueryDeviceList(struct HDIDeviceManager * self,struct DeviceInfoList * list)152 static void DevmgrFreeQueryDeviceList(struct HDIDeviceManager *self, struct DeviceInfoList *list)
153 {
154     (void)self;
155     DevmgrFreeQueryDeviceListImpl(list);
156 }
157 
DevmgrLoadDevice(struct HDIDeviceManager * iDevMgr,const char * serviceName)158 int32_t DevmgrLoadDevice(struct HDIDeviceManager *iDevMgr, const char *serviceName)
159 {
160     int32_t status = HDF_FAILURE;
161     if (iDevMgr == NULL || serviceName == NULL) {
162         return HDF_ERR_INVALID_PARAM;
163     }
164     HDF_LOGI("load device: %{public}s", serviceName);
165     struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
166     do {
167         if (data == NULL) {
168             status = HDF_ERR_MALLOC_FAIL;
169             break;
170         }
171         if (!HdfRemoteServiceWriteInterfaceToken(iDevMgr->remote, data)) {
172             status = HDF_FAILURE;
173             break;
174         }
175         if (!HdfSbufWriteString(data, serviceName)) {
176             HDF_LOGE("%{public}s: writing service name failed!", __func__);
177             break;
178         }
179         status = DeviceManagerHdiCall(iDevMgr, DEVMGR_SERVICE_LOAD_DEVICE, data, NULL);
180         if (status != HDF_SUCCESS) {
181             HDF_LOGE("failed to load device %{public}s", serviceName);
182         }
183     } while (0);
184 
185     HdfSbufRecycle(data);
186     return status;
187 }
188 
DevmgrUnloadDevice(struct HDIDeviceManager * iDevMgr,const char * serviceName)189 int32_t DevmgrUnloadDevice(struct HDIDeviceManager *iDevMgr, const char *serviceName)
190 {
191     int32_t status = HDF_FAILURE;
192     if (iDevMgr == NULL || serviceName == NULL) {
193         return HDF_ERR_INVALID_PARAM;
194     }
195     HDF_LOGI("unload device: %{public}s", serviceName);
196 
197     struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
198     do {
199         if (data == NULL) {
200             status = HDF_ERR_MALLOC_FAIL;
201             break;
202         }
203         if (!HdfRemoteServiceWriteInterfaceToken(iDevMgr->remote, data)) {
204             status = HDF_FAILURE;
205             break;
206         }
207         if (!HdfSbufWriteString(data, serviceName)) {
208             HDF_LOGE("%{public}s: writing service name failed!", __func__);
209             break;
210         }
211         status = DeviceManagerHdiCall(iDevMgr, DEVMGR_SERVICE_UNLOAD_DEVICE, data, NULL);
212         if (status != HDF_SUCCESS) {
213             HDF_LOGE("failed to unload device %{public}s", serviceName);
214         }
215     } while (0);
216 
217     HdfSbufRecycle(data);
218     return status;
219 }
220 
HDIDeviceManagerConstruct(struct HDIDeviceManager * inst)221 static void HDIDeviceManagerConstruct(struct HDIDeviceManager *inst)
222 {
223     inst->FreeQueryDeviceList = DevmgrFreeQueryDeviceList;
224     inst->QueryUsableDeviceInfo = DevmgrQueryUsableDeviceInfo;
225     inst->QueryUnusableDeviceInfo = DevmgrQueryUnusableDeviceInfo;
226     inst->LoadDevice = DevmgrLoadDevice;
227     inst->UnloadDevice = DevmgrUnloadDevice;
228 }
229 
HDIDeviceManagerGet(void)230 struct HDIDeviceManager *HDIDeviceManagerGet(void)
231 {
232     struct HDIServiceManager *serviceMgr = HDIServiceManagerGet();
233     if (serviceMgr == NULL) {
234         return NULL;
235     }
236     struct HdfRemoteService *remote = serviceMgr->GetService(serviceMgr, DEVICE_MANAGER_SERVICE);
237     HDIServiceManagerRelease(serviceMgr);
238     if (remote == NULL) {
239         HDF_LOGE("%{public}s: hdi service %{public}s not found", __func__, DEVICE_MANAGER_SERVICE);
240         return NULL;
241     }
242 
243     struct HDIDeviceManager *iDevMgr = OsalMemAlloc(sizeof(struct HDIDeviceManager));
244     if (iDevMgr == NULL) {
245         HDF_LOGE("%{public}s: OOM", __func__);
246         HdfRemoteServiceRecycle(remote);
247         return NULL;
248     }
249     if (!HdfRemoteServiceSetInterfaceDesc(remote, "HDI.IDeviceManager.V1_0")) {
250         HDF_LOGE("%{public}s: failed to init interface desc", __func__);
251         HdfRemoteServiceRecycle(remote);
252         return NULL;
253     }
254     iDevMgr->remote = remote;
255     HDIDeviceManagerConstruct(iDevMgr);
256     return iDevMgr;
257 }
258 
HDIDeviceManagerRelease(struct HDIDeviceManager * devmgr)259 void HDIDeviceManagerRelease(struct HDIDeviceManager *devmgr)
260 {
261     if (devmgr == NULL) {
262         return;
263     }
264 
265     HdfRemoteServiceRecycle(devmgr->remote);
266     OsalMemFree(devmgr);
267 }