• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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