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.c
18 * \brief Hal4Nfc source.
19 *
20 * Project: NFC-FRI 1.1
21 *
22 * $Date: Fri Jun 11 09:32:23 2010 $
23 * $Author: ing07385 $
24 * $Revision: 1.192 $
25 * $Aliases: NFC_FRI1.1_WK1023_R35_1 $
26 *
27 */
28
29/* ---------------------------Include files ---------------------------------*/
30
31#include <phHal4Nfc.h>
32#include <phHal4Nfc_Internal.h>
33#include <phOsalNfc.h>
34#include <phHciNfc.h>
35#include <phLlcNfc.h>
36#include <phDal4Nfc.h>
37#include <phDnldNfc.h>
38#include <phOsalNfc_Timer.h>
39
40/* ------------------------------- Macros -----------------------------------*/
41#ifndef HAL_UNIT_TEST
42#define STATIC static
43#else
44#define STATIC
45#endif/*#ifndef UNIT_TEST*/
46#define HAL4_LAYERS                 3
47#define LAYER_HCI                   2
48#define LAYER_LLC                   1
49#define LAYER_DAL                   0
50
51/* --------------------Structures and enumerations --------------------------*/
52
53phHal_sHwReference_t *gpphHal4Nfc_Hwref;
54
55static void phHal4Nfc_IoctlComplete(
56                                    phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
57                                    void     *pInfo
58                                    );
59
60static void phHal4Nfc_LowerNotificationHandler(
61                                        void    *pContext,
62                                        void    *pHwRef,
63                                        uint8_t  type,
64                                        void     *pInfo
65                                        );
66static void phHal4Nfc_HandleEvent(
67                              phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
68                              void     *pInfo
69                              );
70
71static void phHal4Nfc_OpenComplete(
72                                   phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
73                                   void *pInfo
74                                   );
75
76static void phHal4Nfc_CloseComplete(
77                                    phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
78                                    void *pInfo
79                                    );
80
81static void phHal4Nfc_DownloadComplete(
82                                void *pContext,
83                                void *pHwRef,
84                                uint8_t type,
85                                void *pInfo
86                                );
87
88static NFCSTATUS phHal4Nfc_Configure_Layers(
89                                phNfcLayer_sCfg_t       **pphLayer
90                                );
91
92
93/*Callback for Self tests*/
94static void phHal4Nfc_SelfTestComplete(
95                                       phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
96                                       void *pInfo
97                                       );
98
99/**
100 *  The open callback function to be called by the HCI when open (initializaion)
101 *  sequence is completed  or if there is an error in initialization.
102 *  It is passed as a parameter to HCI when calling HCI Init.
103 */
104
105static void phHal4Nfc_OpenComplete(
106                                   phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
107                                   void *pInfo
108                                   )
109{
110    NFCSTATUS status = ((phNfc_sCompletionInfo_t *)pInfo)->status;
111    pphHal4Nfc_GenCallback_t pUpper_OpenCb
112                                    = Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb;
113    void                   *pUpper_Context
114                                = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
115    if(status == NFCSTATUS_SUCCESS)
116    {
117        PHDBG_INFO("Hal4:Open Successful");
118#ifdef MERGE_SAK_SW1 /*Software Workaround*/
119        if(eHal4StateOpenAndReady == Hal4Ctxt->Hal4NextState)
120        {
121            status = phHciNfc_System_Configure (
122                                    Hal4Ctxt->psHciHandle,
123                                    (void *)gpphHal4Nfc_Hwref,
124                                    PH_HAL4NFC_TGT_MERGE_ADDRESS,
125                                    PH_HAL4NFC_TGT_MERGE_SAK /*config value*/
126                                    );
127        }
128        if(NFCSTATUS_PENDING != status)
129#endif/*#ifdef MERGE_SAK_SW1*/
130        {
131            /*Update State*/
132            Hal4Ctxt->Hal4CurrentState = Hal4Ctxt->Hal4NextState;
133            Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
134            Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb = NULL;
135            if(NULL != pUpper_OpenCb)
136            {
137                /*Upper layer's Open Cb*/
138                (*pUpper_OpenCb)(Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
139                    NFCSTATUS_SUCCESS
140                    );
141            }
142        }
143    }
144    else/*Open did not succeed.Go back to reset state*/
145    {
146        Hal4Ctxt->Hal4CurrentState = eHal4StateClosed;
147        Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
148        Hal4Ctxt->psHciHandle = NULL;
149        phOsalNfc_FreeMemory((void *)Hal4Ctxt->pHal4Nfc_LayerCfg);
150        Hal4Ctxt->pHal4Nfc_LayerCfg = NULL;
151        phOsalNfc_FreeMemory((void *)Hal4Ctxt);
152        gpphHal4Nfc_Hwref->hal_context = NULL;
153        gpphHal4Nfc_Hwref = NULL;
154        PHDBG_INFO("Hal4:Open Failed");
155        /*Call upper layer's Open Cb with error status*/
156        if(NULL != pUpper_OpenCb)
157        {
158            /*Upper layer's Open Cb*/
159            (*pUpper_OpenCb)(pUpper_Context,status);
160        }
161    }
162    return;
163}
164
165/**
166 *  The close callback function called by the HCI when close  sequence is
167 *  completed or if there is an error in closing.
168 *  It is passed as a parameter to HCI when calling HCI Release.
169 */
170static void phHal4Nfc_CloseComplete(
171                                    phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
172                                    void *pInfo
173                                    )
174{
175    NFCSTATUS   status= ((phNfc_sCompletionInfo_t *)pInfo)->status;
176    pphHal4Nfc_GenCallback_t pUpper_CloseCb;
177    void                    *pUpper_Context;
178    uint8_t                 RemoteDevNumber = 0;
179    pUpper_CloseCb = Hal4Ctxt->sUpperLayerInfo.pUpperCloseCb;
180    pUpper_Context = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
181    /*Update state*/
182    Hal4Ctxt->Hal4CurrentState = Hal4Ctxt->Hal4NextState;
183    Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
184    /*If Closed successfully*/
185    if(NFCSTATUS_SUCCESS == status)
186    {
187        Hal4Ctxt->psHciHandle = NULL;
188        /*Free all heap allocations*/
189        phOsalNfc_FreeMemory((void *)Hal4Ctxt->pHal4Nfc_LayerCfg);
190        Hal4Ctxt->pHal4Nfc_LayerCfg = NULL;
191        /*Free ADD context info*/
192        if(NULL != Hal4Ctxt->psADDCtxtInfo)
193        {
194            while(RemoteDevNumber < MAX_REMOTE_DEVICES)
195            {
196                if(NULL != Hal4Ctxt->rem_dev_list[RemoteDevNumber])
197                {
198                    phOsalNfc_FreeMemory((void *)
199                                    (Hal4Ctxt->rem_dev_list[RemoteDevNumber]));
200                    Hal4Ctxt->rem_dev_list[RemoteDevNumber] = NULL;
201                }
202                RemoteDevNumber++;
203            }
204            Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
205            phOsalNfc_FreeMemory(Hal4Ctxt->psADDCtxtInfo);
206        }/*if(NULL != Hal4Ctxt->psADDCtxtInfo)*/
207        /*Free Trcv context info*/
208        if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
209        {
210            if(NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer)
211            {
212                    phOsalNfc_FreeMemory(
213                        Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer
214                        );
215            }
216            if((NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
217                && (NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData))
218            {
219                phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData);
220            }
221            phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo);
222        }/*if(NULL != Hal4Ctxt->psTrcvCtxtInfo)*/
223        /*Free Hal context and Hardware reference*/
224        gpphHal4Nfc_Hwref->hal_context = NULL;
225        gpphHal4Nfc_Hwref = NULL;
226        phOsalNfc_FreeMemory((void *)Hal4Ctxt);
227    }/* if(NFCSTATUS_SUCCESS == status)*/
228    /*Call Upper layer's Close Cb with status*/
229    (*pUpper_CloseCb)(pUpper_Context,status);
230    return;
231}
232
233
234/*
235* For configuring the various layers during the Initialization call
236*
237*
238*/
239static
240NFCSTATUS
241phHal4Nfc_Configure_Layers(
242                        phNfcLayer_sCfg_t       **pphLayer
243                        )
244{
245    uint8_t index = HAL4_LAYERS - 1;
246    uint8_t i = 0;
247    NFCSTATUS status = NFCSTATUS_SUCCESS ;
248    PHDBG_INFO("Hal4:Configuring layers");
249    *pphLayer = (phNfcLayer_sCfg_t *) phOsalNfc_GetMemory(
250                            sizeof(phNfcLayer_sCfg_t) * HAL4_LAYERS);
251
252    if( NULL == *pphLayer)
253    {
254        status = PHNFCSTVAL(CID_NFC_HAL,
255                    NFCSTATUS_INSUFFICIENT_RESOURCES);/*Memory allocation error*/
256    }
257    else
258    {
259
260        (void)memset((void *)*pphLayer,0,(
261                                sizeof(phNfcLayer_sCfg_t) * HAL4_LAYERS));
262
263        for(i=0 ; i < HAL4_LAYERS ;i++, index-- )
264        {
265            (*pphLayer + i)->layer_index = index;
266            switch(index)
267            {
268                case LAYER_HCI: /*Configure Hci*/
269                {
270                    (*pphLayer+i)->layer_name  =(uint8_t *) "Hci";
271                    (*pphLayer+i)->layer_registry  = NULL;
272                    (*pphLayer+i)->layer_next  =
273                                    (((phNfcLayer_sCfg_t *)*pphLayer) + i + 1);
274                    break;
275                }
276                case LAYER_LLC:/*Configure LLC*/
277                {
278                    (*pphLayer+i)->layer_registry  = phLlcNfc_Register;
279                    (*pphLayer+i)->layer_name  = (uint8_t *)"Llc";
280                    (*pphLayer+i)->layer_next  =
281                                    (((phNfcLayer_sCfg_t *)*pphLayer) + i + 1);
282                    break;
283                }
284                case LAYER_DAL: /*Configure the DAL*/
285                {
286                    (*pphLayer+i)->layer_registry  = phDal4Nfc_Register;
287                    (*pphLayer+i)->layer_name  = (uint8_t *)"Dal";
288                    (*pphLayer+i)->layer_next  = NULL ;
289                    break;
290                }
291                default:
292                    break;
293            } /* End of Switch */
294        }   /* End of For Loop */
295    }   /* End of NULL Check */
296
297    return status ;
298}
299
300
301
302#ifdef ANDROID
303
304#define LOG_TAG "NFC-HCI"
305
306#include <utils/Log.h>
307#include <dlfcn.h>
308
309#define FW_PATH "/vendor/firmware/libpn544_fw.so"
310
311const unsigned char *nxp_nfc_full_version = NULL;
312const unsigned char *nxp_nfc_fw = NULL;
313
314int dlopen_firmware() {
315    void *p;
316
317    void *handle = dlopen(FW_PATH, RTLD_NOW);
318    if (handle == NULL) {
319        ALOGE("Could not open %s", FW_PATH);
320        return -1;
321    }
322
323    p = dlsym(handle, "nxp_nfc_full_version");
324    if (p == NULL) {
325        ALOGE("Could not link nxp_nfc_full_version");
326        return -1;
327    }
328    nxp_nfc_full_version = (unsigned char *)p;
329
330    p = dlsym(handle, "nxp_nfc_fw");
331    if (p == NULL) {
332        ALOGE("Could not link nxp_nfc_fw");
333        return -1;
334    }
335    nxp_nfc_fw = (unsigned char *)p;
336
337    return 0;
338}
339#endif
340
341/**
342 *  The open function called by the upper HAL when HAL4 is to be opened
343 *  (initialized).
344 *
345 */
346NFCSTATUS phHal4Nfc_Open(
347                         phHal_sHwReference_t       *psHwReference,
348                         phHal4Nfc_InitType_t        InitType,
349                         pphHal4Nfc_GenCallback_t    pOpenCallback,
350                         void                       *pContext
351                         )
352{
353    NFCSTATUS openRetVal = NFCSTATUS_SUCCESS;
354    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
355    phHciNfc_Init_t   eHciInitType = (phHciNfc_Init_t)InitType;
356    /*Set Default Clock settings once*/
357    static phHal_sHwConfig_t sHwConfig = {
358        {0},
359        NXP_DEFAULT_CLK_REQUEST,
360        NXP_DEFAULT_INPUT_CLK
361        };
362    /*NULL checks*/
363    if(NULL == psHwReference || NULL == pOpenCallback)
364    {
365        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
366        openRetVal = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
367    }
368    else if(NULL != gpphHal4Nfc_Hwref)
369    {
370        /*Hal4 context is open or open in progress ,return Ctxt already open*/
371        openRetVal =  PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_ALREADY_INITIALISED);
372    }
373    else/*Do an initialization*/
374    {
375#ifdef ANDROID
376        dlopen_firmware();
377#endif
378
379        /*If hal4 ctxt in Hwreference is NULL create a new context*/
380        if(NULL == ((phHal_sHwReference_t *)psHwReference)->hal_context)
381        {
382            Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)
383                                phOsalNfc_GetMemory((uint32_t)sizeof(
384                                                        phHal4Nfc_Hal4Ctxt_t)
385                                                        );
386            ((phHal_sHwReference_t *)psHwReference)->hal_context = Hal4Ctxt;
387        }
388        else/*Take context from Hw reference*/
389        {
390            Hal4Ctxt = ((phHal_sHwReference_t *)psHwReference)->hal_context;
391        }
392        if(NULL == Hal4Ctxt)
393        {
394            openRetVal = PHNFCSTVAL(CID_NFC_HAL,
395                        NFCSTATUS_INSUFFICIENT_RESOURCES);
396        }
397        else
398        {
399            (void)memset((void *)Hal4Ctxt,
400                        0,
401                        ((uint32_t)sizeof(phHal4Nfc_Hal4Ctxt_t)));
402            /* Configure layers if not configured */
403            if( NULL == Hal4Ctxt->pHal4Nfc_LayerCfg )
404            {
405                openRetVal = phHal4Nfc_Configure_Layers(
406                                                  &(Hal4Ctxt->pHal4Nfc_LayerCfg)
407                                                  );
408            }
409
410            if( openRetVal == NFCSTATUS_SUCCESS )
411            {
412                /*update Next state*/
413                Hal4Ctxt->Hal4NextState = (HCI_NFC_DEVICE_TEST == eHciInitType?
414                                eHal4StateSelfTestMode:eHal4StateOpenAndReady);
415                /*Store callback and context ,and set Default settings in Context*/
416                Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb = pOpenCallback;
417                Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
418                Hal4Ctxt->sTgtConnectInfo.EmulationState = NFC_EVT_DEACTIVATED;
419                gpphHal4Nfc_Hwref = psHwReference;
420                PHDBG_INFO("Hal4:Calling Hci-Init");
421                openRetVal = phHciNfc_Initialise (
422                                        (void *)&Hal4Ctxt->psHciHandle,
423                                        psHwReference,
424                                        eHciInitType,
425                                        &sHwConfig,
426                                        (pphNfcIF_Notification_CB_t)
427                                            phHal4Nfc_LowerNotificationHandler,
428                                        (void *)Hal4Ctxt,
429                                        Hal4Ctxt->pHal4Nfc_LayerCfg
430                                        );
431                /*Hci Init did not succeed.free Resources and return*/
432                if( (openRetVal != NFCSTATUS_SUCCESS)
433                            && (PHNFCSTATUS (openRetVal) != NFCSTATUS_PENDING) )
434                {
435                    phOsalNfc_FreeMemory(Hal4Ctxt->pHal4Nfc_LayerCfg);
436                    phOsalNfc_FreeMemory(Hal4Ctxt);
437                    Hal4Ctxt = NULL;
438                }
439            }/*if( openRetVal == NFCSTATUS_SUCCESS )*/
440            else/*Free the context*/
441            {
442                phOsalNfc_FreeMemory(Hal4Ctxt);
443            }/*else*/
444        }
445    }
446    return openRetVal;
447}
448
449/**  The I/O Control function allows the caller to use (vendor-) specific
450*  functionality provided by the lower layer or by the hardware. */
451NFCSTATUS phHal4Nfc_Ioctl(
452                          phHal_sHwReference_t       *psHwReference,
453                          uint32_t                    IoctlCode,
454                          phNfc_sData_t              *pInParam,
455                          phNfc_sData_t              *pOutParam,
456                          pphHal4Nfc_IoctlCallback_t  pIoctlCallback,
457                          void                       *pContext
458                          )
459{
460    NFCSTATUS RetStatus = NFCSTATUS_FAILED;
461    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
462    uint32_t config_type = 0;
463    uint8_t ind = 0;
464    /*NULL checks*/
465    if((NULL == psHwReference)
466        || (NULL == pIoctlCallback)
467        )
468    {
469        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
470        RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
471    }
472    /*Only the Ioctls NFC_FW_DOWNLOAD_CHECK and NFC_FW_DOWNLOAD are allowed in
473      the uninitialized state of HAL*/
474    else if(NULL == psHwReference->hal_context)
475    {
476#ifdef FW_DOWNLOAD
477
478#if  !defined (NXP_FW_INTEGRITY_VERIFY)
479        if(NFC_FW_DOWNLOAD_CHECK == IoctlCode)
480        {
481            RetStatus = phDnldNfc_Run_Check(
482                psHwReference
483                );
484        }
485        else
486#endif /* !defined (NXP_FW_INTEGRITY_VERIFY) */
487        if((NFC_FW_DOWNLOAD == IoctlCode)
488            &&(NULL == gpphHal4Nfc_Hwref))/*Indicates current state is shutdown*/
489        {
490            Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)
491                phOsalNfc_GetMemory((uint32_t)sizeof(
492                                                phHal4Nfc_Hal4Ctxt_t)
493                                                );
494            if(NULL == Hal4Ctxt)
495            {
496                RetStatus = PHNFCSTVAL(CID_NFC_HAL,
497                    NFCSTATUS_INSUFFICIENT_RESOURCES);
498            }
499            else
500            {
501                ((phHal_sHwReference_t *)psHwReference)->hal_context
502                    = Hal4Ctxt;
503                (void)memset((void *)Hal4Ctxt,
504                                 0,
505                                   ((uint32_t)sizeof(phHal4Nfc_Hal4Ctxt_t)));
506                Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
507                Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb
508                    = pIoctlCallback;/*Register upper layer callback*/
509                Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam = pOutParam;
510                /*Upgrade the firmware*/
511                RetStatus = phDnldNfc_Upgrade (
512                        psHwReference,
513                        phHal4Nfc_DownloadComplete,
514                        Hal4Ctxt
515                        );
516                if((NFCSTATUS_SUCCESS == RetStatus)
517                    || (NFCSTATUS_PENDING != PHNFCSTATUS(RetStatus))
518                    )
519                {
520                    phOsalNfc_FreeMemory(Hal4Ctxt);
521                    ((phHal_sHwReference_t *)psHwReference)->hal_context = NULL;
522                }
523            }
524        }
525        else
526#endif/*NFC_FW_DOWNLOAD*/
527        {
528            RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED);
529        }
530    }
531    else/*Status is Initialised*/
532    {
533        /*Register upper layer context*/
534        Hal4Ctxt = psHwReference->hal_context;
535        Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam = pOutParam;
536        switch(IoctlCode)
537        {
538        /*Self test Ioctls*/
539        case DEVMGMT_ANTENNA_TEST:
540        case DEVMGMT_SWP_TEST:
541        case DEVMGMT_NFCWI_TEST:
542            if(eHal4StateSelfTestMode ==Hal4Ctxt->Hal4CurrentState)
543            {
544                RetStatus = phHciNfc_System_Test(
545                    Hal4Ctxt->psHciHandle,
546                    (void *)psHwReference,
547                    IoctlCode ,
548                    pInParam
549                    );
550            }
551            break;
552        /*PRBS Test*/
553        case DEVMGMT_PRBS_TEST:
554            RetStatus = phHciNfc_PRBS_Test(
555                Hal4Ctxt->psHciHandle,
556                (void *)psHwReference,
557                IoctlCode ,
558                pInParam
559                );
560            break;
561        /*To Set Antenna Power Level*/
562        case NFC_ANTENNA_CWG:
563            if(eHal4StateSelfTestMode ==Hal4Ctxt->Hal4CurrentState)
564            {
565                RetStatus = phHciNfc_System_Configure (
566                    Hal4Ctxt->psHciHandle,
567                    (void *)psHwReference,
568                    NFC_ANTENNA_CWG,
569                    pInParam->buffer[0] /**Set Power Level*/
570                    );
571
572            }
573            break;
574        /*Not allowed when Init is complete*/
575        case NFC_FW_DOWNLOAD_CHECK:
576        case NFC_FW_DOWNLOAD:
577            RetStatus = PHNFCSTVAL(CID_NFC_HAL,
578                NFCSTATUS_BUSY);
579            break;
580        /*Gpio read*/
581        case NFC_GPIO_READ:
582            /* if(eHal4StateSelfTestMode == Hal4Ctxt->Hal4CurrentState) */
583            {
584                RetStatus = phHciNfc_System_Get_Info(
585                    Hal4Ctxt->psHciHandle,
586                    (void *)psHwReference,
587                    IoctlCode ,
588                    pOutParam->buffer
589                    );
590            }
591            break;
592        /*Used to Read Memory/Registers .3 bytes of Array passed form the
593          address to read from in MSB first format.*/
594        case NFC_MEM_READ:
595            {
596                if((NULL != pInParam)
597                    && (pInParam->length == 3))
598                {
599                    for( ind = 0; ind < 3; ind++ )
600                    {
601                        config_type = ((config_type << BYTE_SIZE )
602                                        | (pInParam->buffer[ind] ));
603                    }
604                    RetStatus = phHciNfc_System_Get_Info(
605                        Hal4Ctxt->psHciHandle,
606                        (void *)psHwReference,
607                        config_type ,
608                        pOutParam->buffer
609                        );
610                }
611                else
612                {
613                    RetStatus = PHNFCSTVAL(CID_NFC_HAL,
614                        NFCSTATUS_INVALID_PARAMETER);
615                }
616            }
617            break;
618        /*Used to Write Memory/Registers .First 3 bytes of Array passed in MSB
619          first format form the address to write to.The 4th Byte is the 8 bit
620          value to be written to the address*/
621        case NFC_MEM_WRITE:
622            {
623                if((NULL != pInParam)
624                    && (pInParam->length == 4))
625                {
626                    for( ind = 0; ind < 3; ind++ )
627                    {
628                        config_type = ((config_type << BYTE_SIZE )
629                                        | (pInParam->buffer[ind] ));
630                    }
631                    RetStatus = phHciNfc_System_Configure (
632                        Hal4Ctxt->psHciHandle,
633                        (void *)psHwReference,
634                        config_type,
635                        pInParam->buffer[3] /*config value*/
636                        );
637                }
638                else
639                {
640                    RetStatus = PHNFCSTVAL(CID_NFC_HAL ,
641                        NFCSTATUS_INVALID_PARAMETER);
642                }
643            }
644            break;
645        default:
646            break;
647        }
648        if(NFCSTATUS_PENDING == RetStatus)/*Callback Pending*/
649        {
650            /*Register upper layer callback and context*/
651            Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
652            Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb= pIoctlCallback;
653            /*Store the Ioctl code*/
654            Hal4Ctxt->Ioctl_Type = IoctlCode;
655        }
656    }
657    return RetStatus;
658}
659
660
661/**
662 *  The close function called by the upper layer when HAL4 is to be closed
663 *  (shutdown).
664 */
665NFCSTATUS phHal4Nfc_Close(
666                          phHal_sHwReference_t *psHwReference,
667                          pphHal4Nfc_GenCallback_t pCloseCallback,
668                          void *pContext
669                          )
670{
671    NFCSTATUS closeRetVal = NFCSTATUS_SUCCESS;
672    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
673    /*NULL checks*/
674    if(NULL == psHwReference || NULL == pCloseCallback)
675    {
676        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
677        closeRetVal = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
678    }
679    else if((NULL == psHwReference->hal_context)
680                        || (((phHal4Nfc_Hal4Ctxt_t *)
681                                psHwReference->hal_context)->Hal4CurrentState
682                                               < eHal4StateSelfTestMode)
683                        || (((phHal4Nfc_Hal4Ctxt_t *)
684                                psHwReference->hal_context)->Hal4NextState
685                                               == eHal4StateClosed))
686    {
687        /*return already closed*/
688        closeRetVal= PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_NOT_INITIALISED);
689    }
690    else  /*Close the HAL*/
691    {
692        /*Get Hal4 context from Hw reference*/
693        Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)((phHal_sHwReference_t *)
694                                               psHwReference)->hal_context;
695        /*Unregister Tag Listener*/
696        if(NULL != Hal4Ctxt->psADDCtxtInfo)
697        {
698            Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
699        }
700        /*store Callback and Context*/
701        Hal4Ctxt->sUpperLayerInfo.pUpperCloseCb = pCloseCallback;
702        Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
703        /*Call Hci Release*/
704        PHDBG_INFO("Hal4:Calling Hci Release");
705        closeRetVal =(NFCSTATUS)phHciNfc_Release(
706                                    (void *)Hal4Ctxt->psHciHandle,
707                                    psHwReference,
708                                    (pphNfcIF_Notification_CB_t)
709                                    phHal4Nfc_LowerNotificationHandler,
710                                    (void *)Hal4Ctxt
711                                    );
712        /*Update Next state and exit*/
713        if( PHNFCSTATUS (closeRetVal) == NFCSTATUS_PENDING )
714        {
715            Hal4Ctxt->Hal4NextState = eHal4StateClosed;
716            Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
717        }
718        else
719        {
720
721        }
722    }
723    return closeRetVal;
724}
725
726/*Forcibly shutdown the HAl4.Frees all Resources in use by Hal4 before shutting
727  down*/
728void phHal4Nfc_Hal4Reset(
729                         phHal_sHwReference_t *pHwRef,
730                         void                 *pContext
731                         )
732{
733    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
734    NFCSTATUS             closeRetVal = NFCSTATUS_SUCCESS;
735    uint8_t               RemoteDevNumber = 0;
736    if(pHwRef ==NULL)
737    {
738        closeRetVal = PHNFCSTVAL(CID_NFC_HAL , NFCSTATUS_INVALID_PARAMETER);
739    }
740    else if(pHwRef->hal_context != NULL)
741    {
742        /*Get the Hal context*/
743        Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pHwRef->hal_context;
744        /*store the upper layer context*/
745        Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
746        Hal4Ctxt->Hal4NextState = eHal4StateClosed;
747        Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
748        /*Call Hci Release*/
749        PHDBG_INFO("Hal4:Calling Hci Release");
750        closeRetVal =(NFCSTATUS)phHciNfc_Release(
751                                            (void *)Hal4Ctxt->psHciHandle,
752                                            pHwRef,
753                                            (pphNfcIF_Notification_CB_t)NULL,
754                                            (void *)Hal4Ctxt
755                                            );/*Clean up Hci*/
756        Hal4Ctxt->Hal4CurrentState = eHal4StateClosed;
757        phOsalNfc_FreeMemory((void *)Hal4Ctxt->pHal4Nfc_LayerCfg);
758        Hal4Ctxt->pHal4Nfc_LayerCfg = NULL;
759        /*Free ADD context*/
760        if(NULL != Hal4Ctxt->psADDCtxtInfo)
761        {
762            Hal4Ctxt->sUpperLayerInfo.pTagDiscoveryNotification = NULL;
763            while(RemoteDevNumber < MAX_REMOTE_DEVICES)
764            {
765                if(NULL != Hal4Ctxt->rem_dev_list[RemoteDevNumber])
766                {
767                    phOsalNfc_FreeMemory((void *)
768                            (Hal4Ctxt->rem_dev_list[RemoteDevNumber]));
769                    Hal4Ctxt->rem_dev_list[RemoteDevNumber] = NULL;
770                }
771                RemoteDevNumber++;
772            }
773            Hal4Ctxt->psADDCtxtInfo->nbr_of_devices = 0;
774            phOsalNfc_FreeMemory(Hal4Ctxt->psADDCtxtInfo);
775        }
776        /*Free Trcv context*/
777        if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
778        {
779            if(NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer)
780            {
781                phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo
782                                                    ->sLowerRecvData.buffer);
783            }
784            if((NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
785                && (NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData))
786            {
787                phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData);
788            }
789            phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo);
790        }
791        phOsalNfc_FreeMemory(Hal4Ctxt);/*Free the context*/
792        pHwRef->hal_context = NULL;
793        gpphHal4Nfc_Hwref = NULL;
794    }
795    else
796    {
797        /*Hal4 Context is already closed.Return Success*/
798    }
799    /*Reset Should always return Success*/
800    if(closeRetVal != NFCSTATUS_SUCCESS)
801    {
802        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
803    }
804    return;
805}
806
807/**
808 *  \if hal
809 *   \ingroup grp_hal_common
810 *  \else
811 *   \ingroup grp_mw_external_hal_funcs
812 *  \endif
813 *
814 *  Retrieves the capabilities of the device represented by the Hardware
815 *  Reference parameter.
816 *  The HW, SW versions, the MTU and other mandatory information are located
817 *  inside the pDevCapabilities parameter.
818 */
819NFCSTATUS phHal4Nfc_GetDeviceCapabilities(
820                            phHal_sHwReference_t          *psHwReference,
821                            phHal_sDeviceCapabilities_t   *psDevCapabilities,
822                            void                          *pContext
823                            )
824{
825    NFCSTATUS retstatus = NFCSTATUS_SUCCESS;
826    /*NULL checks*/
827    if(psDevCapabilities == NULL || psHwReference == NULL || pContext == NULL)
828    {
829        retstatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
830    }
831    /*Check for Initialized state*/
832    else if((NULL == psHwReference->hal_context)
833                        || (((phHal4Nfc_Hal4Ctxt_t *)
834                                psHwReference->hal_context)->Hal4CurrentState
835                                               < eHal4StateOpenAndReady)
836                        || (((phHal4Nfc_Hal4Ctxt_t *)
837                                psHwReference->hal_context)->Hal4NextState
838                                               == eHal4StateClosed))
839    {
840        retstatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED);
841    }
842    else/*Provide Device capabilities and Version Info to the caller*/
843    {
844        (void)memcpy((void *)psDevCapabilities,
845            (void *)&(psHwReference->device_info),
846            sizeof(phHal_sDeviceCapabilities_t));
847        psDevCapabilities->ReaderSupProtocol.Felica         = TRUE;
848        psDevCapabilities->ReaderSupProtocol.ISO14443_4A    = TRUE;
849        psDevCapabilities->ReaderSupProtocol.ISO14443_4B    = TRUE;
850        psDevCapabilities->ReaderSupProtocol.ISO15693       = TRUE;
851        psDevCapabilities->ReaderSupProtocol.Jewel          = TRUE;
852        psDevCapabilities->ReaderSupProtocol.MifareStd      = TRUE;
853        psDevCapabilities->ReaderSupProtocol.MifareUL       = TRUE;
854        psDevCapabilities->ReaderSupProtocol.NFC            = TRUE;
855        psDevCapabilities->EmulationSupProtocol.Felica      = FALSE;
856        psDevCapabilities->EmulationSupProtocol.ISO14443_4A = FALSE;
857        psDevCapabilities->EmulationSupProtocol.ISO14443_4B = FALSE;
858        psDevCapabilities->EmulationSupProtocol.ISO15693    = FALSE;
859        psDevCapabilities->EmulationSupProtocol.Jewel       = FALSE;
860        psDevCapabilities->EmulationSupProtocol.MifareStd   = FALSE;
861        psDevCapabilities->EmulationSupProtocol.MifareUL    = FALSE;
862        psDevCapabilities->EmulationSupProtocol.NFC         = TRUE;
863        psDevCapabilities->hal_version = (
864                    (((PH_HAL4NFC_INTERFACE_VERSION << BYTE_SIZE)
865                      |(PH_HAL4NFC_INTERFACE_REVISION)<<BYTE_SIZE)
866                      |(PH_HAL4NFC_INTERFACE_PATCH)<<BYTE_SIZE)
867                      |PH_HAL4NFC_INTERAFECE_BUILD
868                      );
869    }
870    return retstatus;
871}
872
873/*
874 * Handles all notifications received from HCI layer.
875 *
876 */
877static void phHal4Nfc_LowerNotificationHandler(
878                                    void    *pContext,
879                                    void    *pHwRef,
880                                    uint8_t  type,
881                                    void     *pInfo
882                                    )
883{
884    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
885    if((NULL == pInfo) || (NULL == pHwRef)
886        || (NULL == pContext))
887    {
888        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
889    }
890    else
891    {
892        /*A copy of hardware reference is maintained in HAL for comparing passed
893          and returned context.Set to NULL after a Shutdown*/
894        if(NULL != gpphHal4Nfc_Hwref)/*Get context from Hw ref*/
895        {
896            Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)gpphHal4Nfc_Hwref->hal_context;
897            if(NFC_INVALID_RELEASE_TYPE == Hal4Ctxt->sTgtConnectInfo.ReleaseType)
898            {
899                Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pContext;
900                gpphHal4Nfc_Hwref = (phHal_sHwReference_t *)pHwRef;
901            }
902        }
903        else/*No Copy of Hw ref in HAL.Copy both Hwref and Hal context passed
904             by Hci*/
905        {
906            Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pContext;
907            gpphHal4Nfc_Hwref = (phHal_sHwReference_t *)pHwRef;
908        }
909        /*Check the type of notification received from Hci and handle it
910          accordingly*/
911        switch(type)
912        {
913            case NFC_NOTIFY_INIT_COMPLETED:
914            case NFC_NOTIFY_INIT_FAILED:
915                phHal4Nfc_OpenComplete(Hal4Ctxt,pInfo);
916                break;
917            case NFC_IO_SUCCESS:
918            case NFC_IO_ERROR:
919                phHal4Nfc_IoctlComplete(Hal4Ctxt,pInfo);
920                break;
921            case NFC_NOTIFY_RESULT:
922                phHal4Nfc_SelfTestComplete(Hal4Ctxt,pInfo);
923                break;
924            case NFC_NOTIFY_DEINIT_COMPLETED:
925            case NFC_NOTIFY_DEINIT_FAILED:
926                phHal4Nfc_CloseComplete(Hal4Ctxt,pInfo);
927                break;
928            case NFC_NOTIFY_POLL_ENABLED:
929            case NFC_NOTIFY_POLL_DISABLED:
930            case NFC_NOTIFY_POLL_RESTARTED:
931            case NFC_NOTIFY_CONFIG_ERROR:
932            case NFC_NOTIFY_CONFIG_SUCCESS:
933                phHal4Nfc_ConfigureComplete(Hal4Ctxt,pInfo,type);
934                break;
935            case NFC_NOTIFY_TARGET_DISCOVERED:
936            case NFC_NOTIFY_DISCOVERY_ERROR:
937                phHal4Nfc_TargetDiscoveryComplete(Hal4Ctxt,pInfo);
938                break;
939            case NFC_NOTIFY_TARGET_REACTIVATED:
940                phHal4Nfc_ReactivationComplete(Hal4Ctxt,pInfo);
941                break;
942            case NFC_NOTIFY_EVENT:
943                PHDBG_INFO("Hal4:Calling Event callback");
944                phHal4Nfc_HandleEvent(Hal4Ctxt,pInfo);
945                break;
946            case NFC_NOTIFY_TARGET_CONNECTED:
947                PHDBG_INFO("Hal4:Calling Hal4 Connect complete");
948                phHal4Nfc_ConnectComplete(Hal4Ctxt,pInfo);
949                break;
950
951            case NFC_NOTIFY_TARGET_DISCONNECTED:
952            {
953                PHDBG_INFO("Hal4:Target Disconnected");
954                if(Hal4Ctxt->Hal4NextState == eHal4StatePresenceCheck)
955                {
956                    phHal4Nfc_PresenceChkComplete(Hal4Ctxt,pInfo);
957                }
958                else
959                {
960                    phHal4Nfc_DisconnectComplete(Hal4Ctxt,pInfo);
961                }
962                break;
963            }
964            case NFC_NOTIFY_TRANSCEIVE_COMPLETED:
965            case NFC_NOTIFY_TRANSCEIVE_ERROR    :
966                PHDBG_INFO("Hal4:Transceive Callback");
967                if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
968                {
969#ifdef TRANSACTION_TIMER
970                    if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
971                        != PH_OSALNFC_INVALID_TIMER_ID)
972                    {
973                        phOsalNfc_Timer_Stop(
974                            Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
975                            );
976                        phOsalNfc_Timer_Delete(
977                            Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
978                            );
979                        Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
980                                    = PH_OSALNFC_INVALID_TIMER_ID;
981                    }
982#endif /*TRANSACTION_TIMER*/
983                    phHal4Nfc_TransceiveComplete(Hal4Ctxt,pInfo);
984                }
985                break;
986            case NFC_NOTIFY_SEND_COMPLETED   :
987                PHDBG_INFO("Hal4:NfcIp1 Send Callback");
988                if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
989                {
990                    phHal4Nfc_SendCompleteHandler(Hal4Ctxt,pInfo);
991                }
992                break;
993            case NFC_NOTIFY_TRANSACTION  :
994                phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
995                break;
996            case NFC_NOTIFY_RECV_ERROR    :
997            case NFC_NOTIFY_RECV_EVENT    :
998                PHDBG_INFO("Hal4:Receive Event");
999                if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
1000                {
1001                    if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
1002                        != PH_OSALNFC_INVALID_TIMER_ID)
1003                    {
1004                        phOsalNfc_Timer_Stop(
1005                            Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
1006                            );
1007                        phOsalNfc_Timer_Delete(
1008                            Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
1009                            );
1010                        Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
1011                            = PH_OSALNFC_INVALID_TIMER_ID;
1012                    }
1013                }
1014                phHal4Nfc_RecvCompleteHandler(Hal4Ctxt,pInfo);
1015                break;
1016            case NFC_NOTIFY_TARGET_PRESENT:
1017                phHal4Nfc_PresenceChkComplete(Hal4Ctxt,pInfo);
1018                break;
1019            case NFC_NOTIFY_DEVICE_ERROR:
1020            {
1021                NFCSTATUS status = NFCSTATUS_BOARD_COMMUNICATION_ERROR;
1022                pphHal4Nfc_GenCallback_t pUpper_OpenCb
1023                                                = Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb;
1024                void                   *pUpper_Context
1025                                            = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
1026                static phHal4Nfc_NotificationInfo_t uNotificationInfo;
1027                if(NULL != Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler)
1028                {
1029                    Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
1030                    Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler(
1031                        Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt,
1032                        NFC_EVENT_NOTIFICATION,
1033                        uNotificationInfo,
1034                        NFCSTATUS_BOARD_COMMUNICATION_ERROR
1035                        );
1036                }
1037                else if (( eHal4StateSelfTestMode == Hal4Ctxt->Hal4NextState )
1038                    || ( eHal4StateOpenAndReady == Hal4Ctxt->Hal4NextState ) )
1039                {
1040                    Hal4Ctxt->Hal4CurrentState = eHal4StateClosed;
1041                    Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
1042                    (void)phHciNfc_Release((void *)Hal4Ctxt->psHciHandle,
1043                                              pHwRef, (pphNfcIF_Notification_CB_t)NULL,
1044                                               (void *)Hal4Ctxt);/*Clean up Hci*/
1045                    Hal4Ctxt->psHciHandle = NULL;
1046                    phOsalNfc_FreeMemory((void *)Hal4Ctxt->pHal4Nfc_LayerCfg);
1047                    Hal4Ctxt->pHal4Nfc_LayerCfg = NULL;
1048                    phOsalNfc_FreeMemory((void *)Hal4Ctxt);
1049                    gpphHal4Nfc_Hwref->hal_context = NULL;
1050                    gpphHal4Nfc_Hwref = NULL;
1051                    PHDBG_INFO("Hal4:Open Failed");
1052                    /*Call upper layer's Open Cb with error status*/
1053                    if(NULL != pUpper_OpenCb)
1054                    {
1055                        /*Upper layer's Open Cb*/
1056                        (*pUpper_OpenCb)(pUpper_Context,status);
1057                    }
1058                }
1059                else
1060                {
1061                    Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
1062                    phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1);
1063                }
1064                break;
1065            }
1066            case NFC_NOTIFY_CONNECT_FAILED:
1067            case NFC_NOTIFY_DISCONNECT_FAILED:
1068            /*Generic Error type received from Hci.Handle the error based on
1069              Hal4 next state and which past callback was Pending*/
1070            case NFC_NOTIFY_ERROR:
1071            {
1072                PHDBG_WARNING("Hal4:Error Notification from HCI");
1073                switch(Hal4Ctxt->Hal4NextState)
1074                {
1075                    case eHal4StateClosed:
1076                        phHal4Nfc_CloseComplete(Hal4Ctxt,pInfo);
1077                        break;
1078                    case eHal4StateSelfTestMode:
1079                        phHal4Nfc_SelfTestComplete(Hal4Ctxt,pInfo);
1080                        break;
1081                    case eHal4StateConfiguring:
1082                        phHal4Nfc_ConfigureComplete(Hal4Ctxt,pInfo,type);
1083                        break;
1084                    case eHal4StateTargetDiscovered:
1085                    case eHal4StateTargetActivate:
1086                    {
1087                        if(NULL != Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb)
1088                        {
1089                            if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
1090                            {
1091                                 phHal4Nfc_ConfigureComplete(Hal4Ctxt,pInfo,type);
1092                            }
1093                            else
1094                            {
1095                                phHal4Nfc_ConnectComplete(Hal4Ctxt,pInfo);
1096                            }
1097                        }
1098                        else
1099                        {
1100                            phHal4Nfc_TargetDiscoveryComplete(Hal4Ctxt,pInfo);
1101                        }
1102                        break;
1103                    }
1104                    case eHal4StateTargetConnected:
1105                        phHal4Nfc_ConnectComplete(Hal4Ctxt,pInfo);
1106                        break;
1107                    case eHal4StateOpenAndReady:
1108                        phHal4Nfc_DisconnectComplete(Hal4Ctxt,pInfo);
1109                        break;
1110                    case eHal4StatePresenceCheck:
1111                        phHal4Nfc_PresenceChkComplete(Hal4Ctxt,pInfo);
1112                        break;
1113                    default:
1114                        PHDBG_WARNING("Unknown Error notification");
1115                        break;
1116                }
1117                break;
1118            }/*End of switch(Hal4Ctxt->Hal4State)*/
1119            default:
1120                phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
1121                break;
1122        }/*End of switch(type)*/
1123    }
1124    return;
1125}
1126
1127
1128/*Event handler for HAL-HCI interface*/
1129static void phHal4Nfc_HandleEvent(
1130                       phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
1131                       void *pInfo
1132                       )
1133{
1134    phHal_sEventInfo_t *psEventInfo = (phHal_sEventInfo_t *)pInfo;
1135    static phNfc_sNotificationInfo_t sNotificationInfo;
1136    phHal4Nfc_NotificationInfo_t uNotificationInfo = {NULL};
1137    NFCSTATUS RetStatus = NFCSTATUS_FAILED;
1138    /*Check if Hal4 Close has already been called*/
1139    if(eHal4StateClosed != Hal4Ctxt->Hal4NextState)
1140    {
1141        switch(psEventInfo->eventType)
1142        {
1143        case NFC_EVT_ACTIVATED:/*Target Activated*/
1144        {
1145            if(psEventInfo->eventHost == phHal_eHostController)
1146            {
1147                switch(psEventInfo->eventSource)
1148                {
1149                    case phHal_eNfcIP1_Target:
1150                        phHal4Nfc_P2PActivateComplete(Hal4Ctxt,pInfo);
1151                        break;
1152                    case phHal_eISO14443_A_PICC:
1153                    case phHal_eISO14443_B_PICC:
1154                        sNotificationInfo.info = psEventInfo;
1155                        sNotificationInfo.status = NFCSTATUS_SUCCESS;
1156                        sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
1157                        pInfo = &sNotificationInfo;
1158                        phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
1159                        break;
1160                    default:
1161                        break;
1162                }
1163            }
1164        }
1165            break;
1166        case NFC_EVT_DEACTIVATED:/*Target Deactivated*/
1167        {
1168            if(psEventInfo->eventHost == phHal_eHostController)
1169            {
1170                switch(psEventInfo->eventSource)
1171                {
1172                case phHal_eNfcIP1_Target:
1173                    phHal4Nfc_HandleP2PDeActivate(Hal4Ctxt,pInfo);
1174                    break;
1175                case phHal_eISO14443_A_PICC:
1176                case phHal_eISO14443_B_PICC:
1177                    sNotificationInfo.info = psEventInfo;
1178                    sNotificationInfo.status = NFCSTATUS_SUCCESS;
1179                    sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
1180                    pInfo = &sNotificationInfo;
1181                    phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
1182                    break;
1183                default:
1184                    break;
1185                }
1186            }
1187        }
1188            break;
1189        /*Set Protection Event*/
1190        case NFC_EVT_PROTECTED:
1191        {
1192#ifdef IGNORE_EVT_PROTECTED
1193            /*Ignore_Event_Protected is set to false during Field Off event and
1194              Set protection Configuration.After a NFC_EVT_PROTECTED is received
1195              once all subsequent NFC_EVT_PROTECTED events are ignored*/
1196            if(FALSE == Hal4Ctxt->Ignore_Event_Protected)
1197            {
1198                Hal4Ctxt->Ignore_Event_Protected = TRUE;
1199#endif/*#ifdef IGNORE_EVT_PROTECTED*/
1200                sNotificationInfo.info = psEventInfo;
1201                sNotificationInfo.status = NFCSTATUS_SUCCESS;
1202                sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
1203                pInfo = &sNotificationInfo;
1204                phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
1205#ifdef IGNORE_EVT_PROTECTED
1206            }
1207#endif/*#ifdef IGNORE_EVT_PROTECTED*/
1208            break;
1209        }
1210        /*NFC_UICC_RDPHASES_DEACTIVATE_REQ*/
1211        case NFC_UICC_RDPHASES_DEACTIVATE_REQ:
1212        {
1213            if(NULL != gpphHal4Nfc_Hwref)
1214            {
1215                gpphHal4Nfc_Hwref->uicc_rdr_active = FALSE;
1216            }
1217            break;
1218        }
1219        case NFC_UICC_RDPHASES_ACTIVATE_REQ:
1220        {
1221            if(NULL != gpphHal4Nfc_Hwref)
1222            {
1223                gpphHal4Nfc_Hwref->uicc_rdr_active = TRUE;
1224            }
1225            /*If a NFC_UICC_RDPHASES_ACTIVATE_REQ is received before a configure
1226             discovery,then create a ADD context info*/
1227            if (NULL == Hal4Ctxt->psADDCtxtInfo)
1228            {
1229                Hal4Ctxt->psADDCtxtInfo= (pphHal4Nfc_ADDCtxtInfo_t)
1230                    phOsalNfc_GetMemory((uint32_t)
1231                    (sizeof(phHal4Nfc_ADDCtxtInfo_t)));
1232                if(NULL != Hal4Ctxt->psADDCtxtInfo)
1233                {
1234                    (void)memset(Hal4Ctxt->psADDCtxtInfo,0,
1235                        sizeof(phHal4Nfc_ADDCtxtInfo_t)
1236                        );
1237                }
1238            }
1239            if(NULL != Hal4Ctxt->psADDCtxtInfo)
1240            {
1241                Hal4Ctxt->psADDCtxtInfo->sADDCfg.PollDevInfo.PollEnabled
1242                                |= psEventInfo->eventInfo.rd_phases;
1243                /*Configure HCI Discovery*/
1244                RetStatus = phHciNfc_Config_Discovery(
1245                    (void *)Hal4Ctxt->psHciHandle,
1246                    gpphHal4Nfc_Hwref,
1247                    &(Hal4Ctxt->psADDCtxtInfo->sADDCfg)
1248                    );
1249                Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == RetStatus?
1250                                                eHal4StateConfiguring:
1251                                                Hal4Ctxt->Hal4NextState);
1252            }
1253            break;
1254        }
1255        /*Call Default Event handler for these Events*/
1256        case NFC_INFO_TXLDO_OVERCUR:
1257        case NFC_INFO_MEM_VIOLATION:
1258        case NFC_INFO_TEMP_OVERHEAT:
1259        case NFC_INFO_LLC_ERROR:
1260        {
1261            sNotificationInfo.info = psEventInfo;
1262            sNotificationInfo.status = NFCSTATUS_SUCCESS;
1263            sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
1264            pInfo = &sNotificationInfo;
1265            PHDBG_INFO("Hal4:Exception events");
1266            if(NULL != Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler)
1267            {
1268                /*Pass on Event notification info from Hci to Upper layer*/
1269                uNotificationInfo.psEventInfo = psEventInfo;
1270                Hal4Ctxt->sUpperLayerInfo.pDefaultEventHandler(
1271                    Hal4Ctxt->sUpperLayerInfo.DefaultListenerCtxt,
1272                    sNotificationInfo.type,
1273                    uNotificationInfo,
1274                    NFCSTATUS_SUCCESS
1275                    );
1276            }
1277            break;
1278        }
1279        /*Call emulation Event handler fto handle these Events*/
1280        case NFC_EVT_TRANSACTION:
1281        case NFC_EVT_START_OF_TRANSACTION:
1282        case NFC_EVT_END_OF_TRANSACTION:
1283        case NFC_EVT_CONNECTIVITY:
1284        case NFC_EVT_OPERATION_ENDED:
1285        case NFC_EVT_MIFARE_ACCESS:
1286        case NFC_EVT_APDU_RECEIVED:
1287        case NFC_EVT_EMV_CARD_REMOVAL:
1288            sNotificationInfo.info = psEventInfo;
1289            sNotificationInfo.status = NFCSTATUS_SUCCESS;
1290            sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
1291            pInfo = &sNotificationInfo;
1292            PHDBG_INFO("Hal4:Event transaction\n");
1293            phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
1294            break;
1295        case NFC_EVT_FIELD_ON:
1296            Hal4Ctxt->psEventInfo = sNotificationInfo.info = psEventInfo;
1297            sNotificationInfo.status = NFCSTATUS_SUCCESS;
1298            sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
1299            pInfo = &sNotificationInfo;
1300            PHDBG_INFO("Hal4:Event Field ON\n");
1301            phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
1302            break;
1303        case NFC_EVT_FIELD_OFF:
1304    #ifdef IGNORE_EVT_PROTECTED
1305            Hal4Ctxt->Ignore_Event_Protected = FALSE;
1306    #endif/*#ifdef IGNORE_EVT_PROTECTED*/
1307            Hal4Ctxt->psEventInfo = sNotificationInfo.info = psEventInfo;
1308            sNotificationInfo.status = NFCSTATUS_SUCCESS;
1309            sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
1310            pInfo = &sNotificationInfo;
1311            PHDBG_INFO("Hal4:Event Field OFF\n");
1312            phHal4Nfc_HandleEmulationEvent(Hal4Ctxt,pInfo);
1313            break;
1314        default:
1315            PHDBG_WARNING("Hal4:Unhandled Event type received");
1316            break;
1317        }/*End of switch*/
1318    }/*if(eHal4StateClosed != Hal4Ctxt->Hal4NextState)*/
1319    return;
1320}
1321
1322
1323/*Callback handler for Self Test Ioctl completion*/
1324static void phHal4Nfc_SelfTestComplete(
1325                                       phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
1326                                       void *pInfo
1327                                       )
1328{
1329    NFCSTATUS status = NFCSTATUS_FAILED;
1330    phNfc_sData_t *SelfTestResults
1331        = (phNfc_sData_t *)(((phNfc_sCompletionInfo_t *)pInfo)->info);
1332    pphHal4Nfc_IoctlCallback_t pUpper_IoctlCb
1333        = Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb;
1334    void  *pUpper_Context = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
1335    /*check for Success*/
1336    if(( DEVMGMT_SWP_TEST == Hal4Ctxt->Ioctl_Type )
1337        || ( DEVMGMT_ANTENNA_TEST == Hal4Ctxt->Ioctl_Type ))
1338    {
1339        status = NFCSTATUS_SUCCESS;
1340    }
1341    else if((SelfTestResults->length > 0) && (0 == SelfTestResults->buffer[0]))
1342    {
1343        status = NFCSTATUS_SUCCESS;
1344    }
1345    else
1346    {
1347        if (NULL != pInfo)
1348        {
1349            status = ((phNfc_sCompletionInfo_t *)pInfo)->status;
1350        }
1351    }
1352
1353    /*Copy response buffer and length*/
1354    (void)memcpy(Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam->buffer,
1355                 SelfTestResults->buffer,
1356                 SelfTestResults->length);
1357    Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam->length
1358                                        = SelfTestResults->length;
1359    /*Call registered Ioctl callback*/
1360    (*pUpper_IoctlCb)(
1361                pUpper_Context,
1362                Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam,
1363                status
1364                );
1365    return;
1366}
1367
1368
1369static void phHal4Nfc_IoctlComplete(
1370                                    phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
1371                                    void *pInfo
1372                                    )
1373{
1374    /*Copy status*/
1375    NFCSTATUS status = (((phNfc_sCompletionInfo_t *)pInfo)->status);
1376    pphHal4Nfc_IoctlCallback_t pUpper_IoctlCb
1377                                    = Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb;
1378#ifdef MERGE_SAK_SW2
1379    pphHal4Nfc_GenCallback_t pConfigCallback =
1380        Hal4Ctxt->sUpperLayerInfo.pConfigCallback;
1381#endif/*#ifdef MERGE_SAK_SW2*/
1382    void  *pUpper_Context = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
1383    Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb = NULL;
1384#ifdef MERGE_SAK_SW1 /*Software workaround 1*/
1385    if(eHal4StateOpenAndReady == Hal4Ctxt->Hal4NextState)
1386    {
1387        Hal4Ctxt->Hal4CurrentState = Hal4Ctxt->Hal4NextState;
1388        Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
1389        /*Upper layer's Open Cb*/
1390        (*Hal4Ctxt->sUpperLayerInfo.pUpperOpenCb)(
1391            Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
1392            NFCSTATUS_SUCCESS
1393            );
1394    }
1395#endif/*#ifdef MERGE_SAK_SW1*/
1396#ifdef MERGE_SAK_SW2 /*Software workaround 2*/
1397    else if((eHal4StateConfiguring == Hal4Ctxt->Hal4NextState)
1398            &&(NULL != pConfigCallback))
1399    {
1400        Hal4Ctxt->sUpperLayerInfo.pConfigCallback = NULL;
1401        Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
1402        (*pConfigCallback)(
1403            Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,status
1404            );
1405    }
1406    else
1407#endif/*#ifdef MERGE_SAK_SW2*/
1408    {
1409        /*for NFC_MEM_READ and NFC_GPIO_READ ,provide one Byte Response*/
1410        if ((NFC_MEM_READ == Hal4Ctxt->Ioctl_Type)
1411            || (NFC_GPIO_READ == Hal4Ctxt->Ioctl_Type)
1412            )
1413        {
1414            Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam->length
1415                = sizeof (uint8_t);
1416        }
1417         /*Call registered Ioctl callback*/
1418        if(NULL != pUpper_IoctlCb)
1419        {
1420            (*pUpper_IoctlCb)(
1421                pUpper_Context,
1422                Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam,
1423                status
1424                );
1425        }
1426    }
1427    return;
1428}
1429
1430#ifdef FW_DOWNLOAD
1431/**Callback handler for Download completion*/
1432STATIC void phHal4Nfc_DownloadComplete(
1433                                void *pContext,
1434                                void *pHwRef,
1435                                uint8_t type,
1436                                void *pInfo
1437                                )
1438{
1439    phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
1440    NFCSTATUS status = NFCSTATUS_FAILED;
1441    pphHal4Nfc_IoctlCallback_t pUpper_DnldCb = NULL;
1442    phNfc_sData_t *pIoctlOutParam = NULL;
1443    phHal_sHwReference_t *psHwRef = NULL;
1444    void  *pUpper_Context = NULL;
1445    /*NULL checks*/
1446    if((NULL == pInfo) || (NULL == pHwRef) || (NULL == pContext))
1447    {
1448        phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
1449    }
1450    else
1451    {
1452        type = type;
1453        Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pContext;
1454        /*Copy back stored context/callback for the upper layer*/
1455        pUpper_Context = Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt;
1456        pIoctlOutParam = Hal4Ctxt->sUpperLayerInfo.pIoctlOutParam;
1457        pUpper_DnldCb = Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb;
1458        Hal4Ctxt->sUpperLayerInfo.pUpperIoctlCb = NULL;
1459        /*Copy download status*/
1460        status = (((phNfc_sCompletionInfo_t *)pInfo)->status);
1461        /*copy hw reference*/
1462        psHwRef = (phHal_sHwReference_t *)pHwRef;
1463        /*Free the temporary hal context used only for the sake of download*/
1464        phOsalNfc_FreeMemory(psHwRef->hal_context);
1465        psHwRef->hal_context = NULL;
1466        /*Call upper layer callback*/
1467        if(NULL != pUpper_DnldCb)
1468        {
1469            (*pUpper_DnldCb)(
1470                pUpper_Context,
1471                pIoctlOutParam,
1472                status
1473                );
1474        }
1475    }
1476    return;
1477}
1478#endif /*FW_DOWNLOAD*/
1479
1480