diff options
author | Daniel Tomas <dtomas.nxp@gmail.com> | 2011-05-26 15:52:17 +0200 |
---|---|---|
committer | Nick Pelly <npelly@google.com> | 2011-06-28 14:30:24 -0700 |
commit | b313c3d09c64c31439332e88e0aca676ae1858b5 (patch) | |
tree | 0529b38fd67f61dfae286e968a9e81fa57f4da1d /src/phLlcNfc_Timer.c | |
parent | 8d4d6a13c4c3bf4e966d12297cc9a9f6cf9d42a8 (diff) | |
download | external_libnfc-nxp-b313c3d09c64c31439332e88e0aca676ae1858b5.zip external_libnfc-nxp-b313c3d09c64c31439332e88e0aca676ae1858b5.tar.gz external_libnfc-nxp-b313c3d09c64c31439332e88e0aca676ae1858b5.tar.bz2 |
Patch to add the windowing support in the libnfc
This patch enables windowing of LLC packets send from chipset to host.
The host will now wait for up to 4 LLC packets from the chipset before
sending an ACK (S-Frame RR).
Change-Id: I6a70e1d780847a104e3ec8e403593a69e222aec9
Diffstat (limited to 'src/phLlcNfc_Timer.c')
-rw-r--r-- | src/phLlcNfc_Timer.c | 165 |
1 files changed, 131 insertions, 34 deletions
diff --git a/src/phLlcNfc_Timer.c b/src/phLlcNfc_Timer.c index c079760..06ca7e4 100644 --- a/src/phLlcNfc_Timer.c +++ b/src/phLlcNfc_Timer.c @@ -44,8 +44,6 @@ /***************************** Macros *******************************/ /**< Timer for connection timer index */ #define PH_LLCNFC_CONNECTION_TO_INDEX (0x00) -/**< 0x0A Timer for ack time out value */ -#define PH_LLCNFC_ACK_TO_VALUE (1000) /**< Maximum guard timer can be present */ #define PH_LLCNFC_MAX_GUARD_TIMER (0x04) /** Connection time out bit to set */ @@ -60,6 +58,8 @@ #define PH_LLCNFC_CON_TO_BIT_VAL (0x01) /** Guard time out bit to set */ #define PH_LLCNFC_GUARD_TO_BIT_VAL (0x02) +/** ACK time out bit to set */ +#define PH_LLCNFC_ACK_TO_BIT_VAL (0x04) #define GUARD_TO_URSET @@ -84,7 +84,7 @@ void phLlcNfc_AckTimeoutCb ( uint32_t TimerId ); -#endif +#endif /* #ifdef PIGGY_BACK */ /* This callback is for connection time out */ static @@ -290,17 +290,22 @@ phLlcNfc_StartTimers ( /* Get the ack timer flag */ timerstarted = (uint8_t)GET_BITS8 ( ps_timer_info->timer_flag, - PH_LLCNFC_GUARD_TO_BIT, + PH_LLCNFC_ACK_TO_BIT, PH_LLCNFC_TO_NOOFBITS); - if (0 == timerstarted) + + if (FALSE == timerstarted) { /* Timer not started, so start the timer */ ps_timer_info->timer_flag = (uint8_t) SET_BITS8 (ps_timer_info->timer_flag, - PH_LLCNFC_GUARD_TO_BIT - PH_LLCNFC_TO_NOOFBITS - (PH_LLCNFC_GUARD_TO_BIT - 1)); + PH_LLCNFC_ACK_TO_BIT, + PH_LLCNFC_TO_NOOFBITS, + (PH_LLCNFC_ACK_TO_BIT - 1)); } + + + timer_resolution = ps_timer_info->ack_to_value = (uint16_t) + PH_LLCNFC_ACK_TO_VALUE; timerid = ps_timer_info->timer_id[PH_LLCNFC_ACKTIMER]; Callback = (ppCallBck_t)&phLlcNfc_AckTimeoutCb; break; @@ -380,7 +385,7 @@ phLlcNfc_StopTimers ( { /* The number of guard timer count is more than the guard timer to delete */ - while (start_index < no_of_guard_to_del) + while (start_index < (timer_count - no_of_guard_to_del)) { /* Copy the previous stored timer values to the present */ ps_timer_info->guard_to_value[start_index] = (uint16_t) @@ -457,11 +462,14 @@ phLlcNfc_StopTimers ( #ifdef PIGGY_BACK case PH_LLCNFC_ACKTIMER: { + timerflag = (timerflag & PH_LLCNFC_ACK_TO_BIT_VAL); + ps_timer_info->timer_flag = (uint8_t) SET_BITS8 (ps_timer_info->timer_flag, - PH_LLCNFC_GUARD_TO_BIT, + PH_LLCNFC_ACK_TO_BIT, PH_LLCNFC_TO_NOOFBITS, 0); timerid = ps_timer_info->timer_id[PH_LLCNFC_ACKTIMER]; + ps_timer_info->ack_to_value = 0; break; } #endif /* #ifdef PIGGY_BACK */ @@ -486,7 +494,7 @@ phLlcNfc_StopTimers ( PHNFC_UNUSED_VARIABLE (result); PHNFC_UNUSED_VARIABLE (TimerType); - PHNFC_UNUSED_VARIABLE (no_of_gaurd_to_del); + PHNFC_UNUSED_VARIABLE (no_of_guard_to_del); #endif /* #ifdef LLC_TIMER_ENABLE */ } @@ -602,23 +610,25 @@ phLlcNfc_GuardTimeoutCb ( NFCSTATUS result = NFCSTATUS_SUCCESS; phLlcNfc_Timerinfo_t *ps_timer_info = NULL; phLlcNfc_Frame_t *ps_frame_info = NULL; - phLlcNfc_LlcPacket_t *ps_packet_info = NULL; + phLlcNfc_LlcPacket_t s_packet_info; uint8_t index = 0; + /* zero_to_index = Time out index has become 0 */ uint8_t zero_to_index = 0; + #if defined (GUARD_TO_ERROR) phNfc_sCompletionInfo_t notifyinfo = {0,0,0}; #endif /* #if defined (GUARD_TO_ERROR) */ - PHNFC_UNUSED_VARIABLE(pContext); PH_LLCNFC_PRINT("\n\nLLC : GUARD TIMEOUT CB CALLED \n\n"); - if ((NULL != gpphLlcNfc_Ctxt) && (TimerId == - gpphLlcNfc_Ctxt->s_timerinfo.timer_id[PH_LLCNFC_GUARDTIMER]) && - (PH_LLCNFC_GUARD_TO_BIT_VAL == - (gpphLlcNfc_Ctxt->s_timerinfo.timer_flag & + if ((NULL != gpphLlcNfc_Ctxt) && (TimerId == + gpphLlcNfc_Ctxt->s_timerinfo.timer_id[PH_LLCNFC_GUARDTIMER]) && + (PH_LLCNFC_GUARD_TO_BIT_VAL == + (gpphLlcNfc_Ctxt->s_timerinfo.timer_flag & PH_LLCNFC_GUARD_TO_BIT_VAL))) { uint8_t timer_expired = FALSE; + ps_frame_info = &(gpphLlcNfc_Ctxt->s_frameinfo); ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo); @@ -632,8 +642,15 @@ phLlcNfc_GuardTimeoutCb ( send called */ while (index < ps_timer_info->guard_to_count) { + /* This loop runs for all the timer present in the data structure. + This means if there are 2 I frame has been sent and + response is not received for the I frames sent then the + each time this timer expires, the time out value is decremented + by the PH_LLCNFC_RESOLUTION value */ if (0 != ps_timer_info->guard_to_value[index]) { + /* If timer value is not zero then enter, + this means that the value is not zero */ if (ps_timer_info->guard_to_value[index] > 0) { if (ps_timer_info->guard_to_value[index] >= @@ -651,10 +668,20 @@ phLlcNfc_GuardTimeoutCb ( if (0 == ps_timer_info->guard_to_value[index]) { + /* Timer value has expired, so resend has to be done + Timer value is 0 */ + ps_timer_info->frame_type[index] = (uint8_t)resend_i_frame; + if (FALSE == timer_expired) + { + /* As the statement is in the loop, so there are possibilities + of more than 1 timer value can be 0, so if previous timer + value has already been 0, then again dont change the + index */ zero_to_index = index; timer_expired = TRUE; } } + } index = (uint8_t)(index + 1); } @@ -686,7 +713,6 @@ phLlcNfc_GuardTimeoutCb ( timer_count = ps_timer_info->guard_to_count; - /* Check before changing the index to resend, if index already exist then dont set the index */ while ((FALSE == while_exit) && (start_index < timer_count)) @@ -702,13 +728,29 @@ phLlcNfc_GuardTimeoutCb ( } } - if (TRUE == while_exit) + if (FALSE == while_exit) { + /* This " ps_timer_info->index_to_send " member is + useful, when 2 time out values are 0, then + only first timed out value has to be resent and + other has to wait until the the first timed out + I frame is resent + This statement is executed only if, none of the timer + has expires previously, this is the first timer in the + list that has time out value has 0 + */ ps_timer_info->index_to_send = zero_to_index; } + else + { + /* This statement is executed only if, any one of the time + out value was 0 previously, so first resend has to be done + for the previous I frame, so the index is set to the previous + I frame + */ + ps_timer_info->index_to_send = start_index; + } - ps_timer_info->frame_type[zero_to_index] = (uint8_t) - resend_i_frame; /* Now resend the frame stored */ result = phLlcNfc_H_SendTimedOutIFrame (gpphLlcNfc_Ctxt, &(ps_frame_info->s_send_store), @@ -741,16 +783,15 @@ phLlcNfc_GuardTimeoutCb ( #if (!defined (GUARD_TO_ERROR) && defined (GUARD_TO_URSET)) PH_LLCNFC_PRINT("U-RSET IS SENT \n"); - ps_packet_info = &(gpphLlcNfc_Ctxt->s_frameinfo.s_llcpacket); - result = phLlcNfc_H_CreateUFramePayload(gpphLlcNfc_Ctxt, - ps_packet_info, - &(ps_packet_info->llcbuf_len), + result = phLlcNfc_H_CreateUFramePayload(gpphLlcNfc_Ctxt, + &(s_packet_info), + &(s_packet_info.llcbuf_len), phLlcNfc_e_rset); - result = phLlcNfc_Interface_Write(gpphLlcNfc_Ctxt, - (uint8_t*)&(ps_packet_info->s_llcbuf), - (uint32_t)ps_packet_info->llcbuf_len); + result = phLlcNfc_Interface_Write(gpphLlcNfc_Ctxt, + (uint8_t*)&(s_packet_info.s_llcbuf), + (uint32_t)s_packet_info.llcbuf_len); ps_frame_info->write_status = result; if (NFCSTATUS_PENDING == result) @@ -782,15 +823,71 @@ phLlcNfc_GuardTimeoutCb ( } #ifdef PIGGY_BACK + static void phLlcNfc_AckTimeoutCb ( uint32_t TimerId ) { + NFCSTATUS result = NFCSTATUS_SUCCESS; + phLlcNfc_Frame_t *ps_frame_info = NULL; + phLlcNfc_Timerinfo_t *ps_timer_info = NULL; + phLlcNfc_LlcPacket_t s_packet_info; + + PH_LLCNFC_PRINT("\n\nLLC : ACK TIMEOUT CB CALLED\n\n"); + if ((NULL != gpphLlcNfc_Ctxt) && (TimerId == + gpphLlcNfc_Ctxt->s_timerinfo.timer_id[PH_LLCNFC_ACKTIMER]) + && (PH_LLCNFC_ACK_TO_BIT_VAL == + (gpphLlcNfc_Ctxt->s_timerinfo.timer_flag & + PH_LLCNFC_ACK_TO_BIT_VAL))) + { + ps_frame_info = &(gpphLlcNfc_Ctxt->s_frameinfo); + ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo); + + phLlcNfc_StopTimers (PH_LLCNFC_ACKTIMER, 0); + + if (NFCSTATUS_BUSY == PHNFCSTATUS (ps_frame_info->write_status)) + { + /* Any how write cannot be done and some frame is ready to be sent + so this frame will act as the ACK */ + result = phLlcNfc_H_WriteWaitCall (gpphLlcNfc_Ctxt); + } + else + { + /* Create S frame */ + (void)phLlcNfc_H_CreateSFramePayload (ps_frame_info, &(s_packet_info), phLlcNfc_e_rr); + + result = phLlcNfc_Interface_Write(gpphLlcNfc_Ctxt, + (uint8_t *)&(s_packet_info.s_llcbuf), + (uint32_t)(s_packet_info.llcbuf_len)); + + if (NFCSTATUS_PENDING == result) + { + if (0 == ps_frame_info->send_error_count) + { + ps_frame_info->write_wait_call = invalid_frame; + } + ps_frame_info->sent_frame_type = s_frame; + } + else + { + if (invalid_frame == ps_frame_info->write_wait_call) + { + ps_frame_info->write_wait_call = s_frame; + } + } + } + } + + /* ACK is sent, so reset the response received count */ + gpphLlcNfc_Ctxt->s_frameinfo.resp_recvd_count = 0; + + PH_LLCNFC_PRINT("\n\nLLC : ACK TIMEOUT CB END\n\n"); } -#endif + +#endif /* #ifdef PIGGY_BACK */ static void @@ -805,7 +902,7 @@ phLlcNfc_ConnectionTimeoutCb ( void *p_upperctxt = NULL; phLlcNfc_Frame_t *ps_frame_info = NULL; phLlcNfc_Timerinfo_t *ps_timer_info = NULL; - PHNFC_UNUSED_VARIABLE(pContext); + phLlcNfc_LlcPacket_t s_packet_info; PH_LLCNFC_PRINT("\n\nLLC : CONNECTION TIMEOUT CB CALLED\n\n"); if ((NULL != gpphLlcNfc_Ctxt) && (TimerId == @@ -834,16 +931,16 @@ phLlcNfc_ConnectionTimeoutCb ( { /* Create a U frame */ result = phLlcNfc_H_CreateUFramePayload(gpphLlcNfc_Ctxt, - &(ps_frame_info->s_llcpacket), - &(ps_frame_info->s_llcpacket.llcbuf_len), + &(s_packet_info), + &(s_packet_info.llcbuf_len), phLlcNfc_e_rset); if (NFCSTATUS_SUCCESS == result) { /* Call DAL write */ result = phLlcNfc_Interface_Write (gpphLlcNfc_Ctxt, - (uint8_t*)&(ps_frame_info->s_llcpacket.s_llcbuf), - (uint32_t)(ps_frame_info->s_llcpacket.llcbuf_len)); + (uint8_t*)&(s_packet_info.s_llcbuf), + (uint32_t)(s_packet_info.llcbuf_len)); } if (NFCSTATUS_PENDING == result) { |