• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }