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* \file  phHal4Nfc_Emulation.c
18* \brief Hal4 Emulation source.
19*
20* Project: NFC-FRI 1.1
21*
22* $Date: Wed May 26 18:03:59 2010 $
23* $Author: ing07385 $
24* $Revision: 1.35 $
25* $Aliases: NFC_FRI1.1_WK1023_R35_1 $
26*
27*/
28
29/* ---------------------------Include files ------------------------------------*/
30#include <phHciNfc.h>
31#include <phHal4Nfc.h>
32#include <phHal4Nfc_Internal.h>
33#include <phOsalNfc.h>
34
35/* ------------------------------- Macros ------------------------------------*/
36
37/* Note : Macros required and used  only in this module to be declared here*/
38
39
40/* --------------------Structures and enumerations --------------------------*/
41
42
43/*Event Notification handler for emulation*/
44void phHal4Nfc_HandleEmulationEvent(
45                                    phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
46                                    void *pInfo
47                                    )
48{
49    phNfc_sNotificationInfo_t *psNotificationInfo = (phNfc_sNotificationInfo_t *)
50                                                                            pInfo;
51    phHal4Nfc_NotificationInfo_t uNotificationInfo = {NULL};
52    /*Pass on Event notification info from Hci to Upper layer*/
53    uNotificationInfo.psEventInfo = psNotificationInfo->info;
54    if(NULL != Hal4Ctxt->sUpperLayerInfo.pEventNotification)
55    {
56        Hal4Ctxt->sUpperLayerInfo.pEventNotification(
57            Hal4Ctxt->sUpperLayerInfo.EventNotificationCtxt,
58            psNotificationInfo->type,
59            uNotificationInfo,
60            NFCSTATUS_SUCCESS
61            );
62    }
63    else/*No Event notification handler registered*/
64    {
65        /*Use default handler to notify to the upper layer*/
66        if(NULL != Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler)
67        {
68            Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler(
69                Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt,
70                psNotificationInfo->type,
71                uNotificationInfo,
72                NFCSTATUS_SUCCESS
73                );
74        }
75    }
76    return;
77}
78
79/*  Switch mode from Virtual to Wired or Vice Versa for SMX.
80*/
81NFCSTATUS phHal4Nfc_Switch_SMX_Mode(
82                                    phHal_sHwReference_t      *psHwReference,
83                                    phHal_eSmartMX_Mode_t      smx_mode,
84                                    pphHal4Nfc_GenCallback_t   pSwitchModecb,
85                                    void                      *pContext
86                                    )
87{
88    NFCSTATUS CfgStatus = NFCSTATUS_PENDING;
89    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
90    static phHal_sADD_Cfg_t sSmxCfg;
91
92    /*NULL  checks*/
93    if((NULL == psHwReference) || (NULL == pSwitchModecb))
94    {
95        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
96        CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
97    }
98    /*Check Initialised state*/
99    else if((NULL == psHwReference->hal_context)
100                        || (((phHal4Nfc_Hal4Ctxt_t *)
101                                psHwReference->hal_context)->Hal4CurrentState
102                                               < eHal4StateOpenAndReady)
103                        || (((phHal4Nfc_Hal4Ctxt_t *)
104                                psHwReference->hal_context)->Hal4NextState
105                                               == eHal4StateClosed))
106    {
107        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
108        CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
109    }
110    else
111    {
112        Hal4Ctxt = psHwReference->hal_context;
113        /*Previous POLL Config has not completed or device is connected,
114          do not allow poll*/
115        if(Hal4Ctxt->Hal4NextState == eHal4StateConfiguring)
116        {
117            PHDBG_INFO("Hal4:Configuration in progress.Returning status Busy");
118            CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_BUSY);
119        }
120        else if(Hal4Ctxt->Hal4CurrentState >= eHal4StateOpenAndReady)
121        {
122            /**If config discovery has not been called prior to this ,allocate
123               ADD Context here*/
124            if (NULL == Hal4Ctxt->psADDCtxtInfo)
125            {
126                Hal4Ctxt->psADDCtxtInfo= (pphHal4Nfc_ADDCtxtInfo_t)
127                    phOsalNfc_GetMemory((uint32_t)
128                                        (sizeof(phHal4Nfc_ADDCtxtInfo_t)));
129                if(NULL != Hal4Ctxt->psADDCtxtInfo)
130                {
131                    (void)memset(Hal4Ctxt->psADDCtxtInfo,
132                                    0,sizeof(phHal4Nfc_ADDCtxtInfo_t));
133                }
134            }
135            if(NULL == Hal4Ctxt->psADDCtxtInfo)
136            {
137                phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
138                CfgStatus= PHNFCSTVAL(CID_NFC_HAL ,
139                                        NFCSTATUS_INSUFFICIENT_RESOURCES);
140            }
141            else
142            {
143                /* Switch request to Wired mode */
144                if(eSmartMx_Wired == smx_mode)
145                {
146                    if(Hal4Ctxt->Hal4CurrentState
147                                    == eHal4StateTargetConnected)
148                    {
149                        PHDBG_INFO("Hal4:In Connected state.Returning Busy");
150                        CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_BUSY);
151                    }
152                    /*It is Mandatory to register a listener before switching
153                      to wired mode*/
154                    else if(NULL ==
155                            Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)
156                    {
157                        CfgStatus = PHNFCSTVAL(CID_NFC_HAL ,
158                            NFCSTATUS_FAILED);
159                    }
160                    else
161                    {
162                        Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
163                        Hal4Ctxt->psADDCtxtInfo->smx_discovery = TRUE;
164                        sSmxCfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE;
165                        sSmxCfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = TRUE;
166                        /*Switch mode to wired*/
167                        CfgStatus = phHciNfc_Switch_SmxMode (
168                                                    Hal4Ctxt->psHciHandle,
169                                                    psHwReference,
170                                                    smx_mode,
171                                                    &sSmxCfg
172                                                    );
173                    }
174                }
175                else
176                {
177                    Hal4Ctxt->psADDCtxtInfo->smx_discovery = FALSE;
178                    /*Switch mode to virtual or off*/
179                    CfgStatus = phHciNfc_Switch_SmxMode (
180                                        Hal4Ctxt->psHciHandle,
181                                        psHwReference,
182                                        smx_mode,
183                                        &(Hal4Ctxt->psADDCtxtInfo->sADDCfg)
184                                        );
185                }
186
187                /* Change the State of the HAL only if Switch mode Returns
188                   Success*/
189                if ( NFCSTATUS_PENDING == CfgStatus )
190                {
191                    Hal4Ctxt->Hal4NextState = eHal4StateConfiguring;
192                    Hal4Ctxt->sUpperLayerInfo.pConfigCallback
193                        = pSwitchModecb;
194                }
195            }
196        }
197        else/*Return Status not initialised*/
198        {
199            phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
200            CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
201        }
202    }
203    return CfgStatus;
204}
205
206
207
208/*  Switch mode for Swp.*/
209NFCSTATUS phHal4Nfc_Switch_Swp_Mode(
210                                    phHal_sHwReference_t      *psHwReference,
211                                    phHal_eSWP_Mode_t          swp_mode,
212                                    pphHal4Nfc_GenCallback_t   pSwitchModecb,
213                                    void                      *pContext
214                                    )
215{
216    NFCSTATUS CfgStatus = NFCSTATUS_PENDING;
217    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
218    /*NULL checks*/
219    if(NULL == psHwReference
220        || NULL == pSwitchModecb
221        )
222    {
223        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
224        CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
225    }
226    /*Check Initialised state*/
227    else if((NULL == psHwReference->hal_context)
228                        || (((phHal4Nfc_Hal4Ctxt_t *)
229                                psHwReference->hal_context)->Hal4CurrentState
230                                               < eHal4StateOpenAndReady)
231                        || (((phHal4Nfc_Hal4Ctxt_t *)
232                                psHwReference->hal_context)->Hal4NextState
233                                               == eHal4StateClosed))
234    {
235        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
236        CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
237    }
238    else
239    {
240        Hal4Ctxt = psHwReference->hal_context;
241        /*Previous POLL CFG has not completed or device is connected,
242          do not allow poll*/
243        if(Hal4Ctxt->Hal4NextState == eHal4StateConfiguring)
244        {
245            PHDBG_INFO("Hal4:Configuration in progress.Returning status Busy");
246            CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_BUSY);
247        }
248        else if(Hal4Ctxt->Hal4CurrentState >= eHal4StateOpenAndReady)
249        {
250             /**If config discovery has not been called prior to this ,allocate
251               ADD Context here*/
252            if (NULL == Hal4Ctxt->psADDCtxtInfo)
253            {
254                Hal4Ctxt->psADDCtxtInfo= (pphHal4Nfc_ADDCtxtInfo_t)
255                    phOsalNfc_GetMemory((uint32_t)
256                                        (sizeof(phHal4Nfc_ADDCtxtInfo_t)));
257                if(NULL != Hal4Ctxt->psADDCtxtInfo)
258                {
259                    (void)memset(Hal4Ctxt->psADDCtxtInfo,
260                                    0,sizeof(phHal4Nfc_ADDCtxtInfo_t));
261                }
262            }
263            if(NULL == Hal4Ctxt->psADDCtxtInfo)
264            {
265                phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
266                CfgStatus= PHNFCSTVAL(CID_NFC_HAL ,
267                                        NFCSTATUS_INSUFFICIENT_RESOURCES);
268            }
269            else
270            {
271                /*Switch mode to On or off*/
272                CfgStatus = phHciNfc_Switch_SwpMode(
273                                    Hal4Ctxt->psHciHandle,
274                                    psHwReference,
275                                    swp_mode
276                                    );
277
278                /* Change the State of the HAL only if Switch mode Returns
279                   Success*/
280                if ( NFCSTATUS_PENDING == CfgStatus )
281                {
282                    Hal4Ctxt->Hal4NextState = eHal4StateConfiguring;
283                    Hal4Ctxt->sUpperLayerInfo.pConfigCallback
284                        = pSwitchModecb;
285                }
286            }
287        }
288        else/*Return Status not initialised*/
289        {
290            phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
291            CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
292        }
293    }
294    return CfgStatus;
295}
296
297#ifdef FULL_HAL4_EMULATION_ENABLE
298/*  Switch Emulation mode ON or OFF.*/
299NFCSTATUS phHal4Nfc_Host_Emulation_Mode(
300                                        phHal_sHwReference_t      *psHwReference,
301                                        phNfc_eModeType_t          eModeType,
302                                        pphHal4Nfc_GenCallback_t   pEmulationModecb,
303                                        void                      *pContext
304                                        )
305{
306    NFCSTATUS RetStatus = NFCSTATUS_PENDING;
307    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
308    /*NULL checks*/
309    if(NULL == psHwReference
310        || NULL == pEmulationModecb
311        )
312    {
313        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
314        RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
315    }
316    /*Check Initialised state*/
317    else if((NULL == psHwReference->hal_context)
318                        || (((phHal4Nfc_Hal4Ctxt_t *)
319                                psHwReference->hal_context)->Hal4CurrentState
320                                               < eHal4StateOpenAndReady)
321                        || (((phHal4Nfc_Hal4Ctxt_t *)
322                                psHwReference->hal_context)->Hal4NextState
323                                               == eHal4StateClosed))
324    {
325        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
326        RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
327    }
328    else
329    {
330
331    }
332    return NFCSTATUS_PENDING;
333}
334#endif /*FULL_HAL4_EMULATION_ENABLE*/
335