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
72static
73void
74phLlcNfc_GuardTimeoutCb (
75    uint32_t TimerId,
76    void *pContext
77);
78
79
80#ifdef PIGGY_BACK
81/* This callback is for acknowledge time out */
82static
83void
84phLlcNfc_AckTimeoutCb (
85    uint32_t TimerId
86);
87#endif /* #ifdef PIGGY_BACK */
88
89/* This callback is for connection time out */
90static
91void
92phLlcNfc_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 ****************************/
101static phLlcNfc_Context_t   *gpphLlcNfc_Ctxt = NULL;
102
103/******************** End of Global Variables ***********************/
104
105NFCSTATUS
106phLlcNfc_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
129void
130phLlcNfc_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
155void
156phLlcNfc_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
171NFCSTATUS
172phLlcNfc_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
342void
343phLlcNfc_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
502void
503phLlcNfc_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
583void
584phLlcNfc_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
603static
604void
605phLlcNfc_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
827static
828void
829phLlcNfc_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
892static
893void
894phLlcNfc_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
1021void
1022phLlcNfc_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