• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  Entry point for NFC_TASK
22  *
23  ******************************************************************************/
24 #include <string.h>
25 #include "gki.h"
26 #include "nfc_target.h"
27 #include "bt_types.h"
28 
29 #if (NFC_INCLUDED == TRUE)
30 #include "nfc_api.h"
31 #include "nfc_hal_api.h"
32 #include "nfc_int.h"
33 #include "nci_hmsgs.h"
34 #include "rw_int.h"
35 #include "ce_int.h"
36 #if (NFC_RW_ONLY == FALSE)
37 #include "llcp_int.h"
38 #else
39 #define llcp_cleanup()
40 #endif
41 
42 #if (defined (NFA_INCLUDED) && NFA_INCLUDED == TRUE)
43 #include "nfa_sys.h"
44 #include "nfa_dm_int.h"
45 #endif
46 
47 /*******************************************************************************
48 **
49 ** Function         nfc_start_timer
50 **
51 ** Description      Start a timer for the specified amount of time.
52 **                  NOTE: The timeout resolution is in SECONDS! (Even
53 **                          though the timer structure field is ticks)
54 **
55 ** Returns          void
56 **
57 *******************************************************************************/
nfc_start_timer(TIMER_LIST_ENT * p_tle,UINT16 type,UINT32 timeout)58 void nfc_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout)
59 {
60     BT_HDR *p_msg;
61 
62     /* if timer list is currently empty, start periodic GKI timer */
63     if (nfc_cb.timer_queue.p_first == NULL)
64     {
65         /* if timer starts on other than NFC task (scritp wrapper) */
66         if (GKI_get_taskid () != NFC_TASK)
67         {
68             /* post event to start timer in NFC task */
69             if ((p_msg = (BT_HDR *) GKI_getbuf (BT_HDR_SIZE)) != NULL)
70             {
71                 p_msg->event = BT_EVT_TO_START_TIMER;
72                 GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
73             }
74         }
75         else
76         {
77             /* Start nfc_task 1-sec resolution timer */
78             GKI_start_timer (NFC_TIMER_ID, GKI_SECS_TO_TICKS (1), TRUE);
79         }
80     }
81 
82     GKI_remove_from_timer_list (&nfc_cb.timer_queue, p_tle);
83 
84     p_tle->event = type;
85     p_tle->ticks = timeout;         /* Save the number of seconds for the timer */
86 
87     GKI_add_to_timer_list (&nfc_cb.timer_queue, p_tle);
88 }
89 
90 /*******************************************************************************
91 **
92 ** Function         nfc_remaining_time
93 **
94 ** Description      Return amount of time to expire
95 **
96 ** Returns          time in second
97 **
98 *******************************************************************************/
nfc_remaining_time(TIMER_LIST_ENT * p_tle)99 UINT32 nfc_remaining_time (TIMER_LIST_ENT *p_tle)
100 {
101     return (GKI_get_remaining_ticks (&nfc_cb.timer_queue, p_tle));
102 }
103 
104 /*******************************************************************************
105 **
106 ** Function         nfc_process_timer_evt
107 **
108 ** Description      Process nfc GKI timer event
109 **
110 ** Returns          void
111 **
112 *******************************************************************************/
nfc_process_timer_evt(void)113 void nfc_process_timer_evt (void)
114 {
115     TIMER_LIST_ENT  *p_tle;
116 
117     GKI_update_timer_list (&nfc_cb.timer_queue, 1);
118 
119     while ((nfc_cb.timer_queue.p_first) && (!nfc_cb.timer_queue.p_first->ticks))
120     {
121         p_tle = nfc_cb.timer_queue.p_first;
122         GKI_remove_from_timer_list (&nfc_cb.timer_queue, p_tle);
123 
124         switch (p_tle->event)
125         {
126         case NFC_TTYPE_NCI_WAIT_RSP:
127             nfc_ncif_cmd_timeout();
128             break;
129 
130         case NFC_TTYPE_WAIT_2_DEACTIVATE:
131             nfc_wait_2_deactivate_timeout ();
132             break;
133 
134         default:
135             NFC_TRACE_DEBUG2 ("nfc_process_timer_evt: timer:0x%x event (0x%04x)", p_tle, p_tle->event);
136             NFC_TRACE_DEBUG1 ("nfc_process_timer_evt: unhandled timer event (0x%04x)", p_tle->event);
137         }
138     }
139 
140     /* if timer list is empty stop periodic GKI timer */
141     if (nfc_cb.timer_queue.p_first == NULL)
142     {
143         GKI_stop_timer (NFC_TIMER_ID);
144     }
145 }
146 
147 /*******************************************************************************
148 **
149 ** Function         nfc_stop_timer
150 **
151 ** Description      Stop a timer.
152 **
153 ** Returns          void
154 **
155 *******************************************************************************/
nfc_stop_timer(TIMER_LIST_ENT * p_tle)156 void nfc_stop_timer (TIMER_LIST_ENT *p_tle)
157 {
158     GKI_remove_from_timer_list (&nfc_cb.timer_queue, p_tle);
159 
160     /* if timer list is empty stop periodic GKI timer */
161     if (nfc_cb.timer_queue.p_first == NULL)
162     {
163         GKI_stop_timer (NFC_TIMER_ID);
164     }
165 }
166 
167 /*******************************************************************************
168 **
169 ** Function         nfc_start_quick_timer
170 **
171 ** Description      Start a timer for the specified amount of time.
172 **                  NOTE: The timeout resolution depends on including modules.
173 **                  QUICK_TIMER_TICKS_PER_SEC should be used to convert from
174 **                  time to ticks.
175 **
176 **
177 ** Returns          void
178 **
179 *******************************************************************************/
nfc_start_quick_timer(TIMER_LIST_ENT * p_tle,UINT16 type,UINT32 timeout)180 void nfc_start_quick_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout)
181 {
182     BT_HDR *p_msg;
183 
184     /* if timer list is currently empty, start periodic GKI timer */
185     if (nfc_cb.quick_timer_queue.p_first == NULL)
186     {
187         /* if timer starts on other than NFC task (scritp wrapper) */
188         if (GKI_get_taskid () != NFC_TASK)
189         {
190             /* post event to start timer in NFC task */
191             if ((p_msg = (BT_HDR *) GKI_getbuf (BT_HDR_SIZE)) != NULL)
192             {
193                 p_msg->event = BT_EVT_TO_START_QUICK_TIMER;
194                 GKI_send_msg (NFC_TASK, NFC_MBOX_ID, p_msg);
195             }
196         }
197         else
198         {
199             /* Quick-timer is required for LLCP */
200             GKI_start_timer (NFC_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE);
201         }
202     }
203 
204     GKI_remove_from_timer_list (&nfc_cb.quick_timer_queue, p_tle);
205 
206     p_tle->event = type;
207     p_tle->ticks = timeout; /* Save the number of ticks for the timer */
208 
209     GKI_add_to_timer_list (&nfc_cb.quick_timer_queue, p_tle);
210 }
211 
212 
213 
214 
215 /*******************************************************************************
216 **
217 ** Function         nfc_stop_quick_timer
218 **
219 ** Description      Stop a timer.
220 **
221 ** Returns          void
222 **
223 *******************************************************************************/
nfc_stop_quick_timer(TIMER_LIST_ENT * p_tle)224 void nfc_stop_quick_timer (TIMER_LIST_ENT *p_tle)
225 {
226     GKI_remove_from_timer_list (&nfc_cb.quick_timer_queue, p_tle);
227 
228     /* if timer list is empty stop periodic GKI timer */
229     if (nfc_cb.quick_timer_queue.p_first == NULL)
230     {
231         GKI_stop_timer (NFC_QUICK_TIMER_ID);
232     }
233 }
234 
235 /*******************************************************************************
236 **
237 ** Function         nfc_process_quick_timer_evt
238 **
239 ** Description      Process quick timer event
240 **
241 ** Returns          void
242 **
243 *******************************************************************************/
nfc_process_quick_timer_evt(void)244 void nfc_process_quick_timer_evt (void)
245 {
246     TIMER_LIST_ENT  *p_tle;
247 
248     GKI_update_timer_list (&nfc_cb.quick_timer_queue, 1);
249 
250     while ((nfc_cb.quick_timer_queue.p_first) && (!nfc_cb.quick_timer_queue.p_first->ticks))
251     {
252         p_tle = nfc_cb.quick_timer_queue.p_first;
253         GKI_remove_from_timer_list (&nfc_cb.quick_timer_queue, p_tle);
254 
255         switch (p_tle->event)
256         {
257 #if (NFC_RW_ONLY == FALSE)
258         case NFC_TTYPE_LLCP_LINK_MANAGER:
259         case NFC_TTYPE_LLCP_LINK_INACT:
260         case NFC_TTYPE_LLCP_DATA_LINK:
261         case NFC_TTYPE_LLCP_DELAY_FIRST_PDU:
262             llcp_process_timeout (p_tle);
263             break;
264 #endif
265         case NFC_TTYPE_RW_T1T_RESPONSE:
266             rw_t1t_process_timeout (p_tle);
267             break;
268         case NFC_TTYPE_RW_T2T_RESPONSE:
269             rw_t2t_process_timeout (p_tle);
270             break;
271         case NFC_TTYPE_RW_T3T_RESPONSE:
272             rw_t3t_process_timeout (p_tle);
273             break;
274         case NFC_TTYPE_RW_T4T_RESPONSE:
275             rw_t4t_process_timeout (p_tle);
276             break;
277         case NFC_TTYPE_RW_I93_RESPONSE:
278             rw_i93_process_timeout (p_tle);
279             break;
280 #if (NFC_RW_ONLY == FALSE)
281         case NFC_TTYPE_CE_T4T_UPDATE:
282             ce_t4t_process_timeout (p_tle);
283             break;
284 #endif
285         default:
286             break;
287         }
288     }
289 
290     /* if timer list is empty stop periodic GKI timer */
291     if (nfc_cb.quick_timer_queue.p_first == NULL)
292     {
293         GKI_stop_timer (NFC_QUICK_TIMER_ID);
294     }
295 }
296 
297 /*******************************************************************************
298 **
299 ** Function         nfc_task_shutdown_nfcc
300 **
301 ** Description      Handle NFC shutdown
302 **
303 ** Returns          nothing
304 **
305 *******************************************************************************/
nfc_task_shutdown_nfcc(void)306 void nfc_task_shutdown_nfcc (void)
307 {
308     BT_HDR        *p_msg;
309 
310     /* Free any messages still in the mbox */
311     while ((p_msg = (BT_HDR *) GKI_read_mbox (NFC_MBOX_ID)) != NULL)
312     {
313         GKI_freebuf (p_msg);
314     }
315 
316     nfc_gen_cleanup ();
317 
318     if (nfc_cb.flags & NFC_FL_POWER_OFF_SLEEP)
319     {
320         nfc_set_state (NFC_STATE_W4_HAL_CLOSE);
321         nfc_cb.p_hal->close();
322     }
323     else if (nfc_cb.flags & NFC_FL_POWER_CYCLE_NFCC)
324     {
325         nfc_set_state (NFC_STATE_W4_HAL_OPEN);
326         nfc_cb.p_hal->power_cycle();
327     }
328     else
329     {
330         nfc_set_state (NFC_STATE_W4_HAL_CLOSE);
331         nfc_cb.p_hal->close();
332 
333         /* Perform final clean up */
334         llcp_cleanup ();
335 
336         /* Stop the timers */
337         GKI_stop_timer (NFC_TIMER_ID);
338         GKI_stop_timer (NFC_QUICK_TIMER_ID);
339 #if (defined (NFA_INCLUDED) && NFA_INCLUDED == TRUE)
340         GKI_stop_timer (NFA_TIMER_ID);
341 #endif
342     }
343 }
344 
345 /*******************************************************************************
346 **
347 ** Function         nfc_task
348 **
349 ** Description      NFC event processing task
350 **
351 ** Returns          nothing
352 **
353 *******************************************************************************/
nfc_task(UINT32 param)354 UINT32 nfc_task (UINT32 param)
355 {
356     UINT16  event;
357     BT_HDR  *p_msg;
358     BOOLEAN free_buf;
359 
360     /* Initialize the nfc control block */
361     memset (&nfc_cb, 0, sizeof (tNFC_CB));
362     nfc_cb.trace_level = NFC_INITIAL_TRACE_LEVEL;
363 
364     NFC_TRACE_DEBUG0 ("NFC_TASK started.");
365 
366     /* main loop */
367     while (TRUE)
368     {
369         event = GKI_wait (0xFFFF, 0);
370 
371         /* Handle NFC_TASK_EVT_TRANSPORT_READY from NFC HAL */
372         if (event & NFC_TASK_EVT_TRANSPORT_READY)
373         {
374             NFC_TRACE_DEBUG0 ("NFC_TASK got NFC_TASK_EVT_TRANSPORT_READY.");
375 
376             /* Reset the NFC controller. */
377             nfc_set_state (NFC_STATE_CORE_INIT);
378             nci_snd_core_reset (NCI_RESET_TYPE_RESET_CFG);
379         }
380 
381         if (event & NFC_MBOX_EVT_MASK)
382         {
383             /* Process all incoming NCI messages */
384             while ((p_msg = (BT_HDR *) GKI_read_mbox (NFC_MBOX_ID)) != NULL)
385             {
386                 free_buf = TRUE;
387 
388                 /* Determine the input message type. */
389                 switch (p_msg->event & BT_EVT_MASK)
390                 {
391                     case BT_EVT_TO_NFC_NCI:
392                         free_buf = nfc_ncif_process_event (p_msg);
393                         break;
394 
395                     case BT_EVT_TO_START_TIMER :
396                         /* Start nfc_task 1-sec resolution timer */
397                         GKI_start_timer (NFC_TIMER_ID, GKI_SECS_TO_TICKS (1), TRUE);
398                         break;
399 
400                     case BT_EVT_TO_START_QUICK_TIMER :
401                         /* Quick-timer is required for LLCP */
402                         GKI_start_timer (NFC_QUICK_TIMER_ID, ((GKI_SECS_TO_TICKS (1) / QUICK_TIMER_TICKS_PER_SEC)), TRUE);
403                         break;
404 
405                     case BT_EVT_TO_NFC_MSGS:
406                         nfc_main_handle_hal_evt ((tNFC_HAL_EVT_MSG*)p_msg);
407                         break;
408 
409                     default:
410                         NFC_TRACE_DEBUG1 ("nfc_task: unhandle mbox message, event=%04x", p_msg->event);
411                         break;
412                 }
413 
414                 if (free_buf)
415                 {
416                     GKI_freebuf (p_msg);
417                 }
418             }
419         }
420 
421         /* Process gki timer tick */
422         if (event & NFC_TIMER_EVT_MASK)
423         {
424             nfc_process_timer_evt ();
425         }
426 
427         /* Process quick timer tick */
428         if (event & NFC_QUICK_TIMER_EVT_MASK)
429         {
430             nfc_process_quick_timer_evt ();
431         }
432 
433 #if (defined (NFA_INCLUDED) && NFA_INCLUDED == TRUE)
434         if (event & NFA_MBOX_EVT_MASK)
435         {
436             while ((p_msg = (BT_HDR *) GKI_read_mbox (NFA_MBOX_ID)) != NULL)
437             {
438                 nfa_sys_event (p_msg);
439             }
440         }
441 
442         if (event & NFA_TIMER_EVT_MASK)
443         {
444             nfa_sys_timer_update ();
445         }
446 #endif
447 
448     }
449 
450 
451     NFC_TRACE_DEBUG0 ("nfc_task terminated");
452 
453     GKI_exit_task (GKI_get_taskid ());
454     return 0;
455 }
456 
457 #endif /* NFC_INCLUDED == TRUE */
458