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