Home | History | Annotate | Download | only in src
      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  phLlcNfc_Timer.c
     19 * \brief To create, start, stop and destroy timer.
     20 *
     21 * Project: NFC-FRI-1.1
     22 *
     23 * $Date: Mon Jun 14 11:47:54 2010 $
     24 * $Author: ing02260 $
     25 * $Revision: 1.55 $
     26 * $Aliases: NFC_FRI1.1_WK1023_R35_2,NFC_FRI1.1_WK1023_R35_1 $
     27 *
     28 */
     29 
     30 /*************************** Includes *******************************/
     31 #include <phNfcTypes.h>
     32 #include <phNfcStatus.h>
     33 #include <phOsalNfc.h>
     34 #include <phOsalNfc_Timer.h>
     35 #include <phNfcInterface.h>
     36 #include <phLlcNfc.h>
     37 #include <phLlcNfc_DataTypes.h>
     38 #include <phLlcNfc_Interface.h>
     39 #include <phLlcNfc_Frame.h>
     40 #include <phLlcNfc_Timer.h>
     41 
     42 /*********************** End of includes ****************************/
     43 
     44 /***************************** Macros *******************************/
     45 /**< Timer for connection timer index */
     46 #define PH_LLCNFC_CONNECTION_TO_INDEX       (0x00)
     47 /**< Maximum guard timer can be present */
     48 #define PH_LLCNFC_MAX_GUARD_TIMER           (0x04)
     49 /** Connection time out bit to set */
     50 #define PH_LLCNFC_CON_TO_BIT                (0)
     51 /** Guard time out bit to set */
     52 #define PH_LLCNFC_GUARD_TO_BIT              (1)
     53 /** Ack time out bit to set */
     54 #define PH_LLCNFC_ACK_TO_BIT                (2)
     55 /** No of bits to set */
     56 #define PH_LLCNFC_TO_NOOFBITS               (1)
     57 /** Connection time out bit value */
     58 #define PH_LLCNFC_CON_TO_BIT_VAL            (0x01)
     59 /** Guard time out bit to set */
     60 #define PH_LLCNFC_GUARD_TO_BIT_VAL          (0x02)
     61 /** ACK time out bit to set */
     62 #define PH_LLCNFC_ACK_TO_BIT_VAL            (0x04)
     63 
     64 #define GUARD_TO_URSET
     65 
     66 
     67 /************************ End of macros *****************************/
     68 
     69 /*********************** Local functions ****************************/
     70 /* This callback is for guard time out */
     71 #ifdef LLC_TIMER_ENABLE
     72 static
     73 void
     74 phLlcNfc_GuardTimeoutCb (
     75     uint32_t TimerId,
     76     void *pContext
     77 );
     78 
     79 
     80 #ifdef PIGGY_BACK
     81 /* This callback is for acknowledge time out */
     82 static
     83 void
     84 phLlcNfc_AckTimeoutCb (
     85     uint32_t TimerId
     86 );
     87 #endif /* #ifdef PIGGY_BACK */
     88 
     89 /* This callback is for connection time out */
     90 static
     91 void
     92 phLlcNfc_ConnectionTimeoutCb (
     93     uint32_t TimerId,
     94     void *pContext
     95 );
     96 #endif /* #ifdef LLC_TIMER_ENABLE */
     97 
     98 /******************** End of Local functions ************************/
     99 
    100 /********************** Global variables ****************************/
    101 static phLlcNfc_Context_t   *gpphLlcNfc_Ctxt = NULL;
    102 
    103 /******************** End of Global Variables ***********************/
    104 
    105 NFCSTATUS
    106 phLlcNfc_TimerInit(
    107     phLlcNfc_Context_t  *psLlcCtxt
    108 )
    109 {
    110     NFCSTATUS   result = PHNFCSTVAL(CID_NFC_LLC,
    111                                     NFCSTATUS_INVALID_PARAMETER);
    112     uint8_t     index = 0;
    113     if (NULL != psLlcCtxt)
    114     {
    115         result = NFCSTATUS_SUCCESS;
    116         gpphLlcNfc_Ctxt = psLlcCtxt;
    117         while (index < PH_LLCNFC_MAX_TIMER_USED)
    118         {
    119 #ifdef LLC_TIMER_ENABLE
    120             gpphLlcNfc_Ctxt->s_timerinfo.timer_id[index] =
    121                                     PH_OSALNFC_INVALID_TIMER_ID;
    122 #endif /* #ifdef LLC_TIMER_ENABLE */
    123             index++;
    124         }
    125     }
    126     return result;
    127 }
    128 
    129 void
    130 phLlcNfc_TimerUnInit(
    131     phLlcNfc_Context_t  *psLlcCtxt
    132 )
    133 {
    134     uint8_t     index = 0;
    135     if ((NULL != gpphLlcNfc_Ctxt) &&
    136         (gpphLlcNfc_Ctxt == psLlcCtxt))
    137     {
    138         while (index <= PH_LLCNFC_ACKTIMER)
    139         {
    140             if (PH_LLCNFC_GUARDTIMER == index)
    141             {
    142                 phLlcNfc_StopTimers (index,
    143                         gpphLlcNfc_Ctxt->s_timerinfo.guard_to_count);
    144             }
    145             else
    146             {
    147                 phLlcNfc_StopTimers (index, 0);
    148             }
    149             index++;
    150         }
    151         phLlcNfc_DeleteTimer();
    152     }
    153 }
    154 
    155 void
    156 phLlcNfc_CreateTimers(void)
    157 {
    158     uint8_t     index = 0;
    159 
    160     while (index < PH_LLCNFC_MAX_TIMER_USED)
    161     {
    162 #ifdef LLC_TIMER_ENABLE
    163         gpphLlcNfc_Ctxt->s_timerinfo.timer_id[index] =
    164                             phOsalNfc_Timer_Create();
    165 #endif /* #ifdef LLC_TIMER_ENABLE */
    166         index++;
    167     }
    168     return;
    169 }
    170 
    171 NFCSTATUS
    172 phLlcNfc_StartTimers (
    173     uint8_t             TimerType,
    174     uint8_t             ns_value
    175 )
    176 {
    177     NFCSTATUS               result = NFCSTATUS_SUCCESS;
    178 #ifdef LLC_TIMER_ENABLE
    179 
    180     uint32_t                timerid = 0;
    181     uint8_t                 timerstarted = 0;
    182     uint8_t                 timer_count = 0;
    183     uint16_t                timer_resolution = 0;
    184     ppCallBck_t             Callback = NULL;
    185     phLlcNfc_Timerinfo_t    *ps_timer_info = NULL;
    186 
    187     ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo);
    188     PHNFC_UNUSED_VARIABLE(result);
    189 
    190     PH_LLCNFC_PRINT("\n\nLLC : START TIMER CALLED\n\n");
    191     /* Depending on the timer type, use the Osal callback */
    192     switch(TimerType)
    193     {
    194         case PH_LLCNFC_CONNECTIONTIMER:
    195         {
    196             /* Get the connection timer flag */
    197             timerstarted = (uint8_t)
    198                 GET_BITS8(ps_timer_info->timer_flag,
    199                         PH_LLCNFC_CON_TO_BIT,
    200                         PH_LLCNFC_TO_NOOFBITS);
    201             if (0 == timerstarted)
    202             {
    203                 /* Timer not started, so start the timer */
    204                 gpphLlcNfc_Ctxt->s_timerinfo.timer_flag = (uint8_t)
    205                                 SET_BITS8 (ps_timer_info->timer_flag,
    206                                         PH_LLCNFC_CON_TO_BIT,
    207                                         PH_LLCNFC_TO_NOOFBITS,
    208                                         (PH_LLCNFC_CON_TO_BIT + 1));
    209             }
    210 
    211             timerid = ps_timer_info->timer_id[PH_LLCNFC_CONNECTION_TO_INDEX];
    212             Callback = (ppCallBck_t)&phLlcNfc_ConnectionTimeoutCb;
    213             timer_resolution = ps_timer_info->con_to_value = (uint16_t)
    214                                             PH_LLCNFC_CONNECTION_TO_VALUE;
    215             break;
    216         }
    217 
    218         case PH_LLCNFC_GUARDTIMER:
    219         {
    220             if (ps_timer_info->guard_to_count < PH_LLCNFC_MAX_GUARD_TIMER)
    221             {
    222                 timer_count = ps_timer_info->guard_to_count;
    223                 timer_resolution = (uint16_t)PH_LLCNFC_RESOLUTION;
    224 
    225                 PH_LLCNFC_DEBUG("RESOLUTION VALUE : 0x%02X\n", PH_LLCNFC_RESOLUTION);
    226                 PH_LLCNFC_DEBUG("TIME-OUT VALUE : 0x%02X\n", PH_LLCNFC_GUARD_TO_VALUE);
    227 
    228                 /* Get the guard timer flag */
    229                 timerstarted = (uint8_t)
    230                     GET_BITS8 (ps_timer_info->timer_flag,
    231                             PH_LLCNFC_GUARD_TO_BIT,
    232                             PH_LLCNFC_TO_NOOFBITS);
    233 
    234                 PH_LLCNFC_DEBUG("GUARD TIMER NS INDEX : 0x%02X\n", ns_value);
    235                 PH_LLCNFC_DEBUG("GUARD TIMER COUNT : 0x%02X\n", timer_count);
    236                 PH_LLCNFC_DEBUG("GUARD TIMER STARTED : 0x%02X\n", timerstarted);
    237 
    238                 if (0 == timerstarted)
    239                 {
    240                     /* Timer not started, so start the timer */
    241                     ps_timer_info->timer_flag = (uint8_t)
    242                         SET_BITS8 (ps_timer_info->timer_flag,
    243                                     PH_LLCNFC_GUARD_TO_BIT,
    244                                     PH_LLCNFC_TO_NOOFBITS,
    245                                     PH_LLCNFC_GUARD_TO_BIT);
    246                 }
    247 
    248                 timerid = ps_timer_info->timer_id[PH_LLCNFC_GUARDTIMER];
    249                 Callback = (ppCallBck_t)&phLlcNfc_GuardTimeoutCb;
    250 
    251                 /* Guard time out value */
    252                 ps_timer_info->guard_to_value[timer_count] = (uint16_t)
    253                                         PH_LLCNFC_GUARD_TO_VALUE;
    254 
    255                 ps_timer_info->timer_ns_value[timer_count] = ns_value;
    256                 ps_timer_info->frame_type[timer_count] = (uint8_t)invalid_frame;
    257                 ps_timer_info->iframe_send_count[timer_count] = 0;
    258 
    259                 if ((timer_count > 0) &&
    260                     (ps_timer_info->guard_to_value[(timer_count - 1)] >=
    261                     PH_LLCNFC_GUARD_TO_VALUE))
    262                 {
    263                     /* If the timer has been started already and the
    264                         value is same as the previous means that timer has still
    265                         not expired, so the time out value is increased by
    266                         a resolution */
    267                     ps_timer_info->guard_to_value[timer_count] = (uint16_t)
    268                             (ps_timer_info->guard_to_value[(timer_count - 1)] +
    269                             PH_LLCNFC_RESOLUTION);
    270                 }
    271 
    272                 PH_LLCNFC_DEBUG("GUARD TIMER VALUE : 0x%04X\n", ps_timer_info->guard_to_value[timer_count]);
    273 
    274 
    275                 ps_timer_info->guard_to_count = (uint8_t)(
    276                                         ps_timer_info->guard_to_count + 1);
    277             }
    278             else
    279             {
    280                 /* TIMER should not start, because the time out count has readched the limit */
    281                 timerstarted = TRUE;
    282             }
    283             break;
    284         }
    285 
    286 #ifdef PIGGY_BACK
    287 
    288         case PH_LLCNFC_ACKTIMER:
    289         {
    290             /* Get the ack timer flag */
    291             timerstarted = (uint8_t)GET_BITS8 (
    292                                     ps_timer_info->timer_flag,
    293                                     PH_LLCNFC_ACK_TO_BIT,
    294                                     PH_LLCNFC_TO_NOOFBITS);
    295 
    296             if (FALSE == timerstarted)
    297             {
    298                 /* Timer not started, so start the timer */
    299                 ps_timer_info->timer_flag = (uint8_t)
    300                                 SET_BITS8 (ps_timer_info->timer_flag,
    301                                         PH_LLCNFC_ACK_TO_BIT,
    302                                         PH_LLCNFC_TO_NOOFBITS,
    303                                         (PH_LLCNFC_ACK_TO_BIT - 1));
    304             }
    305 
    306 
    307             timer_resolution = ps_timer_info->ack_to_value = (uint16_t)
    308                                             PH_LLCNFC_ACK_TO_VALUE;
    309             timerid = ps_timer_info->timer_id[PH_LLCNFC_ACKTIMER];
    310             Callback = (ppCallBck_t)&phLlcNfc_AckTimeoutCb;
    311             break;
    312         }
    313 
    314 #endif /* #ifdef PIGGY_BACK */
    315 
    316         default:
    317         {
    318             result = PHNFCSTVAL(CID_NFC_LLC,
    319                                 NFCSTATUS_INVALID_PARAMETER);
    320             break;
    321         }
    322     }
    323     if ((NFCSTATUS_SUCCESS == result) &&
    324         (FALSE == timerstarted))
    325     {
    326         PH_LLCNFC_DEBUG("OSAL START TIMER CALLED TIMER ID : 0x%02X\n", timerid);
    327         phOsalNfc_Timer_Start (timerid, timer_resolution, Callback, NULL);
    328     }
    329 
    330     PH_LLCNFC_PRINT("\n\nLLC : START TIMER END\n\n");
    331 
    332 #else /* #ifdef LLC_TIMER_ENABLE */
    333 
    334     PHNFC_UNUSED_VARIABLE(result);
    335     PHNFC_UNUSED_VARIABLE(TimerType);
    336     PHNFC_UNUSED_VARIABLE(ns_value);
    337 
    338 #endif /* #ifdef LLC_TIMER_ENABLE */
    339     return result;
    340 }
    341 
    342 void
    343 phLlcNfc_StopTimers (
    344     uint8_t             TimerType,
    345     uint8_t             no_of_guard_to_del
    346 )
    347 {
    348     NFCSTATUS               result = NFCSTATUS_SUCCESS;
    349 #ifdef LLC_TIMER_ENABLE
    350 
    351     uint32_t                timerid = 0,
    352                             timerflag = FALSE;
    353     uint8_t                 timer_count = 0;
    354     phLlcNfc_Timerinfo_t    *ps_timer_info = NULL;
    355 
    356 
    357     ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo);
    358     timerflag = ps_timer_info->timer_flag;
    359 
    360     PHNFC_UNUSED_VARIABLE (result);
    361     PH_LLCNFC_PRINT("\n\nLLC : STOP TIMER CALLED\n\n");
    362     switch(TimerType)
    363     {
    364         case PH_LLCNFC_CONNECTIONTIMER:
    365         {
    366             ps_timer_info->timer_flag = (uint8_t)
    367                         SET_BITS8(ps_timer_info->timer_flag,
    368                                 PH_LLCNFC_CON_TO_BIT,
    369                                 PH_LLCNFC_TO_NOOFBITS, 0);
    370             timerid = ps_timer_info->timer_id
    371                                 [PH_LLCNFC_CONNECTION_TO_INDEX];
    372             break;
    373         }
    374 
    375         case PH_LLCNFC_GUARDTIMER:
    376         {
    377             uint8_t             start_index = 0;
    378 
    379             timer_count = ps_timer_info->guard_to_count;
    380 
    381             PH_LLCNFC_DEBUG("GUARD TIMER COUNT BEFORE DELETE: 0x%02X\n", timer_count);
    382             PH_LLCNFC_DEBUG("GUARD TIMER TO DELETE: 0x%02X\n", no_of_guard_to_del);
    383 
    384             if (timer_count > no_of_guard_to_del)
    385             {
    386                 /* The number of guard timer count is more than the
    387                     guard timer to delete  */
    388                 while (start_index < (timer_count - no_of_guard_to_del))
    389                 {
    390                     /* Copy the previous stored timer values to the present */
    391                     ps_timer_info->guard_to_value[start_index] = (uint16_t)
    392                                 (ps_timer_info->guard_to_value[
    393                                 (no_of_guard_to_del + start_index)]);
    394 
    395                     ps_timer_info->iframe_send_count[start_index] = (uint8_t)
    396                                 (ps_timer_info->iframe_send_count[
    397                                 (no_of_guard_to_del + start_index)]);
    398 
    399                     PH_LLCNFC_DEBUG("GUARD TIMER NS INDEX DELETED : 0x%02X\n", ps_timer_info->timer_ns_value[start_index]);
    400 
    401                     ps_timer_info->timer_ns_value[start_index] = (uint8_t)
    402                                 (ps_timer_info->timer_ns_value[
    403                                 (no_of_guard_to_del + start_index)]);
    404 
    405                     ps_timer_info->frame_type[start_index] = (uint8_t)
    406                                 (ps_timer_info->frame_type[
    407                                 (no_of_guard_to_del + start_index)]);
    408 
    409                     start_index = (uint8_t)(start_index + 1);
    410                 }
    411             }
    412             else
    413             {
    414                 while (start_index < no_of_guard_to_del)
    415                 {
    416                     ps_timer_info->guard_to_value[start_index] = 0;
    417 
    418                     ps_timer_info->iframe_send_count[start_index] = 0;
    419 
    420                     PH_LLCNFC_DEBUG("GUARD TIMER NS INDEX DELETED ELSE : 0x%02X\n", ps_timer_info->timer_ns_value[start_index]);
    421 
    422                     ps_timer_info->timer_ns_value[start_index] = 0;
    423 
    424                     ps_timer_info->frame_type[start_index] = 0;
    425 
    426                     start_index = (uint8_t)(start_index + 1);
    427                 }
    428             }
    429 
    430             if (timer_count >= no_of_guard_to_del)
    431             {
    432                 timer_count = (uint8_t)(timer_count - no_of_guard_to_del);
    433             }
    434             else
    435             {
    436                 if (0 != no_of_guard_to_del)
    437                 {
    438                     timer_count = 0;
    439                 }
    440             }
    441 
    442             timerid = ps_timer_info->timer_id[PH_LLCNFC_GUARDTIMER];
    443             ps_timer_info->guard_to_count = timer_count;
    444             PH_LLCNFC_DEBUG("GUARD TIMER COUNT AFTER DELETE: 0x%02X\n", timer_count);
    445 
    446             if (0 == ps_timer_info->guard_to_count)
    447             {
    448                 /* This means that there are no frames to run guard
    449                     timer, so set the timer flag to 0 */
    450                 ps_timer_info->timer_flag = (uint8_t)
    451                         SET_BITS8 (ps_timer_info->timer_flag,
    452                                     PH_LLCNFC_GUARD_TO_BIT,
    453                                     PH_LLCNFC_TO_NOOFBITS, 0);
    454             }
    455             else
    456             {
    457                 timerflag = 0;
    458             }
    459             break;
    460         }
    461 
    462 #ifdef PIGGY_BACK
    463         case PH_LLCNFC_ACKTIMER:
    464         {
    465             timerflag = (timerflag & PH_LLCNFC_ACK_TO_BIT_VAL);
    466 
    467             ps_timer_info->timer_flag = (uint8_t)
    468                                 SET_BITS8 (ps_timer_info->timer_flag,
    469                                         PH_LLCNFC_ACK_TO_BIT,
    470                                         PH_LLCNFC_TO_NOOFBITS, 0);
    471             timerid = ps_timer_info->timer_id[PH_LLCNFC_ACKTIMER];
    472             ps_timer_info->ack_to_value = 0;
    473             break;
    474         }
    475 #endif /* #ifdef PIGGY_BACK */
    476 
    477         default:
    478         {
    479             result = PHNFCSTVAL(CID_NFC_LLC,
    480                                 NFCSTATUS_INVALID_PARAMETER);
    481             break;
    482         }
    483     }
    484 
    485     if ((NFCSTATUS_SUCCESS == result) && (timerflag > 0))
    486     {
    487         PH_LLCNFC_DEBUG("OSAL STOP TIMER CALLED TIMER ID : 0x%02X\n", timerid);
    488         phOsalNfc_Timer_Stop (timerid);
    489     }
    490 
    491     PH_LLCNFC_PRINT("\n\nLLC : STOP TIMER END\n\n");
    492 
    493 #else /* #ifdef LLC_TIMER_ENABLE */
    494 
    495     PHNFC_UNUSED_VARIABLE (result);
    496     PHNFC_UNUSED_VARIABLE (TimerType);
    497     PHNFC_UNUSED_VARIABLE (no_of_guard_to_del);
    498 
    499 #endif /* #ifdef LLC_TIMER_ENABLE */
    500 }
    501 
    502 void
    503 phLlcNfc_StopAllTimers (void)
    504 {
    505 
    506 #ifdef LLC_TIMER_ENABLE
    507 
    508     phLlcNfc_Timerinfo_t    *ps_timer_info = NULL;
    509     uint8_t                 timer_started = 0;
    510     uint32_t                timerid = 0;
    511     uint8_t                 timer_index = 0;
    512 
    513 
    514     ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo);
    515 
    516     PH_LLCNFC_PRINT("\n\nLLC : STOP ALL TIMERS CALLED \n\n");
    517 
    518     timerid = ps_timer_info->timer_id[timer_index];
    519     timer_started = (uint8_t)
    520                 GET_BITS8(ps_timer_info->timer_flag,
    521                         PH_LLCNFC_CON_TO_BIT,
    522                         PH_LLCNFC_TO_NOOFBITS);
    523 
    524     PH_LLCNFC_DEBUG("CONNECTION TIMER ID: 0x%02X\n", timerid);
    525 
    526     if (0 != timer_started)
    527     {
    528         /* Connection timer is started, so now stop it */
    529         ps_timer_info->timer_flag = (uint8_t)
    530                         SET_BITS8 (ps_timer_info->timer_flag,
    531                                     PH_LLCNFC_CON_TO_BIT,
    532                                     PH_LLCNFC_TO_NOOFBITS, 0);
    533 #if 0
    534 
    535         ps_timer_info->con_to_value = 0;
    536 
    537 #endif /* #if 0 */
    538 
    539         phOsalNfc_Timer_Stop (timerid);
    540     }
    541 
    542     timer_index = (uint8_t)(timer_index + 1);
    543     timerid = ps_timer_info->timer_id[timer_index];
    544     timer_started = (uint8_t)GET_BITS8 (ps_timer_info->timer_flag,
    545                                         PH_LLCNFC_GUARD_TO_BIT,
    546                                         PH_LLCNFC_TO_NOOFBITS);
    547 
    548     if (0 != timer_started)
    549     {
    550         /* Guard timer is already started */
    551         ps_timer_info->timer_flag = (uint8_t)
    552                         SET_BITS8 (ps_timer_info->timer_flag,
    553                                     PH_LLCNFC_GUARD_TO_BIT,
    554                                     PH_LLCNFC_TO_NOOFBITS, 0);
    555 
    556         timer_index = 0;
    557         ps_timer_info->guard_to_count = 0;
    558 
    559 #if 0
    560 
    561         /* Reset all the guard timer related variables */
    562         while (timer_index < ps_timer_info->guard_to_count)
    563         {
    564             ps_timer_info->guard_to_value[timer_index] = 0;
    565             ps_timer_info->iframe_send_count[timer_index] = 0;
    566 
    567             timer_index = (uint8_t)(timer_index + 1);
    568         }
    569 
    570 #endif /* #if 0 */
    571 
    572         PH_LLCNFC_DEBUG("GUARD TIMER ID: 0x%02X\n", timerid);
    573 
    574         /* Stop the timer */
    575         phOsalNfc_Timer_Stop (timerid);
    576 
    577         PH_LLCNFC_PRINT("\n\nLLC : STOP ALL TIMERS END \n\n");
    578     }
    579 
    580 #endif /* #ifdef LLC_TIMER_ENABLE */
    581 }
    582 
    583 void
    584 phLlcNfc_DeleteTimer (void)
    585 {
    586     uint8_t     index = 0;
    587     while (index < PH_LLCNFC_MAX_TIMER_USED)
    588     {
    589 #ifdef LLC_TIMER_ENABLE
    590         phOsalNfc_Timer_Delete(
    591             gpphLlcNfc_Ctxt->s_timerinfo.timer_id[index]);
    592         gpphLlcNfc_Ctxt->s_timerinfo.timer_id[index] =
    593                             PH_OSALNFC_INVALID_TIMER_ID;
    594 #endif /* #ifdef LLC_TIMER_ENABLE */
    595         index++;
    596     }
    597 }
    598 
    599 #ifdef LLC_TIMER_ENABLE
    600 
    601 #define LLC_GUARD_TIMER_RETRIES                         (0x03U)
    602 
    603 static
    604 void
    605 phLlcNfc_GuardTimeoutCb (
    606     uint32_t TimerId,
    607     void *pContext
    608 )
    609 {
    610     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
    611     phLlcNfc_Timerinfo_t        *ps_timer_info = NULL;
    612     phLlcNfc_Frame_t            *ps_frame_info = NULL;
    613     phLlcNfc_LlcPacket_t        s_packet_info;
    614     uint8_t                     index = 0;
    615     /* zero_to_index = Time out index has become 0 */
    616     uint8_t                     zero_to_index = 0;
    617 
    618 #if defined (GUARD_TO_ERROR)
    619     phNfc_sCompletionInfo_t     notifyinfo = {0,0,0};
    620 #endif /* #if defined (GUARD_TO_ERROR) */
    621 
    622     PH_LLCNFC_PRINT("\n\nLLC : GUARD TIMEOUT CB CALLED \n\n");
    623 
    624     if ((NULL != gpphLlcNfc_Ctxt) && (TimerId ==
    625         gpphLlcNfc_Ctxt->s_timerinfo.timer_id[PH_LLCNFC_GUARDTIMER]) &&
    626         (PH_LLCNFC_GUARD_TO_BIT_VAL ==
    627         (gpphLlcNfc_Ctxt->s_timerinfo.timer_flag &
    628         PH_LLCNFC_GUARD_TO_BIT_VAL)))
    629     {
    630         uint8_t                 timer_expired = FALSE;
    631 
    632         ps_frame_info = &(gpphLlcNfc_Ctxt->s_frameinfo);
    633         ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo);
    634 
    635 #if !defined (CYCLIC_TIMER)
    636         phOsalNfc_Timer_Stop(
    637                     ps_timer_info->timer_id[PH_LLCNFC_GUARDTIMER]);
    638 #endif
    639 
    640         PH_LLCNFC_DEBUG("NO OF TIMEOUT COUNT : 0x%02X\n", ps_timer_info->guard_to_count);
    641         /* Loop is completely depending on the number of different LLC
    642            send called */
    643         while (index < ps_timer_info->guard_to_count)
    644         {
    645             /* This loop runs for all the timer present in the data structure.
    646                 This means if there are 2 I frame has been sent and
    647                 response is not received for the I frames sent then the
    648                 each time this timer expires, the time out value is decremented
    649                 by the PH_LLCNFC_RESOLUTION value */
    650             if (0 != ps_timer_info->guard_to_value[index])
    651             {
    652                 /* If timer value is not zero then enter,
    653                     this means that the value is not zero */
    654                 if (ps_timer_info->guard_to_value[index] > 0)
    655                 {
    656                     if (ps_timer_info->guard_to_value[index] >=
    657                         PH_LLCNFC_RESOLUTION)
    658                     {
    659                         ps_timer_info->guard_to_value[index] = (uint16_t)
    660                             (ps_timer_info->guard_to_value[index] -
    661                             PH_LLCNFC_RESOLUTION);
    662                     }
    663                     else
    664                     {
    665                         ps_timer_info->guard_to_value[index] = 0;
    666                     }
    667                 }
    668 
    669                 if (0 == ps_timer_info->guard_to_value[index])
    670                 {
    671                     /* Timer value has expired, so resend has to be done
    672                         Timer value is 0 */
    673                     ps_timer_info->frame_type[index] = (uint8_t)resend_i_frame;
    674                     if (FALSE == timer_expired)
    675                     {
    676                         /* As the statement is in the loop, so there are possibilities
    677                             of more than 1 timer value can be 0, so if previous timer
    678                             value has already been 0, then again dont change the
    679                             index */
    680                     zero_to_index = index;
    681                     timer_expired = TRUE;
    682                 }
    683             }
    684             }
    685             index = (uint8_t)(index + 1);
    686         }
    687 
    688 #if !defined (CYCLIC_TIMER)
    689         /* Start the timer again */
    690         phOsalNfc_Timer_Start(
    691                     ps_timer_info->timer_id[PH_LLCNFC_GUARDTIMER],
    692                     PH_LLCNFC_RESOLUTION, phLlcNfc_GuardTimeoutCb, NULL);
    693 #endif
    694         PH_LLCNFC_DEBUG("TIMER EXPIRED : 0x%02X\n", timer_expired);
    695 
    696         if (TRUE == timer_expired)
    697         {
    698             PH_LLCNFC_DEBUG("TIMER EXPIRED INDEX: 0x%02X\n", zero_to_index);
    699             PH_LLCNFC_DEBUG("TIMER EXPIRED NS INDEX: 0x%02X\n", ps_timer_info->timer_ns_value[zero_to_index]);
    700             PH_LLCNFC_DEBUG("TIMER EXPIRED RETRIES : 0x%02X\n", ps_timer_info->iframe_send_count[zero_to_index]);
    701 
    702             PH_LLCNFC_DEBUG("TIMER EXPIRED GUARD TIME-OUT COUNT: 0x%02X\n", ps_timer_info->guard_to_value[zero_to_index]);
    703 
    704             if ((0 == ps_timer_info->guard_to_value[zero_to_index]) &&
    705                 (ps_timer_info->iframe_send_count[zero_to_index] <
    706                 LLC_GUARD_TIMER_RETRIES))
    707             {
    708                 if (ps_frame_info->s_send_store.winsize_cnt > 0)
    709                 {
    710                     uint8_t             start_index = 0;
    711                     uint8_t             timer_count = 0;
    712                     uint8_t             while_exit = FALSE;
    713 
    714                     timer_count = ps_timer_info->guard_to_count;
    715 
    716                     /* Check before changing the index to resend, if index
    717                         already exist then dont set the index */
    718                     while ((FALSE == while_exit) && (start_index < timer_count))
    719                     {
    720                         if (resend_i_frame ==
    721                             ps_timer_info->frame_type[start_index])
    722                         {
    723                             while_exit = TRUE;
    724                         }
    725                         else
    726                         {
    727                             start_index = (uint8_t)(start_index + 1);
    728                         }
    729                     }
    730 
    731                     if (FALSE == while_exit)
    732                     {
    733                         /* This " ps_timer_info->index_to_send " member is
    734                            useful, when 2 time out values are 0, then
    735                            only first timed out value has to be resent and
    736                            other has to wait until the the first timed out
    737                            I frame is resent
    738                            This statement is executed only if, none of the timer
    739                            has expires previously, this is the first timer in the
    740                            list that has time out value has 0
    741                            */
    742                         ps_timer_info->index_to_send = zero_to_index;
    743                     }
    744                     else
    745                     {
    746                         /* This statement is executed only if, any one of the time
    747                            out value was 0 previously, so first resend has to be done
    748                            for the previous I frame, so the index is set to the previous
    749                            I frame
    750                            */
    751                         ps_timer_info->index_to_send = start_index;
    752                     }
    753 
    754                     /* Now resend the frame stored */
    755                     result = phLlcNfc_H_SendTimedOutIFrame (gpphLlcNfc_Ctxt,
    756                                             &(ps_frame_info->s_send_store),
    757                                             0);
    758                 }
    759             }
    760             else
    761             {
    762                 if ((LLC_GUARD_TIMER_RETRIES ==
    763                     ps_timer_info->iframe_send_count[zero_to_index]) &&
    764                     (NULL != gpphLlcNfc_Ctxt->cb_for_if.notify))
    765                 {
    766                     phLlcNfc_StopAllTimers ();
    767 #if defined (GUARD_TO_ERROR)
    768 
    769                     notifyinfo.status = PHNFCSTVAL(CID_NFC_LLC,
    770                                         NFCSTATUS_BOARD_COMMUNICATION_ERROR);
    771 #if 0
    772                     phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1);
    773 #endif /* #if 0 */
    774                     /* Resend done, no answer from the device */
    775                     gpphLlcNfc_Ctxt->cb_for_if.notify (
    776                                     gpphLlcNfc_Ctxt->cb_for_if.pif_ctxt,
    777                                     gpphLlcNfc_Ctxt->phwinfo,
    778                                     NFC_NOTIFY_DEVICE_ERROR,
    779                                     &notifyinfo);
    780 
    781 #endif /* #if defined (GUARD_TO_ERROR) */
    782 
    783 #if (!defined (GUARD_TO_ERROR) && defined (GUARD_TO_URSET))
    784 
    785                     PH_LLCNFC_PRINT("U-RSET IS SENT \n");
    786 
    787                     result = phLlcNfc_H_CreateUFramePayload(gpphLlcNfc_Ctxt,
    788                                         &(s_packet_info),
    789                                         &(s_packet_info.llcbuf_len),
    790                                         phLlcNfc_e_rset);
    791 
    792                     result = phLlcNfc_Interface_Write(gpphLlcNfc_Ctxt,
    793                                     (uint8_t*)&(s_packet_info.s_llcbuf),
    794                                     (uint32_t)s_packet_info.llcbuf_len);
    795 
    796                     ps_frame_info->write_status = result;
    797                     if (NFCSTATUS_PENDING == result)
    798                     {
    799                         /* Start the timer */
    800                         result = phLlcNfc_StartTimers (PH_LLCNFC_CONNECTIONTIMER, 0);
    801                         if (NFCSTATUS_SUCCESS == result)
    802                         {
    803                             ps_frame_info->retry_cnt = 0;
    804                             gpphLlcNfc_Ctxt->s_frameinfo.sent_frame_type =
    805                                                                     u_rset_frame;
    806                             result = NFCSTATUS_PENDING;
    807                         }
    808                     }
    809                     else
    810                     {
    811                         if (NFCSTATUS_BUSY == PHNFCSTATUS (result))
    812                         {
    813                             ps_frame_info->write_wait_call = u_rset_frame;
    814                         }
    815                     }
    816 
    817 #endif /* #if defined (GUARD_TO_ERROR) */
    818                 }
    819             }
    820         }
    821     }
    822     PH_LLCNFC_PRINT("\n\nLLC : GUARD TIMEOUT CB END\n\n");
    823 }
    824 
    825 #ifdef PIGGY_BACK
    826 
    827 static
    828 void
    829 phLlcNfc_AckTimeoutCb (
    830     uint32_t TimerId
    831 )
    832 {
    833     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
    834     phLlcNfc_Frame_t            *ps_frame_info = NULL;
    835     phLlcNfc_Timerinfo_t        *ps_timer_info = NULL;
    836     phLlcNfc_LlcPacket_t        s_packet_info;
    837 
    838     PH_LLCNFC_PRINT("\n\nLLC : ACK TIMEOUT CB CALLED\n\n");
    839 
    840     if ((NULL != gpphLlcNfc_Ctxt) && (TimerId ==
    841         gpphLlcNfc_Ctxt->s_timerinfo.timer_id[PH_LLCNFC_ACKTIMER])
    842         && (PH_LLCNFC_ACK_TO_BIT_VAL ==
    843         (gpphLlcNfc_Ctxt->s_timerinfo.timer_flag &
    844         PH_LLCNFC_ACK_TO_BIT_VAL)))
    845     {
    846         ps_frame_info = &(gpphLlcNfc_Ctxt->s_frameinfo);
    847         ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo);
    848 
    849         phLlcNfc_StopTimers (PH_LLCNFC_ACKTIMER, 0);
    850 
    851         if (NFCSTATUS_BUSY == PHNFCSTATUS (ps_frame_info->write_status))
    852         {
    853             /* Any how write cannot be done and some frame is ready to be sent
    854             so this frame will act as the ACK */
    855             result = phLlcNfc_H_WriteWaitCall (gpphLlcNfc_Ctxt);
    856         }
    857         else
    858         {
    859             /* Create S frame */
    860             (void)phLlcNfc_H_CreateSFramePayload (ps_frame_info, &(s_packet_info), phLlcNfc_e_rr);
    861 
    862             result = phLlcNfc_Interface_Write(gpphLlcNfc_Ctxt,
    863                         (uint8_t *)&(s_packet_info.s_llcbuf),
    864                         (uint32_t)(s_packet_info.llcbuf_len));
    865 
    866             if (NFCSTATUS_PENDING == result)
    867             {
    868                 if (0 == ps_frame_info->send_error_count)
    869                 {
    870                     ps_frame_info->write_wait_call = invalid_frame;
    871                 }
    872                 ps_frame_info->sent_frame_type = s_frame;
    873             }
    874             else
    875             {
    876                 if (invalid_frame == ps_frame_info->write_wait_call)
    877                 {
    878                     ps_frame_info->write_wait_call = s_frame;
    879                 }
    880             }
    881         }
    882     }
    883 
    884     /* ACK is sent, so reset the response received count */
    885     gpphLlcNfc_Ctxt->s_frameinfo.resp_recvd_count = 0;
    886 
    887     PH_LLCNFC_PRINT("\n\nLLC : ACK TIMEOUT CB END\n\n");
    888 }
    889 
    890 #endif /* #ifdef PIGGY_BACK */
    891 
    892 static
    893 void
    894 phLlcNfc_ConnectionTimeoutCb (
    895     uint32_t TimerId,
    896     void *pContext
    897 )
    898 {
    899     NFCSTATUS                   result = NFCSTATUS_SUCCESS;
    900     phNfc_sCompletionInfo_t     notifyinfo = {0,0,0};
    901     pphNfcIF_Notification_CB_t  notifyul = NULL;
    902     void                        *p_upperctxt = NULL;
    903     phLlcNfc_Frame_t            *ps_frame_info = NULL;
    904     phLlcNfc_Timerinfo_t        *ps_timer_info = NULL;
    905     phLlcNfc_LlcPacket_t        s_packet_info;
    906 
    907     PH_LLCNFC_PRINT("\n\nLLC : CONNECTION TIMEOUT CB CALLED\n\n");
    908     if ((NULL != gpphLlcNfc_Ctxt) && (TimerId ==
    909         gpphLlcNfc_Ctxt->s_timerinfo.timer_id[PH_LLCNFC_CONNECTIONTIMER])
    910         && (PH_LLCNFC_CON_TO_BIT_VAL ==
    911         (gpphLlcNfc_Ctxt->s_timerinfo.timer_flag &
    912         PH_LLCNFC_CON_TO_BIT_VAL)))
    913     {
    914         ps_frame_info = &(gpphLlcNfc_Ctxt->s_frameinfo);
    915         ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo);
    916         if (ps_timer_info->con_to_value > 0)
    917         {
    918 #if !defined (CYCLIC_TIMER)
    919             phOsalNfc_Timer_Stop(
    920                     ps_timer_info->timer_id[PH_LLCNFC_CONNECTIONTIMER]);
    921             /* phLlcNfc_StopTimers(PH_LLCNFC_CONNECTIONTIMER, 0); */
    922 #endif
    923             ps_timer_info->con_to_value = 0;
    924 
    925             if (0 == ps_timer_info->con_to_value)
    926             {
    927                 PH_LLCNFC_DEBUG("TIMER EXPIRED RETRY COUNT : %02X\n", ps_frame_info->retry_cnt);
    928                 phLlcNfc_StopTimers (PH_LLCNFC_CONNECTIONTIMER, 0);
    929 
    930                 if (ps_frame_info->retry_cnt < PH_LLCNFC_MAX_RETRY_COUNT)
    931                 {
    932                     /* Create a U frame */
    933                     result = phLlcNfc_H_CreateUFramePayload(gpphLlcNfc_Ctxt,
    934                                         &(s_packet_info),
    935                                         &(s_packet_info.llcbuf_len),
    936                                         phLlcNfc_e_rset);
    937 
    938                     if (NFCSTATUS_SUCCESS == result)
    939                     {
    940                         /* Call DAL write */
    941                         result = phLlcNfc_Interface_Write (gpphLlcNfc_Ctxt,
    942                                 (uint8_t*)&(s_packet_info.s_llcbuf),
    943                                 (uint32_t)(s_packet_info.llcbuf_len));
    944                     }
    945                     if (NFCSTATUS_PENDING == result)
    946                     {
    947                         /* Start the timer */
    948                         result = phLlcNfc_StartTimers(PH_LLCNFC_CONNECTIONTIMER, 0);
    949                         if (NFCSTATUS_SUCCESS == result)
    950                         {
    951                             ps_frame_info->retry_cnt++;
    952                             result = NFCSTATUS_PENDING;
    953                         }
    954                     }
    955                     else
    956                     {
    957                         if (NFCSTATUS_BUSY == PHNFCSTATUS(result))
    958                         {
    959                             result = NFCSTATUS_PENDING;
    960                         }
    961                     }
    962                 }
    963                 else
    964                 {
    965                     PH_LLCNFC_PRINT("RETRY COUNT LIMIT REACHED \n");
    966                     if ((ps_frame_info->retry_cnt == PH_LLCNFC_MAX_RETRY_COUNT)
    967                         && (NULL != gpphLlcNfc_Ctxt->cb_for_if.notify))
    968                     {
    969                         void            *p_hw_info = NULL;
    970                         uint8_t         type = 0;
    971 
    972                         p_hw_info = gpphLlcNfc_Ctxt->phwinfo;
    973                         notifyinfo.status = PHNFCSTVAL(CID_NFC_LLC,
    974                                             NFCSTATUS_BOARD_COMMUNICATION_ERROR);
    975 
    976                         notifyul = gpphLlcNfc_Ctxt->cb_for_if.notify;
    977                         p_upperctxt = gpphLlcNfc_Ctxt->cb_for_if.pif_ctxt;
    978                         type = NFC_NOTIFY_ERROR;
    979                         if (init_u_rset_frame == ps_frame_info->sent_frame_type)
    980                         {
    981                             type = NFC_NOTIFY_INIT_FAILED;
    982                             /* Release if, the initialisation is not complete */
    983                             result = phLlcNfc_Release(gpphLlcNfc_Ctxt, p_hw_info);
    984                             gpphLlcNfc_Ctxt = NULL;
    985                         }
    986                         else
    987                         {
    988                             type = NFC_NOTIFY_DEVICE_ERROR;
    989                             notifyinfo.status = PHNFCSTVAL(CID_NFC_LLC,
    990                                             NFCSTATUS_BOARD_COMMUNICATION_ERROR);
    991 #if 0
    992                             phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1);
    993 #endif /* #if 0 */
    994                         }
    995                         /* Notify the upper layer */
    996                         notifyul(p_upperctxt, p_hw_info, type, &notifyinfo);
    997                     }
    998                 }
    999             }
   1000 #if !defined (CYCLIC_TIMER)
   1001             else
   1002             {
   1003                 /* Start the timer again */
   1004                 phOsalNfc_Timer_Start(
   1005                             ps_timer_info->timer_id[PH_LLCNFC_CONNECTIONTIMER],
   1006                             ps_timer_info->con_to_value, phLlcNfc_ConnectionTimeoutCb, NULL);
   1007             }
   1008 #endif
   1009         }
   1010     }
   1011     PH_LLCNFC_PRINT("\n\nLLC : CONNECTION TIMEOUT CB END\n\n");
   1012 }
   1013 #endif /* #ifdef LLC_TIMER_ENABLE */
   1014 
   1015 #ifdef LLC_URSET_NO_DELAY
   1016 
   1017     /* NO definition required */
   1018 
   1019 #else /* #ifdef LLC_URSET_NO_DELAY */
   1020 
   1021 void
   1022 phLlcNfc_URSET_Delay_Notify (
   1023     uint32_t            delay_id,
   1024     void                *pContext)
   1025 {
   1026     phLlcNfc_Frame_t            *ps_frame_info = NULL;
   1027     phNfc_sCompletionInfo_t     notifyinfo = {0,0,0};
   1028 
   1029     if (NULL != gpphLlcNfc_Ctxt)
   1030     {
   1031         ps_frame_info = &(gpphLlcNfc_Ctxt->s_frameinfo);
   1032 
   1033         phOsalNfc_Timer_Stop (delay_id);
   1034         phOsalNfc_Timer_Delete (delay_id);
   1035         if (ps_frame_info->s_send_store.winsize_cnt > 0)
   1036         {
   1037 #if 0
   1038 
   1039             /* Resend I frame */
   1040             (void)phLlcNfc_H_SendTimedOutIFrame (gpphLlcNfc_Ctxt,
   1041                                         &(ps_frame_info->s_send_store), 0);
   1042 
   1043 #else
   1044 
   1045             (void)phLlcNfc_H_SendUserIFrame (gpphLlcNfc_Ctxt,
   1046                                         &(ps_frame_info->s_send_store));
   1047 
   1048 #endif /* #if 0 */
   1049             gpphLlcNfc_Ctxt->state = phLlcNfc_Resend_State;
   1050         }
   1051         else
   1052         {
   1053             if ((init_u_rset_frame == ps_frame_info->sent_frame_type) &&
   1054                 (NULL != gpphLlcNfc_Ctxt->cb_for_if.notify))
   1055             {
   1056                 ps_frame_info->sent_frame_type = write_resp_received;
   1057                 notifyinfo.status = NFCSTATUS_SUCCESS;
   1058                 /* Send the notification to the upper layer */
   1059                 gpphLlcNfc_Ctxt->cb_for_if.notify (
   1060                             gpphLlcNfc_Ctxt->cb_for_if.pif_ctxt,
   1061                             gpphLlcNfc_Ctxt->phwinfo,
   1062                             NFC_NOTIFY_INIT_COMPLETED,
   1063                             &notifyinfo);
   1064             }
   1065         }
   1066     }
   1067 }
   1068 
   1069 #endif /* #ifdef LLC_URSET_NO_DELAY */
   1070 
   1071