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