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*/
58phLibNfc_SE_List_t sSecuredElementInfo[PHLIBNFC_MAXNO_OF_SE];
59
60/*
61*************************** Static Function Declaration ***********************
62*/
63
64/* Response callback for SE Set Mode*/
65STATIC
66void phLibNfc_SE_SetMode_cb(void  *context, NFCSTATUS status);
67
68
69/* SE register listner response notification */
70STATIC
71void 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*/
83NFCSTATUS 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*/
131STATIC 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 */
320NFCSTATUS 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*/
358NFCSTATUS 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
441NFCSTATUS 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*/
669STATIC 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