• 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     char *base = NULL;
49     int32_t deviceType;
50 
51     while ((svrName = HdfSbufReadString(reply))) {
52         const size_t svrNameLen = strlen(svrName) + 1;
53         base = (char *)OsalMemCalloc(sizeof(*node) + svrNameLen);
54         if (base == NULL) {
55             DevmgrFreeQueryDeviceListImpl(list);
56             return HDF_FAILURE;
57         }
58         node = (struct DeviceInfoNode *)base;
59         node->svcName = base + sizeof(*node);
60         if (strcpy_s(node->svcName, svrNameLen, svrName) != EOK) {
61             HDF_LOGE("strcpy service name %{public}s failed", svrName);
62             OsalMemFree(base);
63             continue;
64         }
65         HDF_LOGD("%{public}s %{public}s", __func__, svrName);
66         HdfSbufReadInt32(reply, &deviceType);
67         if (deviceType != HDF_LOCAL_SERVICE && deviceType != HDF_REMOTE_SERVICE) {
68             HDF_LOGE("device type error %{public}d ", deviceType);
69             OsalMemFree(base);
70             continue;
71         }
72         node->deviceType = deviceType;
73         DListInsertTail(&node->node, &list->list);
74         list->deviceCnt++;
75     }
76 
77     return HDF_SUCCESS;
78 }
79 
DevmgrQueryDeviceInfo(struct HDIDeviceManager * iDevMgr,struct DeviceInfoList * list,int32_t type)80 static int32_t DevmgrQueryDeviceInfo(struct HDIDeviceManager *iDevMgr, struct DeviceInfoList *list, int32_t type)
81 {
82     struct HdfSBuf *reply = NULL;
83     struct HdfSBuf *data = NULL;
84     int32_t ret;
85 
86     reply = HdfSbufTypedObtain(SBUF_IPC);
87     if (reply == NULL) {
88         return HDF_ERR_MALLOC_FAIL;
89     }
90 
91     data = HdfSbufTypedObtain(SBUF_IPC);
92     if (data == NULL) {
93         HdfSbufRecycle(reply);
94         return HDF_ERR_MALLOC_FAIL;
95     }
96     do {
97         if (!HdfRemoteServiceWriteInterfaceToken(iDevMgr->remote, data)) {
98             ret = HDF_FAILURE;
99             break;
100         }
101         list->deviceCnt = 0;
102         DListHeadInit(&list->list);
103 
104         HdfSbufWriteInt32(data, type);
105         ret = DeviceManagerHdiCall(iDevMgr, DEVMGR_SERVICE_QUERY_DEVICE, data, reply);
106         if (ret != HDF_SUCCESS) {
107             HDF_LOGE("DevmgrProxyQueryDevice failed");
108             break;
109         }
110 
111         ret = HdfObtainDeviceInfo(list, reply);
112     } while (0);
113 
114     HdfSbufRecycle(reply);
115     HdfSbufRecycle(data);
116     return ret;
117 }
118 
DevmgrQueryUsableDeviceInfo(struct HDIDeviceManager * self,struct DeviceInfoList * list)119 static int32_t DevmgrQueryUsableDeviceInfo(struct HDIDeviceManager *self, struct DeviceInfoList *list)
120 {
121     if (self == NULL || list == NULL) {
122         return HDF_ERR_INVALID_PARAM;
123     }
124     return DevmgrQueryDeviceInfo(self, list, HDF_SERVICE_USABLE);
125 }
126 
DevmgrQueryUnusableDeviceInfo(struct HDIDeviceManager * self,struct DeviceInfoList * list)127 static int32_t DevmgrQueryUnusableDeviceInfo(struct HDIDeviceManager *self, struct DeviceInfoList *list)
128 {
129     if (self == NULL || list == NULL) {
130         return HDF_ERR_INVALID_PARAM;
131     }
132 
133     return DevmgrQueryDeviceInfo(self, list, HDF_SERVICE_UNUSABLE);
134 }
135 
DevmgrFreeQueryDeviceListImpl(struct DeviceInfoList * list)136 static void DevmgrFreeQueryDeviceListImpl(struct DeviceInfoList *list)
137 {
138     if (list == NULL) {
139         return;
140     }
141 
142     struct DeviceInfoNode *devNode = NULL;
143     struct DeviceInfoNode *tmp = NULL;
144     DLIST_FOR_EACH_ENTRY_SAFE(devNode, tmp, &list->list, struct DeviceInfoNode, node) {
145         DListRemove(&devNode->node);
146         OsalMemFree(devNode);
147     }
148     list->deviceCnt = 0;
149 }
150 
DevmgrFreeQueryDeviceList(struct HDIDeviceManager * self,struct DeviceInfoList * list)151 static void DevmgrFreeQueryDeviceList(struct HDIDeviceManager *self, struct DeviceInfoList *list)
152 {
153     (void)self;
154     DevmgrFreeQueryDeviceListImpl(list);
155 }
156 
DevmgrProcessLoad(struct HDIDeviceManager * iDevMgr,const char * serviceName,int32_t id)157 static int32_t DevmgrProcessLoad(struct HDIDeviceManager *iDevMgr, const char *serviceName, int32_t id)
158 {
159     int32_t status = HDF_FAILURE;
160     struct HdfSBuf *data = HdfSbufTypedObtain(SBUF_IPC);
161     do {
162         if (data == NULL) {
163             status = HDF_ERR_MALLOC_FAIL;
164             break;
165         }
166         if (!HdfRemoteServiceWriteInterfaceToken(iDevMgr->remote, data)) {
167             status = HDF_FAILURE;
168             break;
169         }
170         if (!HdfSbufWriteString(data, serviceName)) {
171             HDF_LOGE("%{public}s: writing service name failed!", __func__);
172             break;
173         }
174         status = DeviceManagerHdiCall(iDevMgr, id, data, NULL);
175         if (status != HDF_SUCCESS) {
176             HDF_LOGE("failed to process load/unload device %{public}s code:%{public}d", serviceName, id);
177         }
178     } while (0);
179 
180     HdfSbufRecycle(data);
181     return status;
182 }
183 
DevmgrLoadDevice(struct HDIDeviceManager * iDevMgr,const char * serviceName)184 int32_t DevmgrLoadDevice(struct HDIDeviceManager *iDevMgr, const char *serviceName)
185 {
186     if (iDevMgr == NULL || serviceName == NULL) {
187         return HDF_ERR_INVALID_PARAM;
188     }
189 
190     HDF_LOGI("load device: %{public}s", serviceName);
191 
192     return DevmgrProcessLoad(iDevMgr, serviceName, DEVMGR_SERVICE_LOAD_DEVICE);
193 }
194 
DevmgrUnloadDevice(struct HDIDeviceManager * iDevMgr,const char * serviceName)195 int32_t DevmgrUnloadDevice(struct HDIDeviceManager *iDevMgr, const char *serviceName)
196 {
197     if (iDevMgr == NULL || serviceName == NULL) {
198         return HDF_ERR_INVALID_PARAM;
199     }
200 
201     HDF_LOGI("unload device: %{public}s", serviceName);
202 
203     return DevmgrProcessLoad(iDevMgr, serviceName, DEVMGR_SERVICE_UNLOAD_DEVICE);
204 }
205 
HDIDeviceManagerConstruct(struct HDIDeviceManager * inst)206 static void HDIDeviceManagerConstruct(struct HDIDeviceManager *inst)
207 {
208     inst->FreeQueryDeviceList = DevmgrFreeQueryDeviceList;
209     inst->QueryUsableDeviceInfo = DevmgrQueryUsableDeviceInfo;
210     inst->QueryUnusableDeviceInfo = DevmgrQueryUnusableDeviceInfo;
211     inst->LoadDevice = DevmgrLoadDevice;
212     inst->UnloadDevice = DevmgrUnloadDevice;
213 }
214 
HDIDeviceManagerGet(void)215 struct HDIDeviceManager *HDIDeviceManagerGet(void)
216 {
217     struct HDIServiceManager *serviceMgr = HDIServiceManagerGet();
218     if (serviceMgr == NULL) {
219         return NULL;
220     }
221     struct HdfRemoteService *remote = serviceMgr->GetService(serviceMgr, DEVICE_MANAGER_SERVICE);
222     HDIServiceManagerRelease(serviceMgr);
223     if (remote == NULL) {
224         HDF_LOGE("%{public}s: hdi service %{public}s not found", __func__, DEVICE_MANAGER_SERVICE);
225         return NULL;
226     }
227 
228     struct HDIDeviceManager *iDevMgr = OsalMemAlloc(sizeof(struct HDIDeviceManager));
229     if (iDevMgr == NULL) {
230         HDF_LOGE("%{public}s: OOM", __func__);
231         HdfRemoteServiceRecycle(remote);
232         return NULL;
233     }
234     if (!HdfRemoteServiceSetInterfaceDesc(remote, "HDI.IDeviceManager.V1_0")) {
235         HDF_LOGE("%{public}s: failed to init interface desc", __func__);
236         HdfRemoteServiceRecycle(remote);
237         HDIDeviceManagerRelease(iDevMgr);
238         return NULL;
239     }
240     iDevMgr->remote = remote;
241     HDIDeviceManagerConstruct(iDevMgr);
242     return iDevMgr;
243 }
244 
HDIDeviceManagerRelease(struct HDIDeviceManager * devmgr)245 void HDIDeviceManagerRelease(struct HDIDeviceManager *devmgr)
246 {
247     if (devmgr == NULL) {
248         return;
249     }
250 
251     HdfRemoteServiceRecycle(devmgr->remote);
252     OsalMemFree(devmgr);
253 }