• 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 <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