1 /*
2 * Copyright (c) 2021-2022 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 "device_service_stub.h"
17 #include "devsvc_manager_clnt.h"
18 #include "hdf_base.h"
19 #include "hdf_log.h"
20 #include "hdf_sbuf.h"
21 #include "osal_mem.h"
22 #ifdef __USER__
23 #include <pthread.h>
24 #endif
25
DeviceServiceStubDispatch(struct HdfRemoteService * stub,int code,struct HdfSBuf * data,struct HdfSBuf * reply)26 int DeviceServiceStubDispatch(
27 struct HdfRemoteService *stub, int code, struct HdfSBuf *data, struct HdfSBuf *reply)
28 {
29 struct DeviceServiceStub *service = (struct DeviceServiceStub *)stub;
30 struct IDeviceIoService *ioService = service->super.deviceObject.service;
31 int ret = HDF_FAILURE;
32
33 #ifdef __USER__
34 pthread_rwlock_rdlock(&service->super.deviceObject.mutex);
35 #endif
36
37 if (ioService == NULL) {
38 #ifdef __USER__
39 pthread_rwlock_unlock(&service->super.deviceObject.mutex);
40 #endif
41 return HDF_FAILURE;
42 }
43
44 struct HdfDeviceIoClient client = {
45 .device = &service->super.deviceObject,
46 .priv = NULL,
47 };
48
49 if (ioService->Dispatch != NULL) {
50 ret = ioService->Dispatch(&client, code, data, reply);
51 }
52
53 #ifdef __USER__
54 pthread_rwlock_unlock(&service->super.deviceObject.mutex);
55 #endif
56 return ret;
57 }
58
59 static struct HdfRemoteDispatcher g_deviceServiceDispatcher = {
60 .Dispatch = DeviceServiceStubDispatch
61 };
62
DeviceServiceStubPublishService(struct HdfDeviceNode * service)63 int DeviceServiceStubPublishService(struct HdfDeviceNode *service)
64 {
65 int status = HDF_FAILURE;
66 struct DeviceServiceStub *fullService = (struct DeviceServiceStub *)service;
67
68 if (service->servName == NULL) {
69 HDF_LOGE("device %{public}x miss service name", service->devId);
70 return HDF_ERR_INVALID_OBJECT;
71 }
72
73 if (fullService->remote != NULL) {
74 HDF_LOGE("%{public}s:service %{public}s already published", __func__, service->servName);
75 return HDF_ERR_INVALID_OBJECT;
76 }
77
78 if (service->policy != SERVICE_POLICY_PUBLIC && service->policy != SERVICE_POLICY_CAPACITY) {
79 return HDF_ERR_NOT_SUPPORT;
80 }
81
82 fullService->remote = HdfRemoteServiceObtain((struct HdfObject *)fullService, &g_deviceServiceDispatcher);
83 if (fullService->remote == NULL) {
84 return HDF_ERR_MALLOC_FAIL;
85 }
86
87 do {
88 if (service->interfaceDesc != NULL &&
89 !HdfRemoteServiceSetInterfaceDesc(fullService->remote, service->interfaceDesc)) {
90 HDF_LOGE("failed to set device service interface desc");
91 break;
92 }
93 struct DevSvcManagerClnt *serviceManager = DevSvcManagerClntGetInstance();
94 if (serviceManager == NULL) {
95 HDF_LOGE("device service stub failed to publish, svcmgr clnt invalid");
96 status = HDF_DEV_ERR_NO_DEVICE;
97 break;
98 }
99 struct HdfServiceInfo servInfo;
100 HdfServiceInfoInit(&servInfo, service);
101 status = DevSvcManagerClntAddService(&fullService->super.deviceObject, &servInfo);
102 if (status != HDF_SUCCESS) {
103 break;
104 }
105 service->servStatus = true;
106 return HDF_SUCCESS;
107 } while (0);
108
109 HdfRemoteServiceRecycle(fullService->remote);
110 fullService->remote = NULL;
111 return status;
112 }
113
DeviceServiceStubRemoveService(struct HdfDeviceNode * deviceNode)114 int DeviceServiceStubRemoveService(struct HdfDeviceNode *deviceNode)
115 {
116 struct DevSvcManagerClnt *serviceManager = DevSvcManagerClntGetInstance();
117 if (serviceManager == NULL || deviceNode == NULL) {
118 return HDF_FAILURE;
119 }
120 DevSvcManagerClntRemoveService(deviceNode->servName);
121 struct DeviceServiceStub *instance = (struct DeviceServiceStub *)deviceNode;
122 HdfRemoteServiceRecycle(instance->remote);
123 instance->remote = NULL;
124 return HDF_SUCCESS;
125 }
126
DeviceServiceStubConstruct(struct DeviceServiceStub * inst)127 void DeviceServiceStubConstruct(struct DeviceServiceStub *inst)
128 {
129 HdfDeviceNodeConstruct(&inst->super);
130 struct IDeviceNode *serviceIf = (struct IDeviceNode *)inst;
131 if (serviceIf != NULL) {
132 serviceIf->PublishService = DeviceServiceStubPublishService;
133 serviceIf->RemoveService = DeviceServiceStubRemoveService;
134 }
135 }
136
DeviceServiceStubCreate(void)137 struct HdfObject *DeviceServiceStubCreate(void)
138 {
139 struct DeviceServiceStub *instance =
140 (struct DeviceServiceStub *)OsalMemCalloc(sizeof(struct DeviceServiceStub));
141 if (instance != NULL) {
142 DeviceServiceStubConstruct(instance);
143 }
144 return (struct HdfObject *)instance;
145 }
146
DeviceServiceStubRelease(struct HdfObject * object)147 void DeviceServiceStubRelease(struct HdfObject *object)
148 {
149 struct DeviceServiceStub *instance = (struct DeviceServiceStub *)object;
150 if (instance != NULL) {
151 if (instance->remote != NULL) {
152 HdfRemoteServiceRecycle(instance->remote);
153 instance->remote = NULL;
154 }
155 HdfDeviceNodeDestruct(&instance->super);
156 OsalMemFree(instance);
157 }
158 }
159
HdfDeviceObjectCheckInterfaceDesc(struct HdfDeviceObject * dev,struct HdfSBuf * data)160 bool HdfDeviceObjectCheckInterfaceDesc(struct HdfDeviceObject *dev, struct HdfSBuf *data)
161 {
162 if (dev == NULL || data == NULL) {
163 return false;
164 }
165 struct HdfDeviceNode *devNode = CONTAINER_OF(dev, struct HdfDeviceNode, deviceObject);
166 struct DeviceServiceStub *instance = (struct DeviceServiceStub *)devNode;
167 return HdfRemoteServiceCheckInterfaceToken(instance->remote, data);
168 }