xref: /aosp_15_r20/system/nfc/src/nfc/nfc/nfc_task.cc (revision 7eba2f3b06c51ae21384f6a4f14577b668a869b3)
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