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 "liteipc_adapter.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 IpcIoPushInt32(ioPtr, type);
55 IpcIoPushFlatObj(ioPtr, param, paramSz);
56 if (!IpcIoAvailable(ioPtr)) {
57 LOGE("request data serialized failed");
58 return HC_ERROR;
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 IpcIoPushInt32(ioPtr, methodId);
79 IpcIoPushInt32(ioPtr, dataLen + sizeof(int32_t));
80 IpcIoPushInt32(ioPtr, dataCtx->paramCnt);
81 IpcIoPushFlatObj(ioPtr, (const uint8_t *)(dataCtx->tmpData->bufferBase + dataCtx->ioBuffOffset), dataLen);
82 if (dataCtx->withCallback) {
83 SvcIdentity badSvc = {0};
84 ShowIpcSvcInfo(&(dataCtx->cbSvc));
85 if ((sizeof(dataCtx->cbSvc) != sizeof(badSvc)) ||
86 !memcmp(&(dataCtx->cbSvc), &badSvc, sizeof(badSvc))) {
87 LOGE("ipc call with callback, but stub object invalid");
88 dataCtx->withCallback = false;
89 return HC_ERROR;
90 }
91 IpcIoPushInt32(ioPtr, PARAM_TYPE_CB_OBJECT);
92 IpcIoPushSvc(ioPtr, &(dataCtx->cbSvc));
93 LOGI("ipc call with callback, data flag %u", ioPtr->flag);
94 }
95 dataCtx->withCallback = false;
96 if (!IpcIoAvailable(ioPtr)) {
97 LOGE("request data serialized failed");
98 return HC_ERROR;
99 }
100 return HC_SUCCESS;
101 }
102
CliInvokeRetCallback(IOwner owner,int32_t code,IpcIo * reply)103 static int32_t CliInvokeRetCallback(IOwner owner, int32_t code, IpcIo *reply)
104 {
105 IpcIo *dstReply = NULL;
106 errno_t eno;
107
108 LOGI("starting...");
109 if ((reply == NULL) || (owner == NULL)) {
110 LOGE("invalid params");
111 return -1;
112 }
113 if (!IpcIoAvailable(reply)) {
114 LOGE("invalid reply data");
115 return -1;
116 }
117 dstReply = (IpcIo *)owner;
118 eno = memcpy_s(dstReply->bufferCur, dstReply->bufferLeft, reply->bufferCur, reply->bufferLeft);
119 if (eno != EOK) {
120 LOGE("data copy failed");
121 dstReply->flag = 0;
122 dstReply->bufferLeft = 0;
123 return -1;
124 }
125 dstReply->bufferLeft = reply->bufferLeft;
126 LOGI("done, reply data length %zu", dstReply->bufferLeft);
127 return 0;
128 }
129
ActCall(const IClientProxy * clientInst,ProxyDevAuthData * dataCtx)130 int32_t ActCall(const IClientProxy *clientInst, ProxyDevAuthData *dataCtx)
131 {
132 int32_t ret;
133 int32_t ipcRet;
134 if (clientInst == NULL) {
135 LOGE("proxy invalid");
136 return HC_ERROR;
137 }
138 LOGI("start to invoke ipc call...");
139 ipcRet = clientInst->Invoke((IClientProxy *)clientInst, DEV_AUTH_CALL_REQUEST,
140 dataCtx->data, (IOwner)(dataCtx->reply), CliInvokeRetCallback);
141 LOGI("invoke call done, ipc result(%d)", ipcRet);
142 ret = HC_ERROR;
143 if (IpcIoAvailable(dataCtx->reply)) {
144 ret = IpcIoPopInt32(dataCtx->reply);
145 LOGI("service call result(%d)", ret);
146 }
147 return ((ipcRet == 0) && (ret == HC_SUCCESS)) ? HC_SUCCESS : HC_ERR_IPC_INTERNAL_FAILED;
148 }
149
SetCallbackStub(ProxyDevAuthData * dataCtx,const SvcIdentity * cbSvc)150 void SetCallbackStub(ProxyDevAuthData *dataCtx, const SvcIdentity *cbSvc)
151 {
152 (void)memset_s(&(dataCtx->cbSvc), sizeof(SvcIdentity), 0, sizeof(SvcIdentity));
153 if (cbSvc != NULL) {
154 (void)memcpy_s(&(dataCtx->cbSvc), sizeof(SvcIdentity), cbSvc, sizeof(SvcIdentity));
155 }
156 dataCtx->withCallback = true;
157 return;
158 }
159
160 #ifdef __cplusplus
161 }
162 #endif
163