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