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 IpcIo *dstReply = NULL;
107 errno_t eno;
108
109 LOGI("starting...");
110 if ((reply == NULL) || (owner == NULL)) {
111 LOGE("invalid params");
112 return -1;
113 }
114 dstReply = (IpcIo *)owner;
115 eno = memcpy_s(dstReply->bufferCur, dstReply->bufferLeft, reply->bufferCur, reply->bufferLeft);
116 if (eno != EOK) {
117 LOGE("data copy failed");
118 dstReply->flag = 0;
119 dstReply->bufferLeft = 0;
120 return -1;
121 }
122 dstReply->bufferLeft = reply->bufferLeft;
123 LOGI("done, reply data length %zu", dstReply->bufferLeft);
124 return 0;
125 }
126
ActCall(const IClientProxy * clientInst,ProxyDevAuthData * dataCtx)127 int32_t ActCall(const IClientProxy *clientInst, ProxyDevAuthData *dataCtx)
128 {
129 int32_t ret;
130 int32_t ipcRet;
131 if (clientInst == NULL) {
132 LOGE("proxy invalid");
133 return HC_ERROR;
134 }
135 LOGI("start to invoke ipc call...");
136 ipcRet = clientInst->Invoke((IClientProxy *)clientInst, DEV_AUTH_CALL_REQUEST,
137 dataCtx->data, (IOwner)(dataCtx->reply), CliInvokeRetCallback);
138 LOGI("invoke call done, ipc result(%d)", ipcRet);
139 ret = HC_ERROR;
140 ReadInt32(dataCtx->reply, &ret);
141 LOGI("service call result(%d)", ret);
142 return ((ipcRet == 0) && (ret == HC_SUCCESS)) ? HC_SUCCESS : HC_ERR_IPC_INTERNAL_FAILED;
143 }
144
SetCallbackStub(ProxyDevAuthData * dataCtx,const SvcIdentity * cbSvc)145 void SetCallbackStub(ProxyDevAuthData *dataCtx, const SvcIdentity *cbSvc)
146 {
147 (void)memset_s(&(dataCtx->cbSvc), sizeof(SvcIdentity), 0, sizeof(SvcIdentity));
148 if (cbSvc != NULL) {
149 (void)memcpy_s(&(dataCtx->cbSvc), sizeof(SvcIdentity), cbSvc, sizeof(SvcIdentity));
150 }
151 dataCtx->withCallback = true;
152 return;
153 }
154
155 #ifdef __cplusplus
156 }
157 #endif
158