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_callback_stub.h"
17 #include "common_defs.h"
18 #include "device_auth_defines.h"
19 #include "hc_log.h"
20 #include "ipc_adapt.h"
21 #include "ipc_iface.h"
22 #include "liteipc_adapter.h"
23 #include "securec.h"
24
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28
DoCallBack(int32_t callbackId,uintptr_t cbHook,IpcIo * data,IpcIo * reply)29 static void DoCallBack(int32_t callbackId, uintptr_t cbHook, IpcIo *data, IpcIo *reply)
30 {
31 int32_t ret;
32 int32_t i;
33 IpcDataInfo cbDataCache[MAX_REQUEST_PARAMS_NUM] = {{0}};
34
35 if (cbHook == 0x0) {
36 LOGE("Invalid call back hook");
37 return;
38 }
39
40 (void)IpcIoPopUint32(data); /* skip flat object length information */
41 for (i = 0; i < MAX_REQUEST_PARAMS_NUM; i++) {
42 ret = DecodeIpcData((uintptr_t)(data), &(cbDataCache[i].type),
43 &(cbDataCache[i].val), &(cbDataCache[i].valSz));
44 if (ret != HC_SUCCESS) {
45 LOGE("decode failed, ret %d", ret);
46 return;
47 }
48 }
49 ProcCbHook(callbackId, cbHook, cbDataCache, MAX_REQUEST_PARAMS_NUM, (uintptr_t)(reply));
50 return;
51 }
52
CbStubOnRemoteReply(void * ipcMsg,IpcIo * reply)53 static int32_t CbStubOnRemoteReply(void *ipcMsg, IpcIo *reply)
54 {
55 uint32_t flag = 0;
56 int32_t ret = 0;
57 IpcIo replyErr;
58 uint8_t replyBuff[16] = {0}; /* length of reply buffer - 16 */
59
60 /* flag: ipc mode is blocking or non blocking. */
61 GetFlag(ipcMsg, &flag);
62 if (flag != LITEIPC_FLAG_DEFAULT) {
63 /* Ipc mode is non blocking. */
64 LOGI("callback - async call(%u)", flag);
65 /* If the system is based on liteipc, the ipcMsg memory needs to be cleaned manually. */
66 FreeBuffer(NULL, ipcMsg);
67 return 0;
68 }
69 /* Ipc mode is blocking. */
70 if (!IpcIoAvailable(reply)) {
71 IpcIoInit(&replyErr, replyBuff, sizeof(replyBuff), 0);
72 IpcIoPushInt32(&replyErr, HC_ERR_IPC_INTERNAL_FAILED);
73 LOGI("callback - SendReply error code(%d)", HC_ERR_IPC_INTERNAL_FAILED);
74 ret = SendReply(NULL, ipcMsg, &replyErr);
75 } else {
76 LOGI("callback - SendReply done");
77 ret = SendReply(NULL, ipcMsg, reply);
78 }
79 return ret;
80 }
81
CbStubOnRemoteRequest(const IpcContext * ctx,void * ipcMsg,IpcIo * data,void * arg)82 int32_t CbStubOnRemoteRequest(const IpcContext *ctx, void *ipcMsg, IpcIo *data, void *arg)
83 {
84 uint32_t code = 0;
85 int32_t callbackId;
86 uintptr_t cbHook = 0x0;
87 IpcIo reply;
88 uint8_t replyBuff[1024] = {0}; /* length of reply buffer - 1024 */
89 int32_t ret = 0;
90 (void)ctx;
91 (void)arg;
92
93 LOGI("enter invoking callback...");
94 if ((ipcMsg == NULL) || (data == NULL)) {
95 LOGE("invalid param");
96 return -1;
97 }
98
99 GetCode(ipcMsg, &code);
100 LOGI("receive ipc transact code(%u)", code);
101 IpcIoInit(&reply, replyBuff, sizeof(replyBuff), 0);
102 switch (code) {
103 case DEV_AUTH_CALLBACK_REQUEST:
104 callbackId = IpcIoPopInt32(data);
105 cbHook = IpcIoPopUintptr(data);
106 DoCallBack(callbackId, cbHook, data, &reply);
107 break;
108 default:
109 LOGE("Invoke callback cmd code(%u) error", code);
110 break;
111 }
112 ret = CbStubOnRemoteReply(ipcMsg, &reply);
113 LOGI("Invoke callback done, result(%d)", ret);
114 return ret;
115 }
116
117 #ifdef __cplusplus
118 }
119 #endif
120