1 /******************************************************************************
2 *
3 * Copyright (C) 2018-2021 NXP Semiconductors
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #include "NxpEse.h"
19 #include <android-base/logging.h>
20 #include <android-base/stringprintf.h>
21 #include "phNxpEse_Api.h"
22 #ifdef NXP_BOOTTIME_UPDATE
23 #include "eSEClient.h"
24 #endif
25
26 namespace vendor {
27 namespace nxp {
28 namespace nxpese {
29 namespace V1_0 {
30 namespace implementation {
31 using android::base::StringPrintf;
32 // using android::hardware::secure_element::V1_0::implementation::SecureElement;
33 static android::sp<ISecureElementHalCallback> seCallback;
34 static android::sp<
35 ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>
36 seCallback_1_1;
37 static android::sp<ISecureElementHalCallback> virtualISOCallback;
38 static android::sp<
39 ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>
40 virtualISOCallback_1_1;
41 bool isSeHalV1_1 = false;
42 // Methods from ::vendor::nxp::nxpese::V1_0::INxpEse follow.
setSeCallBack(const android::sp<ISecureElementHalCallback> & clientCallback)43 Return<void> NxpEse::setSeCallBack(
44 const android::sp<ISecureElementHalCallback>& clientCallback) {
45 seCallback = clientCallback;
46 return Void();
47 }
48
setSeCallBack_1_1(const sp<::android::hardware::secure_element::V1_1::ISecureElementHalCallback> & clientCallback)49 Return<void> NxpEse::setSeCallBack_1_1(
50 const sp<
51 ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
52 clientCallback) {
53 seCallback_1_1 = clientCallback;
54 isSeHalV1_1 = true;
55 return Void();
56 }
57
setVirtualISOCallBack(const android::sp<ISecureElementHalCallback> & clientCallback)58 Return<void> NxpEse::setVirtualISOCallBack(
59 const android::sp<ISecureElementHalCallback>& clientCallback) {
60 virtualISOCallback = clientCallback;
61 return Void();
62 }
63
setVirtualISOCallBack_1_1(const android::sp<::android::hardware::secure_element::V1_1::ISecureElementHalCallback> & clientCallback)64 Return<void> NxpEse::setVirtualISOCallBack_1_1(
65 const android::sp<
66 ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
67 clientCallback) {
68 virtualISOCallback_1_1 = clientCallback;
69 isSeHalV1_1 = true;
70 return Void();
71 }
initSEService()72 void NxpEse::initSEService() {
73 ESESTATUS status = ESESTATUS_SUCCESS;
74 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
75 phNxpEse_initParams initParams;
76 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
77 initParams.initMode = ESE_MODE_NORMAL;
78 initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
79
80 if (!seCallback && !isSeHalV1_1) return;
81
82 if (!seCallback_1_1 && isSeHalV1_1) return;
83
84 status = phNxpEse_open(initParams);
85 if (status != ESESTATUS_SUCCESS) {
86 goto exit;
87 }
88
89 status = phNxpEse_SetEndPoint_Cntxt(0);
90 if (status != ESESTATUS_SUCCESS) {
91 goto exit1;
92 }
93 status = phNxpEse_init(initParams);
94 if (status != ESESTATUS_SUCCESS) {
95 goto exit1;
96 }
97 status = phNxpEse_ResetEndPoint_Cntxt(0);
98 if (status != ESESTATUS_SUCCESS) {
99 goto exit2;
100 }
101
102 LOG(INFO) << "ESE SPI init complete !!!";
103 exit2:
104 deInitStatus = phNxpEse_deInit();
105 exit1:
106 status = phNxpEse_close(deInitStatus);
107 exit:
108 if (status == ESESTATUS_SUCCESS) {
109 if (isSeHalV1_1)
110 seCallback_1_1->onStateChange_1_1(true, "NXP SE HAL init ok");
111 else
112 seCallback->onStateChange(true);
113 } else {
114 LOG(ERROR) << "eSE-Hal Init failed";
115 if (isSeHalV1_1)
116 seCallback_1_1->onStateChange_1_1(false, "NXP SE HAL init not ok");
117 else
118 seCallback->onStateChange(false);
119 }
120 }
121
initVIrtualISOService()122 void NxpEse::initVIrtualISOService() {
123 ESESTATUS status = ESESTATUS_SUCCESS;
124 phNxpEse_initParams initParams;
125 ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
126 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
127 initParams.initMode = ESE_MODE_NORMAL;
128 initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
129
130 if (!virtualISOCallback && !isSeHalV1_1) return;
131
132 if (!virtualISOCallback_1_1 && isSeHalV1_1) return;
133
134 status = phNxpEse_SetEndPoint_Cntxt(1);
135 if (status != ESESTATUS_SUCCESS) {
136 goto exit1;
137 }
138 status = phNxpEse_init(initParams);
139 if (status != ESESTATUS_SUCCESS) {
140 goto exit1;
141 }
142 status = phNxpEse_ResetEndPoint_Cntxt(1);
143 if (status != ESESTATUS_SUCCESS) {
144 goto exit2;
145 }
146
147 LOG(INFO) << "ESE SPI init complete !!!";
148 exit2:
149 deInitStatus = phNxpEse_deInit();
150 exit1:
151 status = phNxpEse_close(deInitStatus);
152
153 if (status == ESESTATUS_SUCCESS) {
154 if (isSeHalV1_1)
155 virtualISOCallback_1_1->onStateChange_1_1(true, "NXP SE HAL init ok");
156 else
157 virtualISOCallback->onStateChange(true);
158 } else {
159 LOG(ERROR) << "eSE-Hal Init failed";
160 if (isSeHalV1_1)
161 virtualISOCallback_1_1->onStateChange_1_1(false,
162 "NXP SE HAL init not ok");
163 else
164 virtualISOCallback->onStateChange(false);
165 }
166 }
167 #ifdef NXP_BOOTTIME_UPDATE
ioctlHandler(uint64_t ioctlType,ese_nxp_IoctlInOutData_t & inpOutData)168 Return<void> NxpEse::ioctlHandler(uint64_t ioctlType,
169 ese_nxp_IoctlInOutData_t& inpOutData) {
170 switch (ioctlType) {
171 case HAL_ESE_IOCTL_NFC_JCOP_DWNLD: {
172 // nfc_nci_IoctlInOutData_t* inpOutData =
173 // (nfc_nci_IoctlInOutData_t*)inpOutData;
174 int update_state = inpOutData.inp.data.nxpCmd.p_cmd[0];
175 if (update_state == ESE_JCOP_UPDATE_COMPLETED ||
176 update_state == ESE_LS_UPDATE_COMPLETED) {
177 seteSEClientState(update_state);
178 eSEClientUpdate_SE_Thread();
179 }
180 } break;
181 }
182 return Void();
183 }
184 #endif
185
ioctl(uint64_t ioctlType,const hidl_vec<uint8_t> & inOutData,ioctl_cb _hidl_cb)186 Return<void> NxpEse::ioctl(uint64_t ioctlType,
187 const hidl_vec<uint8_t>& inOutData,
188 ioctl_cb _hidl_cb) {
189 ese_nxp_IoctlInOutData_t inpOutData;
190 ese_nxp_IoctlInOutData_t* pInOutData =
191 (ese_nxp_IoctlInOutData_t*)&inOutData[0];
192
193 /*data from proxy->stub is copied to local data which can be updated by
194 * underlying HAL implementation since it's an inout argument*/
195 memcpy(&inpOutData, pInOutData, sizeof(ese_nxp_IoctlInOutData_t));
196 ESESTATUS status = phNxpEse_spiIoctl(ioctlType, &inpOutData);
197 #ifdef NXP_BOOTTIME_UPDATE
198 ioctlHandler(ioctlType, inpOutData);
199 #endif
200 /*copy data and additional fields indicating status of ioctl operation
201 * and context of the caller. Then invoke the corresponding proxy callback*/
202 inpOutData.out.ioctlType = ioctlType;
203 inpOutData.out.result = status;
204 #ifdef NXP_BOOTTIME_UPDATE
205 if (ioctlType == HAL_ESE_IOCTL_GET_ESE_UPDATE_STATE) {
206 inpOutData.out.data.status =
207 (getJcopUpdateRequired() | (getLsUpdateRequired() << 8));
208 }
209 #endif
210 hidl_vec<uint8_t> outputData;
211 outputData.setToExternal((uint8_t*)&inpOutData.out,
212 sizeof(ese_nxp_ExtnOutputData_t));
213 LOG(ERROR) << "GET ESE update state2 = " << inpOutData.out.data.status;
214 _hidl_cb(outputData);
215 return Void();
216 }
217
218 // Methods from ::android::hidl::base::V1_0::IBase follow.
219
220 } // namespace implementation
221 } // namespace V1_0
222 } // namespace nxpese
223 } // namespace nxp
224 } // namespace vendor
225