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