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