1 /******************************************************************************
2 *
3 * Copyright 2018-2020, 2023 NXP
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
19 #ifdef NXP_BOOTTIME_UPDATE
20 #include "eSEClient.h"
21
22 #include <IChannel.h>
23 #include <JcDnld.h>
24 #include <LsClient.h>
25 #include <aidl/vendor/nxp/nxpnfc_aidl/INxpNfc.h>
26 #include <dirent.h>
27 #include <ese_config.h>
28 #include <log/log.h>
29 #include <pthread.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #include <vendor/nxp/nxpnfc/2.0/INxpNfc.h>
35
36 #include "NfcAdaptation.h"
37 #include "NxpEse.h"
38 #include "hal_nxpese.h"
39 #include "phNxpEse_Apdu_Api.h"
40 #include "phNxpEse_Spm.h"
41
42 using android::sp;
43 using android::hardware::hidl_vec;
44 using android::hardware::Void;
45 using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
46 using INxpNfc = vendor::nxp::nxpnfc::V2_0::INxpNfc;
47 using INxpNfcAidl = ::aidl::vendor::nxp::nxpnfc_aidl::INxpNfc;
48
49 std::string NXPNFC_AIDL_HAL_SERVICE_NAME =
50 "vendor.nxp.nxpnfc_aidl.INxpNfc/default";
51
52 sp<INxpNfc> mHalNxpNfc = nullptr;
53 std::shared_ptr<INxpNfcAidl> mAidlHalNxpNfc = nullptr;
54
55 void seteSEClientState(uint8_t state);
56
57 IChannel_t Ch;
58 se_extns_entry se_intf;
59 void* eSEClientUpdate_ThreadHandler(void* data);
60 void* eSEClientUpdate_Thread(void* data);
61 void* eSEUpdate_SE_SeqHandler(void* data);
62 void eSEClientUpdate_Thread();
63 SESTATUS ESE_ChannelInit(IChannel* ch);
64 SESTATUS handleJcopOsDownload();
65 void* LSUpdate_Thread(void* data);
66 uint8_t performLSUpdate();
67 SESTATUS initializeEse(phNxpEse_initMode mode, SEDomainID Id);
68 ese_update_state_t ese_update = ESE_UPDATE_COMPLETED;
69 SESTATUS eSEUpdate_SeqHandler();
SE_Open()70 int16_t SE_Open() { return SESTATUS_SUCCESS; }
71
SE_Reset()72 void SE_Reset() { phNxpEse_coldReset(); }
73
SE_Transmit(uint8_t * xmitBuffer,int32_t xmitBufferSize,uint8_t * recvBuffer,int32_t recvBufferMaxSize,int32_t & recvBufferActualSize,int32_t timeoutMillisec)74 bool SE_Transmit(uint8_t* xmitBuffer, int32_t xmitBufferSize,
75 uint8_t* recvBuffer, int32_t recvBufferMaxSize,
76 int32_t& recvBufferActualSize, int32_t timeoutMillisec) {
77 phNxpEse_data cmdData;
78 phNxpEse_data rspData;
79
80 cmdData.len = xmitBufferSize;
81 cmdData.p_data = xmitBuffer;
82
83 recvBufferMaxSize++;
84 timeoutMillisec++;
85 if (phNxpEse_Transceive(&cmdData, &rspData) != ESESTATUS_SUCCESS) {
86 ALOGE("%s: Ese Transceive failed", __FUNCTION__);
87 }
88 recvBufferActualSize = rspData.len;
89
90 if (rspData.p_data != NULL && rspData.len) {
91 memcpy(&recvBuffer[0], rspData.p_data, rspData.len);
92 }
93
94 ALOGE("%s: size = 0x%x ", __FUNCTION__, recvBufferActualSize);
95 return true;
96 }
97
SE_JcopDownLoadReset()98 void SE_JcopDownLoadReset() { phNxpEse_resetJcopUpdate(); }
99
SE_Close(int16_t mHandle)100 bool SE_Close(int16_t mHandle) {
101 if (mHandle != 0)
102 return true;
103 else
104 return false;
105 }
SE_getInterfaceInfo()106 uint8_t SE_getInterfaceInfo() { return INTF_SE; }
107
108 /***************************************************************************
109 **
110 ** Function: checkEseClientUpdate
111 **
112 ** Description: Check the initial condition
113 and interface for eSE Client update for LS and JCOP download
114 **
115 ** Returns: SUCCESS of ok
116 **
117 *******************************************************************************/
checkEseClientUpdate()118 void checkEseClientUpdate() {
119 ALOGD("%s enter: ", __func__);
120 checkeSEClientRequired(ESE_INTF_SPI);
121 se_intf.isJcopUpdateRequired = getJcopUpdateRequired();
122 se_intf.isLSUpdateRequired = getLsUpdateRequired();
123 se_intf.sJcopUpdateIntferface = getJcopUpdateIntf();
124 se_intf.sLsUpdateIntferface = getLsUpdateIntf();
125 if ((se_intf.isJcopUpdateRequired && se_intf.sJcopUpdateIntferface) ||
126 (se_intf.isLSUpdateRequired && se_intf.sLsUpdateIntferface))
127 seteSEClientState(ESE_UPDATE_STARTED);
128 }
129
130 /***************************************************************************
131 **
132 ** Function: perform_eSEClientUpdate
133 **
134 ** Description: Perform LS and JCOP download during hal service init
135 **
136 ** Returns: SUCCESS / SESTATUS_FAILED
137 **
138 *******************************************************************************/
perform_eSEClientUpdate()139 SESTATUS perform_eSEClientUpdate() {
140 ALOGD("%s enter: ", __func__);
141
142 eSEClientUpdate_Thread();
143 return SESTATUS_SUCCESS;
144 }
145
ESE_ChannelInit(IChannel * ch)146 SESTATUS ESE_ChannelInit(IChannel* ch) {
147 ch->open = SE_Open;
148 ch->close = SE_Close;
149 ch->transceive = SE_Transmit;
150 ch->transceiveRaw = SE_Transmit;
151 ch->doeSE_Reset = SE_Reset;
152 ch->doeSE_JcopDownLoadReset = SE_JcopDownLoadReset;
153 ch->getInterfaceInfo = SE_getInterfaceInfo;
154 return SESTATUS_SUCCESS;
155 }
156
157 /*******************************************************************************
158 **
159 ** Function: eSEClientUpdate_Thread
160 **
161 ** Description: Perform eSE update
162 **
163 ** Returns: SUCCESS of ok
164 **
165 *******************************************************************************/
eSEClientUpdate_Thread()166 void eSEClientUpdate_Thread() {
167 pthread_t thread;
168 pthread_attr_t attr;
169 pthread_attr_init(&attr);
170 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
171 if (pthread_create(&thread, &attr, &eSEClientUpdate_ThreadHandler, NULL) !=
172 0) {
173 ALOGD("Thread creation failed");
174 } else {
175 ALOGD("Thread creation success");
176 }
177 pthread_attr_destroy(&attr);
178 }
179 /*******************************************************************************
180 **
181 ** Function: eSEClientUpdate_Thread
182 **
183 ** Description: Perform eSE update
184 **
185 ** Returns: SUCCESS of ok
186 **
187 *******************************************************************************/
eSEClientUpdate_SE_Thread()188 void eSEClientUpdate_SE_Thread() {
189 pthread_t thread;
190 pthread_attr_t attr;
191 pthread_attr_init(&attr);
192 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
193 if (pthread_create(&thread, &attr, &eSEUpdate_SE_SeqHandler, NULL) != 0) {
194 ALOGD("Thread creation failed");
195 } else {
196 ALOGD("Thread creation success");
197 }
198 pthread_attr_destroy(&attr);
199 }
200 /*******************************************************************************
201 **
202 ** Function: eSEClientUpdate_ThreadHandler
203 **
204 ** Description: Perform JCOP Download
205 **
206 ** Returns: SUCCESS of ok
207 **
208 *******************************************************************************/
eSEUpdate_SE_SeqHandler(void * data)209 void* eSEUpdate_SE_SeqHandler(void* data) {
210 (void)data;
211 ALOGD("%s Enter\n", __func__);
212 eSEUpdate_SeqHandler();
213 ALOGD("%s Exit eSEUpdate_SE_SeqHandler\n", __func__);
214 return NULL;
215 }
216 /*******************************************************************************
217 **
218 ** Function: eSEClientUpdate_ThreadHandler
219 **
220 ** Description: Perform JCOP Download
221 **
222 ** Returns: SUCCESS of ok
223 **
224 *******************************************************************************/
eSEClientUpdate_ThreadHandler(void * data)225 void* eSEClientUpdate_ThreadHandler(void* data) {
226 (void)data;
227 int cnt = 0;
228
229 ALOGD("%s Enter\n", __func__);
230 if (mAidlHalNxpNfc == nullptr) {
231 do {
232 ::ndk::SpAIBinder binder(
233 AServiceManager_checkService(NXPNFC_AIDL_HAL_SERVICE_NAME.c_str()));
234 mAidlHalNxpNfc = INxpNfcAidl::fromBinder(binder);
235 if (!mAidlHalNxpNfc) {
236 usleep(100 * 1000);
237 cnt++;
238 }
239 } while (((mAidlHalNxpNfc == nullptr) && (cnt < 3)));
240 }
241
242 if (mAidlHalNxpNfc) {
243 ALOGD("Boot Time Update not supported for mAidlHalNxpNfc.");
244 ALOGD("%s Exit\n", __func__);
245 pthread_exit(NULL);
246 return NULL;
247 } else {
248 mHalNxpNfc = INxpNfc::tryGetService();
249 if (mHalNxpNfc == nullptr) ALOGD(": Failed to retrieve the NXP NFC HAL!");
250 if (mHalNxpNfc != nullptr) {
251 ALOGD("INxpNfc::getService() returned %p (%s)", mHalNxpNfc.get(),
252 (mHalNxpNfc->isRemote() ? "remote" : "local"));
253 }
254
255 if (mHalNxpNfc != nullptr) {
256 if (!se_intf.isJcopUpdateRequired && mHalNxpNfc->isJcopUpdateRequired()) {
257 se_intf.isJcopUpdateRequired = true;
258 ALOGD(" se_intf.isJcopUpdateRequired = %d",
259 se_intf.isJcopUpdateRequired);
260 }
261 if (!se_intf.isLSUpdateRequired && mHalNxpNfc->isLsUpdateRequired()) {
262 se_intf.isLSUpdateRequired = true;
263 ALOGD("se_intf.isLSUpdateRequired = %d", se_intf.isLSUpdateRequired);
264 }
265 }
266 }
267
268 if (se_intf.isJcopUpdateRequired) {
269 if (se_intf.sJcopUpdateIntferface == ESE_INTF_NFC) {
270 seteSEClientState(ESE_JCOP_UPDATE_REQUIRED);
271 return NULL;
272 } else if (se_intf.sJcopUpdateIntferface == ESE_INTF_SPI) {
273 seteSEClientState(ESE_JCOP_UPDATE_REQUIRED);
274 }
275 }
276
277 if ((ESE_JCOP_UPDATE_REQUIRED != ese_update) &&
278 (se_intf.isLSUpdateRequired)) {
279 if (se_intf.sLsUpdateIntferface == ESE_INTF_NFC) {
280 seteSEClientState(ESE_LS_UPDATE_REQUIRED);
281 return NULL;
282 } else if (se_intf.sLsUpdateIntferface == ESE_INTF_SPI) {
283 seteSEClientState(ESE_LS_UPDATE_REQUIRED);
284 }
285 }
286
287 if ((ese_update == ESE_JCOP_UPDATE_REQUIRED) ||
288 (ese_update == ESE_LS_UPDATE_REQUIRED))
289 eSEUpdate_SeqHandler();
290
291 ALOGD("%s Exit eSEClientUpdate_Thread\n", __func__);
292 return NULL;
293 }
294
295 /*******************************************************************************
296 **
297 ** Function: handleJcopOsDownload
298 **
299 ** Description: Perform JCOP update
300 **
301 ** Returns: SUCCESS of ok
302 **
303 *******************************************************************************/
handleJcopOsDownload()304 SESTATUS handleJcopOsDownload() {
305 SESTATUS status = SESTATUS_FAILED;
306 uint8_t retstat;
307 status = initializeEse(ESE_MODE_OSU, ESE);
308 if (status == SESTATUS_SUCCESS) {
309 retstat = JCDNLD_Init(&Ch);
310 if (retstat != STATUS_SUCCESS) {
311 ALOGE("%s: JCDND initialization failed", __FUNCTION__);
312 if (phNxpEse_ResetEndPoint_Cntxt(0) != ESESTATUS_SUCCESS) {
313 ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
314 }
315 phNxpEse_close(ESESTATUS_SUCCESS);
316 return status;
317 } else {
318 retstat = JCDNLD_StartDownload();
319 if (retstat != SESTATUS_SUCCESS) {
320 ALOGE("%s: JCDNLD_StartDownload failed", __FUNCTION__);
321 }
322 }
323 JCDNLD_DeInit();
324 if (phNxpEse_ResetEndPoint_Cntxt(0) != ESESTATUS_SUCCESS) {
325 ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
326 }
327 phNxpEse_close(ESESTATUS_SUCCESS);
328 }
329 status = SESTATUS_SUCCESS;
330 return status;
331 }
332
333 /*******************************************************************************
334 **
335 ** Function: performLSUpdate
336 **
337 ** Description: Perform LS update
338 **
339 ** Returns: SUCCESS of ok
340 **
341 *******************************************************************************/
performLSUpdate()342 uint8_t performLSUpdate() {
343 const char* SEterminal = "eSEx";
344 bool ret = false;
345 char terminalID[5];
346 uint8_t status = SESTATUS_FAILED;
347 bool isSEPresent = false;
348 bool isVISOPresent = false;
349 ret = geteSETerminalId(terminalID);
350 ALOGI("performLSUpdate Terminal val = %s", terminalID);
351 if ((ret) && (strncmp(SEterminal, terminalID, 3) == 0)) {
352 isSEPresent = true;
353 }
354 ret = geteUICCTerminalId(terminalID);
355 if ((ret) && (strncmp(SEterminal, terminalID, 3) == 0)) {
356 isVISOPresent = true;
357 }
358 seteSEClientState(ESE_UPDATE_STARTED);
359 if (isSEPresent) {
360 ALOGE("%s:On eSE domain ", __FUNCTION__);
361 status = initializeEse(ESE_MODE_NORMAL, ESE);
362 ALOGE("%s:On eSE domain ", __FUNCTION__);
363 if (status == SESTATUS_SUCCESS) {
364 status = performLSDownload(&Ch);
365 if (phNxpEse_ResetEndPoint_Cntxt(ESE) != ESESTATUS_SUCCESS) {
366 ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
367 }
368 }
369 phNxpEse_close(ESESTATUS_SUCCESS);
370 }
371 if (isVISOPresent) {
372 ALOGE("%s:On eUICC domain ", __FUNCTION__);
373 status = initializeEse(ESE_MODE_NORMAL, EUICC);
374 if (status == SESTATUS_SUCCESS) {
375 status = performLSDownload(&Ch);
376 if (phNxpEse_ResetEndPoint_Cntxt(EUICC) != ESESTATUS_SUCCESS) {
377 ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
378 }
379 }
380 phNxpEse_close(ESESTATUS_SUCCESS);
381 }
382 return status;
383 }
384
385 /*******************************************************************************
386 **
387 ** Function: initializeEse
388 **
389 ** Description: Open & Initialize libese
390 **
391 ** Returns: SUCCESS of ok
392 **
393 *******************************************************************************/
initializeEse(phNxpEse_initMode mode,SEDomainID Id)394 SESTATUS initializeEse(phNxpEse_initMode mode, SEDomainID Id) {
395 uint8_t retstat;
396 SESTATUS status = SESTATUS_FAILED;
397 phNxpEse_initParams initParams;
398 memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
399
400 initParams.initMode = mode;
401 ALOGE("%s: Mode = %d", __FUNCTION__, mode);
402 retstat = phNxpEse_open(initParams);
403 if (retstat != ESESTATUS_SUCCESS) {
404 return status;
405 }
406 retstat = phNxpEse_SetEndPoint_Cntxt(Id);
407 if (retstat != ESESTATUS_SUCCESS) {
408 ALOGE("%s: Set SE EndPoint failed", __FUNCTION__);
409 }
410 retstat = phNxpEse_init(initParams);
411 if (retstat != ESESTATUS_SUCCESS) {
412 if (phNxpEse_ResetEndPoint_Cntxt(Id) != ESESTATUS_SUCCESS) {
413 ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
414 }
415 phNxpEse_close(ESESTATUS_SUCCESS);
416 return status;
417 }
418 ESE_ChannelInit(&Ch);
419 status = SESTATUS_SUCCESS;
420 return status;
421 }
422
423 /*******************************************************************************
424 **
425 ** Function: seteSEClientState
426 **
427 ** Description: Function to set the eSEUpdate state
428 **
429 ** Returns: SUCCESS of ok
430 **
431 *******************************************************************************/
seteSEClientState(uint8_t state)432 void seteSEClientState(uint8_t state) {
433 ALOGE("%s: State = %d", __FUNCTION__, state);
434 ese_update = (ese_update_state_t)state;
435 }
436
437 /*******************************************************************************
438 **
439 ** Function: sendeSEUpdateState
440 **
441 ** Description: Notify NFC HAL LS / JCOP download state
442 **
443 ** Returns: SUCCESS of ok
444 **
445 *******************************************************************************/
sendeSEUpdateState(uint8_t state)446 void sendeSEUpdateState(uint8_t state) {
447 ALOGE("%s: State = %d", __FUNCTION__, state);
448 phNxpEse_SPM_SetEseClientUpdateState(state);
449 }
450
451 /*******************************************************************************
452 **
453 ** Function: eSEUpdate_SeqHandler
454 **
455 ** Description: ESE client update handler
456 **
457 ** Returns: SUCCESS of ok
458 **
459 *******************************************************************************/
eSEUpdate_SeqHandler()460 SESTATUS eSEUpdate_SeqHandler() {
461 switch (ese_update) {
462 case ESE_UPDATE_STARTED:
463 break;
464 case ESE_JCOP_UPDATE_REQUIRED:
465 ALOGE("%s: ESE_JCOP_UPDATE_REQUIRED", __FUNCTION__);
466 if (se_intf.isJcopUpdateRequired) {
467 if (se_intf.sJcopUpdateIntferface == ESE_INTF_SPI) {
468 handleJcopOsDownload();
469 sendeSEUpdateState(ESE_JCOP_UPDATE_COMPLETED);
470 setJcopUpdateRequired(false);
471 } else if (se_intf.sJcopUpdateIntferface == ESE_INTF_NFC) {
472 return SESTATUS_SUCCESS;
473 }
474 }
475 [[fallthrough]];
476 case ESE_JCOP_UPDATE_COMPLETED:
477 ALOGE("%s: ESE_JCOP_UPDATE_COMPLETED", __FUNCTION__);
478 [[fallthrough]];
479 case ESE_LS_UPDATE_REQUIRED:
480 if (se_intf.isLSUpdateRequired) {
481 if (se_intf.sLsUpdateIntferface == ESE_INTF_SPI) {
482 performLSUpdate();
483 sendeSEUpdateState(ESE_LS_UPDATE_COMPLETED);
484 setLsUpdateRequired(false);
485 } else if (se_intf.sLsUpdateIntferface == ESE_INTF_NFC) {
486 seteSEClientState(ESE_LS_UPDATE_REQUIRED);
487 return SESTATUS_SUCCESS;
488 }
489 }
490 ALOGE("%s: ESE_LS_UPDATE_REQUIRED", __FUNCTION__);
491 [[fallthrough]];
492 case ESE_LS_UPDATE_COMPLETED:
493 ALOGE("%s: ESE_LS_UPDATE_COMPLETED", __FUNCTION__);
494 [[fallthrough]];
495 case ESE_UPDATE_COMPLETED:
496 seteSEClientState(ESE_UPDATE_COMPLETED);
497 sendeSEUpdateState(ESE_UPDATE_COMPLETED);
498 NxpEse::initSEService();
499 NxpEse::initVIrtualISOService();
500 ALOGE("%s: ESE_UPDATE_COMPLETED", __FUNCTION__);
501 break;
502 }
503 return SESTATUS_SUCCESS;
504 }
505 #endif /* NXP_BOOTTIME_UPDATE */