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_dev_auth_proxy.h"
17
18 #include "common_defs.h"
19 #include "device_auth_defines.h"
20 #include "hc_log.h"
21 #include "ipc_skeleton.h"
22 #include "ipc_adapt.h"
23 #include "ipc_sdk.h"
24 #include "securec.h"
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
GetProxyInstance(const char * serviceName)30 const IClientProxy *GetProxyInstance(const char *serviceName)
31 {
32 IClientProxy *clientProxy = NULL;
33 IUnknown *iUnknown = NULL;
34 int ret;
35
36 iUnknown = SAMGR_GetInstance()->GetDefaultFeatureApi(serviceName);
37 if (iUnknown == NULL) {
38 LOGE("GetDefaultFeatureApi failed");
39 return NULL;
40 }
41 ret = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&clientProxy);
42 if ((ret != 0) || (clientProxy == NULL)) {
43 LOGE("QueryInterface failed, result %d", ret);
44 clientProxy = NULL;
45 }
46 return (const IClientProxy *)clientProxy;
47 }
48
EncodeCallRequest(ProxyDevAuthData * dataCtx,int32_t type,const uint8_t * param,int32_t paramSz)49 int32_t EncodeCallRequest(ProxyDevAuthData *dataCtx, int32_t type, const uint8_t *param, int32_t paramSz)
50 {
51 IpcIo *ioPtr = NULL;
52 LOGI("type %d, paramSz %d", type, paramSz);
53 ioPtr = dataCtx->tmpData;
54 WriteInt32(ioPtr, type);
55 WriteUint32(ioPtr, paramSz);
56 bool ret = WriteBuffer(ioPtr, param, paramSz);
57 if (!ret) {
58 return HC_FALSE;
59 }
60 dataCtx->paramCnt++;
61 return HC_SUCCESS;
62 }
63
FinalCallRequest(ProxyDevAuthData * dataCtx,int32_t methodId)64 int32_t FinalCallRequest(ProxyDevAuthData *dataCtx, int32_t methodId)
65 {
66 int32_t dataLen;
67 IpcIo *ioPtr = NULL;
68
69 dataLen = GetIpcIoDataLength((const IpcIo *)(dataCtx->tmpData));
70 if (dataLen <= 0) {
71 LOGE("data invalid, dataLen %d", dataLen);
72 return HC_ERROR;
73 }
74 ioPtr = dataCtx->data;
75 LOGI("method id %d, param num %d, data length %d, flag %u, io offset %d",
76 methodId, dataCtx->paramCnt, dataLen, ioPtr->flag, dataCtx->ioBuffOffset);
77 /* request data length = number of params + params information */
78 WriteInt32(ioPtr, methodId);
79 WriteInt32(ioPtr, dataLen + sizeof(int32_t));
80 WriteInt32(ioPtr, dataCtx->paramCnt);
81 WriteUint32(ioPtr, dataLen);
82 bool ret = WriteBuffer(ioPtr, (const uint8_t *)(dataCtx->tmpData->bufferBase + dataCtx->ioBuffOffset), dataLen);
83 if (!ret) {
84 return HC_FALSE;
85 }
86 if (dataCtx->withCallback) {
87 SvcIdentity badSvc = { 0 };
88 ShowIpcSvcInfo(&(dataCtx->cbSvc));
89 if ((sizeof(dataCtx->cbSvc) != sizeof(badSvc)) ||
90 !memcmp(&(dataCtx->cbSvc), &badSvc, sizeof(badSvc))) {
91 LOGE("ipc call with callback, but stub object invalid");
92 dataCtx->withCallback = false;
93 return HC_ERROR;
94 }
95 WriteInt32(ioPtr, PARAM_TYPE_CB_OBJECT);
96 if (!WriteRemoteObject(ioPtr, &(dataCtx->cbSvc))) {
97 return HC_FALSE;
98 }
99 LOGI("ipc call with callback, data flag %u", ioPtr->flag);
100 }
101 dataCtx->withCallback = false;
102 return HC_SUCCESS;
103 }
104
CliInvokeRetCallback(IOwner owner,int32_t code,IpcIo * reply)105 static int32_t CliInvokeRetCallback(IOwner owner, int32_t code, IpcIo *reply)
106 {
107 IpcIo *dstReply = NULL;
108 errno_t eno;
109
110 LOGI("starting...");
111 if ((reply == NULL) || (owner == NULL)) {
112 LOGE("invalid params");
113 return -1;
114 }
115 dstReply = (IpcIo *)owner;
116 eno = memcpy_s(dstReply->bufferCur, dstReply->bufferLeft, reply->bufferCur, reply->bufferLeft);
117 if (eno != EOK) {
118 LOGE("data copy failed");
119 dstReply->flag = 0;
120 dstReply->bufferLeft = 0;
121 return -1;
122 }
123 dstReply->bufferLeft = reply->bufferLeft;
124 LOGI("done, reply data length %zu", dstReply->bufferLeft);
125 return 0;
126 }
127
ActCall(const IClientProxy * clientInst,ProxyDevAuthData * dataCtx)128 int32_t ActCall(const IClientProxy *clientInst, ProxyDevAuthData *dataCtx)
129 {
130 int32_t ret;
131 int32_t ipcRet;
132 if (clientInst == NULL) {
133 LOGE("proxy invalid");
134 return HC_ERROR;
135 }
136 LOGI("start to invoke ipc call...");
137 ipcRet = clientInst->Invoke((IClientProxy *)clientInst, DEV_AUTH_CALL_REQUEST,
138 dataCtx->data, (IOwner)(dataCtx->reply), CliInvokeRetCallback);
139 LOGI("invoke call done, ipc result(%d)", ipcRet);
140 ret = HC_ERROR;
141 ReadInt32(dataCtx->reply, &ret);
142 LOGI("service call result(%d)", ret);
143 return ((ipcRet == 0) && (ret == HC_SUCCESS)) ? HC_SUCCESS : HC_ERR_IPC_INTERNAL_FAILED;
144 }
145
SetCallbackStub(ProxyDevAuthData * dataCtx,const SvcIdentity * cbSvc)146 void SetCallbackStub(ProxyDevAuthData *dataCtx, const SvcIdentity *cbSvc)
147 {
148 (void)memset_s(&(dataCtx->cbSvc), sizeof(SvcIdentity), 0, sizeof(SvcIdentity));
149 if (cbSvc != NULL) {
150 (void)memcpy_s(&(dataCtx->cbSvc), sizeof(SvcIdentity), cbSvc, sizeof(SvcIdentity));
151 }
152 dataCtx->withCallback = true;
153 return;
154 }
155
156 #ifdef __cplusplus
157 }
158 #endif
159