Home | History | Annotate | Download | only in nfc
      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