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