1 /*
2  * Copyright (c) 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 "ipc_client_server_proxy.h"
17 
18 #include "device_manager_notify.h"
19 #include "dm_constants.h"
20 #include "dm_log.h"
21 #include "ipc_cmd_register.h"
22 #include "ipc_def.h"
23 
24 namespace OHOS {
25 namespace DistributedHardware {
26 const int32_t INVALID_CB_ID = 0xFF;
27 static uint32_t g_deathCbId = INVALID_CB_ID;
28 static SvcIdentity g_svcIdentity;
29 static std::shared_ptr<IpcRsp> pCurRsp;
30 
HOS_SystemInit(void)31 void __attribute__((weak)) HOS_SystemInit(void)
32 {
33     SAMGR_Bootstrap();
34     return;
35 }
36 
DmDeathCallback(void * arg)37 void DmDeathCallback(void *arg)
38 {
39     (void)arg;
40     LOGI("ATTENTION SERVICE (%{public}s) DEAD !!!\n", DEVICE_MANAGER_SERVICE_NAME);
41     g_deathCbId = INVALID_CB_ID;
42     g_svcIdentity.handle = 0;
43     g_svcIdentity.token = 0;
44     g_svcIdentity.cookie = 0;
45     DeviceManagerNotify::GetInstance().OnRemoteDied();
46 }
47 
SendCmdResultCb(IOwner owner,int32_t code,IpcIo * reply)48 static int32_t SendCmdResultCb(IOwner owner, int32_t code, IpcIo *reply)
49 {
50     (void)code;
51     int32_t cmdCode = *static_cast<int32_t *>(owner);
52     LOGI("SendCmdResultCb code:%{public}d", cmdCode);
53     (void)IpcCmdRegister::GetInstance().ReadResponse(cmdCode, *reply, pCurRsp);
54     return DM_OK;
55 }
56 
GetServerProxy(void)57 IClientProxy *IpcClientServerProxy::GetServerProxy(void)
58 {
59     IClientProxy *clientProxy = nullptr;
60     IUnknown *iUnknown = nullptr;
61 
62     LOGI("start get client proxy");
63     iUnknown = SAMGR_GetInstance()->GetDefaultFeatureApi(DEVICE_MANAGER_SERVICE_NAME);
64     if (iUnknown == nullptr) {
65         return nullptr;
66     }
67     if (iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&clientProxy) != DM_OK ||
68         clientProxy == nullptr) {
69         LOGE("QueryInterface failed");
70     }
71     return clientProxy;
72 }
73 
RegisterServerDeathCb(void)74 int IpcClientServerProxy::RegisterServerDeathCb(void)
75 {
76     g_svcIdentity = SAMGR_GetRemoteIdentity(DEVICE_MANAGER_SERVICE_NAME, nullptr);
77     g_deathCbId = INVALID_CB_ID;
78     if (AddDeathRecipient(g_svcIdentity, DmDeathCallback, nullptr, &g_deathCbId) != EC_SUCCESS) {
79         LOGE("reg death callback failed");
80         return ERR_DM_FAILED;
81     }
82     return DM_OK;
83 }
84 
SendCmd(int32_t cmdCode,std::shared_ptr<IpcReq> req,std::shared_ptr<IpcRsp> rsp)85 int32_t IpcClientServerProxy::SendCmd(int32_t cmdCode, std::shared_ptr<IpcReq> req, std::shared_ptr<IpcRsp> rsp)
86 {
87     LOGI("IpcClientServerProxy::SendCmd:%{public}d", cmdCode);
88     uint8_t data[MAX_DM_IPC_LEN] = {0};
89     IpcIo request;
90 
91     if (IpcCmdRegister::GetInstance().SetRequest(cmdCode, req, request, data, MAX_DM_IPC_LEN) != DM_OK) {
92         return ERR_DM_FAILED;
93     }
94     {
95         std::lock_guard<std::mutex> autoLock(lock_);
96         pCurRsp = rsp;
97         if (serviceProxy_ != nullptr &&
98             serviceProxy_->Invoke(serviceProxy_, cmdCode, &request, &cmdCode, SendCmdResultCb) != 0) {
99             LOGE("serviceProxy_ invoke failed.");
100             return ERR_DM_FAILED;
101         }
102     }
103     LOGI("IpcClientServerProxy::SendCmd:%{public}d, end", cmdCode);
104     return DM_OK;
105 }
106 
Init(void)107 int32_t IpcClientServerProxy::Init(void)
108 {
109     if (serviceProxy_ != nullptr) {
110         LOGI("ServerProxy already Init");
111         return DM_OK;
112     }
113     HOS_SystemInit();
114     serviceProxy_ = GetServerProxy();
115     if (serviceProxy_ == nullptr) {
116         LOGE("get ipc client proxy failed");
117         return ERR_DM_FAILED;
118     }
119     if (RegisterServerDeathCb() != DM_OK) {
120         LOGE("register server death cb failed");
121         return ERR_DM_FAILED;
122     }
123     LOGI("ServerProxyInit ok");
124     return DM_OK;
125 }
126 } // namespace DistributedHardware
127 } // namespace OHOS
128