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