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