phHal4Nfc_ADD.c revision 97ffda519d438861f34d6de511f9025656470af6
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_ADD.c
18 * \brief Hal4Nfc_ADD source.
19 *
20 * Project: NFC-FRI 1.1
21 *
22 * $Date: Mon May 31 11:43:42 2010 $
23 * $Author: ing07385 $
24 * $Revision: 1.151 $
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#define     NFCIP_ACTIVE_SHIFT      0x03U
37#define     NXP_UID                 0x04U
38#define     NXP_MIN_UID_LEN         0x07U
39/* --------------------Structures and enumerations --------------------------*/
40
41NFCSTATUS phHal4Nfc_ConfigParameters(
42                        phHal_sHwReference_t     *psHwReference,
43                        phHal_eConfigType_t       CfgType,
44                        phHal_uConfig_t          *puConfig,
45                        pphHal4Nfc_GenCallback_t  pConfigCallback,
46                        void                     *pContext
47                        )
48{
49    NFCSTATUS CfgStatus = NFCSTATUS_SUCCESS;
50    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
51    /*NULL checks*/
52    if(NULL == psHwReference
53        || NULL == pConfigCallback
54        || NULL == puConfig
55        )
56    {
57        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
58        CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
59    }
60    /*Check if initialised*/
61    else if((NULL == psHwReference->hal_context)
62                        || (((phHal4Nfc_Hal4Ctxt_t *)
63                                psHwReference->hal_context)->Hal4CurrentState
64                                               < eHal4StateOpenAndReady)
65                        || (((phHal4Nfc_Hal4Ctxt_t *)
66                                psHwReference->hal_context)->Hal4NextState
67                                               == eHal4StateClosed))
68    {
69        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
70        CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
71    }
72    else
73    {
74        Hal4Ctxt = psHwReference->hal_context;
75        /*If previous Configuration request has not completed,do not allow new
76          configuration*/
77        if(Hal4Ctxt->Hal4NextState == eHal4StateConfiguring)
78        {
79            PHDBG_INFO("Hal4:PollCfg in progress.Returning status Busy");
80            CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_BUSY);
81        }
82        else if(Hal4Ctxt->Hal4CurrentState >= eHal4StateOpenAndReady)
83        {
84            /*Allocate ADD context*/
85            if (NULL == Hal4Ctxt->psADDCtxtInfo)
86            {
87                Hal4Ctxt->psADDCtxtInfo= (pphHal4Nfc_ADDCtxtInfo_t)
88                    phOsalNfc_GetMemory((uint32_t)
89                    (sizeof(phHal4Nfc_ADDCtxtInfo_t)));
90                if(NULL != Hal4Ctxt->psADDCtxtInfo)
91                {
92                    (void)memset(Hal4Ctxt->psADDCtxtInfo,0,
93                        sizeof(phHal4Nfc_ADDCtxtInfo_t)
94                        );
95                }
96            }
97            if(NULL == Hal4Ctxt->psADDCtxtInfo)
98            {
99                phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
100                CfgStatus= PHNFCSTVAL(CID_NFC_HAL ,
101                    NFCSTATUS_INSUFFICIENT_RESOURCES);
102            }
103            else
104            {
105                /*Register Upper layer context*/
106#ifdef LLCP_DISCON_CHANGES
107                Hal4Ctxt->sUpperLayerInfo.psUpperLayerCfgDiscCtxt = pContext;
108#else /* #ifdef LLCP_DISCON_CHANGES */
109                Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
110#endif /* #ifdef LLCP_DISCON_CHANGES */
111                switch(CfgType)
112                {
113                /*NFC_EMULATION_CONFIG*/
114                case NFC_EMULATION_CONFIG:
115                {
116                    (void)memcpy((void *)&Hal4Ctxt->uConfig,
117                        (void *)puConfig,
118                        sizeof(phHal_uConfig_t)
119                        );
120                    break;
121                }
122                /*P2P Configuration*/
123                case NFC_P2P_CONFIG:
124                {
125                    /*If general bytes are not provided by above layer copy zeros
126                      in general bytes*/
127                    if(puConfig->nfcIPConfig.generalBytesLength == 0)
128                    {
129                        Hal4Ctxt->uConfig.nfcIPConfig.generalBytesLength = 0x00;
130                        (void)memset(Hal4Ctxt->uConfig.nfcIPConfig.generalBytes,
131                                    0,Hal4Ctxt->uConfig.nfcIPConfig.generalBytesLength
132                                    );
133                    }
134                    else
135                    {
136                        (void)memcpy((void *)&Hal4Ctxt->uConfig,
137                            (void *)puConfig,
138                            sizeof(phHal_uConfig_t)
139                            );
140                    }
141                    break;
142                }
143                /*Protection config*/
144                case NFC_SE_PROTECTION_CONFIG:
145                {
146#ifdef IGNORE_EVT_PROTECTED
147                    Hal4Ctxt->Ignore_Event_Protected = FALSE;
148#endif/*#ifdef IGNORE_EVT_PROTECTED*/
149                    (void)memcpy((void *)&Hal4Ctxt->uConfig,
150                        (void *)puConfig,
151                        sizeof(phHal_uConfig_t)
152                        );
153                    break;
154                }
155                default:
156                    CfgStatus = NFCSTATUS_FAILED;
157                    break;
158                }
159                if ( NFCSTATUS_SUCCESS == CfgStatus )
160                {
161                    /*Issue configure with given configuration*/
162                    CfgStatus = phHciNfc_Configure(
163                                    (void *)Hal4Ctxt->psHciHandle,
164                                    (void *)psHwReference,
165                                    CfgType,
166                                    &Hal4Ctxt->uConfig
167                                    );
168                    /* Change the State of the HAL only if status is Pending */
169                    if ( NFCSTATUS_PENDING == CfgStatus )
170                    {
171                        Hal4Ctxt->Hal4NextState = eHal4StateConfiguring;
172                        Hal4Ctxt->sUpperLayerInfo.pConfigCallback
173                            = pConfigCallback;
174                    }
175                }
176            }
177        }
178        else
179        {
180            phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
181            CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
182        }
183    }
184    return CfgStatus;
185}
186
187
188/**Configure the discovery*/
189NFCSTATUS phHal4Nfc_ConfigureDiscovery(
190                        phHal_sHwReference_t          *psHwReference,
191                        phHal_eDiscoveryConfigMode_t   discoveryMode,
192                        phHal_sADD_Cfg_t              *discoveryCfg,
193                        pphHal4Nfc_GenCallback_t       pConfigCallback,
194                        void                          *pContext
195                        )
196{
197    NFCSTATUS CfgStatus = NFCSTATUS_SUCCESS;
198    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
199    if(NULL == psHwReference
200        || NULL == pConfigCallback
201        || NULL == discoveryCfg
202        )
203    {
204        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
205        CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
206    }
207    else if((NULL == psHwReference->hal_context)
208                        || (((phHal4Nfc_Hal4Ctxt_t *)
209                                psHwReference->hal_context)->Hal4CurrentState
210                                               < eHal4StateOpenAndReady)
211                        || (((phHal4Nfc_Hal4Ctxt_t *)
212                                psHwReference->hal_context)->Hal4NextState
213                                               == eHal4StateClosed))
214    {
215        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
216        CfgStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
217    }
218    else
219    {
220        Hal4Ctxt = psHwReference->hal_context;
221        /*If previous Configuration request has not completed ,do not allow
222          new configuration*/
223        if(Hal4Ctxt->Hal4NextState == eHal4StateConfiguring)
224        {
225            PHDBG_INFO("Hal4:PollCfg in progress.Returning status Busy");
226            CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_BUSY);
227        }
228        else if(Hal4Ctxt->Hal4CurrentState >= eHal4StateOpenAndReady)
229        {
230            if (NULL == Hal4Ctxt->psADDCtxtInfo)
231            {
232                Hal4Ctxt->psADDCtxtInfo= (pphHal4Nfc_ADDCtxtInfo_t)
233                    phOsalNfc_GetMemory((uint32_t)
234                    (sizeof(phHal4Nfc_ADDCtxtInfo_t)));
235                if(NULL != Hal4Ctxt->psADDCtxtInfo)
236                {
237                    (void)memset(Hal4Ctxt->psADDCtxtInfo,0,
238                        sizeof(phHal4Nfc_ADDCtxtInfo_t)
239                        );
240                }
241            }
242            if(NULL == Hal4Ctxt->psADDCtxtInfo)
243            {
244                phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
245                CfgStatus= PHNFCSTVAL(CID_NFC_HAL ,
246                    NFCSTATUS_INSUFFICIENT_RESOURCES);
247            }
248            else
249            {
250                /*Register Upper layer context*/
251#ifdef LLCP_DISCON_CHANGES
252                Hal4Ctxt->sUpperLayerInfo.psUpperLayerCfgDiscCtxt = pContext;
253#else /* #ifdef LLCP_DISCON_CHANGES */
254                Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
255#endif /* #ifdef LLCP_DISCON_CHANGES */
256                switch(discoveryMode)
257                {
258                case NFC_DISCOVERY_START:
259                    PHDBG_INFO("Hal4:Call to NFC_DISCOVERY_START");
260                    break;
261                case NFC_DISCOVERY_CONFIG:
262                    PHDBG_INFO("Hal4:Call to NFC_DISCOVERY_CONFIG");
263                    /*Since sADDCfg is allocated in stack ,copy the ADD
264                      configuration structure to HAL4 context*/
265                    (void)memcpy((void *)
266                        &(Hal4Ctxt->psADDCtxtInfo->sADDCfg),
267                        (void *)discoveryCfg,
268                        sizeof(phHal_sADD_Cfg_t)
269                        );
270                    PHDBG_INFO("Hal4:Finished copying sADDCfg");
271                    Hal4Ctxt->psADDCtxtInfo->smx_discovery = FALSE;
272#ifdef UPDATE_NFC_ACTIVE
273                    Hal4Ctxt->psADDCtxtInfo->sADDCfg.PollDevInfo.PollCfgInfo.EnableNfcActive
274                        = ( 0 == Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode?
275                           Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode:
276                           NXP_NFCIP_ACTIVE_DEFAULT);
277                    Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode = ((
278                    Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode <<
279                    (NXP_NFCIP_ACTIVE_DEFAULT * NFCIP_ACTIVE_SHIFT))
280                    | Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode);
281#endif/*#ifdef UPDATE_NFC_ACTIVE*/
282                    /* information system_code(Felica) and
283                    AFI(ReaderB) to be populated later */
284
285                    CfgStatus = phHciNfc_Config_Discovery(
286                        (void *)Hal4Ctxt->psHciHandle,
287                        (void *)psHwReference,
288                        &(Hal4Ctxt->psADDCtxtInfo->sADDCfg)
289                        );/*Configure HCI Discovery*/
290                    break;
291                case NFC_DISCOVERY_STOP:
292                    break;
293                /*Restart Discovery wheel*/
294                case NFC_DISCOVERY_RESUME:
295                    PHDBG_INFO("Hal4:Call to NFC_DISCOVERY_RESUME");
296                    Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
297                    CfgStatus = phHciNfc_Restart_Discovery (
298                                    (void *)Hal4Ctxt->psHciHandle,
299                                    (void *)psHwReference,
300                                    FALSE
301                                    );
302                    break;
303                default:
304                    break;
305                }
306                /* Change the State of the HAL only if HCI Configure
307                   Returns status as Pending */
308                if ( NFCSTATUS_PENDING == CfgStatus )
309                {
310                    (void)memcpy((void *)
311                        &(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig),
312                        (void *)&(discoveryCfg->PollDevInfo.PollCfgInfo),
313                        sizeof(phHal_sPollDevInfo_t)
314                        );
315                    PHDBG_INFO("Hal4:Finished copying PollCfgInfo");
316                    PHDBG_INFO("Hal4:Configure returned NFCSTATUS_PENDING");
317                    Hal4Ctxt->Hal4NextState = eHal4StateConfiguring;
318                    Hal4Ctxt->sUpperLayerInfo.pConfigCallback
319                        = pConfigCallback;
320                }
321                else/*Configure failed.Restore old poll dev info*/
322                {
323                    (void)memcpy((void *)
324                        &(Hal4Ctxt->psADDCtxtInfo->sADDCfg.PollDevInfo.PollCfgInfo),
325                        (void *)&(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig),
326                        sizeof(phHal_sPollDevInfo_t)
327                        );
328                }
329            }
330        }
331        else
332        {
333            phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
334            CfgStatus= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
335        }
336    }
337    return CfgStatus;
338}
339
340
341/*Configuration completion handler*/
342void phHal4Nfc_ConfigureComplete(phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
343                                 void                  *pInfo,
344                                 uint8_t                type
345                                 )
346{
347    pphHal4Nfc_GenCallback_t    pConfigCallback
348                                = Hal4Ctxt->sUpperLayerInfo.pConfigCallback;
349    pphHal4Nfc_ConnectCallback_t pUpperConnectCb
350                    = Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb;
351    NFCSTATUS Status = ((phNfc_sCompletionInfo_t *)pInfo)->status;
352    if((type == NFC_NOTIFY_POLL_ENABLED) ||(type == NFC_NOTIFY_POLL_RESTARTED))
353    {
354        Hal4Ctxt->psADDCtxtInfo->IsPollConfigured = TRUE;
355        PHDBG_INFO("Hal4:Poll Config Complete");
356    }
357    else
358    {
359        Hal4Ctxt->psADDCtxtInfo->IsPollConfigured = FALSE;
360        PHDBG_WARNING("Hal4:Poll disabled,config success or config error");
361    }
362    if(NULL != Hal4Ctxt->sUpperLayerInfo.pConfigCallback)
363    {
364#ifdef MERGE_SAK_SW2
365        if((NFC_UICC_EMULATION == Hal4Ctxt->uConfig.emuConfig.emuType)&&
366           (FALSE ==
367            Hal4Ctxt->uConfig.emuConfig.config.uiccEmuCfg.enableUicc))
368        {
369            Status = phHciNfc_System_Configure (
370                                Hal4Ctxt->psHciHandle,
371                                (void *)gpphHal4Nfc_Hwref,
372                                PH_HAL4NFC_TGT_MERGE_ADDRESS,
373                                PH_HAL4NFC_TGT_MERGE_SAK /*config value*/
374                                );
375        }
376        if(NFCSTATUS_PENDING != Status)
377        {
378#endif/*#ifdef MERGE_SAK_SW2*/
379            Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
380            Hal4Ctxt->sUpperLayerInfo.pConfigCallback = NULL;
381            (*pConfigCallback)(
382#ifdef LLCP_DISCON_CHANGES
383                Hal4Ctxt->sUpperLayerInfo.psUpperLayerCfgDiscCtxt,
384#else /* #ifdef LLCP_DISCON_CHANGES */
385                Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
386#endif /* #ifdef LLCP_DISCON_CHANGES */
387                Status
388                );
389#ifdef MERGE_SAK_SW2
390        }
391#endif/*#ifdef MERGE_SAK_SW2*/
392    }
393    /**if connect failed and discovery wheel was restarted*/
394    else if(Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb)
395    {
396        Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
397        Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL;
398        /*Notify to the upper layer*/
399        (*pUpperConnectCb)(
400            Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
401            Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
402            NFCSTATUS_FAILED
403            );
404    }
405    else
406    {
407        Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
408        /**if disconnect failed and discovery wheel was restarted*/
409        if ( NULL != Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb)
410        {
411            ((phNfc_sCompletionInfo_t *)pInfo)->status = NFCSTATUS_SUCCESS;
412            phHal4Nfc_DisconnectComplete(Hal4Ctxt,pInfo);
413        }
414    }
415}
416
417
418/**Handler for Target discovery completion for all remote device types*/
419void phHal4Nfc_TargetDiscoveryComplete(
420                                       phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
421                                       void                  *pInfo
422                                       )
423{
424    static phHal4Nfc_DiscoveryInfo_t sDiscoveryInfo;
425    NFCSTATUS status = NFCSTATUS_SUCCESS;
426    /**SAK byte*/
427    uint8_t Sak = 0;
428    /*Union type to encapsulate and return the discovery info*/
429    phHal4Nfc_NotificationInfo_t uNotificationInfo;
430    /*All the following types will be discovered as type A ,and differentiation
431      will have to be done within this module based on SAK byte and UID info*/
432    phHal_eRemDevType_t  aRemoteDevTypes[3] = {
433                                               phHal_eISO14443_A_PICC,
434                                               phHal_eNfcIP1_Target,
435                                               phHal_eMifare_PICC
436                                              };
437    /*Count is used to add multiple info into remote dvice list for devices that
438      support multiple protocols*/
439    uint8_t Count = 0,
440        NfcIpDeviceCount = 0;/**<Number of NfcIp devices discovered*/
441    uint16_t nfc_id = 0;
442    /*remote device info*/
443    phHal_sRemoteDevInformation_t *psRemoteDevInfo = NULL;
444    status = ((phNfc_sCompletionInfo_t *)pInfo)->status;
445    /*Update Hal4 state*/
446    Hal4Ctxt->Hal4CurrentState = eHal4StateTargetDiscovered;
447    Hal4Ctxt->Hal4NextState  = eHal4StateInvalid;
448     PHDBG_INFO("Hal4:Remotedevice Discovered");
449    if(NULL != ((phNfc_sCompletionInfo_t *)pInfo)->info)
450    {
451        /*Extract Remote device Info*/
452        psRemoteDevInfo = (phHal_sRemoteDevInformation_t *)
453                                    ((phNfc_sCompletionInfo_t *)pInfo)->info;
454
455        switch(psRemoteDevInfo->RemDevType)
456        {
457            case phHal_eISO14443_A_PICC:/*for TYPE A*/
458            {
459                Sak = psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak;
460                if((Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso14443A)
461                    || (TRUE == Hal4Ctxt->psADDCtxtInfo->smx_discovery))
462                {
463                    /*Check if Iso is Supported*/
464                    if(Sak & ISO_14443_BITMASK)
465                    {
466                        Count++;
467                    }
468                    /*Check for Mifare Supported*/
469                    switch( Sak )
470                    {
471                      case 0x09: // Mini
472                      case 0x08: // 1K
473                      case 0x18: // 4K
474                      case 0x88: // Infineon 1K
475                      case 0x98: // Pro 4K
476                      case 0xB8: // Pro 4K
477                      case 0x28: // 1K emulation
478                      case 0x38: // 4K emulation
479                        aRemoteDevTypes[Count] = phHal_eMifare_PICC;
480                        Count++;
481                        break;
482                    }
483                    if((0 == Sak)&& (0 == Count))
484                    {
485                        /*Mifare check*/
486                        if((NXP_UID ==
487                        psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid[0])
488                        &&(NXP_MIN_UID_LEN <=
489                        psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength))
490                        {
491                            aRemoteDevTypes[Count] = phHal_eMifare_PICC;
492                            Count++;
493                        }
494                    }
495                    if ( !(Sak & NFCIP_BITMASK) )
496                    {
497                        // Always add a separate 3A target on a separate
498                        // handle, so the upper layers can connect to it.
499                        aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC;
500                        Count++;
501                    }
502                }
503                /*Check for P2P target passive*/
504                if((Sak & NFCIP_BITMASK) &&
505                    (NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)&&
506                    (Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode
507                    & phHal_ePassive106))
508                {
509                  if( Sak == 0x53 // Fudan card incompatible to ISO18092
510                      && psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[0] == 0x04
511                      && psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA[1] == 0x00
512                    )
513                  {
514                    aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC;
515                    Count++;
516                  }
517                  else
518                  {
519                    aRemoteDevTypes[Count] = phHal_eNfcIP1_Target;
520                    Count++;
521									}
522                }
523            }/*case phHal_eISO14443_A_PICC:*/
524                break;
525            case phHal_eNfcIP1_Target:/*P2P target detected*/
526                aRemoteDevTypes[Count] = phHal_eNfcIP1_Target;
527                Count++;
528                break;
529             case phHal_eISO14443_B_PICC: /*TYPE_B*/
530#ifdef TYPE_B
531                aRemoteDevTypes[Count] = phHal_eISO14443_B_PICC;
532                Count++;
533                break;
534#endif
535            case phHal_eFelica_PICC: /*Felica*/
536#ifdef TYPE_FELICA
537            {
538                /*nfc_id is used to differentiate between Felica and NfcIp target
539                  discovered in Type F*/
540                nfc_id = (((uint16_t)psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm[0])
541                    << BYTE_SIZE) |
542                    psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm[1];
543                /*check  for NfcIp target*/
544                if(NXP_NFCIP_NFCID2_ID  == nfc_id)
545                {
546                    if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)
547                        &&((Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode
548                             & phHal_ePassive212) ||
549                            (Hal4Ctxt->psADDCtxtInfo->sADDCfg.NfcIP_Mode
550                             & phHal_ePassive424)))
551                    {
552                        aRemoteDevTypes[Count] = phHal_eNfcIP1_Target;
553                        Count++;
554                    }
555                }
556                else/*Felica*/
557                {
558                    if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableFelica212
559                    || Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableFelica424)
560                    {
561                        aRemoteDevTypes[Count] = phHal_eFelica_PICC;
562                        Count++;
563                    }
564                }
565                break;
566            }
567#endif
568            case phHal_eJewel_PICC: /*Jewel*/
569#ifdef TYPE_JEWEL
570            {
571                /*Report Jewel tags only if TYPE A is enabled*/
572                if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso14443A)
573                {
574                    aRemoteDevTypes[Count] = phHal_eJewel_PICC;
575                    Count++;
576                }
577                break;
578            }
579#endif
580#ifdef  TYPE_ISO15693
581            case phHal_eISO15693_PICC: /*ISO15693*/
582            {
583                if(Hal4Ctxt->psADDCtxtInfo->sCurrentPollConfig.EnableIso15693)
584                {
585                    aRemoteDevTypes[Count] = phHal_eISO15693_PICC;
586                    Count++;
587                }
588                break;
589            }
590#endif /* #ifdef    TYPE_ISO15693 */
591            /*Types currently not supported*/
592            case phHal_eISO14443_BPrime_PICC:
593            default:
594                PHDBG_WARNING("Hal4:Notification for Not supported types");
595                break;
596        }/*End of switch*/
597        /*Update status code to success if atleast one device info is available*/
598        status = (((NFCSTATUS_SUCCESS != status)
599                  && (NFCSTATUS_MULTIPLE_TAGS != status))
600                   &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices != 0))?
601                    NFCSTATUS_SUCCESS:status;
602
603        /*Update status to NFCSTATUS_MULTIPLE_PROTOCOLS if count > 1 ,and this
604          is first discovery notification from Hci*/
605        status = ((NFCSTATUS_SUCCESS == status)
606                    &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 0)
607                    &&(Count > 1)?NFCSTATUS_MULTIPLE_PROTOCOLS:status);
608         /*If multiple protocols are supported ,allocate separate remote device
609          information for each protocol supported*/
610        /*Allocate and copy Remote device info into Hal4 Context*/
611        while(Count)
612        {
613            PHDBG_INFO("Hal4:Count is not zero");
614            --Count;
615            /*Allocate memory for each of Count number of
616              devices*/
617            if(NULL == Hal4Ctxt->rem_dev_list[
618                Hal4Ctxt->psADDCtxtInfo->nbr_of_devices])
619            {
620                Hal4Ctxt->rem_dev_list[
621                    Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]
622                = (phHal_sRemoteDevInformation_t *)
623                    phOsalNfc_GetMemory(
624                    (uint32_t)(
625                    sizeof(phHal_sRemoteDevInformation_t))
626                    );
627            }
628            if(NULL == Hal4Ctxt->rem_dev_list[
629                Hal4Ctxt->psADDCtxtInfo->nbr_of_devices])
630            {
631                status =  PHNFCSTVAL(CID_NFC_HAL,
632                    NFCSTATUS_INSUFFICIENT_RESOURCES);
633                phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
634                break;
635            }
636            else
637            {
638                (void)memcpy(
639                    (void *)Hal4Ctxt->rem_dev_list[
640                        Hal4Ctxt->psADDCtxtInfo->nbr_of_devices],
641                        (void *)psRemoteDevInfo,
642                        sizeof(phHal_sRemoteDevInformation_t)
643                        );
644                /*Now copy appropriate device type from aRemoteDevTypes array*/
645                Hal4Ctxt->rem_dev_list[
646                        Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]->RemDevType
647                            =   aRemoteDevTypes[Count];
648                /*Increment number of devices*/
649                Hal4Ctxt->psADDCtxtInfo->nbr_of_devices++;
650            }/*End of else*/
651        }/*End of while*/
652
653        /*If Upper layer is interested only in P2P notifications*/
654        if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)
655           &&(((Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 1)
656              &&(phHal_eNfcIP1_Target == Hal4Ctxt->rem_dev_list[0]->RemDevType))
657              ||(NULL == Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification))
658            )
659        {
660            PHDBG_INFO("Hal4:Trying to notify P2P Listener");
661            /*NFCSTATUS_SUCCESS or NFCSTATUS_MULTIPLE_PROTOCOLS*/
662            if((NFCSTATUS_SUCCESS == status)
663                ||(NFCSTATUS_MULTIPLE_PROTOCOLS == status))
664            {
665                /*Pick only the P2P target device info from the list*/
666                for(Count = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
667                    Count > 0;--Count)
668                {
669                    /*Only one P2P target can be detected in one discovery*/
670                    if(phHal_eNfcIP1_Target ==
671                        Hal4Ctxt->rem_dev_list[Count-1]->RemDevType)
672                    {
673                        (void)memcpy(
674                            (void *)Hal4Ctxt->rem_dev_list[0],
675                            (void *)Hal4Ctxt->rem_dev_list[Count-1],
676                                    sizeof(phHal_sRemoteDevInformation_t)
677                                    );
678                        NfcIpDeviceCount = 1;
679                        break;
680                    }
681                }
682                /*If any P2p devices are discovered free other device info*/
683                while(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > NfcIpDeviceCount)
684                {
685                    phOsalNfc_FreeMemory(Hal4Ctxt->rem_dev_list[
686                        --Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]);
687                    Hal4Ctxt->rem_dev_list[
688                        Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL;
689                }
690                /*Issue P2P notification*/
691                if(NfcIpDeviceCount == 1)
692                {
693                    sDiscoveryInfo.NumberOfDevices
694                        = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
695                    sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list;
696                    uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo;
697                    PHDBG_INFO("Hal4:Calling P2P listener");
698                    (*Hal4Ctxt->sUpperLayerInfo.pP2PNotification)(
699                            (void *)(Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt),
700                            NFC_DISCOVERY_NOTIFICATION,
701                            uNotificationInfo,
702                            NFCSTATUS_SUCCESS
703                            );
704                }
705                else/*Restart Discovery wheel*/
706                {
707                    PHDBG_INFO("Hal4:No P2P device in list");
708                    Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
709                    PHDBG_INFO("Hal4:Restart discovery1");
710                    status = phHciNfc_Restart_Discovery (
711                                        (void *)Hal4Ctxt->psHciHandle,
712                                        (void *)gpphHal4Nfc_Hwref,
713                                        FALSE
714                                        );
715                    Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status?
716                                                        eHal4StateConfiguring:
717                                                    Hal4Ctxt->Hal4NextState);
718                }
719            }
720            /*More discovery info available ,get next info from HCI*/
721            else if((NFCSTATUS_MULTIPLE_TAGS == status)
722                &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices
723                     < MAX_REMOTE_DEVICES))
724            {
725                status = phHciNfc_Select_Next_Target (
726                    Hal4Ctxt->psHciHandle,
727                    (void *)gpphHal4Nfc_Hwref
728                    );
729            }
730            else/*Failed discovery ,restart discovery*/
731            {
732                Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
733                PHDBG_INFO("Hal4:Restart discovery2");
734                status = phHciNfc_Restart_Discovery (
735                                        (void *)Hal4Ctxt->psHciHandle,
736                                        (void *)gpphHal4Nfc_Hwref,
737                                        FALSE
738                                        );/*Restart Discovery wheel*/
739                Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status?
740                                                eHal4StateConfiguring:
741                                                Hal4Ctxt->Hal4NextState);
742            }
743        }/*if((NULL != Hal4Ctxt->sUpperLayerInfo.pP2PNotification)...*/
744        /*Notify if Upper layer is interested in tag notifications,also notify
745          P2p if its in the list with other tags*/
746        else if(NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)
747        {
748            PHDBG_INFO("Hal4:Trying to notify Tag notification");
749            /*Multiple tags in field, get discovery info a second time for the
750              other devices*/
751            if((NFCSTATUS_MULTIPLE_TAGS == status)
752                &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices < MAX_REMOTE_DEVICES))
753            {
754                PHDBG_INFO("Hal4:select next target1");
755                status = phHciNfc_Select_Next_Target (
756                                                    Hal4Ctxt->psHciHandle,
757                                                    (void *)gpphHal4Nfc_Hwref
758                                                    );
759            }
760            /*Single tag multiple protocols scenario,Notify Multiple Protocols
761              status to upper layer*/
762            else if(status == NFCSTATUS_MULTIPLE_PROTOCOLS)
763            {
764                PHDBG_INFO("Hal4:Multiple Tags or protocols");
765                sDiscoveryInfo.NumberOfDevices
766                    = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
767                sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list;
768                uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo;
769                (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)(
770                            (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt),
771                            NFC_DISCOVERY_NOTIFICATION,
772                            uNotificationInfo,
773                            status
774                            );
775            }
776            else /*NFCSTATUS_SUCCESS*/
777            {
778                if(((Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 1)
779                     &&(phHal_eNfcIP1_Target
780                     == Hal4Ctxt->rem_dev_list[0]->RemDevType))
781                     ||(NFCSTATUS_SUCCESS != status)
782                     || (Hal4Ctxt->psADDCtxtInfo->nbr_of_devices == 0)
783                     )/*device detected but upper layer is not interested
784                       in the type(P2P) or activate next failed*/
785                {
786                    while(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > 0)
787                    {
788                        phOsalNfc_FreeMemory(Hal4Ctxt->rem_dev_list[
789                            --Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]);
790                        Hal4Ctxt->rem_dev_list[
791                            Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL;
792                    }
793                    PHDBG_INFO("Hal4:Restart discovery3");
794                    status = phHciNfc_Restart_Discovery (
795                        (void *)Hal4Ctxt->psHciHandle,
796                        (void *)gpphHal4Nfc_Hwref,
797                        FALSE
798                        );/*Restart Discovery wheel*/
799                    Hal4Ctxt->Hal4NextState = (
800                        NFCSTATUS_PENDING == status?eHal4StateConfiguring
801                                                    :Hal4Ctxt->Hal4NextState
802                                                    );
803                }
804                else/*All remote device info available.Notify to upper layer*/
805                {
806                    /*Update status for MULTIPLE_TAGS here*/
807                    status = (Hal4Ctxt->psADDCtxtInfo->nbr_of_devices > 1?
808                                NFCSTATUS_MULTIPLE_TAGS:status);
809                    /*If listener is registered ,call it*/
810                    sDiscoveryInfo.NumberOfDevices
811                        = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
812                    sDiscoveryInfo.ppRemoteDevInfo
813                        = Hal4Ctxt->rem_dev_list;
814                    uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo;
815                    PHDBG_INFO("Hal4:Calling Discovery Handler1");
816                    (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)(
817                        (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt),
818                        NFC_DISCOVERY_NOTIFICATION,
819                        uNotificationInfo,
820                        status
821                        );
822                }
823            }
824        } /*else if(NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)*/
825        else/*listener not registered ,Restart Discovery wheel*/
826        {
827            PHDBG_INFO("Hal4:No listener registered.Ignoring Discovery  \
828                        Notification");
829            Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
830            PHDBG_INFO("Hal4:Restart discovery4");
831            status = phHciNfc_Restart_Discovery (
832                                (void *)Hal4Ctxt->psHciHandle,
833                                (void *)gpphHal4Nfc_Hwref,
834                                FALSE
835                                );
836            Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status?
837                                                eHal4StateConfiguring:
838                                            Hal4Ctxt->Hal4NextState);
839        }
840    }/*if(NULL != ((phNfc_sCompletionInfo_t *)pInfo)->info)*/
841    else/*NULL info received*/
842    {
843        sDiscoveryInfo.NumberOfDevices
844            = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
845        sDiscoveryInfo.ppRemoteDevInfo = Hal4Ctxt->rem_dev_list;
846        uNotificationInfo.psDiscoveryInfo = &sDiscoveryInfo;
847        /*If Discovery info is available from previous notifications try to
848          notify that to the upper layer*/
849        if((NULL != Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)
850#ifdef NFC_RF_NOISE_SW
851          &&((NFCSTATUS_SUCCESS == status)
852            || (NFCSTATUS_MULTIPLE_TAGS == status))
853#endif /* #ifdef NFC_RF_NOISE_SW */
854            )
855        {
856#ifndef NFC_RF_NOISE_SW
857            status = (((NFCSTATUS_SUCCESS != status)
858                  && (NFCSTATUS_MULTIPLE_TAGS != status))
859                   &&(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices != 0))?
860                    NFCSTATUS_SUCCESS:status;
861#endif/*#ifndef NFC_RF_NOISE_SW*/
862            PHDBG_INFO("Hal4:Calling Discovery Handler2");
863            (*Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification)(
864                (void *)(Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt),
865                NFC_DISCOVERY_NOTIFICATION,
866                uNotificationInfo,
867                status
868                );
869        }
870        else/*Restart Discovery wheel*/
871        {
872            Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
873            PHDBG_INFO("Hal4:Restart discovery5");
874            status = phHciNfc_Restart_Discovery (
875                (void *)Hal4Ctxt->psHciHandle,
876                (void *)gpphHal4Nfc_Hwref,
877                FALSE
878                );
879            Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == status?
880                                   eHal4StateConfiguring:Hal4Ctxt->Hal4NextState);
881        }
882    }/*else*/
883    return;
884}
885
886
887/**Register Notification handlers*/
888NFCSTATUS phHal4Nfc_RegisterNotification(
889                        phHal_sHwReference_t         *psHwReference,
890                        phHal4Nfc_RegisterType_t      eRegisterType,
891                        pphHal4Nfc_Notification_t     pNotificationHandler,
892                        void                         *Context
893                        )
894{
895    NFCSTATUS RetStatus = NFCSTATUS_SUCCESS;
896    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
897    if(NULL == pNotificationHandler || NULL == psHwReference)
898    {
899        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
900        RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
901    }
902    else if((NULL == psHwReference->hal_context)
903                        || (((phHal4Nfc_Hal4Ctxt_t *)
904                                psHwReference->hal_context)->Hal4CurrentState
905                                               < eHal4StateOpenAndReady)
906                        || (((phHal4Nfc_Hal4Ctxt_t *)
907                                psHwReference->hal_context)->Hal4NextState
908                                               == eHal4StateClosed))
909    {
910        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
911        RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
912    }
913    else
914    {
915        /*Extract context from hardware reference*/
916        Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
917        switch(eRegisterType)
918        {
919            case eRegisterTagDiscovery:
920                Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt = Context;
921                Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification
922                    = pNotificationHandler;  /*Register the tag Notification*/
923                break;
924            case eRegisterP2PDiscovery:
925                Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt = Context;
926                Hal4Ctxt->sUpperLayerInfo.pP2PNotification
927                    = pNotificationHandler;  /*Register the P2P Notification*/
928                break;
929            case eRegisterHostCardEmulation:
930                RetStatus = NFCSTATUS_FEATURE_NOT_SUPPORTED;
931                break;
932            case eRegisterSecureElement:
933                Hal4Ctxt->sUpperLayerInfo.EventNotificationCtxt = Context;
934                Hal4Ctxt->sUpperLayerInfo.pEventNotification
935                       = pNotificationHandler; /*Register the Se Notification*/
936                break;
937            default:
938                Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt = Context;
939                Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler
940                    = pNotificationHandler;  /*Register the default Notification*/
941                break;
942        }
943        PHDBG_INFO("Hal4:listener registered");
944    }
945    return RetStatus;
946}
947
948
949/**Unregister Notification handlers*/
950NFCSTATUS phHal4Nfc_UnregisterNotification(
951                                  phHal_sHwReference_t     *psHwReference,
952                                  phHal4Nfc_RegisterType_t  eRegisterType,
953                                  void                     *Context
954                                  )
955{
956    NFCSTATUS RetStatus = NFCSTATUS_SUCCESS;
957    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
958    if(psHwReference == NULL)
959    {
960        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
961        RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
962    }
963    else if((NULL == psHwReference->hal_context)
964                        || (((phHal4Nfc_Hal4Ctxt_t *)
965                                psHwReference->hal_context)->Hal4CurrentState
966                                               < eHal4StateOpenAndReady)
967                        || (((phHal4Nfc_Hal4Ctxt_t *)
968                                psHwReference->hal_context)->Hal4NextState
969                                               == eHal4StateClosed))
970    {
971        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
972        RetStatus = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
973    }
974    else
975    {
976        /*Extract context from hardware reference*/
977        Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
978        switch(eRegisterType)
979        {
980        case eRegisterTagDiscovery:
981            Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = Context;
982            Hal4Ctxt->sUpperLayerInfo.DiscoveryCtxt = NULL;
983            /*UnRegister the tag Notification*/
984            Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
985            PHDBG_INFO("Hal4:Tag Discovery Listener Unregistered");
986            break;
987        case eRegisterP2PDiscovery:
988            Hal4Ctxt->sUpperLayerInfo.P2PDiscoveryCtxt = NULL;
989            /*UnRegister the p2p Notification*/
990            Hal4Ctxt->sUpperLayerInfo.pP2PNotification = NULL;
991            PHDBG_INFO("Hal4:P2P Discovery Listener Unregistered");
992            break;
993        case eRegisterHostCardEmulation:/*RFU*/
994            RetStatus = NFCSTATUS_FEATURE_NOT_SUPPORTED;
995            break;
996            /*UnRegister the Se Notification*/
997        case eRegisterSecureElement:
998            Hal4Ctxt->sUpperLayerInfo.EventNotificationCtxt = NULL;
999            Hal4Ctxt->sUpperLayerInfo.pEventNotification = NULL;
1000            PHDBG_INFO("Hal4:SE Listener Unregistered");
1001            break;
1002        default:
1003            Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt = NULL;
1004            /*UnRegister the default Notification*/
1005            Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler = NULL;
1006            PHDBG_INFO("Hal4:Default Listener Unregistered");
1007            break;
1008        }
1009    }
1010    return RetStatus;
1011}
1012
1013
1014