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 case NFC_TTYPE_RW_CI_RESPONSE:
258 rw_ci_process_timeout(p_tle);
259 break;
260 #if (NFC_RW_ONLY == FALSE)
261 case NFC_TTYPE_CE_T4T_UPDATE:
262 ce_t4t_process_timeout(p_tle);
263 break;
264 #endif
265 default:
266 LOG(VERBOSE) << StringPrintf(
267 "nfc_process_quick_timer_evt: unhandled timer event (0x%04x)",
268 p_tle->event);
269 break;
270 }
271 }
272
273 /* if timer list is empty stop periodic GKI timer */
274 if (GKI_timer_list_empty(&nfc_cb.quick_timer_queue)) {
275 GKI_stop_timer(NFC_QUICK_TIMER_ID);
276 }
277 }
278
279 /*******************************************************************************
280 **
281 ** Function nfc_task_shutdown_nfcc
282 **
283 ** Description Handle NFC shutdown
284 **
285 ** Returns nothing
286 **
287 *******************************************************************************/
nfc_task_shutdown_nfcc(void)288 void nfc_task_shutdown_nfcc(void) {
289 NFC_HDR* p_msg;
290
291 /* Free any messages still in the mbox */
292 while ((p_msg = (NFC_HDR*)GKI_read_mbox(NFC_MBOX_ID)) != nullptr) {
293 GKI_freebuf(p_msg);
294 }
295
296 nfc_gen_cleanup();
297
298 if (nfc_cb.flags & NFC_FL_POWER_OFF_SLEEP) {
299 nfc_set_state(NFC_STATE_W4_HAL_CLOSE);
300 nfc_cb.p_hal->close();
301 } else if (nfc_cb.flags & NFC_FL_POWER_CYCLE_NFCC) {
302 nfc_set_state(NFC_STATE_W4_HAL_OPEN);
303 nfc_cb.p_hal->power_cycle();
304 } else {
305 nfc_set_state(NFC_STATE_W4_HAL_CLOSE);
306 nfc_cb.p_hal->close();
307
308 /* Perform final clean up */
309
310 /* Stop the timers */
311 GKI_stop_timer(NFC_TIMER_ID);
312 GKI_stop_timer(NFC_QUICK_TIMER_ID);
313 GKI_stop_timer(NFA_TIMER_ID);
314 }
315 }
316
317 /*******************************************************************************
318 **
319 ** Function nfc_task
320 **
321 ** Description NFC event processing task
322 **
323 ** Returns nothing
324 **
325 *******************************************************************************/
nfc_task(uint32_t arg)326 uint32_t nfc_task(__attribute__((unused)) uint32_t arg) {
327 uint16_t event;
328 NFC_HDR* p_msg;
329 bool free_buf;
330
331 /* Initialize the nfc control block */
332 memset(&nfc_cb, 0, sizeof(tNFC_CB));
333
334 LOG(VERBOSE) << StringPrintf("NFC_TASK started.");
335
336 /* main loop */
337 while (true) {
338 event = GKI_wait(0xFFFF, 0);
339 if (event & EVENT_MASK(GKI_SHUTDOWN_EVT)) {
340 break;
341 }
342 /* Handle NFC_TASK_EVT_TRANSPORT_READY from NFC HAL */
343 if (event & NFC_TASK_EVT_TRANSPORT_READY) {
344 LOG(VERBOSE) << StringPrintf("NFC_TASK got NFC_TASK_EVT_TRANSPORT_READY.");
345
346 /* Reset the NFC controller. */
347 nfc_set_state(NFC_STATE_CORE_INIT);
348
349 /* Reset NCI configurations base on NAME_NCI_RESET_TYPE setting */
350 if (nfc_nci_reset_type == 0x02 || nfc_nci_reset_keep_cfg_enabled) {
351 /* 0x02, keep configurations. */
352 nci_snd_core_reset(NCI_RESET_TYPE_KEEP_CFG);
353 nfc_nci_reset_keep_cfg_enabled = true;
354 } else if (nfc_nci_reset_type == 0x01 &&
355 !nfc_nci_reset_keep_cfg_enabled) {
356 /* 0x01, reset configurations only once every boot. */
357
358 nci_snd_core_reset(NCI_RESET_TYPE_RESET_CFG);
359
360 nfc_nci_reset_keep_cfg_enabled = true;
361 } else {
362 /* Default, reset configurations every time*/
363 nci_snd_core_reset(NCI_RESET_TYPE_RESET_CFG);
364 nfc_nci_reset_keep_cfg_enabled = false;
365 }
366 }
367
368 if (event & NFC_MBOX_EVT_MASK) {
369 /* Process all incoming NCI messages */
370 while ((p_msg = (NFC_HDR*)GKI_read_mbox(NFC_MBOX_ID)) != nullptr) {
371 free_buf = true;
372
373 /* Determine the input message type. */
374 switch (p_msg->event & NFC_EVT_MASK) {
375 case BT_EVT_TO_NFC_NCI:
376 free_buf = nfc_ncif_process_event(p_msg);
377 break;
378
379 case BT_EVT_TO_START_TIMER:
380 /* Start nfc_task 1-sec resolution timer */
381 GKI_start_timer(NFC_TIMER_ID, GKI_SECS_TO_TICKS(1), true);
382 break;
383
384 case BT_EVT_TO_START_QUICK_TIMER:
385 /* Quick-timer is required for LLCP */
386 GKI_start_timer(
387 NFC_QUICK_TIMER_ID,
388 ((GKI_SECS_TO_TICKS(1) / QUICK_TIMER_TICKS_PER_SEC)), true);
389 break;
390
391 case BT_EVT_TO_NFC_MSGS:
392 nfc_main_handle_hal_evt((tNFC_HAL_EVT_MSG*)p_msg);
393 break;
394
395 default:
396 LOG(VERBOSE) << StringPrintf(
397 "nfc_task: unhandle mbox message, event=%04x", p_msg->event);
398 break;
399 }
400
401 if (free_buf) {
402 GKI_freebuf(p_msg);
403 }
404 }
405 }
406
407 /* Process gki timer tick */
408 if (event & NFC_TIMER_EVT_MASK) {
409 nfc_process_timer_evt();
410 }
411
412 /* Process quick timer tick */
413 if (event & NFC_QUICK_TIMER_EVT_MASK) {
414 nfc_process_quick_timer_evt();
415 }
416
417 if (event & NFA_MBOX_EVT_MASK) {
418 while ((p_msg = (NFC_HDR*)GKI_read_mbox(NFA_MBOX_ID)) != nullptr) {
419 nfa_sys_event(p_msg);
420 }
421 }
422
423 if (event & NFA_TIMER_EVT_MASK) {
424 nfa_sys_timer_update();
425 }
426 }
427
428 LOG(VERBOSE) << StringPrintf("nfc_task terminated");
429
430 GKI_exit_task(GKI_get_taskid());
431 return 0;
432 }
433