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 *******************************************************************************/ 58 void 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 *******************************************************************************/ 99 UINT32 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 *******************************************************************************/ 113 void 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 *******************************************************************************/ 156 void 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 *******************************************************************************/ 180 void 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 *******************************************************************************/ 224 void 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 *******************************************************************************/ 244 void 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 *******************************************************************************/ 306 void 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 *******************************************************************************/ 354 UINT32 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