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