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