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