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