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 ioPtr = dataCtx->tmpData;
53 WriteInt32(ioPtr, type);
54 WriteUint32(ioPtr, paramSz);
55 bool ret = WriteBuffer(ioPtr, param, paramSz);
56 if (!ret) {
57 return HC_FALSE;
58 }
59 dataCtx->paramCnt++;
60 return HC_SUCCESS;
61 }
62
FinalCallRequest(ProxyDevAuthData * dataCtx,int32_t methodId)63 int32_t FinalCallRequest(ProxyDevAuthData *dataCtx, int32_t methodId)
64 {
65 int32_t dataLen;
66 IpcIo *ioPtr = NULL;
67
68 dataLen = GetIpcIoDataLength((const IpcIo *)(dataCtx->tmpData));
69 if (dataLen <= 0) {
70 LOGE("data invalid, dataLen %d", dataLen);
71 return HC_ERROR;
72 }
73 ioPtr = dataCtx->data;
74 LOGI("method id %d, param num %d, data length %d, flag %u, io offset %d",
75 methodId, dataCtx->paramCnt, dataLen, ioPtr->flag, dataCtx->ioBuffOffset);
76 /* request data length = number of params + params information */
77 WriteInt32(ioPtr, methodId);
78 WriteInt32(ioPtr, dataLen + sizeof(int32_t));
79 WriteInt32(ioPtr, dataCtx->paramCnt);
80 WriteUint32(ioPtr, dataLen);
81 bool ret = WriteBuffer(ioPtr, (const uint8_t *)(dataCtx->tmpData->bufferBase + dataCtx->ioBuffOffset), dataLen);
82 if (!ret) {
83 return HC_FALSE;
84 }
85 if (dataCtx->withCallback) {
86 SvcIdentity badSvc = { 0 };
87 ShowIpcSvcInfo(&(dataCtx->cbSvc));
88 if ((sizeof(dataCtx->cbSvc) != sizeof(badSvc)) ||
89 !memcmp(&(dataCtx->cbSvc), &badSvc, sizeof(badSvc))) {
90 LOGE("ipc call with callback, but stub object invalid");
91 dataCtx->withCallback = false;
92 return HC_ERROR;
93 }
94 WriteInt32(ioPtr, PARAM_TYPE_CB_OBJECT);
95 if (!WriteRemoteObject(ioPtr, &(dataCtx->cbSvc))) {
96 return HC_FALSE;
97 }
98 LOGI("ipc call with callback, data flag %u", ioPtr->flag);
99 }
100 dataCtx->withCallback = false;
101 return HC_SUCCESS;
102 }
103
CliInvokeRetCallback(IOwner owner,int32_t code,IpcIo * reply)104 static int32_t CliInvokeRetCallback(IOwner owner, int32_t code, IpcIo *reply)
105 {
106 (void)code;
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