• 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 "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