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