• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_Reader.c
18 * \brief Hal4Nfc Reader source.
19 *
20 * Project: NFC-FRI 1.1
21 *
22 * $Date: Mon May 31 11:43:43 2010 $
23 * $Author: ing07385 $
24 * $Revision: 1.120 $
25 * $Aliases: NFC_FRI1.1_WK1023_R35_1 $
26 *
27 */
28 
29 /* ---------------------------Include files ------------------------------------*/
30 #include <phHal4Nfc.h>
31 #include <phHal4Nfc_Internal.h>
32 #include <phOsalNfc.h>
33 #include <phHciNfc.h>
34 #include <phOsalNfc_Timer.h>
35 #include <phNfcConfig.h>
36 
37 
38 /* ------------------------------- Macros ------------------------------------*/
39 #define PH_HAL4NFC_CMD_LENGTH      PHHAL_MAX_DATASIZE+12/**< Cmd length used
40                                                               for Transceive*/
41 #define PH_HAL4NFC_MAX_TRCV_LEN                     4096 /**<Only a max of 1KB
42                                                               can be sent at
43                                                               a time*/
44 #define PH_HAL4NFC_FLAG_0                              0
45 
46 #define PH_HAL4NFC_FLAG_1                              1
47 
48 #define PH_HAL4NFC_SEL_SECTOR1_BYTE0                0xC2
49 #define PH_HAL4NFC_SEL_SECTOR1_BYTE1                0xFF
50 
51 #define PH_HAL4NFC_SEL_SECTOR2_BYTE0                0x02
52 #define PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED        0x00
53 
54 
55 /* --------------------Structures and enumerations --------------------------*/
56 
57 static void phHal4Nfc_Iso_3A_Transceive(
58                         phHal_sTransceiveInfo_t   *psTransceiveInfo,
59                         phHal4Nfc_Hal4Ctxt_t      *Hal4Ctxt
60                         );
61 
62 static void phHal4Nfc_MifareTransceive(
63                         phHal_sTransceiveInfo_t   *psTransceiveInfo,
64                         phHal_sRemoteDevInformation_t  *psRemoteDevInfo,
65                         phHal4Nfc_Hal4Ctxt_t      *Hal4Ctxt
66                         );
67 
68 /*Allows to connect to a single, specific, already known Remote Device.*/
phHal4Nfc_Connect(phHal_sHwReference_t * psHwReference,phHal_sRemoteDevInformation_t * psRemoteDevInfo,pphHal4Nfc_ConnectCallback_t pNotifyConnectCb,void * pContext)69 NFCSTATUS phHal4Nfc_Connect(
70                             phHal_sHwReference_t          *psHwReference,
71                             phHal_sRemoteDevInformation_t *psRemoteDevInfo,
72                             pphHal4Nfc_ConnectCallback_t   pNotifyConnectCb,
73                             void                          *pContext
74                             )
75 {
76     NFCSTATUS RetStatus = NFCSTATUS_SUCCESS;
77     phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
78     uint8_t RemoteDevCount = 0;
79     int32_t MemCmpRet = 0;
80     /*NULL chks*/
81     if(NULL == psHwReference
82         || NULL == pNotifyConnectCb
83         || NULL == psRemoteDevInfo)
84     {
85         phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
86         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
87     }
88     /*Check initialised state*/
89     else if((NULL == psHwReference->hal_context)
90                         || (((phHal4Nfc_Hal4Ctxt_t *)
91                                 psHwReference->hal_context)->Hal4CurrentState
92                                                < eHal4StateOpenAndReady)
93                         || (((phHal4Nfc_Hal4Ctxt_t *)
94                                 psHwReference->hal_context)->Hal4NextState
95                                                == eHal4StateClosed))
96     {
97         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED);
98     }
99     else if ((psRemoteDevInfo ==
100              ((phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context)->
101                 sTgtConnectInfo.psConnectedDevice)
102              &&((phHal_eNfcIP1_Target == psRemoteDevInfo->RemDevType)
103                 ||(phHal_eJewel_PICC == psRemoteDevInfo->RemDevType)))
104     {
105         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FEATURE_NOT_SUPPORTED);
106     }
107     else
108     {
109         /*Get Hal ctxt from hardware reference*/
110         Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
111         /*Register upper layer context*/
112         Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
113         /*Register upper layer callback*/
114         Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = pNotifyConnectCb;
115         /*Allow Connect only if no other remote device is connected*/
116         if((eHal4StateTargetDiscovered == Hal4Ctxt->Hal4CurrentState)
117             && (NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice))
118         {
119             RemoteDevCount = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
120             while(0 != RemoteDevCount)
121             {
122                 RemoteDevCount--;
123                 /*Check if handle provided by upper layer matches with any
124                   remote device in the list*/
125                 if(psRemoteDevInfo
126                     == (Hal4Ctxt->rem_dev_list[RemoteDevCount]))
127                 {
128 
129                     Hal4Ctxt->sTgtConnectInfo.psConnectedDevice
130                                   = Hal4Ctxt->rem_dev_list[RemoteDevCount];
131                     break;
132                 }
133             }/*End of while*/
134 
135             if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
136             {
137                 /*No matching device handle in list*/
138                 RetStatus = PHNFCSTVAL(CID_NFC_HAL ,
139                                         NFCSTATUS_INVALID_REMOTE_DEVICE);
140             }
141             else
142             {
143                 MemCmpRet = phOsalNfc_MemCompare(
144                     (void *)&(psRemoteDevInfo->RemoteDevInfo),
145                     (void *)&(Hal4Ctxt->rem_dev_list[Hal4Ctxt
146                     ->psADDCtxtInfo->nbr_of_devices - 1]->RemoteDevInfo),
147                     sizeof(phHal_uRemoteDevInfo_t));
148 
149                 /*If device is already selected issue connect from here*/
150                 if(0 == MemCmpRet)
151                 {
152                     RetStatus = phHciNfc_Connect(Hal4Ctxt->psHciHandle,
153                         (void *)psHwReference,
154                         Hal4Ctxt->rem_dev_list[RemoteDevCount]);
155                     if(NFCSTATUS_PENDING == RetStatus)
156                     {
157                         Hal4Ctxt->Hal4NextState = eHal4StateTargetConnected;
158                     }
159 
160                 }
161                 else/*Select the matching device to connect to*/
162                 {
163                     RetStatus = phHciNfc_Reactivate (
164                         Hal4Ctxt->psHciHandle,
165                         (void *)psHwReference,
166                         Hal4Ctxt->rem_dev_list[RemoteDevCount]
167                         );
168                     Hal4Ctxt->Hal4NextState = eHal4StateTargetActivate;
169                 }
170                 if(NFCSTATUS_PENDING != RetStatus)
171                 {
172                     /*Rollback state*/
173                     Hal4Ctxt->Hal4CurrentState = eHal4StateOpenAndReady;
174                     Hal4Ctxt->sTgtConnectInfo.psConnectedDevice =  NULL;
175                     Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = NULL;
176                     Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL;
177                 }
178             }
179         }
180         /*Issue Reconnect*/
181         else if(psRemoteDevInfo ==
182                     Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
183         {
184             RetStatus = phHciNfc_Reactivate (
185                 Hal4Ctxt->psHciHandle,
186                 (void *)psHwReference,
187                 psRemoteDevInfo
188                 );
189                 Hal4Ctxt->Hal4NextState = eHal4StateTargetActivate;
190         }
191 #ifdef RECONNECT_SUPPORT
192         else if (psRemoteDevInfo !=
193                     Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
194         {
195             phHal_sRemoteDevInformation_t           *ps_store_connected_device =
196                                                 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice;
197 
198             RemoteDevCount = Hal4Ctxt->psADDCtxtInfo->nbr_of_devices;
199 
200             while (0 != RemoteDevCount)
201             {
202                 RemoteDevCount--;
203                 /*Check if handle provided by upper layer matches with any
204                   remote device in the list*/
205                 if(psRemoteDevInfo == (Hal4Ctxt->rem_dev_list[RemoteDevCount]))
206                 {
207                     break;
208                 }
209             }/*End of while*/
210 
211             if (ps_store_connected_device ==
212                 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
213             {
214                 RetStatus = phHciNfc_Reactivate (Hal4Ctxt->psHciHandle,
215                                                 (void *)psHwReference,
216                                                 psRemoteDevInfo);
217 
218                 if (NFCSTATUS_PENDING == RetStatus)
219                 {
220                     Hal4Ctxt->sTgtConnectInfo.psConnectedDevice =
221                                     Hal4Ctxt->rem_dev_list[RemoteDevCount];
222                     Hal4Ctxt->Hal4NextState = eHal4StateTargetActivate;
223                 }
224             }
225         }
226 #endif /* #ifdef RECONNECT_SUPPORT */
227         else if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
228         {
229             /*Wrong state to issue connect*/
230             RetStatus = PHNFCSTVAL(CID_NFC_HAL,
231                                     NFCSTATUS_INVALID_REMOTE_DEVICE);
232         }
233         else/*No Target or already connected to device*/
234         {
235             RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FAILED);
236         }
237 
238     }
239     return RetStatus;
240 }
241 
242 /*For Ordering Transceive Info for ISO_3A type tags*/
phHal4Nfc_Iso_3A_Transceive(phHal_sTransceiveInfo_t * psTransceiveInfo,phHal4Nfc_Hal4Ctxt_t * Hal4Ctxt)243 static void phHal4Nfc_Iso_3A_Transceive(
244                         phHal_sTransceiveInfo_t   *psTransceiveInfo,
245                         phHal4Nfc_Hal4Ctxt_t      *Hal4Ctxt
246                         )
247 {
248     uint16_t i;
249     uint16_t counter= 0;
250     /* Mifare UL, Keep MIFARE RAW command as it is */
251     Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type
252                     = (uint8_t)psTransceiveInfo->cmd.MfCmd;
253     /* Set flags for Select Sector */
254     if (psTransceiveInfo->sSendData.buffer[0] != phHal_eMifareWrite4)
255     {
256         if (Hal4Ctxt->SelectSectorFlag == PH_HAL4NFC_FLAG_0)
257         {
258             /* First Select Sector command */
259             if ((psTransceiveInfo->sSendData.buffer[1] == PH_HAL4NFC_SEL_SECTOR1_BYTE0) &&
260                 (psTransceiveInfo->sSendData.buffer[2] == PH_HAL4NFC_SEL_SECTOR1_BYTE1))
261             {
262                 Hal4Ctxt->SelectSectorFlag++;
263                 PHDBG_INFO("Inside 3ATrancv,first cmd, SelectSectorFlag is 1");
264                 for (i = 1; i < psTransceiveInfo->sSendData.length; i++)
265                 {
266                     psTransceiveInfo->sSendData.buffer[i - 1] =
267                         psTransceiveInfo->sSendData.buffer[i];
268                 }
269 
270                 psTransceiveInfo->sSendData.length--;
271             }
272             else
273             {
274                 PHDBG_INFO("Inside 3ATrancv,first cmd,setting SelectSectorFlag 0");
275                 Hal4Ctxt->SelectSectorFlag = 0;
276             }
277         }
278         else if (Hal4Ctxt->SelectSectorFlag == PH_HAL4NFC_FLAG_1)
279         {
280             if ((psTransceiveInfo->sSendData.buffer[1] < PH_HAL4NFC_SEL_SECTOR2_BYTE0) &&
281                 (psTransceiveInfo->sSendData.buffer[2] == PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED) &&
282                 (psTransceiveInfo->sSendData.buffer[3] == PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED) &&
283                 (psTransceiveInfo->sSendData.buffer[4] == PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED))
284             {
285                 Hal4Ctxt->SelectSectorFlag++;
286                 PHDBG_INFO("Inside 3ATrancv,2nd cmd, SelectSectorFlag set to 2");
287                 for (i = 1; i < psTransceiveInfo->sSendData.length; i++)
288                 {
289                     psTransceiveInfo->sSendData.buffer[i - 1] =
290                         psTransceiveInfo->sSendData.buffer[i];
291                 }
292 
293                 psTransceiveInfo->sSendData.length--;
294             }
295             else
296             {
297                 PHDBG_INFO("Inside 3ATrancv,2nd cmd, SelectSectorFlag set to 0");
298                 Hal4Ctxt->SelectSectorFlag = 0;
299             }
300         }
301         else
302         {
303             Hal4Ctxt->SelectSectorFlag = 0;
304         }
305     }
306     else
307     {
308         PHDBG_INFO("Inside 3ATrancv,Mifarewrite4");
309         /* Convert MIFARE RAW to MIFARE CMD */
310         if (psTransceiveInfo->cmd.MfCmd == phHal_eMifareRaw)
311         {
312             psTransceiveInfo->cmd.MfCmd =
313                 (phHal_eMifareCmdList_t)psTransceiveInfo->sSendData.buffer[0];
314 
315             Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type =
316                 (uint8_t)psTransceiveInfo->cmd.MfCmd;
317 
318             Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.addr =
319                 psTransceiveInfo->addr =
320                 psTransceiveInfo->sSendData.buffer[1];
321 
322             for (counter = 2; counter < psTransceiveInfo->sSendData.length;
323                  counter++)
324             {
325                 psTransceiveInfo->sSendData.buffer[counter - 2] =
326                     psTransceiveInfo->sSendData.buffer[counter];
327             }
328             PHDBG_INFO("Hal4:Inside 3A_Trcv() ,minus length by 4");
329             psTransceiveInfo->sSendData.length =
330                 psTransceiveInfo->sSendData.length - 4;
331         }
332         else
333         {
334             Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type
335                         = (uint8_t)psTransceiveInfo->cmd.MfCmd;
336         }
337     }
338     return;
339 }
340 
341 /*For Ordering Transceive Info for Mifare tags*/
phHal4Nfc_MifareTransceive(phHal_sTransceiveInfo_t * psTransceiveInfo,phHal_sRemoteDevInformation_t * psRemoteDevInfo,phHal4Nfc_Hal4Ctxt_t * Hal4Ctxt)342 static void phHal4Nfc_MifareTransceive(
343                         phHal_sTransceiveInfo_t   *psTransceiveInfo,
344                         phHal_sRemoteDevInformation_t  *psRemoteDevInfo,
345                         phHal4Nfc_Hal4Ctxt_t      *Hal4Ctxt
346                         )
347 {
348     uint16_t counter;
349     if (
350 #ifndef DISABLE_MIFARE_UL_WRITE_WORKAROUND
351         phHal_eMifareWrite4 != psTransceiveInfo->sSendData.buffer[0]
352 #else
353         1
354 #endif/*#ifndef DISABLE_MIFARE_UL_WRITE_WORKAROUND*/
355         )
356 
357     {
358         /* Mifare UL, Keep MIFARE RAW command as it is */
359         Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type
360                         = (uint8_t)psTransceiveInfo->cmd.MfCmd;
361 
362     }
363     else
364     {
365         /* Convert MIFARE RAW to MIFARE CMD */
366         if (psTransceiveInfo->cmd.MfCmd == phHal_eMifareRaw)
367         {
368             psTransceiveInfo->cmd.MfCmd =
369                 (phHal_eMifareCmdList_t)psTransceiveInfo->sSendData.buffer[0];
370 
371             Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type =
372                 (uint8_t)psTransceiveInfo->cmd.MfCmd;
373 
374             Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.addr =
375                 psTransceiveInfo->addr =
376                 psTransceiveInfo->sSendData.buffer[1];
377 
378             for (counter = 2; counter < psTransceiveInfo->sSendData.length;
379                  counter++)
380             {
381                 psTransceiveInfo->sSendData.buffer[counter - 2] =
382                     psTransceiveInfo->sSendData.buffer[counter];
383             }
384             PHDBG_INFO("Hal4:Inside MifareTrcv() ,minus length by 4");
385             psTransceiveInfo->sSendData.length =
386                 psTransceiveInfo->sSendData.length - 4;
387 
388         }
389         else
390         {
391             Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.cmd_type
392                         = (uint8_t)psTransceiveInfo->cmd.MfCmd;
393         }
394     }
395     return;
396 }
397 
398 /*  The phHal4Nfc_Transceive function allows the Initiator to send and receive
399  *  data to and from the Remote Device selected by the caller.*/
phHal4Nfc_Transceive(phHal_sHwReference_t * psHwReference,phHal_sTransceiveInfo_t * psTransceiveInfo,phHal_sRemoteDevInformation_t * psRemoteDevInfo,pphHal4Nfc_TransceiveCallback_t pTrcvCallback,void * pContext)400 NFCSTATUS phHal4Nfc_Transceive(
401                                phHal_sHwReference_t          *psHwReference,
402                                phHal_sTransceiveInfo_t       *psTransceiveInfo,
403                                phHal_sRemoteDevInformation_t  *psRemoteDevInfo,
404                                pphHal4Nfc_TransceiveCallback_t pTrcvCallback,
405                                void                           *pContext
406                                )
407 {
408     NFCSTATUS RetStatus = NFCSTATUS_PENDING;
409     phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)pContext;
410 
411     /*NULL checks*/
412     if((NULL == psHwReference)
413         ||( NULL == pTrcvCallback )
414         || (NULL == psRemoteDevInfo)
415         || (NULL == psTransceiveInfo)
416         || (NULL == psTransceiveInfo->sRecvData.buffer)
417         || (NULL == psTransceiveInfo->sSendData.buffer)
418         )
419     {
420         phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
421         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
422     }
423 #ifdef HAL_TRCV_LIMIT
424     else if(PH_HAL4NFC_MAX_TRCV_LEN < psTransceiveInfo->sSendData.length)
425     {
426         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_ALLOWED);
427     }
428 #endif/*#ifdef HAL_TRCV_LIMIT*/
429     /*Check initialised state*/
430     else if((NULL == psHwReference->hal_context)
431                         || (((phHal4Nfc_Hal4Ctxt_t *)
432                                 psHwReference->hal_context)->Hal4CurrentState
433                                                < eHal4StateOpenAndReady)
434                         || (((phHal4Nfc_Hal4Ctxt_t *)
435                                 psHwReference->hal_context)->Hal4NextState
436                                                == eHal4StateClosed))
437     {
438         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED);
439     }
440     else
441     {
442         Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
443         gpphHal4Nfc_Hwref = (phHal_sHwReference_t *)psHwReference;
444         if((eHal4StateTargetConnected != Hal4Ctxt->Hal4CurrentState)
445             ||(eHal4StateInvalid != Hal4Ctxt->Hal4NextState))
446         {
447             /*Hal4 state Busy*/
448             RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_BUSY);
449             PHDBG_INFO("HAL4:Trcv Failed.Returning Busy");
450         }
451         else if(psRemoteDevInfo != Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
452         {
453             /*No such Target connected*/
454             RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_REMOTE_DEVICE);
455         }
456         else
457         {
458             /*allocate Trcv context*/
459             if(NULL == Hal4Ctxt->psTrcvCtxtInfo)
460             {
461                 Hal4Ctxt->psTrcvCtxtInfo= (pphHal4Nfc_TrcvCtxtInfo_t)
462                 phOsalNfc_GetMemory((uint32_t)(sizeof(phHal4Nfc_TrcvCtxtInfo_t)));
463                 if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
464                 {
465                     (void)memset(Hal4Ctxt->psTrcvCtxtInfo,0,
466                                         sizeof(phHal4Nfc_TrcvCtxtInfo_t));
467                     Hal4Ctxt->psTrcvCtxtInfo->RecvDataBufferStatus
468                         = NFCSTATUS_PENDING;
469                     Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
470                                                 = PH_OSALNFC_INVALID_TIMER_ID;
471                 }
472             }
473             if(NULL == Hal4Ctxt->psTrcvCtxtInfo)
474             {
475                 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
476                 RetStatus= PHNFCSTVAL(CID_NFC_HAL ,
477                                             NFCSTATUS_INSUFFICIENT_RESOURCES);
478             }
479             else
480             {
481                 /*Process transceive based on Remote device type*/
482                 switch(Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemDevType)
483                 {
484                 case phHal_eISO14443_3A_PICC:
485                     phHal4Nfc_Iso_3A_Transceive(
486                                         psTransceiveInfo,
487                                         Hal4Ctxt
488                                         );
489                     break;
490                 case phHal_eMifare_PICC:
491                     PHDBG_INFO("Mifare Cmd received");
492                     phHal4Nfc_MifareTransceive(
493                                         psTransceiveInfo,
494                                         psRemoteDevInfo,
495                                         Hal4Ctxt
496                                         );
497 
498 #if 0
499                     Hal4Ctxt->psTrcvCtxtInfo->
500                         XchangeInfo.params.tag_info.cmd_type
501                                         = (uint8_t)psTransceiveInfo->cmd.MfCmd;
502 #endif
503                     break;
504                 case phHal_eISO14443_A_PICC:
505                 case phHal_eISO14443_B_PICC:
506                     PHDBG_INFO("ISO14443 Cmd received");
507                     Hal4Ctxt->psTrcvCtxtInfo->
508                         XchangeInfo.params.tag_info.cmd_type
509                             = (uint8_t)psTransceiveInfo->cmd.Iso144434Cmd;
510                     break;
511                 case phHal_eISO15693_PICC:
512                     PHDBG_INFO("ISO15693 Cmd received");
513                     Hal4Ctxt->psTrcvCtxtInfo->
514                         XchangeInfo.params.tag_info.cmd_type
515                             = (uint8_t)psTransceiveInfo->cmd.Iso15693Cmd;
516                     break;
517                 case phHal_eNfcIP1_Target:
518                     {
519                         PHDBG_INFO("NfcIP1 Transceive");
520                         Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData
521                             = &(psTransceiveInfo->sSendData);
522                         Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData =
523                             &(psTransceiveInfo->sRecvData);
524                     }
525                     break;
526                 case phHal_eFelica_PICC:
527                     PHDBG_INFO("Felica Cmd received");
528                     Hal4Ctxt->psTrcvCtxtInfo->
529                         XchangeInfo.params.tag_info.cmd_type
530                         = (uint8_t)psTransceiveInfo->cmd.FelCmd;
531                     break;
532                 case phHal_eJewel_PICC:
533                     PHDBG_INFO("Jewel Cmd received");
534                     Hal4Ctxt->psTrcvCtxtInfo->
535                         XchangeInfo.params.tag_info.cmd_type
536                         = (uint8_t)psTransceiveInfo->cmd.JewelCmd;
537                     break;
538                 case phHal_eISO14443_BPrime_PICC:
539                     RetStatus = PHNFCSTVAL(CID_NFC_HAL ,
540                                               NFCSTATUS_FEATURE_NOT_SUPPORTED);
541                     break;
542                 default:
543                     PHDBG_WARNING("Invalid Device type received");
544                     RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_FAILED);
545                     break;
546 
547                 }
548             }
549         }
550         /*If status is anything other than NFCSTATUS_PENDING ,an error has
551           already occured, so dont process any further and return*/
552         if(RetStatus == NFCSTATUS_PENDING)
553         {
554             if(phHal_eNfcIP1_Target ==
555                   Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemDevType)
556             {
557                 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
558                 /*Register upper layer callback*/
559                 Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb  = pTrcvCallback;
560                 if(PH_HAL4NFC_MAX_SEND_LEN
561                     >= psTransceiveInfo->sSendData.length)
562                 {
563                     Hal4Ctxt->psTrcvCtxtInfo->
564                         XchangeInfo.params.nfc_info.more_info = FALSE;
565                     Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length
566                                 = (uint8_t)psTransceiveInfo->sSendData.length;
567                     Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer
568                         = psTransceiveInfo->sSendData.buffer;
569                     /*Number of bytes remaining for next send*/
570                     Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length = 0;
571                 }
572                 else
573                 {
574                     Hal4Ctxt->psTrcvCtxtInfo->
575                         XchangeInfo.params.nfc_info.more_info = TRUE;
576                     Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer
577                         = Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer;
578                     Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length
579                                                 = PH_HAL4NFC_MAX_SEND_LEN;
580 #if 0
581                     Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->buffer
582                                                 += PH_HAL4NFC_MAX_SEND_LEN;
583 #else
584                     Hal4Ctxt->psTrcvCtxtInfo->NumberOfBytesSent
585                         += PH_HAL4NFC_MAX_SEND_LEN;
586 #endif
587                     /*Number of bytes remaining for next send*/
588                     Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData->length
589                                                -= PH_HAL4NFC_MAX_SEND_LEN;
590                 }
591                 Hal4Ctxt->Hal4NextState = eHal4StateTransaction;
592 #ifdef TRANSACTION_TIMER
593                 /**Create a timer to keep track of transceive timeout*/
594                 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
595                     == PH_OSALNFC_INVALID_TIMER_ID)
596                 {
597                     PHDBG_INFO("HAL4: Transaction Timer Create for transceive");
598                     Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
599                         = phOsalNfc_Timer_Create();
600                 }
601                 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
602                     == PH_OSALNFC_INVALID_TIMER_ID)
603                 {
604                     RetStatus = PHNFCSTVAL(CID_NFC_HAL ,
605                         NFCSTATUS_INSUFFICIENT_RESOURCES);
606                 }
607                 else
608 #endif/*TRANSACTION_TIMER*/
609                 {
610                     PHDBG_INFO("Hal4:Calling phHciNfc_Send_Data from Hal4_Transceive()");
611                     RetStatus = phHciNfc_Send_Data (
612                                     Hal4Ctxt->psHciHandle,
613                                     psHwReference,
614                                     Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
615                                     &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo)
616                                     );
617                     if(NFCSTATUS_PENDING == RetStatus)
618                     {
619                         Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress = TRUE;
620                     }
621                 }
622             }
623             else if(psTransceiveInfo->sSendData.length > PH_HAL4NFC_CMD_LENGTH)
624             {
625                 RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_PARAMETER);
626             }
627             else if((psTransceiveInfo->sSendData.length == 0)
628                     && (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length != 0))
629             {
630                 PHDBG_INFO("Hal4:Read remaining bytes");
631                 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData
632                                             = &(psTransceiveInfo->sRecvData);
633                 /*Number of read bytes left is greater than bytes requested
634                     by upper layer*/
635                 if(Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length
636                     < Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length)
637                 {
638                     (void)memcpy(Hal4Ctxt->psTrcvCtxtInfo
639                                                 ->psUpperRecvData->buffer,
640                         (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer
641                         + Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset)
642                         ,Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length);
643                     Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length -=
644                         Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length;
645                     Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset
646                         += Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length;
647                     RetStatus = PHNFCSTVAL(CID_NFC_HAL ,
648                                                 NFCSTATUS_MORE_INFORMATION);
649                 }
650                 else/*Number of read bytes left is smaller.Copy all bytes
651                       and free Hal's buffer*/
652                 {
653                     Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length
654                         = Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length;
655                     (void)memcpy(Hal4Ctxt->psTrcvCtxtInfo
656                                                         ->psUpperRecvData
657                                                                     ->buffer,
658                         (Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer
659                             + Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset)
660                         ,Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length);
661                     phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo
662                                                     ->sLowerRecvData.buffer);
663                     Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer = NULL;
664                     Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length = 0;
665                     Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset   = 0;
666                     RetStatus = NFCSTATUS_SUCCESS;
667                 }
668             }
669             else/*No more bytes remaining in Hal.Read from device*/
670             {
671                  /*Register upper layer context*/
672                 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = pContext;
673                 /*Register upper layer callback*/
674                 Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb  = pTrcvCallback;
675                 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params.tag_info.addr
676                                                     = psTransceiveInfo->addr;
677                 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_length
678                                 = (uint16_t)psTransceiveInfo->sSendData.length;
679                 Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.tx_buffer
680                                         = psTransceiveInfo->sSendData.buffer;
681                 Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData
682                                             = &(psTransceiveInfo->sRecvData);
683 #ifdef TRANSACTION_TIMER
684                 /**Create a timer to keep track of transceive timeout*/
685                 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
686                                     == PH_OSALNFC_INVALID_TIMER_ID)
687                 {
688                     PHDBG_INFO("HAL4: Transaction Timer Create for transceive");
689                     Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
690                                             = phOsalNfc_Timer_Create();
691                 }
692                 if(Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId
693                     == PH_OSALNFC_INVALID_TIMER_ID)
694                 {
695                     RetStatus = PHNFCSTVAL(CID_NFC_HAL ,
696                                            NFCSTATUS_INSUFFICIENT_RESOURCES);
697                 }
698                 else
699 #endif /*TRANSACTION_TIMER*/
700                 {
701                     PHDBG_INFO("Calling phHciNfc_Exchange_Data");
702                     RetStatus = phHciNfc_Exchange_Data(
703                         Hal4Ctxt->psHciHandle,
704                         psHwReference,
705                         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
706                         &(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo)
707                         );
708 
709                     if(NFCSTATUS_PENDING == RetStatus)
710                     {
711                         Hal4Ctxt->Hal4NextState = eHal4StateTransaction;
712 #ifdef TRANSACTION_TIMER
713                         /**Start timer to keep track of transceive timeout*/
714                         phOsalNfc_Timer_Start(
715                             Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId,
716                             PH_HAL4NFC_TRANSCEIVE_TIMEOUT,
717                             phHal4Nfc_TrcvTimeoutHandler
718                             );
719 #endif/*#ifdef TRANSACTION_TIMER*/
720                     }
721                     else
722                     {
723                         Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
724                     }
725                 }
726             }
727         }
728     }
729     return RetStatus;
730 }
731 
732 #ifdef TRANSACTION_TIMER
733 /**Handle transceive timeout*/
phHal4Nfc_TrcvTimeoutHandler(uint32_t TrcvTimerId)734 void phHal4Nfc_TrcvTimeoutHandler(uint32_t TrcvTimerId)
735 {
736     phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = gpphHal4Nfc_Hwref->hal_context;
737     pphHal4Nfc_ReceiveCallback_t pUpperRecvCb = NULL;
738     pphHal4Nfc_TransceiveCallback_t pUpperTrcvCb = NULL;
739     phOsalNfc_Timer_Stop(TrcvTimerId);
740     phOsalNfc_Timer_Delete(TrcvTimerId);
741     Hal4Ctxt->psTrcvCtxtInfo->TransactionTimerId = PH_OSALNFC_INVALID_TIMER_ID;
742     Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
743     /*For a P2P target*/
744     if(Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb != NULL)
745     {
746         pUpperRecvCb = Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb;
747         Hal4Ctxt->psTrcvCtxtInfo->pP2PRecvCb = NULL;
748         (*pUpperRecvCb)(
749             Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
750             NULL,
751             NFCSTATUS_RF_TIMEOUT
752             );
753     }
754     else
755     {
756         /*For a P2P Initiator and tags*/
757         if(Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb != NULL)
758         {
759             pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb;
760             Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL;
761             (*pUpperTrcvCb)(
762                         Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
763                         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
764                         NULL,
765                         NFCSTATUS_RF_TIMEOUT
766                         );
767         }
768     }
769 }
770 #endif /*TRANSACTION_TIMER*/
771 
772 
773 /**The function allows to disconnect from a specific Remote Device.*/
phHal4Nfc_Disconnect(phHal_sHwReference_t * psHwReference,phHal_sRemoteDevInformation_t * psRemoteDevInfo,phHal_eReleaseType_t ReleaseType,pphHal4Nfc_DiscntCallback_t pDscntCallback,void * pContext)774 NFCSTATUS phHal4Nfc_Disconnect(
775                         phHal_sHwReference_t          *psHwReference,
776                         phHal_sRemoteDevInformation_t *psRemoteDevInfo,
777                         phHal_eReleaseType_t           ReleaseType,
778                         pphHal4Nfc_DiscntCallback_t    pDscntCallback,
779                         void                             *pContext
780                         )
781 {
782     NFCSTATUS RetStatus = NFCSTATUS_PENDING;
783     phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
784     PHDBG_INFO("Hal4:Inside Hal4 disconnect");
785     /*NULL checks*/
786     if(NULL == psHwReference || NULL == pDscntCallback
787         || NULL == psRemoteDevInfo)
788     {
789         phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
790         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_INVALID_PARAMETER);
791     }
792     /*Check Initialised state*/
793     else if((NULL == psHwReference->hal_context)
794                         || (((phHal4Nfc_Hal4Ctxt_t *)
795                                 psHwReference->hal_context)->Hal4CurrentState
796                                                < eHal4StateOpenAndReady)
797                         || (((phHal4Nfc_Hal4Ctxt_t *)
798                                 psHwReference->hal_context)->Hal4NextState
799                                                == eHal4StateClosed))
800     {
801         RetStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_NOT_INITIALISED);
802     }
803     else if(((phHal4Nfc_Hal4Ctxt_t *)
804                     psHwReference->hal_context)->Hal4CurrentState
805                     != eHal4StateTargetConnected)
806     {
807         PHDBG_INFO("Hal4:Current sate is not connect.Release returning failed");
808         RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_FAILED);
809     }
810     else
811     {
812         Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
813         if((Hal4Ctxt->sTgtConnectInfo.psConnectedDevice == NULL)
814             || (psRemoteDevInfo != Hal4Ctxt->sTgtConnectInfo.psConnectedDevice))
815         {
816             PHDBG_INFO("Hal4:disconnect returning INVALID_REMOTE_DEVICE");
817             RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_REMOTE_DEVICE);
818         }
819         else
820         {
821             /*Register upper layer context*/
822             Hal4Ctxt->sUpperLayerInfo.psUpperLayerDisconnectCtxt = pContext;
823             /*Register upper layer callback*/
824             Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb  = pDscntCallback;
825             /*Register Release Type*/
826             Hal4Ctxt->sTgtConnectInfo.ReleaseType = ReleaseType;
827             if((eHal4StateTransaction == Hal4Ctxt->Hal4NextState)
828                 &&((phHal_eNfcIP1_Target != psRemoteDevInfo->RemDevType)
829                 ||((NFC_DISCOVERY_CONTINUE != ReleaseType)
830                    &&(NFC_DISCOVERY_RESTART != ReleaseType))))
831             {
832                 Hal4Ctxt->sTgtConnectInfo.ReleaseType
833                                                   = NFC_INVALID_RELEASE_TYPE;
834                 PHDBG_INFO("Hal4:disconnect returning NFCSTATUS_NOT_ALLOWED");
835                 RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_NOT_ALLOWED);
836             }
837             else if((eHal4StateTransaction == Hal4Ctxt->Hal4NextState)
838                     &&(NULL != Hal4Ctxt->psTrcvCtxtInfo)
839                     &&(TRUE == Hal4Ctxt->psTrcvCtxtInfo->P2P_Send_In_Progress))
840             {
841                 /*store the hardware reference for executing disconnect later*/
842                 gpphHal4Nfc_Hwref = psHwReference;
843                 PHDBG_INFO("Hal4:disconnect deferred");
844             }
845             else/*execute disconnect*/
846             {
847                 RetStatus = phHal4Nfc_Disconnect_Execute(psHwReference);
848             }
849         }
850     }
851     return RetStatus;
852 }
853 
854 /**Execute Hal4 Disconnect*/
phHal4Nfc_Disconnect_Execute(phHal_sHwReference_t * psHwReference)855 NFCSTATUS phHal4Nfc_Disconnect_Execute(
856                             phHal_sHwReference_t  *psHwReference
857                             )
858 {
859     NFCSTATUS RetStatus = NFCSTATUS_PENDING;
860     phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt =
861         (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
862     phHal_eSmartMX_Mode_t SmxMode = eSmartMx_Default;
863     PHDBG_INFO("Hal4:Inside Hal4 disconnect execute");
864     switch(Hal4Ctxt->sTgtConnectInfo.ReleaseType)
865     {
866         /*Switch mode to Default*/
867         case NFC_SMARTMX_RELEASE:
868             SmxMode = eSmartMx_Default;
869             RetStatus = phHciNfc_Switch_SmxMode (
870                 Hal4Ctxt->psHciHandle,
871                 psHwReference,
872                 SmxMode,
873                 &(Hal4Ctxt->psADDCtxtInfo->sADDCfg)
874                 );
875             break;
876         /*Disconnect and continue polling wheel*/
877         case NFC_DISCOVERY_CONTINUE:
878         {
879             RetStatus = phHciNfc_Disconnect (
880                                     Hal4Ctxt->psHciHandle,
881                                     psHwReference,
882                                     FALSE
883                                     );
884             if(NFCSTATUS_PENDING != RetStatus)
885             {
886                 PHDBG_INFO("Hal4:Hci disconnect failed.Restarting discovery");
887                 RetStatus = phHciNfc_Restart_Discovery (
888                                     (void *)Hal4Ctxt->psHciHandle,
889                                     (void *)gpphHal4Nfc_Hwref,
890                                     FALSE
891                                     );
892                 if(NFCSTATUS_PENDING != RetStatus)
893                 {
894                     PHDBG_INFO("Hal4:Hci Restart discovery also failed");
895                 }
896             }
897             break;
898         }
899         /*Disconnect and restart polling wheel*/
900         case NFC_DISCOVERY_RESTART:
901             RetStatus = phHciNfc_Disconnect (
902                                 Hal4Ctxt->psHciHandle,
903                                 psHwReference,
904                                 TRUE
905                                 );
906             break;
907         default:
908             RetStatus = PHNFCSTVAL(CID_NFC_HAL,
909                 NFCSTATUS_FEATURE_NOT_SUPPORTED);
910             break;
911     }
912     Hal4Ctxt->sTgtConnectInfo.ReleaseType = NFC_INVALID_RELEASE_TYPE;
913     /*Update or rollback next state*/
914     Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == RetStatus?
915                     eHal4StateOpenAndReady:Hal4Ctxt->Hal4NextState);
916     return  RetStatus;
917 }
918 
919 /*The function allows to check for presence in vicinity of connected remote
920   device.*/
phHal4Nfc_PresenceCheck(phHal_sHwReference_t * psHwReference,pphHal4Nfc_GenCallback_t pPresenceChkCb,void * context)921 NFCSTATUS phHal4Nfc_PresenceCheck(
922                                 phHal_sHwReference_t     *psHwReference,
923                                 pphHal4Nfc_GenCallback_t  pPresenceChkCb,
924                                 void *context
925                                 )
926 {
927     NFCSTATUS RetStatus = NFCSTATUS_FAILED;
928     phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = NULL;
929     /*NULL  checks*/
930     if((NULL == pPresenceChkCb) || (NULL == psHwReference))
931     {
932         RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_INVALID_PARAMETER);
933     }
934     /*Check Initialised state*/
935     else if((NULL == psHwReference->hal_context)
936                         || (((phHal4Nfc_Hal4Ctxt_t *)
937                                 psHwReference->hal_context)->Hal4CurrentState
938                                                < eHal4StateOpenAndReady)
939                         || (((phHal4Nfc_Hal4Ctxt_t *)
940                                 psHwReference->hal_context)->Hal4NextState
941                                                == eHal4StateClosed))
942     {
943         PHDBG_INFO("HAL4:Context not Open");
944         RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_NOT_INITIALISED);
945     }
946     /*check connected state and session alive*/
947     else if((((phHal4Nfc_Hal4Ctxt_t *)
948              psHwReference->hal_context)->Hal4CurrentState
949                                 < eHal4StateTargetConnected)||
950             (NULL == ((phHal4Nfc_Hal4Ctxt_t *)
951               psHwReference->hal_context)->sTgtConnectInfo.psConnectedDevice)||
952             (FALSE == ((phHal4Nfc_Hal4Ctxt_t *)
953                         psHwReference->hal_context)->sTgtConnectInfo.
954                                     psConnectedDevice->SessionOpened))
955     {
956         PHDBG_INFO("HAL4:No target connected");
957         RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_RELEASED);
958     }
959     else
960     {
961         Hal4Ctxt = (phHal4Nfc_Hal4Ctxt_t *)psHwReference->hal_context;
962         /*allow only one Presence chk command at any point in time*/
963         if (eHal4StatePresenceCheck != Hal4Ctxt->Hal4NextState)
964         {
965             Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = context;
966             Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb = pPresenceChkCb;
967             RetStatus = phHciNfc_Presence_Check(Hal4Ctxt->psHciHandle,
968                                                 psHwReference
969                                                 );
970             Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == RetStatus?
971                 eHal4StatePresenceCheck:Hal4Ctxt->Hal4NextState);
972         }
973         else/*Ongoing presence chk*/
974         {
975             RetStatus = PHNFCSTVAL(CID_NFC_HAL,NFCSTATUS_BUSY);
976         }
977     }
978     return RetStatus;
979 }
980 
phHal4Nfc_PresenceChkComplete(phHal4Nfc_Hal4Ctxt_t * Hal4Ctxt,void * pInfo)981 void phHal4Nfc_PresenceChkComplete(
982                                    phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
983                                    void *pInfo
984                                    )
985 {
986     NFCSTATUS RetStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status;
987     Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
988     /*Notify to upper layer*/
989     if(NULL != Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb)
990     {
991         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->SessionOpened
992                      =(uint8_t)(NFCSTATUS_SUCCESS == RetStatus?TRUE:FALSE);
993         (*Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb)(
994                         Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
995                         RetStatus
996                         );
997     }
998     return;
999 }
1000 
1001 /*Callback for reactivate target and to select appropriate target incase
1002  of multiple targets*/
phHal4Nfc_ReactivationComplete(phHal4Nfc_Hal4Ctxt_t * Hal4Ctxt,void * pInfo)1003 void phHal4Nfc_ReactivationComplete(
1004                                     phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
1005                                     void *pInfo
1006                                     )
1007 {
1008     NFCSTATUS Status = ((phNfc_sCompletionInfo_t *)pInfo)->status;
1009     /*A NFCSTATUS_SUCCESS status returned here means that the correct device
1010      to connect to has now been selected.So issue connect from here to complete
1011      activation*/
1012     if(NFCSTATUS_SUCCESS == Status)
1013     {
1014         Hal4Ctxt->Hal4NextState = eHal4StateTargetConnected;
1015         Status = phHciNfc_Connect(
1016             Hal4Ctxt->psHciHandle,
1017             gpphHal4Nfc_Hwref,
1018             Hal4Ctxt->sTgtConnectInfo.psConnectedDevice
1019             );
1020         Status = (NFCSTATUS_PENDING == Status)?
1021                     NFCSTATUS_PENDING:NFCSTATUS_FAILED;
1022     }
1023     else/*Device unavailable, return error in connect Callback*/
1024     {
1025         Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
1026         if(NULL != Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb)
1027         {
1028             (*Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb)(
1029                                 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
1030                                 Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
1031                                 Status
1032                                 );
1033         }
1034     }
1035     return;
1036 }
1037 
1038 
phHal4Nfc_ConnectComplete(phHal4Nfc_Hal4Ctxt_t * Hal4Ctxt,void * pInfo)1039 void phHal4Nfc_ConnectComplete(
1040                                phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
1041                                void *pInfo
1042                                )
1043 {
1044     NFCSTATUS ConnectStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status;
1045     pphHal4Nfc_ConnectCallback_t pUpperConnectCb
1046                                 = Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb;
1047     /*Flag to decide whether or not upper layer callback has to be called*/
1048     uint8_t CallConnectCb = TRUE;
1049     /*Remote device Connect successful*/
1050     if((NFCSTATUS_SUCCESS == ConnectStatus)
1051 		||(eHal4StateTargetConnected == Hal4Ctxt->Hal4CurrentState))
1052     {
1053         PHDBG_INFO("Hal4:Connect status Success");
1054         Hal4Ctxt->Hal4CurrentState = eHal4StateTargetConnected;
1055         Hal4Ctxt->Hal4NextState = eHal4StateInvalid;
1056         /* Open the Session */
1057         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->SessionOpened =
1058             (uint8_t)(NFCSTATUS_SUCCESS == ConnectStatus?TRUE:FALSE);
1059         Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL;
1060 
1061     }
1062     else/*Remote device Connect failed*/
1063     {
1064         Hal4Ctxt->Hal4CurrentState = eHal4StateOpenAndReady;
1065         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->SessionOpened = FALSE;
1066         /*For a NfcIp1 target and case where it is not a internal reconnect
1067           from Hal4 ,notify callback to upper layer*/
1068         if((phHal_eNfcIP1_Target
1069             == Hal4Ctxt->rem_dev_list[0]->RemDevType)
1070             || (NULL != Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb))
1071         {
1072             Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL;
1073         }
1074         else/*do not notify callback*/
1075         {
1076             CallConnectCb = FALSE;
1077         }
1078         /*Free the remote device list*/
1079         do
1080         {
1081             Hal4Ctxt->psADDCtxtInfo->nbr_of_devices--;
1082             if(NULL != Hal4Ctxt->rem_dev_list[
1083                         Hal4Ctxt->psADDCtxtInfo->nbr_of_devices])
1084             {
1085                 phOsalNfc_FreeMemory((void *)
1086                         (Hal4Ctxt->rem_dev_list[
1087                             Hal4Ctxt->psADDCtxtInfo->nbr_of_devices]));
1088                 Hal4Ctxt->rem_dev_list[
1089                     Hal4Ctxt->psADDCtxtInfo->nbr_of_devices] = NULL;
1090             }
1091         }while(0 < Hal4Ctxt->psADDCtxtInfo->nbr_of_devices);
1092 
1093         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = NULL;
1094     }
1095     if(TRUE == CallConnectCb)
1096     {
1097         PHDBG_INFO("Hal4:Calling Connect callback");
1098         /*Notify to the upper layer*/
1099         (*pUpperConnectCb)(
1100                     Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
1101                     Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
1102                     ConnectStatus
1103                     );
1104     }
1105     else
1106     {
1107         PHDBG_INFO("Hal4:Connect failed ,Restarting discovery");
1108         /*Restart the Discovery wheel*/
1109         ConnectStatus = phHciNfc_Restart_Discovery (
1110                                     (void *)Hal4Ctxt->psHciHandle,
1111                                     (void *)gpphHal4Nfc_Hwref,
1112                                     FALSE
1113                                     );
1114         Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == ConnectStatus?
1115                                     eHal4StateConfiguring:eHal4StateInvalid);
1116     }
1117     return;
1118 }
1119 
1120 
1121 
1122 
phHal4Nfc_DisconnectComplete(phHal4Nfc_Hal4Ctxt_t * Hal4Ctxt,void * pInfo)1123 void phHal4Nfc_DisconnectComplete(
1124                                   phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
1125                                   void *pInfo
1126                                   )
1127 {
1128     NFCSTATUS ConnectStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status;
1129     phHal_sRemoteDevInformation_t *psConnectedDevice = NULL;
1130     pphHal4Nfc_DiscntCallback_t pUpperDisconnectCb = NULL;
1131     pphHal4Nfc_TransceiveCallback_t pUpperTrcvCb = NULL;
1132     PHDBG_INFO("Hal4:Inside Hal4 disconnect callback");
1133     if(NULL == Hal4Ctxt)
1134     {
1135         phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
1136     }
1137     else if(NFCSTATUS_SUCCESS != ConnectStatus)/*Restart the Discovery wheel*/
1138     {
1139         ConnectStatus = phHciNfc_Restart_Discovery (
1140                                     (void *)Hal4Ctxt->psHciHandle,
1141                                     (void *)gpphHal4Nfc_Hwref,
1142                                     FALSE
1143                                     );
1144         Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == ConnectStatus?
1145                                     eHal4StateConfiguring:eHal4StateInvalid);
1146     }
1147     else/*Remote device Disconnect successful*/
1148     {
1149         psConnectedDevice = Hal4Ctxt->sTgtConnectInfo.psConnectedDevice;
1150         pUpperDisconnectCb = Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb;
1151         /*Deallocate psTrcvCtxtInfo*/
1152         if(NULL != Hal4Ctxt->psTrcvCtxtInfo)
1153         {
1154             if(NULL == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice)
1155             {
1156                if(NULL != Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData)
1157                 {
1158                     phOsalNfc_FreeMemory(
1159                         Hal4Ctxt->psTrcvCtxtInfo->psUpperSendData);
1160                 }
1161             }
1162             else
1163             {
1164                 if(phHal_eNfcIP1_Target
1165                     == Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemDevType)
1166                 {
1167                     pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb;
1168                     Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length = 0;
1169                     pUpperTrcvCb = Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb;
1170                     Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb = NULL;
1171                 }
1172             }
1173             if(NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer)
1174             {
1175                 phOsalNfc_FreeMemory(
1176                     Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer);
1177             }
1178 
1179             phOsalNfc_FreeMemory(Hal4Ctxt->psTrcvCtxtInfo);
1180             Hal4Ctxt->psTrcvCtxtInfo = NULL;
1181         }
1182         /*Free the remote device list*/
1183         do
1184         {
1185             if(NULL != Hal4Ctxt->rem_dev_list[Hal4Ctxt->
1186                 psADDCtxtInfo->nbr_of_devices-1])
1187             {
1188                 phOsalNfc_FreeMemory((void *)
1189                     (Hal4Ctxt->rem_dev_list[Hal4Ctxt->
1190                     psADDCtxtInfo->nbr_of_devices-1]));
1191                 Hal4Ctxt->rem_dev_list[Hal4Ctxt->
1192                     psADDCtxtInfo->nbr_of_devices-1] = NULL;
1193             }
1194         }while(--(Hal4Ctxt->psADDCtxtInfo->nbr_of_devices));
1195 
1196         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice = NULL;
1197         /*Disconnect successful.Go to Ready state*/
1198         Hal4Ctxt->Hal4CurrentState = Hal4Ctxt->Hal4NextState;
1199         Hal4Ctxt->sTgtConnectInfo.pUpperDisconnectCb = NULL;
1200         Hal4Ctxt->Hal4NextState = (
1201             eHal4StateOpenAndReady == Hal4Ctxt->Hal4NextState?
1202             eHal4StateInvalid:Hal4Ctxt->Hal4NextState);
1203         /*Issue any pending Trcv callback*/
1204         if(NULL != pUpperTrcvCb)
1205         {
1206             (*pUpperTrcvCb)(
1207                 Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
1208                 psConnectedDevice,
1209                 NULL,
1210                 NFCSTATUS_FAILED
1211                 );
1212         }
1213         /*Notify upper layer*/
1214         if(NULL != pUpperDisconnectCb)
1215         {
1216             PHDBG_INFO("Hal4:Calling Upper layer disconnect callback");
1217             (*pUpperDisconnectCb)(
1218                         Hal4Ctxt->sUpperLayerInfo.psUpperLayerDisconnectCtxt,
1219                         psConnectedDevice,
1220                         ConnectStatus
1221                         );
1222         }
1223     }
1224     return;
1225 }
1226 
1227 
1228 /*Transceive complete handler function*/
phHal4Nfc_TransceiveComplete(phHal4Nfc_Hal4Ctxt_t * Hal4Ctxt,void * pInfo)1229 void phHal4Nfc_TransceiveComplete(
1230                                   phHal4Nfc_Hal4Ctxt_t  *Hal4Ctxt,
1231                                   void *pInfo
1232                                   )
1233 {
1234     /*Copy status code*/
1235     NFCSTATUS TrcvStatus = ((phNfc_sCompletionInfo_t *)pInfo)->status;
1236     /*Update next state*/
1237     Hal4Ctxt->Hal4NextState = (eHal4StateTransaction
1238              == Hal4Ctxt->Hal4NextState?eHal4StateInvalid:Hal4Ctxt->Hal4NextState);
1239     /*Reset SelectSectorFlag for Mifare*/
1240     if (Hal4Ctxt->SelectSectorFlag == 2)
1241     {
1242         TrcvStatus = NFCSTATUS_SUCCESS;
1243         PHDBG_INFO("Inside Hal4TrcvComplete SelectSectorFlag is 2");
1244         Hal4Ctxt->SelectSectorFlag = 0;
1245     }
1246 
1247     if(NULL == Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData)
1248     {
1249         /*if recv buffer is Null*/
1250         phOsalNfc_RaiseException(phOsalNfc_e_PrecondFailed,1);
1251         TrcvStatus = NFCSTATUS_FAILED;
1252     }
1253     else if(TrcvStatus == NFCSTATUS_SUCCESS)
1254     {
1255         /*Check if recvdata buffer given by upper layer is big enough to
1256         receive all response bytes.If it is not big enough ,copy number
1257         of bytes requested by upper layer to the buffer.Remaining
1258         bytes are retained in Hal4 and upper layer has to issue another
1259         transceive call to read the same.*/
1260         if(((phNfc_sTransactionInfo_t *)pInfo)
1261             ->length  > Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length )
1262         {
1263             TrcvStatus = PHNFCSTVAL(CID_NFC_HAL ,NFCSTATUS_MORE_INFORMATION);
1264             Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length
1265                 = ((phNfc_sTransactionInfo_t *)pInfo)->length
1266                 - Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length;
1267 
1268             Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer
1269                 = (uint8_t *)phOsalNfc_GetMemory(
1270                 Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length
1271                 );
1272             if(NULL != Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer)
1273             {
1274                 (void)memcpy(
1275                     Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.buffer,
1276                     (((phNfc_sTransactionInfo_t *)pInfo)->buffer
1277                     + Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData
1278                     ->length)
1279                     ,Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length
1280                     );
1281             }
1282             else
1283             {
1284                 TrcvStatus = PHNFCSTVAL(CID_NFC_HAL,
1285                     NFCSTATUS_INSUFFICIENT_RESOURCES);
1286                 phOsalNfc_RaiseException(phOsalNfc_e_NoMemory,0);
1287             }
1288 
1289         }
1290         else/*Buffer provided by upper layer is big enough to hold all read
1291               bytes*/
1292         {
1293             Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length
1294                 = ((phNfc_sTransactionInfo_t *)pInfo)->length;
1295             Hal4Ctxt->psTrcvCtxtInfo->sLowerRecvData.length = 0;
1296         }
1297         (void)memcpy(Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->buffer,
1298             ((phNfc_sTransactionInfo_t *)pInfo)->buffer,
1299             Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length
1300             );
1301 
1302     }
1303     else/*Error scenario.Set received bytes length to zero*/
1304     {
1305         Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData->length = 0;
1306     }
1307     (void)memset((void *)&(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params),
1308                   0,
1309                   sizeof(Hal4Ctxt->psTrcvCtxtInfo->XchangeInfo.params)
1310                 );
1311     Hal4Ctxt->psTrcvCtxtInfo->LowerRecvBufferOffset = 0;
1312     /*Issue transceive callback*/
1313     (*Hal4Ctxt->psTrcvCtxtInfo->pUpperTranceiveCb)(
1314         Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt,
1315         Hal4Ctxt->sTgtConnectInfo.psConnectedDevice,
1316         Hal4Ctxt->psTrcvCtxtInfo->psUpperRecvData,
1317         TrcvStatus
1318         );
1319     return;
1320 }
1321