Home | History | Annotate | Download | only in sys
      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  *  This is the main implementation file for the NFA system manager.
     22  *
     23  ******************************************************************************/
     24 #include <string.h>
     25 #include "nfa_api.h"
     26 #include "nfa_dm_int.h"
     27 #include "nfa_sys.h"
     28 #include "nfa_sys_int.h"
     29 #include "nfa_sys_ptim.h"
     30 
     31 /* protocol timer update period, in milliseconds */
     32 #ifndef NFA_SYS_TIMER_PERIOD
     33 #define NFA_SYS_TIMER_PERIOD 10
     34 #endif
     35 
     36 /* system manager control block definition */
     37 tNFA_SYS_CB nfa_sys_cb = {
     38     0,
     39 }; /* nfa_sys control block. statically initialize 'flags' field to 0 */
     40 
     41 /*******************************************************************************
     42 **
     43 ** Function         nfa_sys_init
     44 **
     45 ** Description      NFA initialization; called from task initialization.
     46 **
     47 **
     48 ** Returns          void
     49 **
     50 *******************************************************************************/
     51 void nfa_sys_init(void) {
     52   memset(&nfa_sys_cb, 0, sizeof(tNFA_SYS_CB));
     53   nfa_sys_cb.flags |= NFA_SYS_FL_INITIALIZED;
     54   nfa_sys_ptim_init(&nfa_sys_cb.ptim_cb, NFA_SYS_TIMER_PERIOD,
     55                     p_nfa_sys_cfg->timer);
     56   nfa_sys_cb.trace_level = p_nfa_sys_cfg->trace_level;
     57 }
     58 
     59 /*******************************************************************************
     60 **
     61 ** Function         nfa_sys_event
     62 **
     63 ** Description      BTA event handler; called from task event handler.
     64 **
     65 **
     66 ** Returns          void
     67 **
     68 *******************************************************************************/
     69 void nfa_sys_event(NFC_HDR* p_msg) {
     70   uint8_t id;
     71   bool freebuf = true;
     72 
     73   NFA_TRACE_EVENT1("NFA got event 0x%04X", p_msg->event);
     74 
     75   /* get subsystem id from event */
     76   id = (uint8_t)(p_msg->event >> 8);
     77 
     78   /* verify id and call subsystem event handler */
     79   if ((id < NFA_ID_MAX) && (nfa_sys_cb.is_reg[id])) {
     80     freebuf = (*nfa_sys_cb.reg[id]->evt_hdlr)(p_msg);
     81   } else {
     82     NFA_TRACE_WARNING1("NFA got unregistered event id %d", id);
     83   }
     84 
     85   if (freebuf) {
     86     GKI_freebuf(p_msg);
     87   }
     88 }
     89 
     90 /*******************************************************************************
     91 **
     92 ** Function         nfa_sys_timer_update
     93 **
     94 ** Description      Update the BTA timer list and handle expired timers.
     95 **
     96 ** Returns          void
     97 **
     98 *******************************************************************************/
     99 void nfa_sys_timer_update(void) {
    100   if (!nfa_sys_cb.timers_disabled) {
    101     nfa_sys_ptim_timer_update(&nfa_sys_cb.ptim_cb);
    102   }
    103 }
    104 
    105 /*******************************************************************************
    106 **
    107 ** Function         nfa_sys_register
    108 **
    109 ** Description      Called by other BTA subsystems to register their event
    110 **                  handler.
    111 **
    112 **
    113 ** Returns          void
    114 **
    115 *******************************************************************************/
    116 void nfa_sys_register(uint8_t id, const tNFA_SYS_REG* p_reg) {
    117   nfa_sys_cb.reg[id] = (tNFA_SYS_REG*)p_reg;
    118   nfa_sys_cb.is_reg[id] = true;
    119 
    120   if ((id != NFA_ID_DM) && (id != NFA_ID_SYS))
    121     nfa_sys_cb.enable_cplt_mask |= (0x0001 << id);
    122 
    123   if (id != NFA_ID_SYS) {
    124     if (p_reg->proc_nfcc_pwr_mode)
    125       nfa_sys_cb.proc_nfcc_pwr_mode_cplt_mask |= (0x0001 << id);
    126   }
    127 
    128   NFA_TRACE_DEBUG2("nfa_sys_register () id=%i, enable_cplt_mask=0x%x", id,
    129                    nfa_sys_cb.enable_cplt_mask);
    130 }
    131 
    132 /*******************************************************************************
    133 **
    134 ** Function         nfa_sys_check_disabled
    135 **
    136 ** Description      If all subsystems above DM have been disabled, then
    137 **                  disable DM. Called during NFA shutdown
    138 **
    139 ** Returns          void
    140 **
    141 *******************************************************************************/
    142 void nfa_sys_check_disabled(void) {
    143   uint8_t id;
    144   uint8_t done = true;
    145 
    146   /* Check if all subsystems above DM have been disabled. */
    147   for (id = (NFA_ID_DM + 1); id < NFA_ID_MAX; id++) {
    148     if (nfa_sys_cb.is_reg[id]) {
    149       /* as long as one subsystem is not done */
    150       done = false;
    151       break;
    152     }
    153   }
    154 
    155   /* All subsystems disabled. disable DM */
    156   if ((done) && (nfa_sys_cb.is_reg[NFA_ID_DM])) {
    157     (*nfa_sys_cb.reg[NFA_ID_DM]->disable)();
    158   }
    159 }
    160 
    161 /*******************************************************************************
    162 **
    163 ** Function         nfa_sys_deregister
    164 **
    165 ** Description      Called by other BTA subsystems to de-register
    166 **                  handler.
    167 **
    168 **
    169 ** Returns          void
    170 **
    171 *******************************************************************************/
    172 void nfa_sys_deregister(uint8_t id) {
    173   NFA_TRACE_DEBUG1("nfa_sys: deregistering subsystem %i", id);
    174 
    175   nfa_sys_cb.is_reg[id] = false;
    176 
    177   /* If not deregistering DM, then check if any other subsystems above DM are
    178    * still  */
    179   /* registered. */
    180   if (id != NFA_ID_DM) {
    181     /* If all subsystems above NFA_DM have been disabled, then okay to disable
    182      * DM */
    183     nfa_sys_check_disabled();
    184   } else {
    185     /* DM (the final sub-system) is deregistering. Clear pending timer events in
    186      * nfa_sys. */
    187     nfa_sys_ptim_init(&nfa_sys_cb.ptim_cb, NFA_SYS_TIMER_PERIOD,
    188                       p_nfa_sys_cfg->timer);
    189   }
    190 }
    191 
    192 /*******************************************************************************
    193 **
    194 ** Function         nfa_sys_is_register
    195 **
    196 ** Description      Called by other BTA subsystems to get registeration
    197 **                  status.
    198 **
    199 **
    200 ** Returns          void
    201 **
    202 *******************************************************************************/
    203 bool nfa_sys_is_register(uint8_t id) { return nfa_sys_cb.is_reg[id]; }
    204 
    205 /*******************************************************************************
    206 **
    207 ** Function         nfa_sys_is_graceful_disable
    208 **
    209 ** Description      Called by other BTA subsystems to get disable
    210 **                  parameter.
    211 **
    212 **
    213 ** Returns          void
    214 **
    215 *******************************************************************************/
    216 bool nfa_sys_is_graceful_disable(void) { return nfa_sys_cb.graceful_disable; }
    217 
    218 /*******************************************************************************
    219 **
    220 ** Function         nfa_sys_enable_subsystems
    221 **
    222 ** Description      Call on NFA Start up
    223 **
    224 ** Returns          void
    225 **
    226 *******************************************************************************/
    227 void nfa_sys_enable_subsystems(void) {
    228   uint8_t id;
    229 
    230   NFA_TRACE_DEBUG0("nfa_sys: enabling subsystems");
    231 
    232   /* Enable all subsystems except SYS */
    233   for (id = NFA_ID_DM; id < NFA_ID_MAX; id++) {
    234     if (nfa_sys_cb.is_reg[id]) {
    235       if (nfa_sys_cb.reg[id]->enable != NULL) {
    236         /* Subsytem has a Disable funciton. Call it now */
    237         (*nfa_sys_cb.reg[id]->enable)();
    238       } else {
    239         /* Subsytem does not have a Enable function. Report Enable on behalf of
    240          * subsystem */
    241         nfa_sys_cback_notify_enable_complete(id);
    242       }
    243     }
    244   }
    245 }
    246 
    247 /*******************************************************************************
    248 **
    249 ** Function         nfa_sys_disable_subsystems
    250 **
    251 ** Description      Call on NFA shutdown. Disable all subsystems above NFA_DM
    252 **
    253 ** Returns          void
    254 **
    255 *******************************************************************************/
    256 void nfa_sys_disable_subsystems(bool graceful) {
    257   uint8_t id;
    258   bool done = true;
    259 
    260   NFA_TRACE_DEBUG1("nfa_sys: disabling subsystems:%d", graceful);
    261   nfa_sys_cb.graceful_disable = graceful;
    262 
    263   /* Disable all subsystems above NFA_DM. (NFA_DM and NFA_SYS will be disabled
    264    * last) */
    265   for (id = (NFA_ID_DM + 1); id < NFA_ID_MAX; id++) {
    266     if (nfa_sys_cb.is_reg[id]) {
    267       done = false;
    268       if (nfa_sys_cb.reg[id]->disable != NULL) {
    269         /* Subsytem has a Disable funciton. Call it now */
    270         (*nfa_sys_cb.reg[id]->disable)();
    271       } else {
    272         /* Subsytem does not have a Disable function. Deregister on behalf of
    273          * subsystem */
    274         nfa_sys_deregister(id);
    275       }
    276     }
    277   }
    278 
    279   /* If All subsystems disabled. disable DM */
    280   if ((done) && (nfa_sys_cb.is_reg[NFA_ID_DM])) {
    281     (*nfa_sys_cb.reg[NFA_ID_DM]->disable)();
    282   }
    283 }
    284 
    285 /*******************************************************************************
    286 **
    287 ** Function         nfa_sys_notify_nfcc_power_mode
    288 **
    289 ** Description      Call to notify NFCC power mode to NFA sub-modules
    290 **
    291 ** Returns          void
    292 **
    293 *******************************************************************************/
    294 void nfa_sys_notify_nfcc_power_mode(uint8_t nfcc_power_mode) {
    295   uint8_t id;
    296 
    297   NFA_TRACE_DEBUG1("nfa_sys: notify NFCC power mode(%d) to subsystems",
    298                    nfcc_power_mode);
    299 
    300   /* Notify NFCC power state to all subsystems except NFA_SYS */
    301   for (id = NFA_ID_DM; id < NFA_ID_MAX; id++) {
    302     if ((nfa_sys_cb.is_reg[id]) && (nfa_sys_cb.reg[id]->proc_nfcc_pwr_mode)) {
    303       /* Subsytem has a funciton for processing NFCC power mode. Call it now */
    304       (*nfa_sys_cb.reg[id]->proc_nfcc_pwr_mode)(nfcc_power_mode);
    305     }
    306   }
    307 }
    308 
    309 /*******************************************************************************
    310 **
    311 ** Function         nfa_sys_sendmsg
    312 **
    313 ** Description      Send a GKI message to BTA.  This function is designed to
    314 **                  optimize sending of messages to BTA.  It is called by BTA
    315 **                  API functions and call-in functions.
    316 **
    317 **
    318 ** Returns          void
    319 **
    320 *******************************************************************************/
    321 void nfa_sys_sendmsg(void* p_msg) {
    322   GKI_send_msg(NFC_TASK, p_nfa_sys_cfg->mbox, p_msg);
    323 }
    324 
    325 /*******************************************************************************
    326 **
    327 ** Function         nfa_sys_start_timer
    328 **
    329 ** Description      Start a protocol timer for the specified amount
    330 **                  of time in milliseconds.
    331 **
    332 ** Returns          void
    333 **
    334 *******************************************************************************/
    335 void nfa_sys_start_timer(TIMER_LIST_ENT* p_tle, uint16_t type,
    336                          int32_t timeout) {
    337   nfa_sys_ptim_start_timer(&nfa_sys_cb.ptim_cb, p_tle, type, timeout);
    338 }
    339 
    340 /*******************************************************************************
    341 **
    342 ** Function         nfa_sys_stop_timer
    343 **
    344 ** Description      Stop a BTA timer.
    345 **
    346 ** Returns          void
    347 **
    348 *******************************************************************************/
    349 void nfa_sys_stop_timer(TIMER_LIST_ENT* p_tle) {
    350   nfa_sys_ptim_stop_timer(&nfa_sys_cb.ptim_cb, p_tle);
    351 }
    352 
    353 /*******************************************************************************
    354 **
    355 ** Function         nfa_sys_disable_timers
    356 **
    357 ** Description      Disable sys timer event handling
    358 **
    359 ** Returns          void
    360 **
    361 *******************************************************************************/
    362 void nfa_sys_disable_timers(void) { nfa_sys_cb.timers_disabled = true; }
    363 
    364 /*******************************************************************************
    365 **
    366 ** Function         nfa_sys_set_trace_level
    367 **
    368 ** Description      Set trace level for BTA
    369 **
    370 ** Returns          void
    371 **
    372 *******************************************************************************/
    373 void nfa_sys_set_trace_level(uint8_t level) { nfa_sys_cb.trace_level = level; }
    374