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*/
phHal4Nfc_HandleEmulationEvent(phHal4Nfc_Hal4Ctxt_t * Hal4Ctxt,void * pInfo)44 void 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 */
phHal4Nfc_Switch_SMX_Mode(phHal_sHwReference_t * psHwReference,phHal_eSmartMX_Mode_t smx_mode,pphHal4Nfc_GenCallback_t pSwitchModecb,void * pContext)81 NFCSTATUS 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.*/
phHal4Nfc_Switch_Swp_Mode(phHal_sHwReference_t * psHwReference,phHal_eSWP_Mode_t swp_mode,pphHal4Nfc_GenCallback_t pSwitchModecb,void * pContext)209 NFCSTATUS 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.*/
phHal4Nfc_Host_Emulation_Mode(phHal_sHwReference_t * psHwReference,phNfc_eModeType_t eModeType,pphHal4Nfc_GenCallback_t pEmulationModecb,void * pContext)299 NFCSTATUS 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