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