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