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