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 "ipc_server_stub.h"
17
18 #include "securec.h"
19
20 #include "liteipc_adapter.h"
21 #include "ohos_init.h"
22 #include "samgr_lite.h"
23 #include "iproxy_server.h"
24
25 #include "device_manager_log.h"
26 #include "device_manager_errno.h"
27 #include "dm_subscribe_info.h"
28
29 #include "ipc_cmd_register.h"
30 #include "ipc_def.h"
31 #include "ipc_server_listenermgr.h"
32 #include "ipc_server_adapter.h"
33
34 namespace {
35 const int32_t WAIT_FOR_SERVER = 2;
36 const int32_t STACK_SIZE = 0x800;
37 const int32_t QUEUE_SIZE = 20;
38 }
39
40 using namespace OHOS::DistributedHardware;
41
42 struct DefaultFeatureApi {
43 INHERIT_SERVER_IPROXY;
44 };
45
46 struct DeviceManagerSamgrService {
47 INHERIT_SERVICE;
48 INHERIT_IUNKNOWNENTRY(DefaultFeatureApi);
49 Identity identity;
50 };
51
DeathCb(const IpcContext * context,void * ipcMsg,IpcIo * data,void * arg)52 static int32_t DeathCb(const IpcContext *context, void *ipcMsg, IpcIo *data, void *arg)
53 {
54 (void)context;
55 (void)ipcMsg;
56 (void)data;
57 if (arg == NULL) {
58 DMLOG(DM_LOG_ERROR, "package name is NULL.");
59 return DEVICEMANAGER_INVALID_PARAM;
60 }
61 CommonSvcId svcId = {0};
62 std::string pkgName = (const char *)arg;
63 if (IpcServerListenermgr::GetInstance().GetListenerByPkgName(pkgName, &svcId) != DEVICEMANAGER_OK) {
64 DMLOG(DM_LOG_ERROR, "not found client by package name.");
65 free(arg);
66 arg = NULL;
67 return DEVICEMANAGER_FAILED;
68 }
69 IpcServerListenermgr::GetInstance().UnregisterListener(pkgName);
70 free(arg);
71 arg = NULL;
72 #ifdef __LINUX__
73 BinderRelease(svcId.ipcCtx, svcId.handle);
74 #endif
75 SvcIdentity sid = {0};
76 sid.handle = svcId.handle;
77 sid.token = svcId.token;
78 sid.cookie = svcId.cookie;
79 UnregisterDeathCallback(sid, svcId.cbId);
80 return DEVICEMANAGER_OK;
81 }
82
RegisterDeviceManagerListener(IpcIo * req,IpcIo * reply)83 int32_t RegisterDeviceManagerListener(IpcIo *req, IpcIo *reply)
84 {
85 DMLOG(DM_LOG_INFO, "register service listener.");
86 size_t len = 0;
87 uint8_t *name = IpcIoPopString(req, &len);
88 SvcIdentity *svc = IpcIoPopSvc(req);
89 if (name == NULL || svc == NULL || len == 0) {
90 DMLOG(DM_LOG_ERROR, "get para failed");
91 return DEVICEMANAGER_INVALID_PARAM;
92 }
93
94 CommonSvcId svcId = {0};
95 svcId.handle = svc->handle;
96 svcId.token = svc->token;
97 svcId.cookie = svc->cookie;
98
99 SvcIdentity sid = *svc;
100 #ifdef __LINUX__
101 svcId.ipcCtx = svc->ipcContext;
102 BinderAcquire(svcId.ipcCtx, svcId.handle);
103 free(svc);
104 svc = NULL;
105 #endif
106 char *pkgName = (char *)malloc(len + 1);
107 if (pkgName == NULL) {
108 DMLOG(DM_LOG_ERROR, "malloc failed!");
109 return DEVICEMANAGER_MALLOC_ERROR;
110 }
111 if (strcpy_s(pkgName, len + 1, (const char *)name) != DEVICEMANAGER_OK) {
112 DMLOG(DM_LOG_ERROR, "strcpy_s failed!");
113 free(pkgName);
114 return DEVICEMANAGER_COPY_FAILED;
115 }
116 uint32_t cbId = 0;
117 RegisterDeathCallback(NULL, sid, DeathCb, pkgName, &cbId);
118 svcId.cbId = cbId;
119 std::string strPkgName = (const char *)name;
120 return IpcServerListenermgr::GetInstance().RegisterListener(strPkgName, &svcId);
121 }
122
UnRegisterDeviceManagerListener(IpcIo * req,IpcIo * reply)123 int32_t UnRegisterDeviceManagerListener(IpcIo *req, IpcIo *reply)
124 {
125 DMLOG(DM_LOG_INFO, "unregister service listener.");
126 size_t len = 0;
127 std::string pkgName = (const char *)IpcIoPopString(req, &len);
128 if (pkgName == "" || len == 0) {
129 DMLOG(DM_LOG_ERROR, "get para failed");
130 return DEVICEMANAGER_FAILED;
131 }
132 CommonSvcId svcId;
133 if (IpcServerListenermgr::GetInstance().GetListenerByPkgName(pkgName, &svcId) != DEVICEMANAGER_OK) {
134 DMLOG(DM_LOG_ERROR, "not found listener by package name.");
135 return DEVICEMANAGER_FAILED;
136 }
137 int32_t ret = IpcServerListenermgr::GetInstance().UnregisterListener(pkgName);
138 if (ret == DEVICEMANAGER_OK) {
139 #ifdef __LINUX__
140 BinderRelease(svcId.ipcCtx, svcId.handle);
141 #endif
142 SvcIdentity sid;
143 sid.handle = svcId.handle;
144 sid.token = svcId.token;
145 sid.cookie = svcId.cookie;
146 ret = UnregisterDeathCallback(sid, svcId.cbId);
147 }
148 return ret;
149 }
150
GetName(Service * service)151 static const char *GetName(Service *service)
152 {
153 (void)service;
154 return DEVICE_MANAGER_SERVICE_NAME;
155 }
156
Initialize(Service * service,Identity identity)157 static BOOL Initialize(Service *service, Identity identity)
158 {
159 if (service == NULL) {
160 DMLOG(DM_LOG_WARN, "invalid param");
161 return FALSE;
162 }
163
164 DeviceManagerSamgrService *mgrService = (DeviceManagerSamgrService *)service;
165 mgrService->identity = identity;
166 return TRUE;
167 }
168
MessageHandle(Service * service,Request * request)169 static BOOL MessageHandle(Service *service, Request *request)
170 {
171 if ((service == NULL) || (request == NULL)) {
172 DMLOG(DM_LOG_WARN, "invalid param");
173 return FALSE;
174 }
175 return TRUE;
176 }
177
GetTaskConfig(Service * service)178 static TaskConfig GetTaskConfig(Service *service)
179 {
180 (void)service;
181 TaskConfig config = {LEVEL_HIGH, PRI_BELOW_NORMAL, STACK_SIZE, QUEUE_SIZE, SHARED_TASK};
182 return config;
183 }
184
OnRemoteRequest(IServerProxy * iProxy,int32_t funcId,void * origin,IpcIo * req,IpcIo * reply)185 static int32_t OnRemoteRequest(IServerProxy *iProxy, int32_t funcId, void *origin,
186 IpcIo *req, IpcIo *reply)
187 {
188 DMLOG(DM_LOG_INFO, "Receive funcId:%d", funcId);
189 (void)origin;
190 return IpcCmdRegister::GetInstance().OnIpcServerCmd(funcId, *req, *reply);
191 }
192
HOS_SystemInit(void)193 static void HOS_SystemInit(void)
194 {
195 SAMGR_Bootstrap();
196 return;
197 }
198
IpcServerStubInit(void)199 int32_t IpcServerStubInit(void)
200 {
201 HOS_SystemInit();
202 return DEVICEMANAGER_OK;
203 }
204
DevMgrSvcInit(void)205 static void DevMgrSvcInit(void)
206 {
207 sleep(WAIT_FOR_SERVER);
208 static DeviceManagerSamgrService service = {
209 .GetName = GetName,
210 .Initialize = Initialize,
211 .MessageHandle = MessageHandle,
212 .GetTaskConfig = GetTaskConfig,
213 SERVER_IPROXY_IMPL_BEGIN,
214 .Invoke = OnRemoteRequest,
215 IPROXY_END,
216 };
217
218 if (!SAMGR_GetInstance()->RegisterService((Service *)&service)) {
219 DMLOG(DM_LOG_ERROR, "%s, RegisterService failed", DEVICE_MANAGER_SERVICE_NAME);
220 return;
221 }
222 if (!SAMGR_GetInstance()->RegisterDefaultFeatureApi(DEVICE_MANAGER_SERVICE_NAME, GET_IUNKNOWN(service))) {
223 DMLOG(DM_LOG_ERROR, "%s, RegisterDefaultFeatureApi failed", DEVICE_MANAGER_SERVICE_NAME);
224 return;
225 }
226 DMLOG(DM_LOG_INFO, "%s, init success", DEVICE_MANAGER_SERVICE_NAME);
227 }
228 SYSEX_SERVICE_INIT(DevMgrSvcInit);
229