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