2 * Copyright (C) 2010 NXP Semiconductors
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * =========================================================================== *
21 * \file phHciNfc_WI.c *
22 * \brief HCI WI gate Management Routines. *
25 * Project: NFC-FRI-1.1 *
27 * $Date: Tue Aug 18 10:22:34 2009 $ *
28 * $Author: ing04880 $ *
30 * $Aliases: NFC_FRI1.1_WK934_R31_1,NFC_FRI1.1_WK941_PREP1,NFC_FRI1.1_WK941_PREP2,NFC_FRI1.1_WK941_1,NFC_FRI1.1_WK943_R32_1,NFC_FRI1.1_WK949_PREP1,NFC_FRI1.1_WK943_R32_10,NFC_FRI1.1_WK943_R32_13,NFC_FRI1.1_WK943_R32_14,NFC_FRI1.1_WK1007_R33_1,NFC_FRI1.1_WK1007_R33_4,NFC_FRI1.1_WK1017_PREP1,NFC_FRI1.1_WK1017_R34_1,NFC_FRI1.1_WK1017_R34_2,NFC_FRI1.1_WK1023_R35_1 $ * *
31 * =========================================================================== *
35 ***************************** Header File Inclusion ****************************
37 #include <phNfcCompId.h>
38 #include <phHciNfc_Pipe.h>
39 #include <phHciNfc_WI.h>
40 #include <phOsalNfc.h>
41 #include <phHciNfc_Emulation.h>
43 ****************************** Macro Definitions *******************************
45 /* WI gate specific Events definition */
46 #define NXP_EVT_SE_START_OF_TRANSACTION (0x01U)
47 #define NXP_EVT_SE_END_OF_TRANSACTION (0x02U)
48 #define NXP_EVT_SE_SWITCH_MODE (0x03U)
49 #define NXP_EVT_SE_TRANSACTION (0x04U)
51 /* WI Gate registry Settings */
52 /* set default mode mode as virtual mode */
53 #define NXP_SE_DEFAULTMODE_INDEX (0x01)
54 #define NXP_SE_EVENTS_INDEX (0x05)
56 /* Set Bit 0 and Bit 1 to report Start of transaction and End of transaction*/
57 #define WI_ENABLE_EVENTS (0x04)
58 #define WI_VIRTUALMODE (0x01)
59 #define WI_OFFMODE (0x00)
60 #define AID_SIZE (0x20)
61 /****************** Structure and Enumeration ****************************/
64 /****************** Static Function Declaration **************************/
66 static uint8_t paypass_removal[2] = {0x50, 0x00};
67 static uint8_t mifare_access = 0x60;
71 phHciNfc_Recv_WI_Response(
84 phHciNfc_Recv_WI_Event(
97 phHciNfc_Send_WI_Event(
98 phHciNfc_sContext_t *psHciContext,
106 phHciNfc_WI_InfoUpdate(
107 phHciNfc_sContext_t *psHciContext,
114 #if defined (WI_UPDATE_SEQ)
117 phHciNfc_WI_Update_Sequence(
118 phHciNfc_sContext_t *psHciContext,
119 phHciNfc_eSeqType_t WI_seq
121 #endif /* #if defined (WI_UPDATE_SEQ) */
124 *************************** Function Definitions ***************************
130 phHciNfc_WI_Init_Resources(
131 phHciNfc_sContext_t *psHciContext
134 NFCSTATUS status = NFCSTATUS_SUCCESS;
135 phHciNfc_WI_Info_t *p_WI_info=NULL;
137 if( NULL == psHciContext )
139 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
143 if(( NULL == psHciContext->p_wi_info ) &&
144 (phHciNfc_Allocate_Resource((void **)(&p_WI_info),
145 sizeof(phHciNfc_WI_Info_t))== NFCSTATUS_SUCCESS))
147 psHciContext->p_wi_info = p_WI_info;
148 p_WI_info->current_seq = eWI_PipeOpen;
149 p_WI_info->next_seq = eWI_PipeOpen;
150 p_WI_info->pipe_id = (uint8_t)HCI_UNKNOWN_PIPE_ID;
154 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INSUFFICIENT_RESOURCES);
162 phHciNfc_WI_Get_PipeID(
163 phHciNfc_sContext_t *psHciContext,
167 NFCSTATUS status = NFCSTATUS_SUCCESS;
169 if( (NULL != psHciContext)
170 && ( NULL != ppipe_id )
171 && ( NULL != psHciContext->p_wi_info )
174 phHciNfc_WI_Info_t *p_wi_info=NULL;
175 p_wi_info = (phHciNfc_WI_Info_t *)
176 psHciContext->p_wi_info ;
177 *ppipe_id = p_wi_info->pipe_id ;
181 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
188 phHciNfc_WI_Update_PipeInfo(
189 phHciNfc_sContext_t *psHciContext,
191 phHciNfc_Pipe_Info_t *pPipeInfo
194 NFCSTATUS status = NFCSTATUS_SUCCESS;
196 if( NULL == psHciContext )
198 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
200 else if(NULL == psHciContext->p_wi_info)
202 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
206 phHciNfc_WI_Info_t *p_WI_info=NULL;
207 p_WI_info = (phHciNfc_WI_Info_t *)
208 psHciContext->p_wi_info ;
209 /* Update the pipe_id of the WI Gate obtained from HCI Response */
210 p_WI_info->pipe_id = pipeID;
211 p_WI_info->p_pipe_info = pPipeInfo;
212 if ( NULL != pPipeInfo)
214 /* Update the Response Receive routine of the WI Gate */
215 pPipeInfo->recv_resp = &phHciNfc_Recv_WI_Response;
216 /* Update the event Receive routine of the WI Gate */
217 pPipeInfo->recv_event = &phHciNfc_Recv_WI_Event;
224 #if defined (WI_UPDATE_SEQ)
227 phHciNfc_WI_Update_Sequence(
228 phHciNfc_sContext_t *psHciContext,
229 phHciNfc_eSeqType_t WI_seq
232 NFCSTATUS status = NFCSTATUS_SUCCESS;
233 phHciNfc_WI_Info_t *p_WI_info=NULL;
234 if( NULL == psHciContext )
236 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
238 else if ( NULL == psHciContext->p_wi_info )
240 status = PHNFCSTVAL(CID_NFC_HCI,
241 NFCSTATUS_INVALID_HCI_INFORMATION);
245 p_WI_info = (phHciNfc_WI_Info_t *)
246 psHciContext->p_wi_info ;
252 p_WI_info->current_seq = eWI_PipeOpen;
253 p_WI_info->next_seq = eWI_SetDefaultMode ;
257 p_WI_info->current_seq = p_WI_info->next_seq;
262 p_WI_info->current_seq = eWI_PipeOpen;
263 p_WI_info->next_seq = eWI_PipeClose ;
269 }/* End of Update Sequence Switch */
274 #endif /* #if defined (WI_UPDATE_SEQ) */
277 phHciNfc_WI_Configure_Default(
283 NFCSTATUS status = NFCSTATUS_SUCCESS;
284 static uint8_t param = 0;
285 phHciNfc_sContext_t *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
287 if( (NULL == psHciContext)||(NULL == pHwRef))
289 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
291 else if ( NULL == psHciContext->p_wi_info )
293 status = PHNFCSTVAL(CID_NFC_HCI,
294 NFCSTATUS_INVALID_HCI_INFORMATION);
298 phHciNfc_WI_Info_t *p_wi_info=NULL;
299 phHciNfc_Pipe_Info_t *p_pipe_info=NULL;
301 p_wi_info = (phHciNfc_WI_Info_t*)psHciContext->p_wi_info;
303 p_pipe_info = p_wi_info->p_pipe_info;
304 if(NULL == p_pipe_info)
306 status = PHNFCSTVAL(CID_NFC_HCI,
307 NFCSTATUS_INVALID_HCI_INFORMATION);
311 p_pipe_info->reg_index = NXP_SE_DEFAULTMODE_INDEX;
312 /* Enable/Disable Default Virtual Mode for SmartMx */
313 param = (uint8_t)enable_type;
314 p_pipe_info->param_info =(void*)¶m ;
315 p_pipe_info->param_length = sizeof(param) ;
316 status = phHciNfc_Send_Generic_Cmd(psHciContext,pHwRef,
317 p_wi_info->pipe_id,(uint8_t)ANY_SET_PARAMETER);
319 }/* End of else part*/
325 phHciNfc_WI_Get_Default(
330 NFCSTATUS status = NFCSTATUS_SUCCESS;
331 phHciNfc_sContext_t *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
333 if( (NULL == psHciContext)||(NULL == pHwRef))
335 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
337 else if ( NULL == psHciContext->p_wi_info )
339 status = PHNFCSTVAL(CID_NFC_HCI,
340 NFCSTATUS_INVALID_HCI_INFORMATION);
344 phHciNfc_WI_Info_t *p_wiinfo=NULL;
345 phHciNfc_Pipe_Info_t *p_pipe_info=NULL;
347 p_wiinfo = (phHciNfc_WI_Info_t*)psHciContext->p_wi_info;
349 p_pipe_info = p_wiinfo->p_pipe_info;
350 if(NULL == p_pipe_info)
352 status = PHNFCSTVAL(CID_NFC_HCI,
353 NFCSTATUS_INVALID_HCI_INFORMATION);
357 p_pipe_info->reg_index = NXP_SE_DEFAULTMODE_INDEX;
359 status = phHciNfc_Send_Generic_Cmd(psHciContext,pHwRef,
361 (uint8_t)ANY_GET_PARAMETER);
363 }/* End of else part*/
370 phHciNfc_WI_Configure_Mode(
373 phHal_eSmartMX_Mode_t e_smx_mode
376 NFCSTATUS status = NFCSTATUS_SUCCESS;
377 static uint8_t param = 0;
378 phHciNfc_sContext_t *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
380 if( (NULL == psHciContext)||(NULL == pHwRef))
382 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
384 else if ( NULL == psHciContext->p_wi_info )
386 status = PHNFCSTVAL(CID_NFC_HCI,
387 NFCSTATUS_INVALID_HCI_INFORMATION);
391 phHciNfc_WI_Info_t *p_wi_info=NULL;
392 phHciNfc_Pipe_Info_t *p_pipe_info=NULL;
394 p_wi_info = (phHciNfc_WI_Info_t*)psHciContext->p_wi_info;
396 p_pipe_info = p_wi_info->p_pipe_info;
397 if(NULL == p_pipe_info)
399 status = PHNFCSTVAL(CID_NFC_HCI,
400 NFCSTATUS_INVALID_HCI_INFORMATION);
404 /* Switch the Mode of the SmartMx */
405 param = (uint8_t)e_smx_mode;
406 p_pipe_info->param_info =(void*)¶m ;
407 p_pipe_info->param_length = sizeof(param) ;
408 status = phHciNfc_Send_WI_Event( psHciContext, pHwRef,
409 p_wi_info->pipe_id, NXP_EVT_SE_SWITCH_MODE );
410 /* Send the Success Status as this is an event */
411 status = ( (status == NFCSTATUS_PENDING)?
412 NFCSTATUS_SUCCESS : status);
414 }/* End of else part*/
421 phHciNfc_WI_Configure_Notifications(
424 phHciNfc_WI_Events_t eNotification
427 NFCSTATUS status = NFCSTATUS_SUCCESS;
428 static uint8_t param = 0;
429 phHciNfc_sContext_t *psHciContext = ((phHciNfc_sContext_t *)psHciHandle);
431 if( (NULL == psHciContext)||(NULL == pHwRef))
433 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
435 else if ( NULL == psHciContext->p_wi_info )
437 status = PHNFCSTVAL(CID_NFC_HCI,
438 NFCSTATUS_INVALID_HCI_INFORMATION);
442 phHciNfc_WI_Info_t *p_wi_info=NULL;
443 phHciNfc_Pipe_Info_t *p_pipe_info=NULL;
446 p_wi_info = (phHciNfc_WI_Info_t*)psHciContext->p_wi_info;
447 p_pipe_info = p_wi_info->p_pipe_info;
448 if(NULL == p_pipe_info)
450 status = PHNFCSTVAL(CID_NFC_HCI,
451 NFCSTATUS_INVALID_HCI_INFORMATION);
455 if(eEnableEvents == eNotification)
457 /* Enable start and end of transaction events*/
458 param = WI_ENABLE_EVENTS;
465 p_pipe_info->reg_index = NXP_SE_EVENTS_INDEX;
466 p_pipe_info->param_info =(void*)¶m ;
467 p_pipe_info->param_length = sizeof(param) ;
469 status = phHciNfc_Send_Generic_Cmd(psHciContext,pHwRef,
470 p_wi_info->pipe_id,(uint8_t)ANY_SET_PARAMETER);
478 * \brief Sends WI gate specfic HCI Events to the connected reader device.
479 * This function Sends the WI mode specific HCI Event frames in the HCP packet format to the
480 * connected reader device.
485 phHciNfc_Send_WI_Event(
486 phHciNfc_sContext_t *psHciContext,
492 phHciNfc_HCP_Packet_t *hcp_packet = NULL;
493 phHciNfc_HCP_Message_t *hcp_message = NULL;
494 phHciNfc_Pipe_Info_t *p_pipe_info = NULL;
497 NFCSTATUS status = NFCSTATUS_SUCCESS;
499 if( (NULL == psHciContext)
500 || ( pipe_id > PHHCINFC_MAX_PIPE)
501 ||(NULL == psHciContext->p_pipe_list[pipe_id])
504 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
505 HCI_DEBUG("%s: Invalid Arguments passed \n",
506 "phHciNfc_Send_WI_Event");
510 p_pipe_info = (phHciNfc_Pipe_Info_t *)
511 psHciContext->p_pipe_list[pipe_id];
512 psHciContext->tx_total = 0 ;
513 length =length+HCP_HEADER_LEN ;
515 if( NXP_EVT_SE_SWITCH_MODE == event)
517 hcp_packet = (phHciNfc_HCP_Packet_t *) psHciContext->send_buffer;
518 /* Construct the HCP Frame */
519 phHciNfc_Build_HCPFrame(hcp_packet,HCP_CHAINBIT_DEFAULT,
520 (uint8_t) pipe_id, HCP_MSG_TYPE_EVENT, event);
521 hcp_message = &(hcp_packet->msg.message);
522 phHciNfc_Append_HCPFrame((uint8_t *)hcp_message->payload,
523 i, (uint8_t *)p_pipe_info->param_info,
524 p_pipe_info->param_length);
525 length =(uint8_t)(length + i + p_pipe_info->param_length);
529 status = PHNFCSTVAL( CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INSTRUCTION );
530 HCI_DEBUG("%s: Invalid Send Event Request \n","phHciNfc_Send_WI_Event");
533 if( NFCSTATUS_SUCCESS == status )
535 p_pipe_info->sent_msg_type = HCP_MSG_TYPE_EVENT ;
536 p_pipe_info->prev_msg = event ;
537 psHciContext->tx_total = length;
539 /* Send the Constructed HCP packet to the lower layer */
540 status = phHciNfc_Send_HCP( psHciContext, pHwRef );
541 p_pipe_info->prev_status = NFCSTATUS_PENDING;
549 phHciNfc_Recv_WI_Response(
560 NFCSTATUS status = NFCSTATUS_SUCCESS;
561 phHciNfc_sContext_t *psHciContext =
562 (phHciNfc_sContext_t *)psContext;
565 if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pResponse)
568 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
570 else if(NULL == psHciContext->p_wi_info)
572 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_FEATURE_NOT_SUPPORTED);
576 phHciNfc_WI_Info_t *p_wiinfo=NULL;
577 uint8_t prev_cmd = ANY_GET_PARAMETER;
578 p_wiinfo = (phHciNfc_WI_Info_t *)psHciContext->p_wi_info ;
580 if( NULL == p_wiinfo->p_pipe_info)
582 status = PHNFCSTVAL(CID_NFC_HCI,
583 NFCSTATUS_INVALID_HCI_INFORMATION);
587 prev_cmd = p_wiinfo->p_pipe_info->prev_msg ;
590 case ANY_GET_PARAMETER:
592 if (length > HCP_HEADER_LEN)
594 status = phHciNfc_WI_InfoUpdate (psHciContext,
595 p_wiinfo->p_pipe_info->reg_index,
596 &pResponse[HCP_HEADER_LEN],
597 (uint8_t)(length - HCP_HEADER_LEN));
601 status = PHNFCSTVAL(CID_NFC_HCI,
602 NFCSTATUS_INVALID_HCI_RESPONSE);
606 case ANY_SET_PARAMETER:
608 HCI_PRINT("WI Parameter Set \n");
609 status = phHciNfc_EmuMgmt_Update_Seq(psHciContext,
615 HCI_PRINT("WI gate open pipe complete\n");
616 status = phHciNfc_EmuMgmt_Update_Seq(psHciContext,
622 HCI_PRINT("WI close pipe complete\n");
623 status = phHciNfc_EmuMgmt_Update_Seq(psHciContext,
629 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_RESPONSE);
633 if( NFCSTATUS_SUCCESS == status )
635 p_wiinfo->p_pipe_info->prev_status = NFCSTATUS_SUCCESS;
636 p_wiinfo->current_seq = p_wiinfo->next_seq;
645 phHciNfc_Recv_WI_Event(
656 NFCSTATUS status = NFCSTATUS_SUCCESS;
657 phHal_sEventInfo_t EventInfo;
658 /* phNfc_sNotificationInfo_t NotificationInfo; */
659 phHciNfc_sContext_t *psHciContext =(phHciNfc_sContext_t *)psContext;
662 if( (NULL == psHciContext) || (NULL == pHwRef) || (NULL == pEvent)
665 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_PARAMETER);
667 else if(NULL == psHciContext->p_wi_info)
669 status = PHNFCSTVAL(CID_NFC_HCI, NFCSTATUS_INVALID_HCI_INFORMATION);
673 phHciNfc_HCP_Packet_t *p_packet = NULL;
674 phHciNfc_HCP_Message_t *message = NULL;
675 phHciNfc_WI_Info_t *p_wi_info = NULL;
676 uint8_t EventType = 0;
678 p_wi_info = (phHciNfc_WI_Info_t *)psHciContext->p_wi_info ;
680 p_packet = (phHciNfc_HCP_Packet_t *)pEvent;
681 message = &(p_packet->msg.message);
682 /* Get the instruction bits from the Message Header */
683 EventType = (uint8_t) GET_BITS8( message->msg_header,
684 HCP_MSG_INSTRUCTION_OFFSET, HCP_MSG_INSTRUCTION_LEN);
686 EventInfo.eventHost = phHal_eHostController;
687 EventInfo.eventSource = phHal_ePICC_DevType;
688 /* Now check for possible Transaction events for reporting */
691 case NXP_EVT_SE_START_OF_TRANSACTION:
693 EventInfo.eventType = NFC_EVT_START_OF_TRANSACTION;
696 case NXP_EVT_SE_END_OF_TRANSACTION:
698 EventInfo.eventType = NFC_EVT_END_OF_TRANSACTION;
701 case NXP_EVT_SE_TRANSACTION:
703 EventInfo.eventType = NFC_EVT_TRANSACTION;
704 EventInfo.eventInfo.aid.buffer = (uint8_t *)p_wi_info->aid;
705 /* check for AID data is at least 1 byte is their */
706 if (length > HCP_HEADER_LEN)
708 EventInfo.eventInfo.aid.length = length - HCP_HEADER_LEN;
709 memcpy((void *)p_wi_info->aid, message->payload,
710 EventInfo.eventInfo.aid.length );
713 /* Filter Transaction event */
714 if (EventInfo.eventInfo.aid.length == 4)
716 EventInfo.eventType = NFC_EVT_APDU_RECEIVED;
718 else if (EventInfo.eventInfo.aid.length == 2)
720 if (!memcmp(paypass_removal, EventInfo.eventInfo.aid.buffer, EventInfo.eventInfo.aid.length))
722 EventInfo.eventType = NFC_EVT_EMV_CARD_REMOVAL;
724 else if(mifare_access == EventInfo.eventInfo.aid.buffer[0])
726 EventInfo.eventType = NFC_EVT_MIFARE_ACCESS;
730 EventInfo.eventInfo.aid.buffer = (uint8_t *)p_wi_info->aid;
731 (void) memcpy((void *)p_wi_info->aid,message->payload,
732 EventInfo.eventInfo.aid.length );
737 status = PHNFCSTVAL(CID_NFC_HCI,
738 NFCSTATUS_INVALID_HCI_INSTRUCTION);
742 if (NFCSTATUS_SUCCESS == status )
744 phHciNfc_Notify_Event( psHciContext, pHwRef,
745 NFC_NOTIFY_EVENT, (void*)&EventInfo);
753 phHciNfc_WI_InfoUpdate(
754 phHciNfc_sContext_t *psHciContext,
760 NFCSTATUS status = NFCSTATUS_SUCCESS;
761 phHciNfc_WI_Info_t *p_wiinfo = NULL;
763 p_wiinfo = psHciContext->p_wi_info;
765 if ((NXP_SE_DEFAULTMODE_INDEX == index) &&
766 (sizeof(*reg_value) == reg_length))
768 p_wiinfo->default_type = *reg_value;
772 status = PHNFCSTVAL(CID_NFC_HCI,
773 NFCSTATUS_INVALID_HCI_RESPONSE);