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