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 /*!
18 * \file phLibNfc_initiator.c
19
20 * Project: NFC FRI 1.1
21 *
22 * $Date: Fri Apr 23 14:34:08 2010 $
23 * $Author: ing07385 $
24 * $Revision: 1.53 $
25 * $Aliases: NFC_FRI1.1_WK1014_SDK,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1019_SDK,NFC_FRI1.1_WK1024_SDK $
26 *
27 */
28
29 /*
30 ************************* Header Files ****************************************
31 */
32
33 #include <phLibNfcStatus.h>
34 #include <phLibNfc.h>
35 #include <phHal4Nfc.h>
36 #include <phOsalNfc.h>
37 #include <phLibNfc_Internal.h>
38 #include <phLibNfc_SE.h>
39 #include <phLibNfc_ndef_raw.h>
40 #include <phLibNfc_initiator.h>
41 #include <phLibNfc_discovery.h>
42
43
44 /*
45 *************************** Macro's ****************************************
46 */
47
48 #ifndef STATIC_DISABLE
49 #define STATIC static
50 #else
51 #define STATIC
52 #endif
53
54 /*
55 *************************** Global Variables **********************************
56 */
57
58 #define PN544_IO_TIMEOUT_RESPONSE 0x89
59
60 /*
61 *************************** Static Function Declaration ***********************
62 */
63
64 /* Target discvovery notification callback */
65 STATIC void phLibNfc_NotificationRegister_Resp_Cb (
66 void *context,
67 phHal_eNotificationType_t type,
68 phHal4Nfc_NotificationInfo_t info,
69 NFCSTATUS status
70 );
71
72 /*Remote device connect response callback*/
73 STATIC void phLibNfc_RemoteDev_Connect_Cb(
74 void *pContext,
75 phHal_sRemoteDevInformation_t *pRmtdev_info,
76 NFCSTATUS status
77 );
78
79 #ifdef RECONNECT_SUPPORT
80 STATIC
81 void
82 phLibNfc_config_discovery_con_failure_cb (
83 void *context,
84 NFCSTATUS status);
85 #endif /* #ifdef RECONNECT_SUPPORT */
86
87 /*Remote device disconnect response callback*/
88 STATIC void phLibNfc_RemoteDev_Disconnect_cb(
89 void *context,
90 phHal_sRemoteDevInformation_t *reg_handle,
91 NFCSTATUS status
92 );
93 /*Remote device Transceive response callback*/
94 STATIC void phLibNfc_RemoteDev_Transceive_Cb(void *context,
95 phHal_sRemoteDevInformation_t *pRmtdev_info,
96 phNfc_sData_t *response,
97 NFCSTATUS status
98 );
99 /*Set P2P config paramater response callback*/
100 STATIC void phLibNfc_Mgt_SetP2P_ConfigParams_Cb(
101 void *context,
102 NFCSTATUS status
103 );
104
105
106 /*
107 *************************** Function Definitions ******************************
108 */
109
110 /**
111 * Response to target discovery.
112 */
113 STATIC
phLibNfc_NotificationRegister_Resp_Cb(void * context,phHal_eNotificationType_t type,phHal4Nfc_NotificationInfo_t info,NFCSTATUS status)114 void phLibNfc_NotificationRegister_Resp_Cb (
115 void *context,
116 phHal_eNotificationType_t type,
117 phHal4Nfc_NotificationInfo_t info,
118 NFCSTATUS status
119 )
120 {
121 NFCSTATUS RetVal = NFCSTATUS_SUCCESS,
122 Status = NFCSTATUS_SUCCESS;
123 uint16_t DeviceIndx, DeviceIndx1;
124 uint8_t sak_byte=0;
125 uint8_t tag_disc_flg = 0;
126 phLibNfc_NtfRegister_RspCb_t pClientCb=NULL;
127 pClientCb =gpphLibContext->CBInfo.pClientNtfRegRespCB;
128 PHNFC_UNUSED_VARIABLE(context);
129
130
131 if(( type != NFC_DISCOVERY_NOTIFICATION )
132 &&(PHNFCSTATUS(status)!=NFCSTATUS_DESELECTED))
133 {
134 Status = NFCSTATUS_FAILED;
135 }
136 else if (PHNFCSTATUS(status) == NFCSTATUS_DESELECTED)
137 {
138 return;
139 }
140 else
141 {
142 DeviceIndx=0;DeviceIndx1=0;
143 while(DeviceIndx < info.psDiscoveryInfo->NumberOfDevices)
144 {
145 switch(info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx]->RemDevType)
146 {
147 case phHal_eMifare_PICC:
148 {
149 /*Mifare Tag discovered*/
150 sak_byte = info.psDiscoveryInfo->
151 ppRemoteDevInfo[DeviceIndx]->RemoteDevInfo.Iso14443A_Info.Sak;
152 if((TRUE == gpphLibContext->RegNtfType.MifareUL)&& (sak_byte==0x00))
153 {
154 /*Copy the tag related info*/
155 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
156 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
157 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
158 (uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
159 gpphLibContext->Discov_handle[DeviceIndx1] =
160 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
161 DeviceIndx1++;
162 tag_disc_flg++;
163 }
164
165 if((TRUE == gpphLibContext->RegNtfType.MifareStd)&&
166 (((sak_byte & 0x18)==0x08)||((sak_byte & 0x18)==0x18)))
167 {
168 /*Copy the tag related info*/
169 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
170 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
171 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
172 (uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
173 gpphLibContext->Discov_handle[DeviceIndx1]=
174 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
175 DeviceIndx1++;
176 tag_disc_flg++;
177 }
178
179 }break;
180 case phHal_eISO14443_A_PICC:
181 {
182 /*ISO 14443-A type tag discovered*/
183 if(TRUE == gpphLibContext->RegNtfType.ISO14443_4A)
184 {
185 /*Copy the ISO type A tag info*/
186 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
187 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
188 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
189 (uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
190 gpphLibContext->Discov_handle[DeviceIndx1] =
191 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
192 DeviceIndx1++;
193 tag_disc_flg++;
194 }
195 }break;
196 case phHal_eISO14443_3A_PICC:
197 {
198 /*ISO 14443-A type tag discovered*/
199 if(TRUE == gpphLibContext->RegNtfType.MifareUL)
200 {
201 /*Copy the ISO type A tag info*/
202 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
203 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
204 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
205 (uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
206 gpphLibContext->Discov_handle[DeviceIndx1] =
207 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
208 DeviceIndx1++;
209 tag_disc_flg++;
210 }
211 }break;
212 case phHal_eISO14443_B_PICC:
213 {
214 /*ISO 14443-B type tag Discovered */
215 if(TRUE == gpphLibContext->RegNtfType.ISO14443_4B)
216 {
217 /*Copy the Type B tag info */
218 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
219 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
220 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
221 (uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
222 gpphLibContext->Discov_handle[DeviceIndx1] =
223 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
224 DeviceIndx1++;
225 tag_disc_flg++;
226 }
227 }break;
228 case phHal_eFelica_PICC:
229 {
230 /*Felica Type Tag Discovered */
231 if(TRUE == gpphLibContext->RegNtfType.Felica)
232 {
233 /*Copy the Felica tag info */
234 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
235 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
236 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
237 (uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
238 gpphLibContext->Discov_handle[DeviceIndx1] =
239 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
240 DeviceIndx1++;
241 tag_disc_flg++;
242 }
243 }break;
244 case phHal_eJewel_PICC:
245 {
246 /*Jewel Type Tag Discovered */
247 if(TRUE == gpphLibContext->RegNtfType.Jewel)
248 {
249 /*Copy the Felica tag info */
250 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
251 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
252 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
253 (uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
254 gpphLibContext->Discov_handle[DeviceIndx1] =
255 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
256 DeviceIndx1++;
257 tag_disc_flg++;
258 }
259 }
260 break;
261 case phHal_eISO15693_PICC:
262 {
263 /*Jewel Type Tag Discovered */
264 if(TRUE == gpphLibContext->RegNtfType.ISO15693)
265 {
266 /*Copy the Felica tag info */
267 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
268 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
269 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
270 (uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
271 gpphLibContext->Discov_handle[DeviceIndx1] =
272 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
273 DeviceIndx1++;
274 tag_disc_flg++;
275 }
276 }
277 break;
278 case phHal_eNfcIP1_Target:
279 {
280 if(TRUE == gpphLibContext->RegNtfType.NFC)
281 {
282 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
283 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
284 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
285 (uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx].psRemoteDevInfo;
286 gpphLibContext->Discov_handle[DeviceIndx1] =
287 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
288 DeviceIndx1++;
289 tag_disc_flg++;
290 }
291 }
292 break;
293 case phHal_eNfcIP1_Initiator:
294 {
295 if(TRUE == gpphLibContext->RegNtfType.NFC)
296 {
297 gpphLibContext->LibNfcState.cur_state=eLibNfcHalStateConnect;
298 gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo=
299 info.psDiscoveryInfo->ppRemoteDevInfo[DeviceIndx];
300 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev =
301 (uint32_t)gpphLibContext->psRemoteDevList[DeviceIndx1].psRemoteDevInfo;
302 gpphLibContext->sNfcIp_Context.Rem_Initiator_Handle=
303 gpphLibContext->psRemoteDevList[DeviceIndx1].hTargetDev;
304 DeviceIndx1++;
305 tag_disc_flg++;
306 }
307 }
308 break;
309 default :
310 {
311 break;
312 }
313 }
314 DeviceIndx++;
315 }
316 }
317
318 if((tag_disc_flg >0 )&&(status != NFCSTATUS_FAILED))
319 {
320 gpphLibContext->dev_cnt = tag_disc_flg;
321 /* Check for if the discovered tags are multiple or
322 Multiple protocol tag */
323 if((gpphLibContext->dev_cnt > 1)&&(
324 (status ==NFCSTATUS_MULTIPLE_PROTOCOLS) ||
325 (status ==NFCSTATUS_MULTIPLE_TAGS)) )
326 {
327 status = status;
328 }
329 else
330 {
331 status =NFCSTATUS_SUCCESS;
332 }
333 /*Notify to upper layer the no of tag discovered and
334 the protocol */
335 if (NULL != pClientCb)
336 {
337 pClientCb(
338 (void*)gpphLibContext->CBInfo.pClientNtfRegRespCntx,
339 gpphLibContext->psRemoteDevList,
340 gpphLibContext->dev_cnt,
341 status
342 );
343 }
344
345 }
346 else if(PHNFCSTATUS(status)==NFCSTATUS_DESELECTED)
347 {
348 info.psDiscoveryInfo->NumberOfDevices = 0;
349 if (NULL != pClientCb)
350 {
351 gpphLibContext->LibNfcState.cur_state=eLibNfcHalStateRelease;
352 pClientCb((void*)gpphLibContext->CBInfo.pClientNtfRegRespCntx,
353 NULL,
354 0,
355 status);
356 }
357
358 }
359 else /*Reconfigure the discovery wheel*/
360 {
361 RetVal = phHal4Nfc_ConfigureDiscovery ( gpphLibContext->psHwReference,
362 NFC_DISCOVERY_RESUME,
363 &(gpphLibContext->sADDconfig),
364 phLibNfc_config_discovery_cb,
365 gpphLibContext);
366
367 if((RetVal!=NFCSTATUS_SUCCESS) &&(RetVal!=NFCSTATUS_PENDING))
368 {
369 Status = NFCSTATUS_FAILED;
370 }
371
372 }
373 if(Status == NFCSTATUS_FAILED)
374 {
375 if (NULL != pClientCb)
376 {
377 pClientCb(gpphLibContext->CBInfo.pClientNtfRegRespCntx,
378 NULL,
379 0,
380 Status);
381 }
382 }
383 return;
384 }
385
386 /**
387 * This interface registers notification handler for target discovery.
388 */
389 NFCSTATUS
phLibNfc_RemoteDev_NtfRegister(phLibNfc_Registry_Info_t * pRegistryInfo,phLibNfc_NtfRegister_RspCb_t pNotificationHandler,void * pContext)390 phLibNfc_RemoteDev_NtfRegister(
391 phLibNfc_Registry_Info_t* pRegistryInfo,
392 phLibNfc_NtfRegister_RspCb_t pNotificationHandler,
393 void *pContext
394 )
395 {
396 NFCSTATUS RetVal = NFCSTATUS_SUCCESS;
397
398
399 /*Check for valid parameters*/
400 if((NULL == pNotificationHandler)
401 || (NULL == pContext)
402 ||(NULL== pRegistryInfo))
403 {
404 RetVal= NFCSTATUS_INVALID_PARAMETER;
405 }
406 else if((NULL == gpphLibContext) ||
407 (gpphLibContext->LibNfcState.cur_state
408 == eLibNfcHalStateShutdown))
409 {
410 RetVal = NFCSTATUS_NOT_INITIALISED;
411 }
412 else if(gpphLibContext->LibNfcState.next_state
413 == eLibNfcHalStateShutdown)
414 {
415 /*Next state is shutdown*/
416 RetVal= NFCSTATUS_SHUTDOWN;
417 }
418 else
419 {
420
421 PHDBG_INFO("LibNfc:Registering Notification Handler");
422
423
424 (void) memcpy(&(gpphLibContext->RegNtfType),pRegistryInfo,
425 sizeof(phLibNfc_Registry_Info_t));
426 /* Register Discovery Notification Handler*/
427
428 /*Register for NFCIP1 target type*/
429 RetVal = phHal4Nfc_RegisterNotification(
430 gpphLibContext->psHwReference,
431 eRegisterP2PDiscovery,
432 phLibNfc_NotificationRegister_Resp_Cb,
433 (void*)gpphLibContext
434 );
435 /*Register for Tag discovery*/
436 RetVal = phHal4Nfc_RegisterNotification(
437 gpphLibContext->psHwReference,
438 eRegisterTagDiscovery,
439 phLibNfc_NotificationRegister_Resp_Cb,
440 (void*)gpphLibContext
441 );
442 gpphLibContext->CBInfo.pClientNtfRegRespCB = pNotificationHandler;
443 gpphLibContext->CBInfo.pClientNtfRegRespCntx = pContext;
444 /*Register notification handler with below layer*/
445
446 }
447 return RetVal;
448 }
449 /**
450 * This interface unregisters notification handler for target discovery.
451 */
phLibNfc_RemoteDev_NtfUnregister(void)452 NFCSTATUS phLibNfc_RemoteDev_NtfUnregister(void)
453 {
454 NFCSTATUS RetVal = NFCSTATUS_SUCCESS;
455 if((NULL == gpphLibContext) ||
456 (gpphLibContext->LibNfcState.cur_state
457 == eLibNfcHalStateShutdown))
458 {
459 /*Lib Nfc not Initialized*/
460 RetVal = NFCSTATUS_NOT_INITIALISED;
461 }
462 else if(gpphLibContext->LibNfcState.next_state
463 == eLibNfcHalStateShutdown)
464 {
465 /*Lib Nfc Shutdown*/
466 RetVal= NFCSTATUS_SHUTDOWN;
467 }
468 else
469 {
470 /*Unregister notification handler with lower layer */
471 RetVal = phHal4Nfc_UnregisterNotification(
472 gpphLibContext->psHwReference,
473 eRegisterP2PDiscovery,
474 gpphLibContext);
475
476 RetVal = phHal4Nfc_UnregisterNotification(
477 gpphLibContext->psHwReference,
478 eRegisterTagDiscovery,
479 gpphLibContext);
480
481 gpphLibContext->CBInfo.pClientNtfRegRespCB = NULL;
482 gpphLibContext->CBInfo.pClientNtfRegRespCntx =NULL;
483 PHDBG_INFO("LibNfc:Unregister Notification Handler");
484 }
485 return RetVal;
486 }
487
488 #ifdef RECONNECT_SUPPORT
489
490 NFCSTATUS
phLibNfc_RemoteDev_ReConnect(phLibNfc_Handle hRemoteDevice,pphLibNfc_ConnectCallback_t pNotifyReConnect_RspCb,void * pContext)491 phLibNfc_RemoteDev_ReConnect (
492 phLibNfc_Handle hRemoteDevice,
493 pphLibNfc_ConnectCallback_t pNotifyReConnect_RspCb,
494 void *pContext)
495 {
496
497 NFCSTATUS ret_val = NFCSTATUS_FAILED;
498 phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo = NULL;
499
500 if ((NULL == gpphLibContext)
501 || (eLibNfcHalStateShutdown ==
502 gpphLibContext->LibNfcState.cur_state))
503 {
504 ret_val = NFCSTATUS_NOT_INITIALISED;
505 }
506 else if ((NULL == pContext)
507 || (NULL == pNotifyReConnect_RspCb)
508 || (NULL == (void *)hRemoteDevice))
509 {
510 /* Check valid parameters */
511 ret_val = NFCSTATUS_INVALID_PARAMETER;
512 }
513 /* Check valid lib nfc State */
514 else if (gpphLibContext->LibNfcState.next_state
515 == eLibNfcHalStateShutdown)
516 {
517 ret_val = NFCSTATUS_SHUTDOWN;
518 }
519 else if (0 == gpphLibContext->Connected_handle)
520 {
521 ret_val = NFCSTATUS_TARGET_NOT_CONNECTED;
522 }
523 else if ((gpphLibContext->Discov_handle[0] != hRemoteDevice)
524 && (gpphLibContext->Discov_handle[1] != hRemoteDevice)
525 && (gpphLibContext->Discov_handle[2] != hRemoteDevice)
526 && (gpphLibContext->Discov_handle[3] != hRemoteDevice)
527 && (gpphLibContext->Discov_handle[4] != hRemoteDevice)
528 && (gpphLibContext->Discov_handle[5] != hRemoteDevice)
529 && (gpphLibContext->Discov_handle[6] != hRemoteDevice)
530 && (gpphLibContext->Discov_handle[7] != hRemoteDevice)
531 && (gpphLibContext->Discov_handle[8] != hRemoteDevice)
532 && (gpphLibContext->Discov_handle[9] != hRemoteDevice))
533 {
534 ret_val = NFCSTATUS_INVALID_HANDLE;
535 }
536 else
537 {
538 psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t *)hRemoteDevice;
539
540 /* Call the HAL connect*/
541 ret_val = phHal4Nfc_Connect (gpphLibContext->psHwReference,
542 psRemoteDevInfo,
543 phLibNfc_RemoteDev_Connect_Cb,
544 (void *)gpphLibContext);
545
546 if (NFCSTATUS_PENDING == ret_val)
547 {
548 /* If HAL Connect is pending update the LibNFC state machine
549 and store the CB pointer and Context,
550 mark the General CB pending status is TRUE */
551 gpphLibContext->CBInfo.pClientConnectCb = pNotifyReConnect_RspCb;
552 gpphLibContext->CBInfo.pClientConCntx = pContext;
553 gpphLibContext->status.GenCb_pending_status = TRUE;
554 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect;
555
556 gpphLibContext->Prev_Connected_handle = gpphLibContext->Connected_handle;
557
558 gpphLibContext->Connected_handle = hRemoteDevice;
559 }
560 else if (NFCSTATUS_INVALID_REMOTE_DEVICE == PHNFCSTATUS(ret_val))
561 {
562 /* The Handle given for connect is invalid*/
563 ret_val = NFCSTATUS_TARGET_NOT_CONNECTED;
564 }
565 else
566 {
567 /* Lower layer returns internal error code return NFCSTATUS_FAILED*/
568 ret_val = NFCSTATUS_FAILED;
569 }
570 }
571
572 return ret_val;
573 }
574 #endif /* #ifdef RECONNECT_SUPPORT */
575
576
577 /**
578 * Connect to a single Remote Device
579 */
phLibNfc_RemoteDev_Connect(phLibNfc_Handle hRemoteDevice,pphLibNfc_ConnectCallback_t pNotifyConnect_RspCb,void * pContext)580 NFCSTATUS phLibNfc_RemoteDev_Connect(
581 phLibNfc_Handle hRemoteDevice,
582 pphLibNfc_ConnectCallback_t pNotifyConnect_RspCb,
583 void *pContext
584 )
585 {
586
587 NFCSTATUS RetVal = NFCSTATUS_FAILED;
588 phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo;
589
590 if((NULL == gpphLibContext) ||
591 (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
592 {
593 RetVal = NFCSTATUS_NOT_INITIALISED;
594 }/* Check valid parameters*/
595 else if((NULL == pContext)
596 || (NULL == pNotifyConnect_RspCb)
597 || (NULL == (void*)hRemoteDevice))
598 {
599 RetVal= NFCSTATUS_INVALID_PARAMETER;
600 }
601 /* Check valid lib nfc State*/
602 else if(gpphLibContext->LibNfcState.next_state
603 == eLibNfcHalStateShutdown)
604 {
605 RetVal= NFCSTATUS_SHUTDOWN;
606 }
607 else if((gpphLibContext->Discov_handle[0] != hRemoteDevice)&&
608 (gpphLibContext->Discov_handle[1] != hRemoteDevice)&&
609 (gpphLibContext->Discov_handle[2] != hRemoteDevice)&&
610 (gpphLibContext->Discov_handle[3] != hRemoteDevice)&&
611 (gpphLibContext->Discov_handle[4] != hRemoteDevice)&&
612 (gpphLibContext->Discov_handle[5] != hRemoteDevice)&&
613 (gpphLibContext->Discov_handle[6] != hRemoteDevice)&&
614 (gpphLibContext->Discov_handle[7] != hRemoteDevice)&&
615 (gpphLibContext->Discov_handle[8] != hRemoteDevice)&&
616 (gpphLibContext->Discov_handle[9] != hRemoteDevice))
617 {
618 RetVal= NFCSTATUS_INVALID_HANDLE;
619 }
620 else if ((hRemoteDevice != gpphLibContext->Connected_handle)
621 && (0 != gpphLibContext->Connected_handle))
622 {
623 RetVal = NFCSTATUS_FAILED;
624 }
625 else
626 {
627 psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice;
628
629 /* Call the HAL connect*/
630 RetVal = phHal4Nfc_Connect(gpphLibContext->psHwReference,
631 psRemoteDevInfo,
632 phLibNfc_RemoteDev_Connect_Cb,
633 (void* )gpphLibContext);
634 if(RetVal== NFCSTATUS_PENDING)
635 {
636 /* If HAL Connect is pending update the LibNFC state machine
637 and store the CB pointer and Context,
638 mark the General CB pending status is TRUE*/
639 gpphLibContext->CBInfo.pClientConnectCb = pNotifyConnect_RspCb;
640 gpphLibContext->CBInfo.pClientConCntx = pContext;
641 gpphLibContext->status.GenCb_pending_status=TRUE;
642 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect;
643 gpphLibContext->Prev_Connected_handle = gpphLibContext->Connected_handle;
644 gpphLibContext->Connected_handle = hRemoteDevice;
645 }
646 else if(PHNFCSTATUS(RetVal) == NFCSTATUS_INVALID_REMOTE_DEVICE)
647 {
648 /* The Handle given for connect is invalid*/
649 RetVal= NFCSTATUS_TARGET_NOT_CONNECTED;
650 }
651 else
652 {
653 /* Lower layer returns internal error code return NFCSTATUS_FAILED*/
654 RetVal = NFCSTATUS_FAILED;
655 }
656 }
657 return RetVal;
658 }
659
660 #ifdef RECONNECT_SUPPORT
661 STATIC
662 void
phLibNfc_config_discovery_con_failure_cb(void * context,NFCSTATUS status)663 phLibNfc_config_discovery_con_failure_cb (
664 void *context,
665 NFCSTATUS status)
666 {
667 if((phLibNfc_LibContext_t *)context == gpphLibContext)
668 { /*check for same context*/
669 pphLibNfc_ConnectCallback_t ps_client_con_cb =
670 gpphLibContext->CBInfo.pClientConnectCb;
671
672 if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
673 {
674 /*If shutdown called in between allow shutdown to happen*/
675 phLibNfc_Pending_Shutdown();
676 status = NFCSTATUS_SHUTDOWN;
677 }
678 else
679 {
680 gpphLibContext->status.GenCb_pending_status = FALSE;
681 gpphLibContext->status.DiscEnbl_status = FALSE;
682 status = NFCSTATUS_TARGET_LOST;
683
684 phLibNfc_UpdateCurState (status,gpphLibContext);
685 #ifdef RESTART_CFG
686 if(gpphLibContext->status.Discovery_pending_status == TRUE)
687 {
688 NFCSTATUS RetStatus = NFCSTATUS_FAILED;
689 /* Application has called discovery before receiving this callback,
690 so NO notification to the upper layer, instead lower layer
691 discovery is called */
692 gpphLibContext->status.Discovery_pending_status = FALSE;
693 RetStatus = phHal4Nfc_ConfigureDiscovery(
694 gpphLibContext->psHwReference,
695 gpphLibContext->eLibNfcCfgMode,
696 &gpphLibContext->sADDconfig,
697 (pphLibNfc_RspCb_t)
698 phLibNfc_config_discovery_cb,
699 (void *)gpphLibContext);
700 if (NFCSTATUS_PENDING == RetStatus)
701 {
702 (void)phLibNfc_UpdateNextState(gpphLibContext,
703 eLibNfcHalStateConfigReady);
704 gpphLibContext->status.GenCb_pending_status = TRUE;
705 gpphLibContext->status.DiscEnbl_status = TRUE;
706 }
707 }
708
709 #endif /* #ifdef RESTART_CFG */
710 }
711
712 if (NULL != ps_client_con_cb)
713 {
714 gpphLibContext->CBInfo.pClientConnectCb = NULL;
715 /* Call the upper layer callback*/
716 ps_client_con_cb (gpphLibContext->CBInfo.pClientConCntx,
717 0, NULL, status);
718 }
719 } /*End of if-context check*/
720 else
721 { /*exception: wrong context pointer returned*/
722 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
723 status = NFCSTATUS_FAILED;
724 }
725
726
727 }
728 #endif /* #ifdef RECONNECT_SUPPORT */
729 /**
730 * Response callback for remote device connect
731 */
phLibNfc_RemoteDev_Connect_Cb(void * pContext,phHal_sRemoteDevInformation_t * pRmtdev_info,NFCSTATUS status)732 STATIC void phLibNfc_RemoteDev_Connect_Cb(
733 void *pContext,
734 phHal_sRemoteDevInformation_t *pRmtdev_info,
735 NFCSTATUS status
736 )
737 {
738 NFCSTATUS Connect_status = NFCSTATUS_SUCCESS;
739 /*Check valid lib nfc context is returned from lower layer*/
740 if((phLibNfc_LibContext_t *)pContext == gpphLibContext)
741 {
742 gpphLibContext->LastTrancvSuccess = FALSE;
743
744 /* Mark General Callback pending status as false*/
745 gpphLibContext->status.GenCb_pending_status = FALSE;
746
747 /* Check the shutdown is called during the lower layer Connect in process,
748 If yes call shutdown call and return NFCSTATUS_SHUTDOWN */
749 if((eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state))
750 {
751 phLibNfc_Pending_Shutdown();
752 Connect_status = NFCSTATUS_SHUTDOWN;
753
754 }
755 else if(PHNFCSTATUS(status)==NFCSTATUS_SUCCESS)
756 {
757 /* Copy the Remote device address as connected handle*/
758 gpphLibContext->Connected_handle =(uint32_t) pRmtdev_info;
759 /* Update the state to connected and return status as SUCCESS*/
760 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect;
761 Connect_status = NFCSTATUS_SUCCESS;
762 }
763 else
764 { /* if(PHNFCSTATUS(status)==NFCSTATUS_INVALID_REMOTE_DEVICE) */
765 /* If remote device is invalid return as TARGET LOST to upper layer*/
766 /* If error code is other than SUCCESS return NFCSTATUS_TARGET_LOST */
767 Connect_status = NFCSTATUS_TARGET_LOST;
768 gpphLibContext->Connected_handle = gpphLibContext->Prev_Connected_handle ;
769 }
770 gpphLibContext->ndef_cntx.is_ndef = CHK_NDEF_NOT_DONE;
771 /* Update the Current Sate*/
772 phLibNfc_UpdateCurState(Connect_status,(phLibNfc_LibContext_t *)pContext);
773 /* Call the upper layer callback*/
774 gpphLibContext->CBInfo.pClientConnectCb(
775 gpphLibContext->CBInfo.pClientConCntx,
776 (uint32_t)pRmtdev_info,
777 (phLibNfc_sRemoteDevInformation_t*)pRmtdev_info,
778 Connect_status);
779 }
780 else
781 { /*exception: wrong context pointer returned*/
782 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
783 }
784 return;
785 }
786
787 /**
788 * Allows to disconnect from already connected target.
789 */
phLibNfc_RemoteDev_Disconnect(phLibNfc_Handle hRemoteDevice,phLibNfc_eReleaseType_t ReleaseType,pphLibNfc_DisconnectCallback_t pDscntCallback,void * pContext)790 NFCSTATUS phLibNfc_RemoteDev_Disconnect( phLibNfc_Handle hRemoteDevice,
791 phLibNfc_eReleaseType_t ReleaseType,
792 pphLibNfc_DisconnectCallback_t pDscntCallback,
793 void* pContext
794 )
795 {
796 NFCSTATUS RetVal = NFCSTATUS_SUCCESS;
797 phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo=NULL;
798
799 /*Check for valid parameter*/
800 if((NULL == gpphLibContext) ||
801 (gpphLibContext->LibNfcState.cur_state
802 == eLibNfcHalStateShutdown))
803 {
804 RetVal = NFCSTATUS_NOT_INITIALISED;
805 }
806 else if((NULL == pContext) ||
807 (NULL == pDscntCallback)||(hRemoteDevice == 0))
808 {
809 RetVal= NFCSTATUS_INVALID_PARAMETER;
810 }
811 /* Check for valid state,If De initialize is called then
812 return NFCSTATUS_SHUTDOWN */
813 else if(gpphLibContext->LibNfcState.next_state
814 == eLibNfcHalStateShutdown)
815 {
816 RetVal= NFCSTATUS_SHUTDOWN;
817 }
818 else if(gpphLibContext->Connected_handle==0)
819 {
820 RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;
821 }
822 /* The given handle is not the connected handle return NFCSTATUS_INVALID_HANDLE*/
823 else if(hRemoteDevice != gpphLibContext->Connected_handle )
824 {
825 RetVal=NFCSTATUS_INVALID_HANDLE;
826 }
827 else
828 {
829 if((eLibNfcHalStateRelease == gpphLibContext->LibNfcState.next_state)
830 ||((gpphLibContext->sSeContext.eActivatedMode == phLibNfc_SE_ActModeWired)&&
831 (ReleaseType != NFC_SMARTMX_RELEASE))
832 ||((gpphLibContext->sSeContext.eActivatedMode != phLibNfc_SE_ActModeWired)&&
833 (ReleaseType == NFC_SMARTMX_RELEASE)))
834 { /* Previous disconnect callback is pending */
835 RetVal = NFCSTATUS_REJECTED;
836 }
837 #ifndef LLCP_CHANGES
838 else if(eLibNfcHalStateTransaction == gpphLibContext->LibNfcState.next_state)
839 { /* Previous Transaction is Pending*/
840 RetVal = NFCSTATUS_BUSY;
841 PHDBG_INFO("LibNfc:Transaction is Pending");
842 }
843 #endif /* #ifdef LLCP_CHANGES */
844 else
845 {
846 gpphLibContext->ReleaseType = ReleaseType;
847 psRemoteDevInfo = (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice;
848 RetVal = phHal4Nfc_Disconnect(gpphLibContext->psHwReference,
849 (phHal_sRemoteDevInformation_t*)psRemoteDevInfo,
850 gpphLibContext->ReleaseType,
851 (pphHal4Nfc_DiscntCallback_t)
852 phLibNfc_RemoteDev_Disconnect_cb,
853 (void *)gpphLibContext);
854 if( NFCSTATUS_PENDING == PHNFCSTATUS(RetVal))
855 {
856 /*Copy the upper layer Callback pointer and context*/
857 gpphLibContext->CBInfo.pClientDisConnectCb = pDscntCallback;
858 gpphLibContext->CBInfo.pClientDConCntx = pContext;
859 /* Mark general callback pending status as TRUE and update the state*/
860 gpphLibContext->status.GenCb_pending_status=TRUE;
861 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateRelease;
862
863 }
864 else
865 {
866 /*If lower layer returns other than pending
867 (internal error codes) return NFCSTATUS_FAILED */
868 RetVal = NFCSTATUS_FAILED;
869 }
870 }
871 }
872 return RetVal;
873 }
874 /**
875 * Response callback for Remote device Disconnect.
876 */
phLibNfc_RemoteDev_Disconnect_cb(void * context,phHal_sRemoteDevInformation_t * reg_handle,NFCSTATUS status)877 STATIC void phLibNfc_RemoteDev_Disconnect_cb(
878 void *context,
879 phHal_sRemoteDevInformation_t *reg_handle,
880 NFCSTATUS status
881 )
882 {
883 NFCSTATUS DisCnct_status = NFCSTATUS_SUCCESS;
884 pphLibNfc_DisconnectCallback_t pUpper_NtfCb = NULL;
885 void *pUpper_Context = NULL;
886
887 /* Copy the upper layer Callback and context*/
888 pUpper_NtfCb = gpphLibContext->CBInfo.pClientDisConnectCb;
889 pUpper_Context = gpphLibContext->CBInfo.pClientDConCntx;
890
891 /* Check valid context is returned or not */
892 if((phLibNfc_LibContext_t *)context != gpphLibContext)
893 {
894 /*exception: wrong context pointer returned*/
895 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
896 }
897 else
898 {
899 /* Mark the General callback pending status FALSE */
900 gpphLibContext->status.GenCb_pending_status = FALSE;
901 gpphLibContext->CBInfo.pClientDisConnectCb = NULL;
902 gpphLibContext->CBInfo.pClientDConCntx = NULL;
903
904 gpphLibContext->ndef_cntx.is_ndef = CHK_NDEF_NOT_DONE;
905 gpphLibContext->LastTrancvSuccess = FALSE;
906 /*Reset Connected handle */
907 gpphLibContext->Connected_handle=0x0000;
908 /*Reset previous Connected handle */
909 gpphLibContext->Prev_Connected_handle = 0x0000;
910
911 if(gpphLibContext->sSeContext.eActivatedMode == phLibNfc_SE_ActModeWired)
912 {
913 gpphLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeDefault;
914 }
915 if(NULL != gpphLibContext->psBufferedAuth)
916 {
917 if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
918 {
919 phOsalNfc_FreeMemory(
920 gpphLibContext->psBufferedAuth->sRecvData.buffer);
921 }
922 if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
923 {
924 phOsalNfc_FreeMemory(
925 gpphLibContext->psBufferedAuth->sSendData.buffer);
926 }
927 phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
928 gpphLibContext->psBufferedAuth = NULL;
929 }
930 }
931 /* Check DeInit is called or not */
932 if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
933 {
934 /*call shutdown and return status as NFCSTATUS_SHUTDOWN */
935 phLibNfc_Pending_Shutdown();
936 DisCnct_status = NFCSTATUS_SHUTDOWN;
937 }
938 else if(NFCSTATUS_SUCCESS == status)
939 {
940 DisCnct_status = NFCSTATUS_SUCCESS;
941 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateRelease;
942 }
943 else
944 {
945 DisCnct_status = NFCSTATUS_FAILED;
946 phLibNfc_UpdateCurState(DisCnct_status,(phLibNfc_LibContext_t *)context);
947 }
948 /* Call the upper layer Callback */
949 (*pUpper_NtfCb)(pUpper_Context,
950 (uint32_t)reg_handle,
951 DisCnct_status);
952 return;
953 }
954
955 /**
956 * This interface allows to perform Read/write operation on remote device.
957 */
958 NFCSTATUS
phLibNfc_RemoteDev_Transceive(phLibNfc_Handle hRemoteDevice,phLibNfc_sTransceiveInfo_t * psTransceiveInfo,pphLibNfc_TransceiveCallback_t pTransceive_RspCb,void * pContext)959 phLibNfc_RemoteDev_Transceive(phLibNfc_Handle hRemoteDevice,
960 phLibNfc_sTransceiveInfo_t* psTransceiveInfo,
961 pphLibNfc_TransceiveCallback_t pTransceive_RspCb,
962 void* pContext
963 )
964 {
965 NFCSTATUS RetVal = NFCSTATUS_SUCCESS;
966
967 /*Check for valid parameter */
968
969 if((NULL == gpphLibContext) ||
970 (gpphLibContext->LibNfcState.cur_state
971 == eLibNfcHalStateShutdown))
972 {
973 RetVal = NFCSTATUS_NOT_INITIALISED;
974 }
975 else if((NULL == psTransceiveInfo)
976 || (NULL == pTransceive_RspCb)
977 || (NULL == (void *)hRemoteDevice)
978 || (NULL == psTransceiveInfo->sRecvData.buffer)
979 || (NULL == psTransceiveInfo->sSendData.buffer)
980 || (NULL == pContext))
981 {
982 RetVal= NFCSTATUS_INVALID_PARAMETER;
983 }
984 /* Check the state for DeInit is called or not,if yes return NFCSTATUS_SHUTDOWN*/
985 else if(gpphLibContext->LibNfcState.next_state
986 == eLibNfcHalStateShutdown)
987 {
988 RetVal= NFCSTATUS_SHUTDOWN;
989 }/* If there is no handle connected return NFCSTATUS_TARGET_NOT_CONNECTED*/
990 else if(gpphLibContext->Connected_handle==0)
991 {
992 RetVal=NFCSTATUS_TARGET_NOT_CONNECTED;
993 }/* If the given handle is not the connected handle return NFCSTATUS_INVALID_HANDLE */
994 else if(gpphLibContext->Connected_handle!= hRemoteDevice )
995 {
996 RetVal=NFCSTATUS_INVALID_HANDLE;
997 } /*If the transceive is called before finishing the previous transceive function
998 return NFCSTATUS_REJECTED */
999 else if((eLibNfcHalStateTransaction ==
1000 gpphLibContext->LibNfcState.next_state)
1001 ||(phHal_eNfcIP1_Initiator==
1002 ((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType))
1003 {
1004 RetVal = NFCSTATUS_REJECTED;
1005 }
1006 #ifdef LLCP_TRANSACT_CHANGES
1007 else if ((LLCP_STATE_RESET_INIT != gpphLibContext->llcp_cntx.sLlcpContext.state)
1008 && (LLCP_STATE_CHECKED != gpphLibContext->llcp_cntx.sLlcpContext.state))
1009 {
1010 RetVal= NFCSTATUS_BUSY;
1011 }
1012 #endif /* #ifdef LLCP_TRANSACT_CHANGES */
1013 else
1014 {
1015 gpphLibContext->ndef_cntx.eLast_Call = RawTrans;
1016 (void)memcpy((void *)(gpphLibContext->psTransInfo),
1017 (void *)psTransceiveInfo,
1018 sizeof(phLibNfc_sTransceiveInfo_t));
1019 /* Check the given Mifare command is supported or not ,
1020 If not return NFCSTATUS_COMMAND_NOT_SUPPORTED */
1021 if( (((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType ==
1022 phHal_eMifare_PICC)&&
1023 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRaw ) &&
1024 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareAuthentA ) &&
1025 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareAuthentB ) &&
1026 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRead16 ) &&
1027 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRead ) &&
1028 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareWrite16 ) &&
1029 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareWrite4 ) &&
1030 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareDec ) &&
1031 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareTransfer ) &&
1032 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareRestore ) &&
1033 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareReadSector ) &&
1034 ( gpphLibContext->psTransInfo->cmd.MfCmd != phHal_eMifareWriteSector ))
1035 {
1036 RetVal = NFCSTATUS_COMMAND_NOT_SUPPORTED;
1037 }
1038 if(eLibNfcHalStatePresenceChk !=
1039 gpphLibContext->LibNfcState.next_state)
1040 {
1041 PHDBG_INFO("LibNfc:Transceive In Progress");
1042 if((((phHal_sRemoteDevInformation_t*)hRemoteDevice)->RemDevType ==
1043 phHal_eMifare_PICC) && (((phHal_sRemoteDevInformation_t*)
1044 hRemoteDevice)->RemoteDevInfo.Iso14443A_Info.Sak != 0)&&
1045 (phHal_eMifareAuthentA == gpphLibContext->psTransInfo->cmd.MfCmd))
1046 {
1047 if(NULL != gpphLibContext->psBufferedAuth)
1048 {
1049 if(NULL != gpphLibContext->psBufferedAuth->sRecvData.buffer)
1050 {
1051 phOsalNfc_FreeMemory(
1052 gpphLibContext->psBufferedAuth->sRecvData.buffer);
1053 }
1054 if(NULL != gpphLibContext->psBufferedAuth->sSendData.buffer)
1055 {
1056 phOsalNfc_FreeMemory(
1057 gpphLibContext->psBufferedAuth->sSendData.buffer);
1058 }
1059 phOsalNfc_FreeMemory(gpphLibContext->psBufferedAuth);
1060 }
1061 gpphLibContext->psBufferedAuth
1062 =(phLibNfc_sTransceiveInfo_t *)
1063 phOsalNfc_GetMemory(sizeof(phLibNfc_sTransceiveInfo_t));
1064 gpphLibContext->psBufferedAuth->addr = psTransceiveInfo->addr;
1065 gpphLibContext->psBufferedAuth->cmd = psTransceiveInfo->cmd;
1066 gpphLibContext->psBufferedAuth->sSendData.length
1067 = psTransceiveInfo->sSendData.length;
1068 gpphLibContext->psBufferedAuth->sRecvData.length
1069 = psTransceiveInfo->sRecvData.length;
1070 gpphLibContext->psBufferedAuth->sSendData.buffer
1071 = (uint8_t *)
1072 phOsalNfc_GetMemory(
1073 gpphLibContext->psTransInfo->sSendData.length);
1074
1075 (void)memcpy((void *)
1076 (gpphLibContext->psBufferedAuth->sSendData.buffer),
1077 (void *)psTransceiveInfo->sSendData.buffer,
1078 psTransceiveInfo->sSendData.length);
1079
1080 gpphLibContext->psBufferedAuth->sRecvData.buffer
1081 = (uint8_t *)
1082 phOsalNfc_GetMemory(
1083 gpphLibContext->psTransInfo->sRecvData.length);
1084 }
1085 /*Call the lower layer Transceive function */
1086 RetVal = phHal4Nfc_Transceive( gpphLibContext->psHwReference,
1087 (phHal_sTransceiveInfo_t*)gpphLibContext->psTransInfo,
1088 (phLibNfc_sRemoteDevInformation_t*)hRemoteDevice,
1089 (pphHal4Nfc_TransceiveCallback_t)
1090 phLibNfc_RemoteDev_Transceive_Cb,
1091 (void* )gpphLibContext);
1092 if(PHNFCSTATUS(RetVal) == NFCSTATUS_PENDING)
1093 {
1094 /* Copy the upper layer callback pointer and context */
1095 gpphLibContext->CBInfo.pClientTransceiveCb = pTransceive_RspCb;
1096 gpphLibContext->CBInfo.pClientTranseCntx = pContext;
1097 /* Mark the General callback pending status is TRUE */
1098 gpphLibContext->status.GenCb_pending_status = TRUE;
1099 /*Transceive is in Progress-Used in Release API*/
1100
1101 /*Update the state machine*/
1102 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateTransaction;
1103 }
1104 }
1105 else
1106 {
1107 gpphLibContext->status.GenCb_pending_status = FALSE;
1108 RetVal = NFCSTATUS_FAILED;
1109 }
1110 }
1111 return RetVal;
1112 }
1113 /**
1114 * Response for Remote device transceive.
1115 */
1116 STATIC
phLibNfc_RemoteDev_Transceive_Cb(void * context,phHal_sRemoteDevInformation_t * pRmtdev_info,phNfc_sData_t * response,NFCSTATUS status)1117 void phLibNfc_RemoteDev_Transceive_Cb(void *context,
1118 phHal_sRemoteDevInformation_t *pRmtdev_info,
1119 phNfc_sData_t *response,
1120 NFCSTATUS status
1121 )
1122 {
1123 NFCSTATUS trans_status = NFCSTATUS_SUCCESS;
1124 phNfc_sData_t *trans_resp= NULL;
1125 void *pUpper_Context = NULL;
1126 pphLibNfc_TransceiveCallback_t pUpper_TagNtfCb =
1127 gpphLibContext->CBInfo.pClientTransceiveCb;
1128
1129 /*Check valid context is returned or not */
1130 if((phLibNfc_LibContext_t *)context == gpphLibContext)
1131 {
1132 trans_resp = &gpphLibContext->psTransInfo->sRecvData;
1133
1134 pUpper_Context = gpphLibContext->CBInfo.pClientTranseCntx;
1135 gpphLibContext->status.GenCb_pending_status = FALSE;
1136
1137 /*If DeInit is called during the transceive,
1138 call the shutdown and return NFCSTATUS_SHUTDOWN*/
1139 if(gpphLibContext->LibNfcState.next_state
1140 == eLibNfcHalStateShutdown)
1141 {
1142 phLibNfc_Pending_Shutdown();
1143 trans_status = NFCSTATUS_SHUTDOWN;
1144 }
1145 /* If Disconnect is called return NFCSTATUS_ABORTED */
1146 else if(eLibNfcHalStateRelease ==
1147 gpphLibContext->LibNfcState.next_state)
1148 {
1149 trans_status = NFCSTATUS_ABORTED;
1150 }
1151 /* If the received lower layer status is not SUCCESS return NFCSTATUS_FAILED */
1152 else if( NFCSTATUS_SUCCESS == status)
1153 {
1154 trans_status = NFCSTATUS_SUCCESS;
1155 }
1156 else if((PHNFCSTATUS(status) != NFCSTATUS_SUCCESS) &&
1157 (phHal_eMifare_PICC == pRmtdev_info->RemDevType) &&
1158 (0x00 != pRmtdev_info->RemoteDevInfo.Iso14443A_Info.Sak))
1159 {
1160 gpphLibContext->LastTrancvSuccess = FALSE;
1161 trans_status = NFCSTATUS_FAILED;
1162 /* card type is mifare 1k/4k, then reconnect */
1163 trans_status = phHal4Nfc_Connect(gpphLibContext->psHwReference,
1164 pRmtdev_info,
1165 (pphHal4Nfc_ConnectCallback_t)
1166 phLibNfc_Reconnect_Mifare_Cb,
1167 (void *)gpphLibContext);
1168 }
1169 else if ((PHNFCSTATUS(status) == PN544_IO_TIMEOUT_RESPONSE) ||
1170 (PHNFCSTATUS(status) == NFCSTATUS_RF_TIMEOUT))
1171 {
1172 // 0x89, 0x09 HCI response values from PN544 indicate timeout
1173 trans_status = NFCSTATUS_TARGET_LOST;
1174 }
1175 else
1176 {
1177 // PN544 did get some reply from tag, just not valid
1178 trans_status = NFCSTATUS_FAILED;
1179 }
1180 /*Update the state machine */
1181 phLibNfc_UpdateCurState(status,gpphLibContext);
1182 gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect;
1183 if(NFCSTATUS_PENDING != trans_status)
1184 {
1185 /* Tranceive over */
1186 PHDBG_INFO("LibNfc:TXRX Callback-Update the Transceive responce");
1187 if (NULL != pUpper_TagNtfCb)
1188 {
1189 if(trans_status == NFCSTATUS_SUCCESS)
1190 {
1191 gpphLibContext->LastTrancvSuccess = TRUE;
1192 pUpper_Context = gpphLibContext->CBInfo.pClientTranseCntx;
1193 trans_resp->buffer = response->buffer;
1194 trans_resp->length = response->length;
1195 /* Notify the upper layer */
1196 PHDBG_INFO("LibNfc:Transceive Complete");
1197 /* Notify the Transceive Completion to upper layer */
1198 gpphLibContext->CBInfo.pClientTransceiveCb(pUpper_Context,
1199 (uint32_t)pRmtdev_info,
1200 trans_resp,
1201 trans_status);
1202 }
1203 else
1204 {
1205 gpphLibContext->LastTrancvSuccess = FALSE;
1206 pUpper_Context = gpphLibContext->CBInfo.pClientTranseCntx;
1207 trans_resp->length = 0;
1208 /* Notify the upper layer */
1209 PHDBG_INFO("LibNfc:Transceive Complete");
1210 /* Notify the Transceive Completion to upper layer */
1211 gpphLibContext->CBInfo.pClientTransceiveCb(pUpper_Context,
1212 (uint32_t)pRmtdev_info,
1213 trans_resp,
1214 trans_status);
1215 }
1216 }
1217 }
1218
1219 }
1220 else
1221 { /*exception: wrong context pointer returned*/
1222 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
1223 }
1224
1225 return;
1226 }
1227 /**
1228 * Interface to configure P2P configurations.
1229 */
1230 NFCSTATUS
phLibNfc_Mgt_SetP2P_ConfigParams(phLibNfc_sNfcIPCfg_t * pConfigInfo,pphLibNfc_RspCb_t pConfigRspCb,void * pContext)1231 phLibNfc_Mgt_SetP2P_ConfigParams(phLibNfc_sNfcIPCfg_t* pConfigInfo,
1232 pphLibNfc_RspCb_t pConfigRspCb,
1233 void* pContext
1234 )
1235 {
1236 NFCSTATUS RetVal = NFCSTATUS_FAILED;
1237 /* LibNfc Initialized or not */
1238 if((NULL == gpphLibContext)||
1239 (gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
1240 {
1241 RetVal = NFCSTATUS_NOT_INITIALISED;
1242 }/* Check for valid parameters */
1243 else if((NULL == pConfigInfo) || (NULL == pConfigRspCb)
1244 || (NULL == pContext))
1245 {
1246 RetVal= NFCSTATUS_INVALID_PARAMETER;
1247 }
1248 else if(gpphLibContext->LibNfcState.next_state == eLibNfcHalStateShutdown)
1249 {
1250 RetVal = NFCSTATUS_SHUTDOWN;
1251 }
1252 else if(TRUE == gpphLibContext->status.GenCb_pending_status)
1253 { /*Previous callback is pending */
1254 RetVal = NFCSTATUS_BUSY;
1255 }
1256 else
1257 {
1258 if(eLibNfcHalStatePresenceChk !=
1259 gpphLibContext->LibNfcState.next_state)
1260 {
1261 phHal_uConfig_t uConfig;
1262 /* copy General bytes of Max length = 48 bytes */
1263 (void)memcpy((void *)&(uConfig.nfcIPConfig.generalBytes),
1264 (void *)pConfigInfo->generalBytes,
1265 pConfigInfo->generalBytesLength);
1266 /* also copy the General Bytes length*/
1267 uConfig.nfcIPConfig.generalBytesLength = pConfigInfo->generalBytesLength;
1268
1269 RetVal = phHal4Nfc_ConfigParameters(
1270 gpphLibContext->psHwReference,
1271 NFC_P2P_CONFIG,
1272 &uConfig,
1273 phLibNfc_Mgt_SetP2P_ConfigParams_Cb,
1274 (void *)gpphLibContext
1275 );
1276 }
1277 else
1278 {
1279 gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb= NULL;
1280 RetVal = NFCSTATUS_PENDING;
1281 }
1282 if(NFCSTATUS_PENDING == RetVal)
1283 {
1284 /* save the context and callback for later use */
1285 gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb = pConfigRspCb;
1286 gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx = pContext;
1287 gpphLibContext->status.GenCb_pending_status=TRUE;
1288 /* Next state is configured */
1289 gpphLibContext->LibNfcState.next_state =eLibNfcHalStateConfigReady;
1290 }
1291 else
1292 {
1293 RetVal = NFCSTATUS_FAILED;
1294 }
1295 }
1296 return RetVal;
1297 }
1298 /**
1299 * Response callback for P2P configurations.
1300 */
phLibNfc_Mgt_SetP2P_ConfigParams_Cb(void * context,NFCSTATUS status)1301 STATIC void phLibNfc_Mgt_SetP2P_ConfigParams_Cb(void *context,
1302 NFCSTATUS status)
1303 {
1304 pphLibNfc_RspCb_t pClientCb=NULL;
1305 void *pUpperLayerContext=NULL;
1306 /* Check for the context returned by below layer */
1307 if((phLibNfc_LibContext_t *)context != gpphLibContext)
1308 { /*wrong context returned*/
1309 phOsalNfc_RaiseException(phOsalNfc_e_InternalErr,1);
1310 }
1311 else
1312 {
1313 if(eLibNfcHalStateShutdown == gpphLibContext->LibNfcState.next_state)
1314 { /*shutdown called before completion of this api allow
1315 shutdown to happen */
1316 phLibNfc_Pending_Shutdown();
1317 status = NFCSTATUS_SHUTDOWN;
1318 }
1319 else
1320 {
1321 gpphLibContext->status.GenCb_pending_status = FALSE;
1322 if(NFCSTATUS_SUCCESS != status)
1323 {
1324 status = NFCSTATUS_FAILED;
1325 }
1326 else
1327 {
1328 status = NFCSTATUS_SUCCESS;
1329 }
1330 }
1331 /*update the current state */
1332 phLibNfc_UpdateCurState(status,gpphLibContext);
1333
1334 pClientCb = gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb;
1335 pUpperLayerContext = gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx;
1336
1337 gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCb = NULL;
1338 gpphLibContext->sNfcIp_Context.pClientNfcIpCfgCntx = NULL;
1339 if (NULL != pClientCb)
1340 {
1341 /* Notify to upper layer status of configure operation */
1342 pClientCb(pUpperLayerContext, status);
1343 }
1344 }
1345 return;
1346 }
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357