1 /*
2  * Copyright (C) 2010 NXP Semiconductors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*!
18  * \file phLibNfc_SE.c
19 
20  * Project: NFC FRI / HALDL
21  *
22  * $Date: Thu Apr 22 13:59:50 2010 $
23  * $Author: ing07385 $
24  * $Revision: 1.65 $
25  * $Aliases: NFC_FRI1.1_WK1014_SDK,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1019_SDK,NFC_FRI1.1_WK1024_SDK $
26  *
27  */
28 
29 /*
30 ************************* Header Files ***************************************
31 */
32 
33 #include <phNfcStatus.h>
34 #include <phLibNfc.h>
35 #include <phHal4Nfc.h>
36 #include <phOsalNfc.h>
37 #include <phLibNfc_Internal.h>
38 #include <phLibNfc_SE.h>
39 #include <phLibNfc_ndef_raw.h>
40 #include <phLibNfc_initiator.h>
41 #include <phLibNfc_discovery.h>
42 
43 /*
44 *************************** Macro's  ****************************************
45 */
46 
47 #ifndef STATIC_DISABLE
48 #define STATIC static
49 #else
50 #define STATIC
51 #endif
52 
53 /*
54 *************************** Global Variables **********************************
55 */
56 
57 /*This Structure  contains the Secure Element information*/
58 phLibNfc_SE_List_t sSecuredElementInfo[PHLIBNFC_MAXNO_OF_SE];
59 
60 /*
61 *************************** Static Function Declaration ***********************
62 */
63 
64 /* Response callback for SE Set Mode*/
65 STATIC
66 void phLibNfc_SE_SetMode_cb(void  *context, NFCSTATUS status);
67 
68 
69 /* SE register listner response notification */
70 STATIC
71 void phLibNfc_SeNotification(void                     *context,
72                         phHal_eNotificationType_t     type,
73                         phHal4Nfc_NotificationInfo_t  info,
74                         NFCSTATUS                     status
75                         );
76 /*
77 *************************** Function Definitions ******************************
78 */
79 
80 /**
81 * Registers notification handler to handle secure element specific events
82 */
phLibNfc_SE_NtfRegister(pphLibNfc_SE_NotificationCb_t pSE_NotificationCb,void * pContext)83 NFCSTATUS phLibNfc_SE_NtfRegister   (
84                             pphLibNfc_SE_NotificationCb_t  pSE_NotificationCb,
85                             void                            *pContext
86                             )
87 {
88      NFCSTATUS         Status = NFCSTATUS_SUCCESS;
89      pphLibNfc_LibContext_t pLibContext=(pphLibNfc_LibContext_t)gpphLibContext;
90 
91      if((NULL == gpphLibContext) ||
92          (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
93      {
94          Status = NFCSTATUS_NOT_INITIALISED;
95      }
96      else if((pSE_NotificationCb == NULL)
97          ||(NULL == pContext))
98      {
99          /*parameters sent by upper layer are not valid*/
100          Status = NFCSTATUS_INVALID_PARAMETER;
101      }
102      else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
103      {
104          Status = NFCSTATUS_SHUTDOWN;
105      }
106      else
107      {
108          /*Register SE notification with lower layer.
109          Any activity on Smx or UICC will be notified */
110          Status = phHal4Nfc_RegisterNotification(
111                                             pLibContext->psHwReference,
112                                             eRegisterSecureElement,
113                                             phLibNfc_SeNotification,
114                                             (void*)pLibContext);
115         if(Status == NFCSTATUS_SUCCESS)
116         {
117             pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb = pSE_NotificationCb;
118             pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt=pContext;
119         }
120         else
121         {
122             /* Registration failed */
123             Status = NFCSTATUS_FAILED;
124         }
125      }
126      return Status;
127 }
128 /**
129 * SE Notification events are notified with this callback
130 */
phLibNfc_SeNotification(void * context,phHal_eNotificationType_t type,phHal4Nfc_NotificationInfo_t info,NFCSTATUS status)131 STATIC void phLibNfc_SeNotification(void  *context,
132                                     phHal_eNotificationType_t    type,
133                                     phHal4Nfc_NotificationInfo_t  info,
134                                     NFCSTATUS                   status)
135 {
136     pphLibNfc_LibContext_t pLibContext=(pphLibNfc_LibContext_t)context;
137     phHal_sEventInfo_t  *pEvtInfo = NULL;
138     phLibNfc_uSeEvtInfo_t Se_Trans_Info={{{0,0},{0,0}}};
139     phLibNfc_SE_List_t  *pSeInfo=NULL;
140 
141     if(pLibContext != gpphLibContext)
142     {
143         /*wrong context returned*/
144         phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
145     }
146     else
147     {
148         if((status == NFCSTATUS_SUCCESS) && (type == NFC_EVENT_NOTIFICATION))
149         {
150             pEvtInfo = info.psEventInfo;
151             status = NFCSTATUS_SUCCESS;
152             if((pEvtInfo->eventSource == phHal_ePICC_DevType )
153                 && (pEvtInfo->eventHost == phHal_eHostController) )
154             {
155                 sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_Type = phLibNfc_SE_Type_SmartMX;
156                 /* Smartx Mx is Activated */
157                 pSeInfo = &sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX];
158             }
159             if(pEvtInfo->eventHost == phHal_eUICCHost)
160             {
161                 /* UICC is Activate */
162                 sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_Type = phLibNfc_SE_Type_UICC;
163                 pSeInfo = &sSecuredElementInfo[LIBNFC_SE_UICC_INDEX];
164             }
165             else
166             {
167                 /*presently Smx event source is not supported */
168             }
169             if(pSeInfo!=NULL)
170             {
171                 switch(pEvtInfo->eventType)
172                 {
173                     case NFC_EVT_TRANSACTION:
174                     {
175                         if((pEvtInfo->eventInfo.aid.length != 0) && ((pEvtInfo->eventInfo.aid.length <= 16)))  // PLG
176                         {
177                             /*copy the Application id on which transaction happened*/
178 							Se_Trans_Info.UiccEvtInfo.aid.buffer =pEvtInfo->eventInfo.aid.buffer;
179 							Se_Trans_Info.UiccEvtInfo.aid.length =pEvtInfo->eventInfo.aid.length;
180                         }
181 						else
182 						{
183 							// PLG patch
184                             Se_Trans_Info.UiccEvtInfo.aid.buffer = NULL;
185 							Se_Trans_Info.UiccEvtInfo.aid.length = 0;
186 						}
187 						if((pEvtInfo->eventHost == phHal_eUICCHost)
188                            && (info.psEventInfo->eventInfo.uicc_info.param.length
189                                 != 0))
190                         {
191                             /*copy the parameters info on which transaction happened*/
192 							Se_Trans_Info.UiccEvtInfo.param.buffer =
193 										info.psEventInfo->eventInfo.uicc_info.param.buffer;
194 							Se_Trans_Info.UiccEvtInfo.param.length =
195 										info.psEventInfo->eventInfo.uicc_info.param.length;
196                         }
197                             /*Notify to upper layer that transaction had happened on the
198                             one of the application stored in UICC or Smx*/
199                         (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
200                             pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
201                             phLibNfc_eSE_EvtStartTransaction,
202                             pSeInfo->hSecureElement,
203                             &Se_Trans_Info,
204                             status);
205                         break;
206                     }
207 
208                     case NFC_EVT_APDU_RECEIVED:
209                     {
210                         if ((pEvtInfo->eventInfo.aid.length != 0) && ((pEvtInfo->eventInfo.aid.length <= 16)))
211                         {
212                             /* Copy received APDU to aid buffer. */
213                             Se_Trans_Info.UiccEvtInfo.aid.buffer = pEvtInfo->eventInfo.aid.buffer;
214                             Se_Trans_Info.UiccEvtInfo.aid.length = pEvtInfo->eventInfo.aid.length;
215                         }
216 
217                         (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
218                             pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
219                             phLibNfc_eSE_EvtApduReceived,
220                             pSeInfo->hSecureElement,
221                             &Se_Trans_Info,
222                             status);
223                         break;
224                     }
225 
226                     case NFC_EVT_MIFARE_ACCESS:
227                     {
228                         /* copy the Block MIFARE accessed */
229                         Se_Trans_Info.UiccEvtInfo.aid.buffer = pEvtInfo->eventInfo.aid.buffer;
230                         Se_Trans_Info.UiccEvtInfo.aid.length = pEvtInfo->eventInfo.aid.length;
231 
232                         (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
233                             pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
234                             phLibNfc_eSE_EvtMifareAccess,
235                             pSeInfo->hSecureElement,
236                             &Se_Trans_Info,
237                             status);
238                         break;
239                     }
240 
241                     case NFC_EVT_EMV_CARD_REMOVAL:
242                     {
243                         (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
244                             pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
245                             phLibNfc_eSE_EvtCardRemoval,
246                             pSeInfo->hSecureElement,
247                             &Se_Trans_Info,
248                             status);
249                         break;
250                     }
251 
252                     case NFC_EVT_END_OF_TRANSACTION:
253                     {
254                         (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
255                             pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
256                             phLibNfc_eSE_EvtEndTransaction,
257                             pSeInfo->hSecureElement,
258                             &Se_Trans_Info,
259                             status);
260                         break;
261                     }
262                     case NFC_EVT_CONNECTIVITY:
263                     {
264                         (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
265                             pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
266                             phLibNfc_eSE_EvtConnectivity,
267                             pSeInfo->hSecureElement,
268                             &Se_Trans_Info,
269                             status);
270                         break;
271                     }
272                     case NFC_EVT_START_OF_TRANSACTION:
273                     {
274                         (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
275                             pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
276                             phLibNfc_eSE_EvtTypeTransaction,
277                             pSeInfo->hSecureElement,
278                             &Se_Trans_Info,
279                             status);
280                         break;
281                     }
282                     case NFC_EVT_FIELD_ON:
283                     {
284                         (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
285                             pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
286                             phLibNfc_eSE_EvtFieldOn,
287                             pSeInfo->hSecureElement,
288                             &Se_Trans_Info,
289                             status);
290                         break;
291                     }
292                     case NFC_EVT_FIELD_OFF:
293                     {
294                         (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
295                              pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
296                              phLibNfc_eSE_EvtFieldOff,
297                              pSeInfo->hSecureElement,
298                              &Se_Trans_Info,
299                              status);
300                         break;
301                     }
302                     default:
303                     {
304                         break;
305                     }
306                 }
307             }
308             else
309             {
310 
311             }
312          }
313     }
314   return;
315 }
316 
317 /**
318  * Unregister the Secured Element Notification.
319  */
phLibNfc_SE_NtfUnregister(void)320 NFCSTATUS phLibNfc_SE_NtfUnregister(void)
321 {
322     NFCSTATUS Status = NFCSTATUS_SUCCESS;
323     pphLibNfc_LibContext_t pLibContext=(pphLibNfc_LibContext_t)gpphLibContext;
324 
325     if((NULL == gpphLibContext) ||
326         (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
327     {
328         /*Lib Nfc is not initialized*/
329         Status = NFCSTATUS_NOT_INITIALISED;
330     }
331     else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
332     {
333         Status = NFCSTATUS_SHUTDOWN;
334     }
335     else
336     {
337         /*Unregister SE event notification with lower layer.
338         even some transaction happens on UICC or Smx will not
339         be notified afterworlds */
340         Status = phHal4Nfc_UnregisterNotification(
341                                                 pLibContext->psHwReference,
342                                                 eRegisterSecureElement,
343                                                 pLibContext);
344         if(Status != NFCSTATUS_SUCCESS)
345         {
346             /*Unregister failed*/
347             Status=NFCSTATUS_FAILED;
348         }
349         pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb=NULL;
350         pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt=NULL;
351     }
352     return Status;
353 }
354 
355 /**
356 * Get list of available Secure Elements
357 */
phLibNfc_SE_GetSecureElementList(phLibNfc_SE_List_t * pSE_List,uint8_t * uSE_count)358 NFCSTATUS phLibNfc_SE_GetSecureElementList(
359                         phLibNfc_SE_List_t*     pSE_List,
360                         uint8_t*                uSE_count
361                         )
362 {
363     NFCSTATUS Status = NFCSTATUS_SUCCESS;
364 	uint8_t    uNo_Of_SE = 0;
365 
366     if((NULL == gpphLibContext) ||
367         (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
368     {
369         Status = NFCSTATUS_NOT_INITIALISED;
370     }
371     else if((NULL ==pSE_List) || (NULL ==uSE_count))
372     {
373         Status = NFCSTATUS_INVALID_PARAMETER;
374     }
375     else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
376     {
377         Status = NFCSTATUS_SHUTDOWN;
378     }
379     else
380     {
381         /*Check for which type of Secure Element is available*/
382         if(gpphLibContext->psHwReference->uicc_connected==TRUE)
383         {
384             /* Populate the UICC type */
385             sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_Type = phLibNfc_SE_Type_UICC;
386 
387             /* Populate the UICC handle */
388             sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement =(phLibNfc_Handle)
389                             (LIBNFC_SE_UICC_INDEX + LIBNFC_SE_BASE_HANDLE);
390 
391 #ifdef NXP_HAL_ENABLE_SMX
392 
393             pSE_List[LIBNFC_SE_UICC_INDEX].eSE_Type =
394 				sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_Type;
395             pSE_List[LIBNFC_SE_UICC_INDEX].hSecureElement = (phLibNfc_Handle)
396                             (LIBNFC_SE_UICC_INDEX + LIBNFC_SE_BASE_HANDLE);
397             pSE_List[LIBNFC_SE_UICC_INDEX].eSE_CurrentState =
398 				sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_CurrentState;
399 #else
400 			pSE_List->eSE_Type =
401 				sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_Type;
402             pSE_List->hSecureElement = (phLibNfc_Handle)
403                             (LIBNFC_SE_UICC_INDEX + LIBNFC_SE_BASE_HANDLE);
404             pSE_List->eSE_CurrentState =
405 				sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_CurrentState;
406 #endif
407             /* update the No of SE retrieved */
408 			uNo_Of_SE ++;
409 
410         }
411         if (gpphLibContext->psHwReference->smx_connected ==TRUE)
412         {
413             /* if the Smx is also connected to the PN544 */
414             /* Populate the SMX type */
415             sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_Type = phLibNfc_SE_Type_SmartMX;
416 
417             /* Populate the SMX handle */
418             sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement =(phLibNfc_Handle)
419                             (LIBNFC_SE_SMARTMX_INDEX + LIBNFC_SE_BASE_HANDLE);
420             pSE_List[LIBNFC_SE_SMARTMX_INDEX].eSE_Type =
421 				sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_Type;
422             pSE_List[LIBNFC_SE_SMARTMX_INDEX].hSecureElement = (phLibNfc_Handle)
423                             (LIBNFC_SE_SMARTMX_INDEX + LIBNFC_SE_BASE_HANDLE);
424             pSE_List[LIBNFC_SE_SMARTMX_INDEX].eSE_CurrentState =
425 				sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_CurrentState;
426 
427             /* update the No of SE retrieved */
428 			uNo_Of_SE ++;
429 
430         }
431 		*uSE_count = uNo_Of_SE;
432     }
433     return Status;
434 }
435 
436 /**
437 * Sets secure element mode.
438 * This  function configures SE to specific mode based on activation mode type
439 */
440 
phLibNfc_SE_SetMode(phLibNfc_Handle hSE_Handle,phLibNfc_eSE_ActivationMode eActivation_mode,pphLibNfc_SE_SetModeRspCb_t pSE_SetMode_Rsp_cb,void * pContext)441 NFCSTATUS phLibNfc_SE_SetMode ( phLibNfc_Handle             hSE_Handle,
442                                phLibNfc_eSE_ActivationMode  eActivation_mode,
443                                pphLibNfc_SE_SetModeRspCb_t  pSE_SetMode_Rsp_cb,
444                                void *                       pContext
445                                )
446 {
447     NFCSTATUS Status = NFCSTATUS_SUCCESS;
448     phHal_eEmulationType_t  eEmulationType = NFC_SMARTMX_EMULATION;
449     pphLibNfc_LibContext_t pLibContext=(pphLibNfc_LibContext_t)gpphLibContext;
450 
451     if((NULL == gpphLibContext) ||
452         (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
453     {
454         Status = NFCSTATUS_NOT_INITIALISED;
455     }
456 	else if((pSE_SetMode_Rsp_cb ==NULL)
457         ||(NULL == pContext)||(NULL==(void *)hSE_Handle))
458     {
459         Status=NFCSTATUS_INVALID_PARAMETER;
460     }
461 	else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
462     {
463         Status = NFCSTATUS_SHUTDOWN;
464     }
465     else if((pLibContext->status.GenCb_pending_status == TRUE)
466           ||(NULL!=pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCb))
467     {
468         /*previous callback is pending still*/
469         Status =NFCSTATUS_REJECTED;
470     }
471     else
472     {
473         phLibNfc_eSE_ActivationMode originalMode = pLibContext->sSeContext.eActivatedMode;
474         switch(eActivation_mode)
475         {
476             case phLibNfc_SE_ActModeVirtual:
477             {
478                 if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement)
479                 {
480                     eEmulationType = NFC_UICC_EMULATION;
481                     /*Enable the UICC -External reader can see it*/
482                     pLibContext->sCardEmulCfg.config.uiccEmuCfg.enableUicc = TRUE;
483                 }
484                 else if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement)
485                 {
486                     eEmulationType = NFC_SMARTMX_EMULATION;
487                     /*Enable the SMX -External reader can see it*/
488                     pLibContext->sCardEmulCfg.config.smartMxCfg.enableEmulation = TRUE;
489                 }
490                 else
491                 {
492                     Status=NFCSTATUS_INVALID_HANDLE;
493                 }
494                 if(Status==NFCSTATUS_SUCCESS)
495                 {
496                     if(pLibContext->sSeContext.eActivatedMode != phLibNfc_SE_ActModeWired)
497                     {
498                         pLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeVirtual;
499                     }
500                     pLibContext->sCardEmulCfg.emuType = eEmulationType;
501                     Status = phHal4Nfc_ConfigParameters(
502                                             pLibContext->psHwReference,
503                                             NFC_EMULATION_CONFIG,
504                                             (phHal_uConfig_t*)&pLibContext->sCardEmulCfg,
505                                             phLibNfc_SE_SetMode_cb,
506                                             pLibContext);
507                 }
508             }
509             break;
510             case phLibNfc_SE_ActModeVirtualVolatile:
511             {
512                 if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement)
513                 {
514                     eEmulationType = NFC_SMARTMX_EMULATION;
515                     /*Enable the SMX -External reader can see it*/
516                     pLibContext->sCardEmulCfg.config.smartMxCfg.enableEmulation = TRUE;
517                     pLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeVirtualVolatile;
518 
519                     Status = phHal4Nfc_Switch_SMX_Mode(
520                                         pLibContext->psHwReference,
521                                         eSmartMx_Virtual,
522                                         phLibNfc_SE_SetMode_cb,
523                                         pLibContext
524                                         );
525                 }
526                 else if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement)
527                 {
528                     eEmulationType = NFC_UICC_EMULATION;
529                     /*Enable the UICC -External reader can see it*/
530                     pLibContext->sCardEmulCfg.config.uiccEmuCfg.enableUicc = TRUE;
531                     pLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeVirtualVolatile;
532 
533                     Status = phHal4Nfc_Switch_Swp_Mode(
534                                         pLibContext->psHwReference,
535                                         eSWP_Switch_On,
536                                         phLibNfc_SE_SetMode_cb,
537                                         pLibContext
538                                         );
539                 }
540                 else
541                 {
542                     Status = NFCSTATUS_INVALID_HANDLE;
543                 }
544             }
545             break;
546             case phLibNfc_SE_ActModeDefault:
547             {
548                 if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement)
549                 {
550                     Status = phHal4Nfc_Switch_SMX_Mode(
551                                         pLibContext->psHwReference,
552                                         eSmartMx_Default,
553                                         phLibNfc_SE_SetMode_cb,
554                                         pLibContext
555                                         );
556                 }
557                 else if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement)
558                 {
559                     Status = phHal4Nfc_Switch_Swp_Mode(
560                                         pLibContext->psHwReference,
561                                         eSWP_Switch_Default,
562                                         phLibNfc_SE_SetMode_cb,
563                                         pLibContext
564                                         );
565                 }
566                 else
567                 {
568                     Status = NFCSTATUS_INVALID_HANDLE;
569                 }
570             }
571             break;
572 
573             case phLibNfc_SE_ActModeWired:
574             {
575                 if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement)
576                 {
577                     if(pLibContext->CBInfo.pClientNtfRegRespCB!=NULL)
578                     {
579                         /*Disable the SMX -External reader can't see it anymore*/
580                         pLibContext->sCardEmulCfg.config.smartMxCfg.enableEmulation = FALSE;
581                         pLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeWired;
582 
583                         Status = phHal4Nfc_Switch_SMX_Mode(
584                                             pLibContext->psHwReference,
585                                             eSmartMx_Wired,
586                                             phLibNfc_SE_SetMode_cb,
587                                             pLibContext
588                                             );
589                     }
590                 }
591                 else if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement)
592                 {
593                     /*This mode is not applicable to UICC*/
594                     Status = NFCSTATUS_REJECTED;
595                 }
596                 else
597                 {
598                     Status = NFCSTATUS_INVALID_HANDLE;
599                 }
600             }
601             break;
602 
603             case phLibNfc_SE_ActModeOff:
604             {
605                 /*UICC emulation deactivate*/
606                 if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement)
607                 {
608                     eEmulationType = NFC_UICC_EMULATION;
609                     /*Disable the UICC -External reader can't see it anymore*/
610                     pLibContext->sCardEmulCfg.config.uiccEmuCfg.enableUicc = FALSE;
611 
612                 }
613                 else if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement)
614                 {
615                     eEmulationType = NFC_SMARTMX_EMULATION;
616                     /*Disable the SMX -External reader can't see it anymore*/
617                     pLibContext->sCardEmulCfg.config.smartMxCfg.enableEmulation=FALSE;
618 
619                 }
620                 else
621                 {
622                     Status = NFCSTATUS_INVALID_HANDLE;
623                 }
624                 if(Status==NFCSTATUS_SUCCESS)
625                 {
626                     pLibContext->sCardEmulCfg.emuType = eEmulationType;
627 
628                     if(pLibContext->sSeContext.eActivatedMode != phLibNfc_SE_ActModeWired)
629                     {
630                          pLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeOff;
631                     }
632 
633                     Status = phHal4Nfc_ConfigParameters(pLibContext->psHwReference,
634                                                             NFC_EMULATION_CONFIG,
635                                                             (phHal_uConfig_t*)&pLibContext->sCardEmulCfg,
636                                                             phLibNfc_SE_SetMode_cb,
637                                                             pLibContext);
638                 }
639             }
640             break;
641             default:
642                 Status=NFCSTATUS_INVALID_PARAMETER;
643                 break;
644 
645         }/*End of eActivation_mode switch */
646         if(Status==NFCSTATUS_PENDING)
647         {
648             pLibContext->sSeContext.hSetemp=hSE_Handle;
649             pLibContext->status.GenCb_pending_status = TRUE;
650             pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCb = pSE_SetMode_Rsp_cb;
651             pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCtxt=pContext;
652         }
653         else if(Status == NFCSTATUS_INVALID_HANDLE)
654         {
655             Status= Status;
656         }
657         else
658         {
659             // Restore original mode
660             pLibContext->sSeContext.eActivatedMode = originalMode;
661             Status = NFCSTATUS_FAILED;
662         }
663     }
664     return Status;
665 }
666 /**
667 * Callback for Se Set mode
668 */
phLibNfc_SE_SetMode_cb(void * context,NFCSTATUS status)669 STATIC void phLibNfc_SE_SetMode_cb(void  *context, NFCSTATUS status)
670 {
671     /* Note that we don't use the passed in context here;
672      * the reason is that there are race-conditions around
673      * the place where this context is stored (mostly in combination
674      * with LLCP), and we may actually get the wrong context.
675      * Since this callback always uses the global context
676      * we don't need the passed in context anyway.
677      */
678     pphLibNfc_LibContext_t pLibContext=gpphLibContext;
679     pphLibNfc_SE_SetModeRspCb_t  pUpperLayerCb=NULL;
680     void                         *pUpperContext=NULL;
681     phLibNfc_Handle              hSeHandle=0;
682     uint8_t                      TempState=FALSE;
683 
684     if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
685     {
686         /*If shutdown is called in between allow shutdown to happen*/
687         phLibNfc_Pending_Shutdown();
688         status = NFCSTATUS_SHUTDOWN;
689     }
690     else
691     {
692         if(status == NFCSTATUS_SUCCESS)
693         {
694             hSeHandle = pLibContext->sSeContext.hSetemp;
695 
696             if(hSeHandle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement)
697             {
698                 if(TRUE==pLibContext->sCardEmulCfg.config.uiccEmuCfg.enableUicc)
699                 {
700                     /*If  Activation mode was virtual allow external reader to see it*/
701                     pLibContext->sSeContext.uUiccActivate = TRUE;
702                     sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_CurrentState = phLibNfc_SE_Active;
703                 }
704                 else
705                 {
706                     /*If  Activation mode was wired don't allow external reader to see it*/
707                     pLibContext->sSeContext.uUiccActivate = FALSE;
708                     sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].eSE_CurrentState =
709                                                                 phLibNfc_SE_Inactive;
710                 }
711                 status = NFCSTATUS_SUCCESS;
712                 TempState = pLibContext->sSeContext.uUiccActivate;
713             }
714             else if (hSeHandle==sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement)
715             {
716                 if(TRUE==pLibContext->sCardEmulCfg.config.smartMxCfg.enableEmulation)
717                 {
718                     /*If  Activation mode was virtual allow external reader to see it*/
719                     pLibContext->sSeContext.uSmxActivate = TRUE;
720                     sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_CurrentState =
721                                                                     phLibNfc_SE_Active;
722                 }
723                 else
724                 {
725                     /*If  Activation mode was wired don't allow external reader to see it*/
726                     pLibContext->sSeContext.uSmxActivate = FALSE;
727                     sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].eSE_CurrentState=
728                                                                     phLibNfc_SE_Inactive;
729                 }
730                 status = NFCSTATUS_SUCCESS;
731                 TempState = pLibContext->sSeContext.uSmxActivate;
732             }
733             else
734             {
735                 status = NFCSTATUS_FAILED;
736             }
737         }
738         else
739         {
740             status = NFCSTATUS_FAILED;
741         }
742         pLibContext->status.GenCb_pending_status = FALSE;
743     }
744 
745     pUpperLayerCb = pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCb;
746     pUpperContext = pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCtxt;
747     pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCb = NULL;
748     pLibContext->sSeContext.sSeCallabackInfo.pSEsetModeCtxt = NULL;
749 	PHNFC_UNUSED_VARIABLE(TempState);
750     /* Call the upper layer cb */
751     if(pUpperLayerCb!= NULL )
752     {
753         (*pUpperLayerCb)(pUpperContext,
754                         hSeHandle,
755 						status);
756     }
757     return;
758 }
759 
760 
761 
762