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