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