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
phLlcNfc_TimerInit(phLlcNfc_Context_t * psLlcCtxt)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
phLlcNfc_TimerUnInit(phLlcNfc_Context_t * psLlcCtxt)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
phLlcNfc_CreateTimers(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
phLlcNfc_StartTimers(uint8_t TimerType,uint8_t ns_value)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
phLlcNfc_StopTimers(uint8_t TimerType,uint8_t no_of_guard_to_del)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
phLlcNfc_StopAllTimers(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
phLlcNfc_DeleteTimer(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
phLlcNfc_GuardTimeoutCb(uint32_t TimerId,void * pContext)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
phLlcNfc_AckTimeoutCb(uint32_t TimerId)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
phLlcNfc_ConnectionTimeoutCb(uint32_t TimerId,void * pContext)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
phLlcNfc_URSET_Delay_Notify(uint32_t delay_id,void * pContext)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