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