Home | History | Annotate | Download | only in dm
      1 /******************************************************************************
      2  *
      3  *
      4  *  Licensed under the Apache License, Version 2.0 (the "License");
      5  *  you may not use this file except in compliance with the License.
      6  *  You may obtain a copy of the License at:
      7  *
      8  *  http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  *  Unless required by applicable law or agreed to in writing, software
     11  *  distributed under the License is distributed on an "AS IS" BASIS,
     12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  *  See the License for the specific language governing permissions and
     14  *  limitations under the License.
     15  *
     16  ******************************************************************************/
     17 
     18 /******************************************************************************
     19  *
     20  *  This file contains the action functions for device manager discovery
     21  *  function.
     22  *
     23  ******************************************************************************/
     24 #include <string>
     25 
     26 #include <android-base/stringprintf.h>
     27 #include <base/logging.h>
     28 
     29 #include "nci_hmsgs.h"
     30 #include "nfa_api.h"
     31 #include "nfa_dm_int.h"
     32 #include "nfa_p2p_int.h"
     33 
     34 #if (NFC_NFCEE_INCLUDED == TRUE)
     35 #include "nfa_ee_api.h"
     36 #include "nfa_ee_int.h"
     37 #endif
     38 #include "nfa_rw_int.h"
     39 
     40 #include "nfc_int.h"
     41 
     42 using android::base::StringPrintf;
     43 
     44 extern bool nfc_debug_enabled;
     45 
     46 /*
     47 **  static functions
     48 */
     49 static uint8_t nfa_dm_get_rf_discover_config(
     50     tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
     51     tNFC_DISCOVER_PARAMS disc_params[], uint8_t max_params);
     52 static tNFA_STATUS nfa_dm_set_rf_listen_mode_config(
     53     tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask);
     54 static void nfa_dm_set_rf_listen_mode_raw_config(
     55     tNFA_DM_DISC_TECH_PROTO_MASK* p_disc_mask);
     56 static tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_disc_get_disc_mask(
     57     tNFC_RF_TECH_N_MODE tech_n_mode, tNFC_PROTOCOL protocol);
     58 static void nfa_dm_notify_discovery(tNFA_DM_RF_DISC_DATA* p_data);
     59 static tNFA_STATUS nfa_dm_disc_notify_activation(tNFC_DISCOVER* p_data);
     60 static void nfa_dm_disc_notify_deactivation(tNFA_DM_RF_DISC_SM_EVENT sm_event,
     61                                             tNFC_DISCOVER* p_data);
     62 static void nfa_dm_disc_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
     63                                    tNFC_CONN* p_data);
     64 static void nfa_dm_disc_kovio_timeout_cback(TIMER_LIST_ENT* p_tle);
     65 static void nfa_dm_disc_report_kovio_presence_check(tNFC_STATUS status);
     66 
     67 static std::string nfa_dm_disc_state_2_str(uint8_t state);
     68 static std::string nfa_dm_disc_event_2_str(uint8_t event);
     69 
     70 typedef struct nfa_dm_p2p_prio_logic {
     71   bool isodep_detected;      /* flag to check if ISO-DEP is detected */
     72   bool timer_expired;        /* flag to check whether timer is expired */
     73   TIMER_LIST_ENT timer_list; /*timer structure pointer */
     74   uint8_t first_tech_mode;
     75 } nfa_dm_p2p_prio_logic_t;
     76 
     77 static nfa_dm_p2p_prio_logic_t p2p_prio_logic_data;
     78 
     79 static void nfa_dm_send_tag_deselect_cmd(tNFA_NFC_PROTOCOL protocol);
     80 
     81 /*******************************************************************************
     82 **
     83 ** Function         nfa_dm_get_rf_discover_config
     84 **
     85 ** Description      Build RF discovery configurations from
     86 **                  tNFA_DM_DISC_TECH_PROTO_MASK
     87 **
     88 ** Returns          number of RF discovery configurations
     89 **
     90 *******************************************************************************/
     91 static uint8_t nfa_dm_get_rf_discover_config(
     92     tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask,
     93     tNFC_DISCOVER_PARAMS disc_params[], uint8_t max_params) {
     94   uint8_t num_params = 0;
     95 
     96   if (nfa_dm_cb.flags & NFA_DM_FLAGS_LISTEN_DISABLED) {
     97     DLOG_IF(INFO, nfc_debug_enabled)
     98         << StringPrintf("listen disabled, rm listen from 0x%x", dm_disc_mask);
     99     dm_disc_mask &= NFA_DM_DISC_MASK_POLL;
    100   }
    101   if (nfa_dm_is_p2p_paused()) {
    102     dm_disc_mask &= ~NFA_DM_DISC_MASK_NFC_DEP;
    103   }
    104 
    105   /* Check polling A */
    106   if (dm_disc_mask &
    107       (NFA_DM_DISC_MASK_PA_T1T | NFA_DM_DISC_MASK_PA_T2T |
    108        NFA_DM_DISC_MASK_PA_ISO_DEP | NFA_DM_DISC_MASK_PA_NFC_DEP |
    109        NFA_DM_DISC_MASK_P_LEGACY)) {
    110     disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_A;
    111     disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pa;
    112     num_params++;
    113 
    114     if (num_params >= max_params) return num_params;
    115   }
    116 
    117   /* Check polling B */
    118   if (dm_disc_mask & NFA_DM_DISC_MASK_PB_ISO_DEP) {
    119     disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_B;
    120     disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pb;
    121     num_params++;
    122 
    123     if (num_params >= max_params) return num_params;
    124   }
    125 
    126   /* Check polling F */
    127   if (dm_disc_mask & (NFA_DM_DISC_MASK_PF_T3T | NFA_DM_DISC_MASK_PF_NFC_DEP)) {
    128     disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_F;
    129     disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pf;
    130     num_params++;
    131 
    132     if (num_params >= max_params) return num_params;
    133   }
    134   if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
    135     /* Check polling Active mode  */
    136     if (dm_disc_mask & NFA_DM_DISC_MASK_PACM_NFC_DEP) {
    137       disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_ACTIVE;
    138       disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pacm;
    139       num_params++;
    140 
    141       if (num_params >= max_params) return num_params;
    142     }
    143   } else {
    144     /* Check polling A Active mode  */
    145     if (dm_disc_mask & NFA_DM_DISC_MASK_PAA_NFC_DEP) {
    146       disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_A_ACTIVE;
    147       disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->paa;
    148       num_params++;
    149 
    150       if (num_params >= max_params) return num_params;
    151     }
    152 
    153     /* Check polling F Active mode  */
    154     if (dm_disc_mask & NFA_DM_DISC_MASK_PFA_NFC_DEP) {
    155       disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_F_ACTIVE;
    156       disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pfa;
    157       num_params++;
    158 
    159       if (num_params >= max_params) return num_params;
    160     }
    161   }
    162   /* Check listening A */
    163   if (dm_disc_mask &
    164       (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T |
    165        NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP)) {
    166     disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_A;
    167     disc_params[num_params].frequency = 1;
    168     num_params++;
    169 
    170     if (num_params >= max_params) return num_params;
    171   }
    172 
    173   /* Check listening B */
    174   if (dm_disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP) {
    175     disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_B;
    176     disc_params[num_params].frequency = 1;
    177     num_params++;
    178 
    179     if (num_params >= max_params) return num_params;
    180   }
    181 
    182   /* Check listening F */
    183   if (dm_disc_mask & (NFA_DM_DISC_MASK_LF_T3T | NFA_DM_DISC_MASK_LF_NFC_DEP)) {
    184     disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_F;
    185     disc_params[num_params].frequency = 1;
    186     num_params++;
    187 
    188     if (num_params >= max_params) return num_params;
    189   }
    190   if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
    191     /* Check polling Active mode  */
    192     if (dm_disc_mask & NFA_DM_DISC_MASK_LACM_NFC_DEP) {
    193       disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_ACTIVE;
    194       disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pacm;
    195       num_params++;
    196       if (num_params >= max_params) return num_params;
    197     }
    198   } else {
    199     /* Check listening A Active mode */
    200     if (dm_disc_mask & NFA_DM_DISC_MASK_LAA_NFC_DEP) {
    201       disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE;
    202       disc_params[num_params].frequency = 1;
    203       num_params++;
    204 
    205       if (num_params >= max_params) return num_params;
    206     }
    207 
    208     /* Check listening F Active mode */
    209     if (dm_disc_mask & NFA_DM_DISC_MASK_LFA_NFC_DEP) {
    210       disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE;
    211       disc_params[num_params].frequency = 1;
    212       num_params++;
    213 
    214       if (num_params >= max_params) return num_params;
    215     }
    216   }
    217 
    218   /* Check polling ISO 15693 */
    219   if (dm_disc_mask & NFA_DM_DISC_MASK_P_T5T) {
    220     disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_V;
    221     disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pi93;
    222     num_params++;
    223 
    224     if (num_params >= max_params) return num_params;
    225   }
    226 
    227   /* Check polling B' */
    228   if (dm_disc_mask & NFA_DM_DISC_MASK_P_B_PRIME) {
    229     disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_B_PRIME;
    230     disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pbp;
    231     num_params++;
    232 
    233     if (num_params >= max_params) return num_params;
    234   }
    235 
    236   /* Check polling KOVIO */
    237   if (dm_disc_mask & NFA_DM_DISC_MASK_P_KOVIO) {
    238     disc_params[num_params].type = NFC_DISCOVERY_TYPE_POLL_KOVIO;
    239     disc_params[num_params].frequency = p_nfa_dm_rf_disc_freq_cfg->pk;
    240     num_params++;
    241 
    242     if (num_params >= max_params) return num_params;
    243   }
    244 
    245   /* Check listening ISO 15693 */
    246   if (dm_disc_mask & NFA_DM_DISC_MASK_L_ISO15693) {
    247     disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_ISO15693;
    248     disc_params[num_params].frequency = 1;
    249     num_params++;
    250 
    251     if (num_params >= max_params) return num_params;
    252   }
    253 
    254   /* Check listening B' */
    255   if (dm_disc_mask & NFA_DM_DISC_MASK_L_B_PRIME) {
    256     disc_params[num_params].type = NFC_DISCOVERY_TYPE_LISTEN_B_PRIME;
    257     disc_params[num_params].frequency = 1;
    258     num_params++;
    259 
    260     if (num_params >= max_params) return num_params;
    261   }
    262 
    263   return num_params;
    264 }
    265 
    266 /*******************************************************************************
    267 **
    268 ** Function         nfa_dm_set_rf_listen_mode_config
    269 **
    270 ** Description      Update listening protocol to NFCC
    271 **
    272 ** Returns          NFA_STATUS_OK if success
    273 **
    274 *******************************************************************************/
    275 static tNFA_STATUS nfa_dm_set_rf_listen_mode_config(
    276     tNFA_DM_DISC_TECH_PROTO_MASK tech_proto_mask) {
    277   uint8_t params[40], *p;
    278   uint8_t platform = 0;
    279   uint8_t sens_info = 0;
    280 
    281   DLOG_IF(INFO, nfc_debug_enabled)
    282       << StringPrintf("tech_proto_mask = 0x%08X", tech_proto_mask);
    283 
    284   /*
    285   ** T1T listen     LA_PROT 0x80, LA_SENS_RES byte1:0x00 byte2:0x0C
    286   ** T2T listen     LA_PROT 0x00
    287   ** T3T listen     No bit for T3T in LF_PROT (CE T3T set listen parameters,
    288   **                system code, NFCID2, etc.)
    289   ** ISO-DEP listen LA_PROT 0x01, LB_PROT 0x01
    290   ** NFC-DEP listen LA_PROT 0x02, LF_PROT 0x02
    291   */
    292 
    293   if (tech_proto_mask & NFA_DM_DISC_MASK_LA_T1T) {
    294     platform = NCI_PARAM_PLATFORM_T1T;
    295   } else if (tech_proto_mask & NFA_DM_DISC_MASK_LA_T2T) {
    296     /* platform = 0 and sens_info = 0 */
    297   } else {
    298     if (tech_proto_mask & NFA_DM_DISC_MASK_LA_ISO_DEP) {
    299       sens_info |= NCI_PARAM_SEL_INFO_ISODEP;
    300     }
    301 
    302     if (tech_proto_mask & NFA_DM_DISC_MASK_LA_NFC_DEP) {
    303       sens_info |= NCI_PARAM_SEL_INFO_NFCDEP;
    304     }
    305   }
    306 
    307   p = params;
    308 
    309   /*
    310   ** for Listen A
    311   **
    312   ** Set ATQA 0x0C00 for T1T listen
    313   ** If the ATQA values are 0x0000, then the FW will use 0x0400
    314   ** which works for ISODEP, T2T and NFCDEP.
    315   */
    316   if (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A] ==
    317       NFA_DM_DISC_HOST_ID_DH) {
    318     UINT8_TO_STREAM(p, NFC_PMID_LA_BIT_FRAME_SDD);
    319     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_BIT_FRAME_SDD);
    320     UINT8_TO_STREAM(p, 0x04);
    321     UINT8_TO_STREAM(p, NFC_PMID_LA_PLATFORM_CONFIG);
    322     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_PLATFORM_CONFIG);
    323     UINT8_TO_STREAM(p, platform);
    324     UINT8_TO_STREAM(p, NFC_PMID_LA_SEL_INFO);
    325     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_SEL_INFO);
    326     UINT8_TO_STREAM(p, sens_info);
    327   } else /* Let NFCC use UICC configuration by configuring with length = 0 */
    328   {
    329     UINT8_TO_STREAM(p, NFC_PMID_LA_BIT_FRAME_SDD);
    330     UINT8_TO_STREAM(p, 0);
    331     UINT8_TO_STREAM(p, NFC_PMID_LA_PLATFORM_CONFIG);
    332     UINT8_TO_STREAM(p, 0);
    333     UINT8_TO_STREAM(p, NFC_PMID_LA_SEL_INFO);
    334     UINT8_TO_STREAM(p, 0);
    335     UINT8_TO_STREAM(p, NFC_PMID_LA_NFCID1);
    336     UINT8_TO_STREAM(p, 0);
    337     UINT8_TO_STREAM(p, NFC_PMID_LA_HIST_BY);
    338     UINT8_TO_STREAM(p, 0);
    339   }
    340 
    341   /* for Listen B */
    342   if (nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B] ==
    343       NFA_DM_DISC_HOST_ID_DH) {
    344     UINT8_TO_STREAM(p, NFC_PMID_LB_SENSB_INFO);
    345     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_SENSB_INFO);
    346     if (tech_proto_mask & NFA_DM_DISC_MASK_LB_ISO_DEP) {
    347       UINT8_TO_STREAM(p, NCI_LISTEN_PROTOCOL_ISO_DEP);
    348     } else {
    349       UINT8_TO_STREAM(p, 0x00);
    350     }
    351   } else /* Let NFCC use UICC configuration by configuring with length = 0 */
    352   {
    353     UINT8_TO_STREAM(p, NFC_PMID_LB_SENSB_INFO);
    354     UINT8_TO_STREAM(p, 0);
    355     UINT8_TO_STREAM(p, NFC_PMID_LB_NFCID0);
    356     UINT8_TO_STREAM(p, 0);
    357     UINT8_TO_STREAM(p, NFC_PMID_LB_APPDATA);
    358     UINT8_TO_STREAM(p, 0);
    359     UINT8_TO_STREAM(p, NFC_PMID_LB_ADC_FO);
    360     UINT8_TO_STREAM(p, 0);
    361     UINT8_TO_STREAM(p, NFC_PMID_LB_H_INFO);
    362     UINT8_TO_STREAM(p, 0);
    363   }
    364 
    365   /* for Listen F */
    366   /* NFCC can support NFC-DEP and T3T listening based on NFCID routing
    367    * regardless of NFC-F tech routing */
    368   UINT8_TO_STREAM(p, NFC_PMID_LF_PROTOCOL);
    369   UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_PROTOCOL);
    370   if ((tech_proto_mask & NFA_DM_DISC_MASK_LF_NFC_DEP) &&
    371       !nfa_dm_is_p2p_paused()) {
    372     UINT8_TO_STREAM(p, NCI_LISTEN_PROTOCOL_NFC_DEP);
    373   } else {
    374     UINT8_TO_STREAM(p, 0x00);
    375   }
    376 
    377   if (p > params) {
    378     nfa_dm_check_set_config((uint8_t)(p - params), params, false);
    379   }
    380 
    381   return NFA_STATUS_OK;
    382 }
    383 
    384 /*******************************************************************************
    385 **
    386 ** Function         nfa_dm_set_total_duration
    387 **
    388 ** Description      Update total duration to NFCC
    389 **
    390 ** Returns          void
    391 **
    392 *******************************************************************************/
    393 static void nfa_dm_set_total_duration(void) {
    394   uint8_t params[10], *p;
    395 
    396   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
    397 
    398   p = params;
    399 
    400   /* for total duration */
    401   UINT8_TO_STREAM(p, NFC_PMID_TOTAL_DURATION);
    402   UINT8_TO_STREAM(p, NCI_PARAM_LEN_TOTAL_DURATION);
    403   UINT16_TO_STREAM(p, nfa_dm_cb.disc_cb.disc_duration);
    404 
    405   if (p > params) {
    406     nfa_dm_check_set_config((uint8_t)(p - params), params, false);
    407   }
    408 }
    409 
    410 /*******************************************************************************
    411 **
    412 ** Function         nfa_dm_set_rf_listen_mode_raw_config
    413 **
    414 ** Description      Set raw listen parameters
    415 **
    416 ** Returns          void
    417 **
    418 *******************************************************************************/
    419 static void nfa_dm_set_rf_listen_mode_raw_config(
    420     tNFA_DM_DISC_TECH_PROTO_MASK* p_disc_mask) {
    421   tNFA_DM_DISC_TECH_PROTO_MASK disc_mask = 0;
    422   tNFA_LISTEN_CFG* p_cfg = &nfa_dm_cb.disc_cb.excl_listen_config;
    423   uint8_t params[250], *p, xx;
    424 
    425   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
    426 
    427   /*
    428   ** Discovery Configuration Parameters for Listen A
    429   */
    430   if ((nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A] ==
    431        NFA_DM_DISC_HOST_ID_DH) &&
    432       (p_cfg->la_enable)) {
    433     p = params;
    434 
    435     UINT8_TO_STREAM(p, NFC_PMID_LA_BIT_FRAME_SDD);
    436     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_BIT_FRAME_SDD);
    437     UINT8_TO_STREAM(p, p_cfg->la_bit_frame_sdd);
    438 
    439     UINT8_TO_STREAM(p, NFC_PMID_LA_PLATFORM_CONFIG);
    440     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_PLATFORM_CONFIG);
    441     UINT8_TO_STREAM(p, p_cfg->la_platform_config);
    442 
    443     UINT8_TO_STREAM(p, NFC_PMID_LA_SEL_INFO);
    444     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LA_SEL_INFO);
    445     UINT8_TO_STREAM(p, p_cfg->la_sel_info);
    446 
    447     if (p_cfg->la_platform_config == NCI_PARAM_PLATFORM_T1T) {
    448       disc_mask |= NFA_DM_DISC_MASK_LA_T1T;
    449     } else {
    450       /* If T4T or NFCDEP */
    451       if (p_cfg->la_sel_info & NCI_PARAM_SEL_INFO_ISODEP) {
    452         disc_mask |= NFA_DM_DISC_MASK_LA_ISO_DEP;
    453       }
    454 
    455       if (p_cfg->la_sel_info & NCI_PARAM_SEL_INFO_NFCDEP) {
    456         disc_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
    457       }
    458 
    459       /* If neither, T4T nor NFCDEP, then its T2T */
    460       if (disc_mask == 0) {
    461         disc_mask |= NFA_DM_DISC_MASK_LA_T2T;
    462       }
    463     }
    464 
    465     UINT8_TO_STREAM(p, NFC_PMID_LA_NFCID1);
    466     UINT8_TO_STREAM(p, p_cfg->la_nfcid1_len);
    467     ARRAY_TO_STREAM(p, p_cfg->la_nfcid1, p_cfg->la_nfcid1_len);
    468 
    469     nfa_dm_check_set_config((uint8_t)(p - params), params, false);
    470   }
    471 
    472   /*
    473   ** Discovery Configuration Parameters for Listen B
    474   */
    475   if ((nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B] ==
    476        NFA_DM_DISC_HOST_ID_DH) &&
    477       (p_cfg->lb_enable)) {
    478     p = params;
    479 
    480     UINT8_TO_STREAM(p, NFC_PMID_LB_SENSB_INFO);
    481     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_SENSB_INFO);
    482     UINT8_TO_STREAM(p, p_cfg->lb_sensb_info);
    483 
    484     UINT8_TO_STREAM(p, NFC_PMID_LB_NFCID0);
    485     UINT8_TO_STREAM(p, p_cfg->lb_nfcid0_len);
    486     ARRAY_TO_STREAM(p, p_cfg->lb_nfcid0, p_cfg->lb_nfcid0_len);
    487 
    488     UINT8_TO_STREAM(p, NFC_PMID_LB_APPDATA);
    489     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_APPDATA);
    490     ARRAY_TO_STREAM(p, p_cfg->lb_app_data, NCI_PARAM_LEN_LB_APPDATA);
    491 
    492     UINT8_TO_STREAM(p, NFC_PMID_LB_SFGI);
    493     UINT8_TO_STREAM(p, 1);
    494     UINT8_TO_STREAM(p, p_cfg->lb_adc_fo);
    495 
    496     UINT8_TO_STREAM(p, NFC_PMID_LB_ADC_FO);
    497     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LB_ADC_FO);
    498     UINT8_TO_STREAM(p, p_cfg->lb_adc_fo);
    499 
    500     nfa_dm_check_set_config((uint8_t)(p - params), params, false);
    501 
    502     if (p_cfg->lb_sensb_info & NCI_LISTEN_PROTOCOL_ISO_DEP) {
    503       disc_mask |= NFA_DM_DISC_MASK_LB_ISO_DEP;
    504     }
    505   }
    506 
    507   /*
    508   ** Discovery Configuration Parameters for Listen F
    509   */
    510   if ((nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F] ==
    511        NFA_DM_DISC_HOST_ID_DH) &&
    512       (p_cfg->lf_enable)) {
    513     p = params;
    514 
    515     UINT8_TO_STREAM(p, NFC_PMID_LF_CON_BITR_F);
    516     UINT8_TO_STREAM(p, 1);
    517     UINT8_TO_STREAM(p, p_cfg->lf_con_bitr_f);
    518 
    519     UINT8_TO_STREAM(p, NFC_PMID_LF_PROTOCOL);
    520     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_PROTOCOL);
    521     UINT8_TO_STREAM(p, p_cfg->lf_protocol_type);
    522 
    523     UINT8_TO_STREAM(p, NFC_PMID_LF_T3T_FLAGS2);
    524     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_T3T_FLAGS2);
    525     UINT16_TO_STREAM(p, p_cfg->lf_t3t_flags);
    526 
    527     /* if the bit at position X is set to 0, SC/NFCID2 with index X shall be
    528      * ignored */
    529     for (xx = 0; xx < NFA_LF_MAX_SC_NFCID2; xx++) {
    530       if ((p_cfg->lf_t3t_flags & (0x0001 << xx)) != 0x0000) {
    531         UINT8_TO_STREAM(p, NFC_PMID_LF_T3T_ID1 + xx);
    532         UINT8_TO_STREAM(p, NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN);
    533         ARRAY_TO_STREAM(p, p_cfg->lf_t3t_identifier[xx],
    534                         NCI_SYSTEMCODE_LEN + NCI_NFCID2_LEN);
    535       }
    536     }
    537 
    538     UINT8_TO_STREAM(p, NFC_PMID_LF_T3T_PMM);
    539     UINT8_TO_STREAM(p, NCI_PARAM_LEN_LF_T3T_PMM);
    540     ARRAY_TO_STREAM(p, p_cfg->lf_t3t_pmm, NCI_PARAM_LEN_LF_T3T_PMM);
    541 
    542     nfa_dm_check_set_config((uint8_t)(p - params), params, false);
    543 
    544     if (p_cfg->lf_t3t_flags != NCI_LF_T3T_FLAGS2_ALL_DISABLED) {
    545       disc_mask |= NFA_DM_DISC_MASK_LF_T3T;
    546     }
    547     if (p_cfg->lf_protocol_type & NCI_LISTEN_PROTOCOL_NFC_DEP) {
    548       disc_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
    549     }
    550   }
    551 
    552   /*
    553   ** Discovery Configuration Parameters for Listen ISO-DEP
    554   */
    555   if ((disc_mask &
    556        (NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LB_ISO_DEP)) &&
    557       (p_cfg->li_enable)) {
    558     p = params;
    559 
    560     UINT8_TO_STREAM(p, NFC_PMID_FWI);
    561     UINT8_TO_STREAM(p, NCI_PARAM_LEN_FWI);
    562     UINT8_TO_STREAM(p, p_cfg->li_fwi);
    563 
    564     if (disc_mask & NFA_DM_DISC_MASK_LA_ISO_DEP) {
    565       UINT8_TO_STREAM(p, NFC_PMID_LA_HIST_BY);
    566       UINT8_TO_STREAM(p, p_cfg->la_hist_bytes_len);
    567       ARRAY_TO_STREAM(p, p_cfg->la_hist_bytes, p_cfg->la_hist_bytes_len);
    568     }
    569 
    570     if (disc_mask & NFA_DM_DISC_MASK_LB_ISO_DEP) {
    571       UINT8_TO_STREAM(p, NFC_PMID_LB_H_INFO);
    572       UINT8_TO_STREAM(p, p_cfg->lb_h_info_resp_len);
    573       ARRAY_TO_STREAM(p, p_cfg->lb_h_info_resp, p_cfg->lb_h_info_resp_len);
    574     }
    575 
    576     nfa_dm_check_set_config((uint8_t)(p - params), params, false);
    577   }
    578 
    579   /*
    580   ** Discovery Configuration Parameters for Listen NFC-DEP
    581   */
    582   if ((disc_mask &
    583        (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LF_NFC_DEP)) &&
    584       (p_cfg->ln_enable)) {
    585     p = params;
    586 
    587     UINT8_TO_STREAM(p, NFC_PMID_WT);
    588     UINT8_TO_STREAM(p, NCI_PARAM_LEN_WT);
    589     UINT8_TO_STREAM(p, p_cfg->ln_wt);
    590 
    591     UINT8_TO_STREAM(p, NFC_PMID_ATR_RES_GEN_BYTES);
    592     UINT8_TO_STREAM(p, p_cfg->ln_atr_res_gen_bytes_len);
    593     ARRAY_TO_STREAM(p, p_cfg->ln_atr_res_gen_bytes,
    594                     p_cfg->ln_atr_res_gen_bytes_len);
    595 
    596     UINT8_TO_STREAM(p, NFC_PMID_ATR_RSP_CONFIG);
    597     UINT8_TO_STREAM(p, 1);
    598     UINT8_TO_STREAM(p, p_cfg->ln_atr_res_config);
    599 
    600     nfa_dm_check_set_config((uint8_t)(p - params), params, false);
    601   }
    602 
    603   *p_disc_mask = disc_mask;
    604 
    605   DLOG_IF(INFO, nfc_debug_enabled)
    606       << StringPrintf("disc_mask = 0x%x", disc_mask);
    607 }
    608 
    609 /*******************************************************************************
    610 **
    611 ** Function         nfa_dm_disc_get_disc_mask
    612 **
    613 ** Description      Convert RF technology, mode and protocol to bit mask
    614 **
    615 ** Returns          tNFA_DM_DISC_TECH_PROTO_MASK
    616 **
    617 *******************************************************************************/
    618 static tNFA_DM_DISC_TECH_PROTO_MASK nfa_dm_disc_get_disc_mask(
    619     tNFC_RF_TECH_N_MODE tech_n_mode, tNFC_PROTOCOL protocol) {
    620   /* Set initial disc_mask to legacy poll or listen */
    621   tNFA_DM_DISC_TECH_PROTO_MASK disc_mask =
    622       ((tech_n_mode & 0x80) ? NFA_DM_DISC_MASK_L_LEGACY
    623                             : NFA_DM_DISC_MASK_P_LEGACY);
    624 
    625   if (NFC_DISCOVERY_TYPE_POLL_A == tech_n_mode) {
    626     switch (protocol) {
    627       case NFC_PROTOCOL_T1T:
    628         disc_mask = NFA_DM_DISC_MASK_PA_T1T;
    629         break;
    630       case NFC_PROTOCOL_T2T:
    631         disc_mask = NFA_DM_DISC_MASK_PA_T2T;
    632         break;
    633       case NFC_PROTOCOL_ISO_DEP:
    634         disc_mask = NFA_DM_DISC_MASK_PA_ISO_DEP;
    635         break;
    636       case NFC_PROTOCOL_NFC_DEP:
    637         disc_mask = NFA_DM_DISC_MASK_PA_NFC_DEP;
    638         break;
    639     }
    640   } else if (NFC_DISCOVERY_TYPE_POLL_B == tech_n_mode) {
    641     if (protocol == NFC_PROTOCOL_ISO_DEP)
    642       disc_mask = NFA_DM_DISC_MASK_PB_ISO_DEP;
    643   } else if (NFC_DISCOVERY_TYPE_POLL_F == tech_n_mode) {
    644     if (protocol == NFC_PROTOCOL_T3T)
    645       disc_mask = NFA_DM_DISC_MASK_PF_T3T;
    646     else if (protocol == NFC_PROTOCOL_NFC_DEP)
    647       disc_mask = NFA_DM_DISC_MASK_PF_NFC_DEP;
    648   } else if (NFC_DISCOVERY_TYPE_POLL_V == tech_n_mode) {
    649     disc_mask = NFA_DM_DISC_MASK_P_T5T;
    650   } else if (NFC_DISCOVERY_TYPE_POLL_B_PRIME == tech_n_mode) {
    651     disc_mask = NFA_DM_DISC_MASK_P_B_PRIME;
    652   } else if (NFC_DISCOVERY_TYPE_POLL_KOVIO == tech_n_mode) {
    653     disc_mask = NFA_DM_DISC_MASK_P_KOVIO;
    654   } else if (NFC_DISCOVERY_TYPE_LISTEN_A == tech_n_mode) {
    655     switch (protocol) {
    656       case NFC_PROTOCOL_T1T:
    657         disc_mask = NFA_DM_DISC_MASK_LA_T1T;
    658         break;
    659       case NFC_PROTOCOL_T2T:
    660         disc_mask = NFA_DM_DISC_MASK_LA_T2T;
    661         break;
    662       case NFC_PROTOCOL_ISO_DEP:
    663         disc_mask = NFA_DM_DISC_MASK_LA_ISO_DEP;
    664         break;
    665       case NFC_PROTOCOL_NFC_DEP:
    666         disc_mask = NFA_DM_DISC_MASK_LA_NFC_DEP;
    667         break;
    668     }
    669   } else if (NFC_DISCOVERY_TYPE_LISTEN_B == tech_n_mode) {
    670     if (protocol == NFC_PROTOCOL_ISO_DEP)
    671       disc_mask = NFA_DM_DISC_MASK_LB_ISO_DEP;
    672   } else if (NFC_DISCOVERY_TYPE_LISTEN_F == tech_n_mode) {
    673     if (protocol == NFC_PROTOCOL_T3T)
    674       disc_mask = NFA_DM_DISC_MASK_LF_T3T;
    675     else if (protocol == NFC_PROTOCOL_NFC_DEP)
    676       disc_mask = NFA_DM_DISC_MASK_LF_NFC_DEP;
    677   } else if (NFC_DISCOVERY_TYPE_LISTEN_ISO15693 == tech_n_mode) {
    678     disc_mask = NFA_DM_DISC_MASK_L_ISO15693;
    679   } else if (NFC_DISCOVERY_TYPE_LISTEN_B_PRIME == tech_n_mode) {
    680     disc_mask = NFA_DM_DISC_MASK_L_B_PRIME;
    681   }
    682   if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
    683     if (NFC_DISCOVERY_TYPE_POLL_ACTIVE == tech_n_mode) {
    684       disc_mask = NFA_DM_DISC_MASK_PACM_NFC_DEP;
    685     } else if (NFC_DISCOVERY_TYPE_LISTEN_ACTIVE == tech_n_mode) {
    686       disc_mask = NFA_DM_DISC_MASK_LACM_NFC_DEP;
    687     }
    688   } else {
    689     if (NFC_DISCOVERY_TYPE_POLL_A_ACTIVE == tech_n_mode) {
    690       disc_mask = NFA_DM_DISC_MASK_PAA_NFC_DEP;
    691     } else if (NFC_DISCOVERY_TYPE_POLL_F_ACTIVE == tech_n_mode) {
    692       disc_mask = NFA_DM_DISC_MASK_PFA_NFC_DEP;
    693     } else if (NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE == tech_n_mode) {
    694       disc_mask = NFA_DM_DISC_MASK_LAA_NFC_DEP;
    695     } else if (NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE == tech_n_mode) {
    696       disc_mask = NFA_DM_DISC_MASK_LFA_NFC_DEP;
    697     }
    698   }
    699 
    700   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    701       "tech_n_mode:0x%X, protocol:0x%X, "
    702       "disc_mask:0x%X",
    703       tech_n_mode, protocol, disc_mask);
    704   return (disc_mask);
    705 }
    706 
    707 /*******************************************************************************
    708 **
    709 ** Function         nfa_dm_disc_discovery_cback
    710 **
    711 ** Description      Discovery callback event from NFC
    712 **
    713 ** Returns          void
    714 **
    715 *******************************************************************************/
    716 static void nfa_dm_disc_discovery_cback(tNFC_DISCOVER_EVT event,
    717                                         tNFC_DISCOVER* p_data) {
    718   tNFA_DM_RF_DISC_SM_EVENT dm_disc_event = NFA_DM_DISC_SM_MAX_EVENT;
    719 
    720   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("event:0x%X", event);
    721 
    722   switch (event) {
    723     case NFC_START_DEVT:
    724       dm_disc_event = NFA_DM_RF_DISCOVER_RSP;
    725       break;
    726     case NFC_RESULT_DEVT:
    727       dm_disc_event = NFA_DM_RF_DISCOVER_NTF;
    728       break;
    729     case NFC_SELECT_DEVT:
    730       dm_disc_event = NFA_DM_RF_DISCOVER_SELECT_RSP;
    731       break;
    732     case NFC_ACTIVATE_DEVT:
    733       dm_disc_event = NFA_DM_RF_INTF_ACTIVATED_NTF;
    734       break;
    735     case NFC_DEACTIVATE_DEVT:
    736       if (p_data->deactivate.is_ntf) {
    737         dm_disc_event = NFA_DM_RF_DEACTIVATE_NTF;
    738         if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) ||
    739             (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)) {
    740           NFC_SetReassemblyFlag(true);
    741           nfa_dm_cb.flags &= ~NFA_DM_FLAGS_RAW_FRAME;
    742         }
    743       } else
    744         dm_disc_event = NFA_DM_RF_DEACTIVATE_RSP;
    745       break;
    746     default:
    747       LOG(ERROR) << StringPrintf("Unexpected event");
    748       return;
    749   }
    750 
    751   tNFA_DM_RF_DISC_DATA nfa_dm_rf_disc_data;
    752   nfa_dm_rf_disc_data.nfc_discover = *p_data;
    753   nfa_dm_disc_sm_execute(dm_disc_event, &nfa_dm_rf_disc_data);
    754 }
    755 
    756 /*******************************************************************************
    757 **
    758 ** Function         nfa_dm_disc_notify_started
    759 **
    760 ** Description      Report NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT or
    761 **                  NFA_RF_DISCOVERY_STARTED_EVT, if needed
    762 **
    763 ** Returns          void
    764 **
    765 *******************************************************************************/
    766 static void nfa_dm_disc_notify_started(tNFA_STATUS status) {
    767   tNFA_CONN_EVT_DATA evt_data;
    768 
    769   if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY) {
    770     nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
    771 
    772     evt_data.status = status;
    773 
    774     if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use)
    775       nfa_dm_conn_cback_event_notify(NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT,
    776                                      &evt_data);
    777     else
    778       nfa_dm_conn_cback_event_notify(NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
    779   }
    780 }
    781 
    782 /*******************************************************************************
    783 **
    784 ** Function         nfa_dm_disc_conn_event_notify
    785 **
    786 ** Description      Notify application of CONN_CBACK event, using appropriate
    787 **                  callback
    788 **
    789 ** Returns          nothing
    790 **
    791 *******************************************************************************/
    792 void nfa_dm_disc_conn_event_notify(uint8_t event, tNFA_STATUS status) {
    793   tNFA_CONN_EVT_DATA evt_data;
    794 
    795   if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_NOTIFY) {
    796     nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_NOTIFY;
    797     evt_data.status = status;
    798 
    799     if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) {
    800       /* Use exclusive RF mode callback */
    801       if (nfa_dm_cb.p_excl_conn_cback)
    802         (*nfa_dm_cb.p_excl_conn_cback)(event, &evt_data);
    803     } else {
    804       (*nfa_dm_cb.p_conn_cback)(event, &evt_data);
    805     }
    806   }
    807 }
    808 
    809 /*******************************************************************************
    810 **
    811 ** Function         nfa_dm_disc_force_to_idle
    812 **
    813 ** Description      Force NFCC to idle state while waiting for deactivation NTF
    814 **
    815 ** Returns          tNFC_STATUS
    816 **
    817 *******************************************************************************/
    818 static tNFC_STATUS nfa_dm_disc_force_to_idle(void) {
    819   tNFC_STATUS status = NFC_STATUS_SEMANTIC_ERROR;
    820 
    821   DLOG_IF(INFO, nfc_debug_enabled)
    822       << StringPrintf("disc_flags = 0x%x", nfa_dm_cb.disc_cb.disc_flags);
    823 
    824   /* do not execute more than one */
    825   if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF) {
    826     nfa_dm_cb.disc_cb.disc_flags &= ~(NFA_DM_DISC_FLAGS_W4_NTF);
    827     nfa_dm_cb.disc_cb.disc_flags |= (NFA_DM_DISC_FLAGS_W4_RSP);
    828     nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
    829     status = NFC_Deactivate(NFC_DEACTIVATE_TYPE_IDLE);
    830   }
    831 
    832   return (status);
    833 }
    834 
    835 /*******************************************************************************
    836 **
    837 ** Function         nfa_dm_disc_deact_ntf_timeout_cback
    838 **
    839 ** Description      Timeout while waiting for deactivation NTF
    840 **
    841 ** Returns          void
    842 **
    843 *******************************************************************************/
    844 static void nfa_dm_disc_deact_ntf_timeout_cback(__attribute__((unused))
    845                                                 TIMER_LIST_ENT* p_tle) {
    846   LOG(ERROR) << __func__;
    847 
    848   nfa_dm_disc_force_to_idle();
    849 }
    850 
    851 /*******************************************************************************
    852 **
    853 ** Function         nfa_dm_send_deactivate_cmd
    854 **
    855 ** Description      Send deactivate command to NFCC, if needed.
    856 **
    857 ** Returns          NFC_STATUS_OK             - deactivate cmd is sent
    858 **                  NCI_STATUS_FAILED         - no buffers
    859 **                  NFC_STATUS_SEMANTIC_ERROR - this function does not attempt
    860 **                                              to send deactivate cmd
    861 **
    862 *******************************************************************************/
    863 static tNFC_STATUS nfa_dm_send_deactivate_cmd(tNFC_DEACT_TYPE deactivate_type) {
    864   tNFC_STATUS status = NFC_STATUS_SEMANTIC_ERROR;
    865   tNFA_DM_DISC_FLAGS w4_flags =
    866       nfa_dm_cb.disc_cb.disc_flags &
    867       (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
    868 
    869   if (!w4_flags) {
    870     /* if deactivate CMD was not sent to NFCC */
    871     nfa_dm_cb.disc_cb.disc_flags |=
    872         (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
    873 
    874     status = NFC_Deactivate(deactivate_type);
    875 
    876     if (!nfa_dm_cb.disc_cb.tle.in_use) {
    877       nfa_dm_cb.disc_cb.tle.p_cback =
    878           (TIMER_CBACK*)nfa_dm_disc_deact_ntf_timeout_cback;
    879       nfa_sys_start_timer(&nfa_dm_cb.disc_cb.tle, 0,
    880                           NFA_DM_DISC_TIMEOUT_W4_DEACT_NTF);
    881     }
    882   } else {
    883     if (deactivate_type == NFC_DEACTIVATE_TYPE_SLEEP) {
    884       status = NFC_STATUS_SEMANTIC_ERROR;
    885     } else if (nfa_dm_cb.disc_cb.tle.in_use) {
    886       status = NFC_STATUS_OK;
    887     } else {
    888       status = nfa_dm_disc_force_to_idle();
    889     }
    890   }
    891 
    892   return status;
    893 }
    894 
    895 /*******************************************************************************
    896 **
    897 ** Function         nfa_dm_start_rf_discover
    898 **
    899 ** Description      Start RF discovery
    900 **
    901 ** Returns          void
    902 **
    903 *******************************************************************************/
    904 void nfa_dm_start_rf_discover(void) {
    905   tNFC_DISCOVER_PARAMS disc_params[NFA_DM_MAX_DISC_PARAMS];
    906   tNFA_DM_DISC_TECH_PROTO_MASK dm_disc_mask = 0, poll_mask, listen_mask;
    907   uint8_t config_params[10], *p;
    908   uint8_t num_params, xx;
    909 
    910   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
    911   /* Make sure that RF discovery was enabled, or some app has exclusive control
    912    */
    913   if ((!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED)) &&
    914       (nfa_dm_cb.disc_cb.excl_disc_entry.in_use == false)) {
    915     return;
    916   }
    917 
    918   /* get listen mode routing table for technology */
    919   nfa_ee_get_tech_route(NFA_EE_PWR_STATE_ON, nfa_dm_cb.disc_cb.listen_RT);
    920 
    921   if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
    922     nfa_dm_set_rf_listen_mode_raw_config(&dm_disc_mask);
    923     dm_disc_mask |= (nfa_dm_cb.disc_cb.excl_disc_entry.requested_disc_mask &
    924                      NFA_DM_DISC_MASK_POLL);
    925     nfa_dm_cb.disc_cb.excl_disc_entry.selected_disc_mask = dm_disc_mask;
    926   } else {
    927     /* Collect RF discovery request from sub-modules */
    928     for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
    929       if (nfa_dm_cb.disc_cb.entry[xx].in_use) {
    930         poll_mask = (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
    931                      NFA_DM_DISC_MASK_POLL);
    932 
    933         /* clear poll mode technolgies and protocols which are already used by
    934          * others */
    935         poll_mask &= ~(dm_disc_mask & NFA_DM_DISC_MASK_POLL);
    936 
    937         listen_mask = 0;
    938 
    939         /*
    940         ** add listen mode technolgies and protocols if host ID is
    941         ** matched to listen mode routing table
    942         */
    943 
    944         /* NFC-A */
    945         if (nfa_dm_cb.disc_cb.entry[xx].host_id ==
    946             nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A]) {
    947           listen_mask |=
    948               nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
    949               (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T |
    950                NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP);
    951           if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
    952             listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
    953                            NFA_DM_DISC_MASK_LACM_NFC_DEP;
    954           } else {
    955             listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
    956                            NFA_DM_DISC_MASK_LAA_NFC_DEP;
    957           }
    958         } else {
    959           /* host can listen ISO-DEP based on AID routing */
    960           listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
    961                           NFA_DM_DISC_MASK_LA_ISO_DEP);
    962           if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
    963             listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
    964                             NFA_DM_DISC_MASK_LACM_NFC_DEP);
    965           } else {
    966             /* host can listen NFC-DEP based on protocol routing */
    967             listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
    968                             NFA_DM_DISC_MASK_LA_NFC_DEP);
    969             listen_mask |= (nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
    970                             NFA_DM_DISC_MASK_LAA_NFC_DEP);
    971           }
    972         }
    973 
    974         /* NFC-B */
    975         /* multiple hosts can listen ISO-DEP based on AID routing */
    976         listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
    977                        NFA_DM_DISC_MASK_LB_ISO_DEP;
    978 
    979         /* NFC-F */
    980         /* NFCC can support NFC-DEP and T3T listening based on NFCID routing
    981          * regardless of NFC-F tech routing */
    982         listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
    983                        (NFA_DM_DISC_MASK_LF_T3T | NFA_DM_DISC_MASK_LF_NFC_DEP);
    984         if (NFC_GetNCIVersion() != NCI_VERSION_2_0) {
    985           listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
    986                          NFA_DM_DISC_MASK_LFA_NFC_DEP;
    987         }
    988         /* NFC-B Prime */
    989         if (nfa_dm_cb.disc_cb.entry[xx].host_id ==
    990             nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_BP]) {
    991           listen_mask |= nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask &
    992                          NFA_DM_DISC_MASK_L_B_PRIME;
    993         }
    994 
    995         /*
    996         ** clear listen mode technolgies and protocols which are already
    997         ** used by others
    998         */
    999 
   1000         /* Check if other modules are listening T1T or T2T */
   1001         if (dm_disc_mask &
   1002             (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T)) {
   1003           listen_mask &=
   1004               ~(NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T |
   1005                 NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP);
   1006         }
   1007 
   1008         /* T1T/T2T has priority on NFC-A */
   1009         if ((dm_disc_mask &
   1010              (NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP)) &&
   1011             (listen_mask &
   1012              (NFA_DM_DISC_MASK_LA_T1T | NFA_DM_DISC_MASK_LA_T2T))) {
   1013           dm_disc_mask &=
   1014               ~(NFA_DM_DISC_MASK_LA_ISO_DEP | NFA_DM_DISC_MASK_LA_NFC_DEP);
   1015         }
   1016 
   1017         /* Don't remove ISO-DEP because multiple hosts can listen ISO-DEP based
   1018          * on AID routing */
   1019 
   1020         /* Check if other modules are listening NFC-DEP */
   1021         if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
   1022           if (dm_disc_mask &
   1023               (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LACM_NFC_DEP)) {
   1024             listen_mask &=
   1025                 ~(NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LACM_NFC_DEP);
   1026           }
   1027         } else {
   1028           if (dm_disc_mask &
   1029               (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LAA_NFC_DEP)) {
   1030             listen_mask &=
   1031                 ~(NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LAA_NFC_DEP);
   1032           }
   1033         }
   1034 
   1035         nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask =
   1036             poll_mask | listen_mask;
   1037 
   1038         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   1039             "nfa_dm_cb.disc_cb.entry[%d].selected_disc_mask = 0x%x", xx,
   1040             nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask);
   1041 
   1042         dm_disc_mask |= nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask;
   1043       }
   1044     }
   1045 
   1046     /* Let P2P set GEN bytes for LLCP to NFCC */
   1047     if (dm_disc_mask & NFA_DM_DISC_MASK_NFC_DEP) {
   1048       nfa_p2p_set_config(dm_disc_mask);
   1049     }
   1050     if (NFC_GetNCIVersion() == NCI_VERSION_1_0) {
   1051       if (dm_disc_mask &
   1052           (NFA_DM_DISC_MASK_PF_NFC_DEP | NFA_DM_DISC_MASK_PF_T3T)) {
   1053         /* According to the NFC Forum Activity spec, controllers must:
   1054          * 1) Poll with RC=0 and SC=FFFF to find NFC-DEP targets
   1055          * 2) Poll with RC=1 and SC=FFFF to find T3T targets
   1056          * Many controllers don't do this yet, and seem to be activating
   1057          * NFC-DEP by default.
   1058          *
   1059          * We can at least fix the scenario where we're not interested
   1060          * in NFC-DEP, by setting RC=1 in that case. Otherwise, keep
   1061          * the default of RC=0. */
   1062         p = config_params;
   1063         UINT8_TO_STREAM(p, NFC_PMID_PF_RC);
   1064         UINT8_TO_STREAM(p, NCI_PARAM_LEN_PF_RC);
   1065         if ((dm_disc_mask & NFA_DM_DISC_MASK_PF_NFC_DEP) &&
   1066             !nfa_dm_is_p2p_paused()) {
   1067           UINT8_TO_STREAM(p, 0x00);  // RC=0
   1068         } else {
   1069           UINT8_TO_STREAM(p, 0x01);  // RC=1
   1070         }
   1071         nfa_dm_check_set_config(p - config_params, config_params, false);
   1072       }
   1073     }
   1074   }
   1075 
   1076   DLOG_IF(INFO, nfc_debug_enabled)
   1077       << StringPrintf("dm_disc_mask = 0x%x", dm_disc_mask);
   1078 
   1079   /* Get Discovery Technology parameters */
   1080   num_params = nfa_dm_get_rf_discover_config(dm_disc_mask, disc_params,
   1081                                              NFA_DM_MAX_DISC_PARAMS);
   1082 
   1083   if (num_params) {
   1084     /*
   1085     ** NFCC will abort programming personality slots if not available.
   1086     ** NFCC programs the personality slots in the following order of RF
   1087     ** technologies: NFC-A, NFC-B, NFC-BP, NFC-I93
   1088     */
   1089 
   1090     /* if this is not for exclusive control */
   1091     if (!nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
   1092       /* update listening protocols in each NFC technology */
   1093       nfa_dm_set_rf_listen_mode_config(dm_disc_mask);
   1094     }
   1095 
   1096     /* Set polling duty cycle */
   1097     nfa_dm_set_total_duration();
   1098     nfa_dm_cb.disc_cb.dm_disc_mask = dm_disc_mask;
   1099 
   1100     NFC_DiscoveryStart(num_params, disc_params, nfa_dm_disc_discovery_cback);
   1101     /* set flag about waiting for response in IDLE state */
   1102     nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
   1103 
   1104     /* register callback to get interface error NTF */
   1105     NFC_SetStaticRfCback(nfa_dm_disc_data_cback);
   1106   } else {
   1107     /* RF discovery is started but there is no valid technology or protocol to
   1108      * discover */
   1109     nfa_dm_disc_notify_started(NFA_STATUS_OK);
   1110   }
   1111 
   1112   /* if Kovio presence check timer is running, timeout callback will reset the
   1113    * activation information */
   1114   if ((nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_KOVIO) ||
   1115       (!nfa_dm_cb.disc_cb.kovio_tle.in_use)) {
   1116     /* reset protocol and hanlde of activated sub-module */
   1117     nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
   1118     nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
   1119   }
   1120 }
   1121 
   1122 /*******************************************************************************
   1123 **
   1124 ** Function         nfa_dm_notify_discovery
   1125 **
   1126 ** Description      Send RF discovery notification to upper layer
   1127 **
   1128 ** Returns          void
   1129 **
   1130 *******************************************************************************/
   1131 static void nfa_dm_notify_discovery(tNFA_DM_RF_DISC_DATA* p_data) {
   1132   tNFA_CONN_EVT_DATA conn_evt;
   1133 
   1134   /* let application select a device */
   1135   conn_evt.disc_result.status = NFA_STATUS_OK;
   1136   memcpy(&(conn_evt.disc_result.discovery_ntf), &(p_data->nfc_discover.result),
   1137          sizeof(tNFC_RESULT_DEVT));
   1138 
   1139   nfa_dm_conn_cback_event_notify(NFA_DISC_RESULT_EVT, &conn_evt);
   1140 }
   1141 
   1142 /*******************************************************************************
   1143 **
   1144 ** Function         nfa_dm_disc_handle_kovio_activation
   1145 **
   1146 ** Description      Handle Kovio activation; whether it's new or repeated
   1147 **                  activation
   1148 **
   1149 ** Returns          TRUE if repeated activation. No need to notify activated
   1150 **                  event to upper layer
   1151 **
   1152 *******************************************************************************/
   1153 bool nfa_dm_disc_handle_kovio_activation(tNFC_DISCOVER* p_data,
   1154                                          tNFA_DISCOVER_CBACK* p_disc_cback) {
   1155   tNFC_DISCOVER disc_data;
   1156 
   1157   if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
   1158     /* if this is new Kovio bar code tag */
   1159     if ((nfa_dm_cb.activated_nfcid_len !=
   1160          p_data->activate.rf_tech_param.param.pk.uid_len) ||
   1161         (memcmp(p_data->activate.rf_tech_param.param.pk.uid,
   1162                 nfa_dm_cb.activated_nfcid, nfa_dm_cb.activated_nfcid_len))) {
   1163       DLOG_IF(INFO, nfc_debug_enabled)
   1164           << StringPrintf("new Kovio tag is detected");
   1165 
   1166       /* notify presence check failure for previous tag, if presence check is
   1167        * pending */
   1168       nfa_dm_disc_report_kovio_presence_check(NFA_STATUS_FAILED);
   1169 
   1170       /* notify deactivation of previous activation before notifying new
   1171        * activation */
   1172       if (p_disc_cback) {
   1173         disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
   1174         (*(p_disc_cback))(NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
   1175       }
   1176 
   1177       /* restart timer */
   1178       nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
   1179                           NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
   1180     } else {
   1181       /* notify presence check ok, if presence check is pending */
   1182       nfa_dm_disc_report_kovio_presence_check(NFC_STATUS_OK);
   1183 
   1184       /* restart timer and do not notify upper layer */
   1185       nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
   1186                           NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
   1187       return true;
   1188     }
   1189   } else {
   1190     /* this is the first activation, so start timer and notify upper layer */
   1191     nfa_dm_cb.disc_cb.kovio_tle.p_cback =
   1192         (TIMER_CBACK*)nfa_dm_disc_kovio_timeout_cback;
   1193     nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
   1194                         NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
   1195   }
   1196 
   1197   return false;
   1198 }
   1199 
   1200 /*******************************************************************************
   1201 **
   1202 ** Function         nfa_dm_disc_notify_activation
   1203 **
   1204 ** Description      Send RF activation notification to sub-module
   1205 **
   1206 ** Returns          NFA_STATUS_OK if success
   1207 **
   1208 *******************************************************************************/
   1209 static tNFA_STATUS nfa_dm_disc_notify_activation(tNFC_DISCOVER* p_data) {
   1210   uint8_t xx, host_id_in_LRT;
   1211   uint8_t iso_dep_t3t__listen = NFA_DM_DISC_NUM_ENTRIES;
   1212 
   1213   tNFC_RF_TECH_N_MODE tech_n_mode = p_data->activate.rf_tech_param.mode;
   1214   tNFC_PROTOCOL protocol = p_data->activate.protocol;
   1215 
   1216   tNFA_DM_DISC_TECH_PROTO_MASK activated_disc_mask;
   1217 
   1218   DLOG_IF(INFO, nfc_debug_enabled)
   1219       << StringPrintf("tech_n_mode:0x%X, proto:0x%X", tech_n_mode, protocol);
   1220 
   1221   if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
   1222     nfa_dm_cb.disc_cb.activated_tech_mode = tech_n_mode;
   1223     nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
   1224     nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
   1225     nfa_dm_cb.disc_cb.activated_protocol = protocol;
   1226     nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
   1227 
   1228     if (protocol == NFC_PROTOCOL_KOVIO) {
   1229       /* check whether it's new or repeated activation */
   1230       if (nfa_dm_disc_handle_kovio_activation(
   1231               p_data, nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)) {
   1232         /* do not notify activation of Kovio to upper layer */
   1233         return (NFA_STATUS_OK);
   1234       }
   1235     }
   1236 
   1237     if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
   1238       (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
   1239           NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
   1240 
   1241     return (NFA_STATUS_OK);
   1242   }
   1243 
   1244   /* if this is NFCEE direct RF interface, notify activation to whoever
   1245    * listening UICC */
   1246   if (p_data->activate.intf_param.type == NFC_INTERFACE_EE_DIRECT_RF) {
   1247     for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
   1248       if ((nfa_dm_cb.disc_cb.entry[xx].in_use) &&
   1249           (nfa_dm_cb.disc_cb.entry[xx].host_id != NFA_DM_DISC_HOST_ID_DH)) {
   1250         nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
   1251         nfa_dm_cb.disc_cb.activated_rf_interface =
   1252             p_data->activate.intf_param.type;
   1253         nfa_dm_cb.disc_cb.activated_protocol = NFC_PROTOCOL_UNKNOWN;
   1254         nfa_dm_cb.disc_cb.activated_handle = xx;
   1255 
   1256         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   1257             "activated_rf_interface:0x%x, activated_handle: 0x%x",
   1258             nfa_dm_cb.disc_cb.activated_rf_interface,
   1259             nfa_dm_cb.disc_cb.activated_handle);
   1260 
   1261         if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
   1262           (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
   1263               NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
   1264 
   1265         return (NFA_STATUS_OK);
   1266       }
   1267     }
   1268     return (NFA_STATUS_FAILED);
   1269   }
   1270 
   1271   /* get bit mask of technolgies/mode and protocol */
   1272   activated_disc_mask = nfa_dm_disc_get_disc_mask(tech_n_mode, protocol);
   1273 
   1274   /* get host ID of technology from listen mode routing table */
   1275   if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) {
   1276     host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_A];
   1277   } else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) {
   1278     host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_B];
   1279   } else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) {
   1280     host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_F];
   1281   } else if (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) {
   1282     host_id_in_LRT = nfa_dm_cb.disc_cb.listen_RT[NFA_DM_DISC_LRT_NFC_BP];
   1283   } else /* DH only */
   1284   {
   1285     host_id_in_LRT = NFA_DM_DISC_HOST_ID_DH;
   1286   }
   1287 
   1288   if (protocol == NFC_PROTOCOL_NFC_DEP) {
   1289     /* Force NFC-DEP to the host */
   1290     host_id_in_LRT = NFA_DM_DISC_HOST_ID_DH;
   1291   }
   1292 
   1293   for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
   1294     /* if any matching NFC technology and protocol */
   1295     if (nfa_dm_cb.disc_cb.entry[xx].in_use) {
   1296       if (nfa_dm_cb.disc_cb.entry[xx].host_id == host_id_in_LRT) {
   1297         if (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
   1298             activated_disc_mask)
   1299           break;
   1300       } else {
   1301         /* check ISO-DEP listening even if host in LRT is not matched */
   1302         if (protocol == NFC_PROTOCOL_ISO_DEP) {
   1303           if ((tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) &&
   1304               (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
   1305                NFA_DM_DISC_MASK_LA_ISO_DEP)) {
   1306             iso_dep_t3t__listen = xx;
   1307           } else if ((tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_B) &&
   1308                      (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
   1309                       NFA_DM_DISC_MASK_LB_ISO_DEP)) {
   1310             iso_dep_t3t__listen = xx;
   1311           }
   1312         }
   1313         /* check T3T listening even if host in LRT is not matched */
   1314         else if (protocol == NFC_PROTOCOL_T3T) {
   1315           if ((tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F) &&
   1316               (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
   1317                NFA_DM_DISC_MASK_LF_T3T)) {
   1318             iso_dep_t3t__listen = xx;
   1319           }
   1320         }
   1321       }
   1322     }
   1323   }
   1324 
   1325   if (xx >= NFA_DM_DISC_NUM_ENTRIES) {
   1326     /* if any ISO-DEP or T3T listening even if host in LRT is not matched */
   1327     xx = iso_dep_t3t__listen;
   1328   }
   1329   if (protocol == NFC_PROTOCOL_NFC_DEP &&
   1330       (tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE ||
   1331        tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE ||
   1332        tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A)) {
   1333     if (appl_dta_mode_flag == 1 && tech_n_mode == NFC_DISCOVERY_TYPE_LISTEN_A) {
   1334       DLOG_IF(INFO, nfc_debug_enabled)
   1335           << StringPrintf("DTA Mode Enabled : NFC-A Passive Listen Mode");
   1336     }
   1337   }
   1338 
   1339   if (xx < NFA_DM_DISC_NUM_ENTRIES) {
   1340     nfa_dm_cb.disc_cb.activated_tech_mode = tech_n_mode;
   1341     nfa_dm_cb.disc_cb.activated_rf_disc_id = p_data->activate.rf_disc_id;
   1342     nfa_dm_cb.disc_cb.activated_rf_interface = p_data->activate.intf_param.type;
   1343     nfa_dm_cb.disc_cb.activated_protocol = protocol;
   1344     nfa_dm_cb.disc_cb.activated_handle = xx;
   1345 
   1346     DLOG_IF(INFO, nfc_debug_enabled)
   1347         << StringPrintf("activated_protocol:0x%x, activated_handle: 0x%x",
   1348                         nfa_dm_cb.disc_cb.activated_protocol,
   1349                         nfa_dm_cb.disc_cb.activated_handle);
   1350 
   1351     if (protocol == NFC_PROTOCOL_KOVIO) {
   1352       /* check whether it's new or repeated activation */
   1353       if (nfa_dm_disc_handle_kovio_activation(
   1354               p_data, nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) {
   1355         /* do not notify activation of Kovio to upper layer */
   1356         return (NFA_STATUS_OK);
   1357       }
   1358     }
   1359 
   1360     if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
   1361       (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
   1362           NFA_DM_RF_DISC_ACTIVATED_EVT, p_data);
   1363 
   1364     return (NFA_STATUS_OK);
   1365   } else {
   1366     nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
   1367     nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
   1368     return (NFA_STATUS_FAILED);
   1369   }
   1370 }
   1371 
   1372 /*******************************************************************************
   1373 **
   1374 ** Function         nfa_dm_disc_notify_deactivation
   1375 **
   1376 ** Description      Send deactivation notification to sub-module
   1377 **
   1378 ** Returns          None
   1379 **
   1380 *******************************************************************************/
   1381 static void nfa_dm_disc_notify_deactivation(tNFA_DM_RF_DISC_SM_EVENT sm_event,
   1382                                             tNFC_DISCOVER* p_data) {
   1383   tNFA_HANDLE xx;
   1384   tNFA_CONN_EVT_DATA evt_data;
   1385   tNFC_DISCOVER disc_data;
   1386 
   1387   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   1388       "activated_handle=%d", nfa_dm_cb.disc_cb.activated_handle);
   1389 
   1390   if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING) {
   1391     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("for sleep wakeup");
   1392     return;
   1393   }
   1394 
   1395   if (sm_event == NFA_DM_RF_DEACTIVATE_RSP) {
   1396     /*
   1397     ** Activation has been aborted by upper layer in
   1398     ** NFA_DM_RFST_W4_ALL_DISCOVERIES or NFA_DM_RFST_W4_HOST_SELECT
   1399     ** Deactivation by upper layer or RF link loss in
   1400     ** NFA_DM_RFST_LISTEN_SLEEP
   1401     ** No sub-module is activated at this state.
   1402     */
   1403 
   1404     if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_SLEEP) {
   1405       if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
   1406         if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback) {
   1407           disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
   1408           (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
   1409               NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
   1410         }
   1411       } else {
   1412         /* let each sub-module handle deactivation */
   1413         for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
   1414           if ((nfa_dm_cb.disc_cb.entry[xx].in_use) &&
   1415               (nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask &
   1416                NFA_DM_DISC_MASK_LISTEN)) {
   1417             disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
   1418             (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
   1419                 NFA_DM_RF_DISC_DEACTIVATED_EVT, &disc_data);
   1420           }
   1421         }
   1422       }
   1423     } else if ((!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING)) ||
   1424                (nfa_dm_cb.disc_cb.deact_notify_pending)) {
   1425       xx = nfa_dm_cb.disc_cb.activated_handle;
   1426 
   1427       /* notify event to activated module if failed while reactivation */
   1428       if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
   1429         if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback) {
   1430           disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
   1431           (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
   1432               NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
   1433         }
   1434       } else if ((xx < NFA_DM_DISC_NUM_ENTRIES) &&
   1435                  (nfa_dm_cb.disc_cb.entry[xx].in_use) &&
   1436                  (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)) {
   1437         (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
   1438             NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
   1439       } else {
   1440         /* notify deactivation to application if there is no activated module */
   1441         evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
   1442         nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data);
   1443       }
   1444     }
   1445   } else {
   1446     if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO) {
   1447       if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
   1448         /* restart timer and do not notify upper layer */
   1449         nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
   1450                             NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
   1451         return;
   1452       }
   1453       /* Otherwise, upper layer initiated deactivation. */
   1454     }
   1455 
   1456     /* notify event to activated module */
   1457     if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
   1458       if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback) {
   1459         disc_data.deactivate.type = NFA_DEACTIVATE_TYPE_IDLE;
   1460         (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
   1461             NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
   1462       }
   1463     } else {
   1464       xx = nfa_dm_cb.disc_cb.activated_handle;
   1465 
   1466       if ((xx < NFA_DM_DISC_NUM_ENTRIES) &&
   1467           (nfa_dm_cb.disc_cb.entry[xx].in_use)) {
   1468         if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
   1469           (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
   1470               NFA_DM_RF_DISC_DEACTIVATED_EVT, p_data);
   1471       }
   1472     }
   1473   }
   1474 
   1475   /* clear activated information */
   1476   nfa_dm_cb.disc_cb.activated_tech_mode = 0;
   1477   nfa_dm_cb.disc_cb.activated_rf_disc_id = 0;
   1478   nfa_dm_cb.disc_cb.activated_rf_interface = 0;
   1479   nfa_dm_cb.disc_cb.activated_protocol = NFA_PROTOCOL_INVALID;
   1480   nfa_dm_cb.disc_cb.activated_handle = NFA_HANDLE_INVALID;
   1481   nfa_dm_cb.disc_cb.deact_notify_pending = false;
   1482 }
   1483 
   1484 /*******************************************************************************
   1485 **
   1486 ** Function         nfa_dm_disc_sleep_wakeup
   1487 **
   1488 ** Description      Put tag to sleep, then wake it up. Can be used Perform
   1489 **                  legacy presence check or to wake up tag that went to HALT
   1490 **                  state
   1491 **
   1492 ** Returns          TRUE if operation started
   1493 **
   1494 *******************************************************************************/
   1495 tNFC_STATUS nfa_dm_disc_sleep_wakeup(void) {
   1496   tNFC_STATUS status = NFC_STATUS_FAILED;
   1497 
   1498   if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) {
   1499     /* Deactivate to sleep mode */
   1500     status = nfa_dm_send_deactivate_cmd(NFC_DEACTIVATE_TYPE_SLEEP);
   1501     if (status == NFC_STATUS_OK) {
   1502       /* deactivate to sleep is sent on behalf of sleep wakeup.
   1503        * set the sleep wakeup information in control block */
   1504       nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
   1505       nfa_dm_cb.disc_cb.deact_pending = false;
   1506     }
   1507   }
   1508 
   1509   return (status);
   1510 }
   1511 
   1512 /*******************************************************************************
   1513 **
   1514 ** Function         nfa_dm_is_raw_frame_session
   1515 **
   1516 ** Description      If NFA_SendRawFrame is called since RF activation,
   1517 **                  this function returns TRUE.
   1518 **
   1519 ** Returns          TRUE if NFA_SendRawFrame is called
   1520 **
   1521 *******************************************************************************/
   1522 bool nfa_dm_is_raw_frame_session(void) {
   1523   return ((nfa_dm_cb.flags & NFA_DM_FLAGS_RAW_FRAME) ? true : false);
   1524 }
   1525 
   1526 /*******************************************************************************
   1527 **
   1528 ** Function         nfa_dm_is_p2p_paused
   1529 **
   1530 ** Description      If NFA_PauseP2p is called sand still effective,
   1531 **                  this function returns TRUE.
   1532 **
   1533 ** Returns          TRUE if NFA_SendRawFrame is called
   1534 **
   1535 *******************************************************************************/
   1536 bool nfa_dm_is_p2p_paused(void) {
   1537   return ((nfa_dm_cb.flags & NFA_DM_FLAGS_P2P_PAUSED) ? true : false);
   1538 }
   1539 
   1540 /*******************************************************************************
   1541 **
   1542 ** Function         nfa_dm_disc_end_sleep_wakeup
   1543 **
   1544 ** Description      Sleep Wakeup is complete
   1545 **
   1546 ** Returns          None
   1547 **
   1548 *******************************************************************************/
   1549 static void nfa_dm_disc_end_sleep_wakeup(tNFC_STATUS status) {
   1550   if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO) &&
   1551       (nfa_dm_cb.disc_cb.kovio_tle.in_use)) {
   1552     /* ignore it while doing Kovio presence check */
   1553     return;
   1554   }
   1555 
   1556   if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING) {
   1557     nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_CHECKING;
   1558 
   1559     /* notify RW module that sleep wakeup is finished */
   1560     nfa_rw_handle_sleep_wakeup_rsp(status);
   1561 
   1562     if (nfa_dm_cb.disc_cb.deact_pending) {
   1563       nfa_dm_cb.disc_cb.deact_pending = false;
   1564       /* Perform pending deactivate command and on response notfiy deactivation
   1565        */
   1566       nfa_dm_cb.disc_cb.deact_notify_pending = true;
   1567       tNFA_DM_RF_DISC_DATA nfa_dm_rf_disc_data;
   1568       nfa_dm_rf_disc_data.deactivate_type =
   1569           nfa_dm_cb.disc_cb.pending_deact_type;
   1570       nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD, &nfa_dm_rf_disc_data);
   1571     }
   1572   }
   1573 }
   1574 
   1575 /*******************************************************************************
   1576 **
   1577 ** Function         nfa_dm_disc_kovio_timeout_cback
   1578 **
   1579 ** Description      Timeout for Kovio bar code tag presence check
   1580 **
   1581 ** Returns          void
   1582 **
   1583 *******************************************************************************/
   1584 static void nfa_dm_disc_kovio_timeout_cback(__attribute__((unused))
   1585                                             TIMER_LIST_ENT* p_tle) {
   1586   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
   1587 
   1588   /* notify presence check failure, if presence check is pending */
   1589   nfa_dm_disc_report_kovio_presence_check(NFC_STATUS_FAILED);
   1590 
   1591   if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) {
   1592     /* restart timer in case that upper layer's presence check interval is too
   1593      * long */
   1594     nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
   1595                         NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
   1596   } else {
   1597     /* notify upper layer deactivated event */
   1598     tNFC_DEACTIVATE_DEVT deact;
   1599     deact.status = NFC_STATUS_OK;
   1600     deact.type = NFC_DEACTIVATE_TYPE_DISCOVERY;
   1601     deact.is_ntf = true;
   1602     tNFC_DISCOVER nfc_discover;
   1603     nfc_discover.deactivate = deact;
   1604     nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF, &nfc_discover);
   1605   }
   1606 }
   1607 
   1608 /*******************************************************************************
   1609 **
   1610 ** Function         nfa_dm_disc_start_kovio_presence_check
   1611 **
   1612 ** Description      Deactivate to discovery mode and wait for activation
   1613 **
   1614 ** Returns          TRUE if operation started
   1615 **
   1616 *******************************************************************************/
   1617 tNFC_STATUS nfa_dm_disc_start_kovio_presence_check(void) {
   1618   tNFC_STATUS status = NFC_STATUS_FAILED;
   1619 
   1620   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
   1621 
   1622   if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO) &&
   1623       (nfa_dm_cb.disc_cb.kovio_tle.in_use)) {
   1624     if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) {
   1625       /* restart timer */
   1626       nfa_sys_start_timer(&nfa_dm_cb.disc_cb.kovio_tle, 0,
   1627                           NFA_DM_DISC_TIMEOUT_KOVIO_PRESENCE_CHECK);
   1628 
   1629       /* Deactivate to discovery mode */
   1630       status = nfa_dm_send_deactivate_cmd(NFC_DEACTIVATE_TYPE_DISCOVERY);
   1631 
   1632       if (status == NFC_STATUS_OK) {
   1633         /* deactivate to sleep is sent on behalf of sleep wakeup.
   1634          * set the sleep wakeup information in control block */
   1635         nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
   1636         nfa_dm_cb.disc_cb.deact_pending = false;
   1637       }
   1638     } else {
   1639       /* wait for next activation */
   1640       nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_CHECKING;
   1641       nfa_dm_cb.disc_cb.deact_pending = false;
   1642       status = NFC_STATUS_OK;
   1643     }
   1644   }
   1645 
   1646   return (status);
   1647 }
   1648 
   1649 /*******************************************************************************
   1650 **
   1651 ** Function         nfa_dm_disc_report_kovio_presence_check
   1652 **
   1653 ** Description      Report Kovio presence check status
   1654 **
   1655 ** Returns          None
   1656 **
   1657 *******************************************************************************/
   1658 static void nfa_dm_disc_report_kovio_presence_check(tNFC_STATUS status) {
   1659   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
   1660 
   1661   if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING) {
   1662     nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_CHECKING;
   1663 
   1664     /* notify RW module that sleep wakeup is finished */
   1665     nfa_rw_handle_presence_check_rsp(status);
   1666 
   1667     if (nfa_dm_cb.disc_cb.deact_pending) {
   1668       nfa_dm_cb.disc_cb.deact_pending = false;
   1669       tNFA_DM_RF_DISC_DATA nfa_dm_rf_disc_data;
   1670       nfa_dm_rf_disc_data.deactivate_type =
   1671           nfa_dm_cb.disc_cb.pending_deact_type;
   1672       nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD, &nfa_dm_rf_disc_data);
   1673     }
   1674   }
   1675 }
   1676 
   1677 /*******************************************************************************
   1678 **
   1679 ** Function         nfa_dm_disc_data_cback
   1680 **
   1681 ** Description      Monitoring interface error through data callback
   1682 **
   1683 ** Returns          void
   1684 **
   1685 *******************************************************************************/
   1686 static void nfa_dm_disc_data_cback(__attribute__((unused)) uint8_t conn_id,
   1687                                    tNFC_CONN_EVT event, tNFC_CONN* p_data) {
   1688   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
   1689 
   1690   /* if selection failed */
   1691   if (event == NFC_ERROR_CEVT) {
   1692     nfa_dm_disc_sm_execute(NFA_DM_CORE_INTF_ERROR_NTF, NULL);
   1693   } else if (event == NFC_DATA_CEVT) {
   1694     GKI_freebuf(p_data->data.p_data);
   1695   }
   1696 }
   1697 
   1698 /*******************************************************************************
   1699 **
   1700 ** Function         nfa_dm_disc_new_state
   1701 **
   1702 ** Description      Processing discovery events in NFA_DM_RFST_IDLE state
   1703 **
   1704 ** Returns          void
   1705 **
   1706 *******************************************************************************/
   1707 void nfa_dm_disc_new_state(tNFA_DM_RF_DISC_STATE new_state) {
   1708   tNFA_CONN_EVT_DATA evt_data;
   1709   tNFA_DM_RF_DISC_STATE old_state = nfa_dm_cb.disc_cb.disc_state;
   1710 
   1711   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   1712       "old_state: %s (%d), new_state: %s (%d) "
   1713       "disc_flags: 0x%x",
   1714       nfa_dm_disc_state_2_str(nfa_dm_cb.disc_cb.disc_state).c_str(),
   1715       nfa_dm_cb.disc_cb.disc_state, nfa_dm_disc_state_2_str(new_state).c_str(),
   1716       new_state, nfa_dm_cb.disc_cb.disc_flags);
   1717 
   1718   nfa_dm_cb.disc_cb.disc_state = new_state;
   1719 
   1720   /* not error recovering */
   1721   if ((new_state == NFA_DM_RFST_IDLE) &&
   1722       (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))) {
   1723     if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING) {
   1724       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_STOPPING;
   1725 
   1726       /* if exclusive RF control is stopping */
   1727       if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) {
   1728         if (old_state > NFA_DM_RFST_DISCOVERY) {
   1729           /* notify deactivation to application */
   1730           evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
   1731           nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data);
   1732         }
   1733 
   1734         nfa_dm_rel_excl_rf_control_and_notify();
   1735       } else {
   1736         evt_data.status = NFA_STATUS_OK;
   1737         nfa_dm_conn_cback_event_notify(NFA_RF_DISCOVERY_STOPPED_EVT, &evt_data);
   1738       }
   1739     }
   1740     if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_DISABLING) {
   1741       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
   1742       nfa_sys_check_disabled();
   1743     }
   1744   }
   1745 }
   1746 
   1747 /*******************************************************************************
   1748 **
   1749 ** Function         nfa_dm_disc_sm_idle
   1750 **
   1751 ** Description      Processing discovery events in NFA_DM_RFST_IDLE state
   1752 **
   1753 ** Returns          void
   1754 **
   1755 *******************************************************************************/
   1756 static void nfa_dm_disc_sm_idle(tNFA_DM_RF_DISC_SM_EVENT event,
   1757                                 tNFA_DM_RF_DISC_DATA* p_data) {
   1758   uint8_t xx;
   1759 
   1760   switch (event) {
   1761     case NFA_DM_RF_DISCOVER_CMD:
   1762       nfa_dm_start_rf_discover();
   1763       break;
   1764 
   1765     case NFA_DM_RF_DISCOVER_RSP:
   1766       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
   1767 
   1768       if (p_data->nfc_discover.status == NFC_STATUS_OK) {
   1769         nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
   1770 
   1771         /* if RF discovery was stopped while waiting for response */
   1772         if (nfa_dm_cb.disc_cb.disc_flags &
   1773             (NFA_DM_DISC_FLAGS_STOPPING | NFA_DM_DISC_FLAGS_DISABLING)) {
   1774           /* stop discovery */
   1775           nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
   1776           NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
   1777           break;
   1778         }
   1779 
   1780         if (nfa_dm_cb.disc_cb.excl_disc_entry.in_use) {
   1781           if (nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags &
   1782               NFA_DM_DISC_FLAGS_NOTIFY) {
   1783             nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags &=
   1784                 ~NFA_DM_DISC_FLAGS_NOTIFY;
   1785 
   1786             if (nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback)
   1787               (*(nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback))(
   1788                   NFA_DM_RF_DISC_START_EVT, &p_data->nfc_discover);
   1789           }
   1790         } else {
   1791           /* notify event to each module which is waiting for start */
   1792           for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
   1793             /* if registered module is waiting for starting discovery */
   1794             if ((nfa_dm_cb.disc_cb.entry[xx].in_use) &&
   1795                 (nfa_dm_cb.disc_cb.dm_disc_mask &
   1796                  nfa_dm_cb.disc_cb.entry[xx].selected_disc_mask) &&
   1797                 (nfa_dm_cb.disc_cb.entry[xx].disc_flags &
   1798                  NFA_DM_DISC_FLAGS_NOTIFY)) {
   1799               nfa_dm_cb.disc_cb.entry[xx].disc_flags &=
   1800                   ~NFA_DM_DISC_FLAGS_NOTIFY;
   1801 
   1802               if (nfa_dm_cb.disc_cb.entry[xx].p_disc_cback)
   1803                 (*(nfa_dm_cb.disc_cb.entry[xx].p_disc_cback))(
   1804                     NFA_DM_RF_DISC_START_EVT, &p_data->nfc_discover);
   1805             }
   1806           }
   1807         }
   1808         nfa_dm_disc_notify_started(p_data->nfc_discover.status);
   1809       } else {
   1810         /* in rare case that the discovery states of NFCC and DH mismatch and
   1811          * NFCC rejects Discover Cmd
   1812          * deactivate idle and then start disvocery when got deactivate rsp */
   1813         nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
   1814         NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
   1815       }
   1816       break;
   1817 
   1818     case NFA_DM_RF_DEACTIVATE_RSP:
   1819       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
   1820 
   1821       /* if NFCC goes to idle successfully */
   1822       if (p_data->nfc_discover.status == NFC_STATUS_OK) {
   1823         /* if DH forced to go idle while waiting for deactivation NTF */
   1824         if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
   1825           nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
   1826                                           &(p_data->nfc_discover));
   1827 
   1828           /* check any pending flags like NFA_DM_DISC_FLAGS_STOPPING or
   1829            * NFA_DM_DISC_FLAGS_DISABLING */
   1830           nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
   1831           /* check if need to restart discovery after resync discovery state
   1832            * with NFCC */
   1833           nfa_dm_start_rf_discover();
   1834         }
   1835         /* Otherwise, deactivating when getting unexpected activation */
   1836       }
   1837       /* Otherwise, wait for deactivation NTF */
   1838       break;
   1839 
   1840     case NFA_DM_RF_DEACTIVATE_NTF:
   1841       /* if NFCC sent this after NFCC had rejected deactivate CMD to idle while
   1842        * deactivating */
   1843       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
   1844         if (p_data->nfc_discover.deactivate.type ==
   1845             NFC_DEACTIVATE_TYPE_DISCOVERY) {
   1846           /* stop discovery */
   1847           nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
   1848           NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
   1849         } else {
   1850           nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
   1851                                           &(p_data->nfc_discover));
   1852           /* check any pending flags like NFA_DM_DISC_FLAGS_STOPPING or
   1853            * NFA_DM_DISC_FLAGS_DISABLING */
   1854           nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
   1855           /* check if need to restart discovery after resync discovery state
   1856            * with NFCC */
   1857           nfa_dm_start_rf_discover();
   1858         }
   1859       }
   1860       /* Otherwise, deactivated when received unexpected activation in idle
   1861        * state */
   1862       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
   1863       break;
   1864 
   1865     case NFA_DM_RF_INTF_ACTIVATED_NTF:
   1866       /* unexpected activation, deactivate to idle */
   1867       nfa_dm_cb.disc_cb.disc_flags |=
   1868           (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
   1869       NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
   1870       break;
   1871 
   1872     case NFA_DM_LP_LISTEN_CMD:
   1873       nfa_dm_disc_new_state(NFA_DM_RFST_LP_LISTEN);
   1874       break;
   1875 
   1876     default:
   1877       LOG(ERROR) << StringPrintf("Unexpected discovery event");
   1878       break;
   1879   }
   1880 }
   1881 
   1882 /*******************************************************************************
   1883 **
   1884 ** Function         nfa_dm_disc_sm_discovery
   1885 **
   1886 ** Description      Processing discovery events in NFA_DM_RFST_DISCOVERY state
   1887 **
   1888 ** Returns          void
   1889 **
   1890 *******************************************************************************/
   1891 static void nfa_dm_disc_sm_discovery(tNFA_DM_RF_DISC_SM_EVENT event,
   1892                                      tNFA_DM_RF_DISC_DATA* p_data) {
   1893   switch (event) {
   1894     case NFA_DM_RF_DEACTIVATE_CMD:
   1895       /* if deactivate CMD was not sent to NFCC */
   1896       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
   1897         nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
   1898         NFC_Deactivate(p_data->deactivate_type);
   1899       }
   1900       break;
   1901     case NFA_DM_RF_DEACTIVATE_RSP:
   1902       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
   1903 
   1904       /* if it's not race condition between deactivate CMD and activate NTF */
   1905       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
   1906         /* do not notify deactivated to idle in RF discovery state
   1907         ** because it is internal or stopping RF discovery
   1908         */
   1909 
   1910         /* there was no activation while waiting for deactivation RSP */
   1911         nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
   1912         nfa_dm_start_rf_discover();
   1913       }
   1914       break;
   1915     case NFA_DM_RF_DISCOVER_NTF:
   1916       nfa_dm_disc_new_state(NFA_DM_RFST_W4_ALL_DISCOVERIES);
   1917       nfa_dm_notify_discovery(p_data);
   1918       break;
   1919     case NFA_DM_RF_INTF_ACTIVATED_NTF:
   1920       if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
   1921         DLOG_IF(INFO, nfc_debug_enabled)
   1922             << StringPrintf("RF Activated while waiting for deactivation RSP");
   1923         /* it's race condition. DH has to wait for deactivation NTF */
   1924         nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_NTF;
   1925       } else {
   1926         if (p_data->nfc_discover.activate.intf_param.type ==
   1927             NFC_INTERFACE_EE_DIRECT_RF) {
   1928           nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_ACTIVE);
   1929         } else if (p_data->nfc_discover.activate.rf_tech_param.mode & 0x80) {
   1930           /* Listen mode */
   1931           nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_ACTIVE);
   1932         } else {
   1933           /* Poll mode */
   1934           nfa_dm_disc_new_state(NFA_DM_RFST_POLL_ACTIVE);
   1935         }
   1936 
   1937         if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
   1938             NFA_STATUS_FAILED) {
   1939           DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   1940               "Not matched, restart discovery after receiving "
   1941               "deactivate ntf");
   1942 
   1943           /* after receiving deactivate event, restart discovery */
   1944           nfa_dm_cb.disc_cb.disc_flags |=
   1945               (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
   1946           NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
   1947         }
   1948       }
   1949       break;
   1950 
   1951     case NFA_DM_RF_DEACTIVATE_NTF:
   1952       /* if there was race condition between deactivate CMD and activate NTF */
   1953       if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF) {
   1954         /* race condition is resolved */
   1955         nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
   1956 
   1957         if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
   1958           /* do not notify deactivated to idle in RF discovery state
   1959           ** because it is internal or stopping RF discovery
   1960           */
   1961 
   1962           nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
   1963           nfa_dm_start_rf_discover();
   1964         }
   1965       }
   1966       break;
   1967     case NFA_DM_LP_LISTEN_CMD:
   1968       break;
   1969     case NFA_DM_CORE_INTF_ERROR_NTF:
   1970       break;
   1971     default:
   1972       LOG(ERROR) << StringPrintf("Unexpected discovery event");
   1973       break;
   1974   }
   1975 }
   1976 
   1977 /*******************************************************************************
   1978 **
   1979 ** Function         nfa_dm_disc_sm_w4_all_discoveries
   1980 **
   1981 ** Description      Processing discovery events in
   1982 **                  NFA_DM_RFST_W4_ALL_DISCOVERIES state
   1983 **
   1984 ** Returns          void
   1985 **
   1986 *******************************************************************************/
   1987 static void nfa_dm_disc_sm_w4_all_discoveries(tNFA_DM_RF_DISC_SM_EVENT event,
   1988                                               tNFA_DM_RF_DISC_DATA* p_data) {
   1989   switch (event) {
   1990     case NFA_DM_RF_DEACTIVATE_CMD:
   1991       /* if deactivate CMD was not sent to NFCC */
   1992       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
   1993         nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
   1994         /* only IDLE mode is allowed */
   1995         NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
   1996       }
   1997       break;
   1998     case NFA_DM_RF_DEACTIVATE_RSP:
   1999       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
   2000       /* notify exiting from w4 all discoverie state */
   2001       nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
   2002                                       &(p_data->nfc_discover));
   2003 
   2004       nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
   2005       nfa_dm_start_rf_discover();
   2006       break;
   2007     case NFA_DM_RF_DISCOVER_NTF:
   2008       /* if deactivate CMD is already sent then ignore discover NTF */
   2009       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
   2010         /* Notification Type = NCI_DISCOVER_NTF_LAST or
   2011          * NCI_DISCOVER_NTF_LAST_ABORT */
   2012         if (p_data->nfc_discover.result.more != NCI_DISCOVER_NTF_MORE) {
   2013           nfa_dm_disc_new_state(NFA_DM_RFST_W4_HOST_SELECT);
   2014         }
   2015         nfa_dm_notify_discovery(p_data);
   2016       }
   2017       break;
   2018     case NFA_DM_RF_INTF_ACTIVATED_NTF:
   2019       /*
   2020       ** This is only for ISO15693.
   2021       ** FW sends activation NTF when all responses are received from tags
   2022       ** without host selecting.
   2023       */
   2024       nfa_dm_disc_new_state(NFA_DM_RFST_POLL_ACTIVE);
   2025 
   2026       if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
   2027           NFA_STATUS_FAILED) {
   2028         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2029             "Not matched, restart discovery after receiving deactivate ntf");
   2030 
   2031         /* after receiving deactivate event, restart discovery */
   2032         NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
   2033       }
   2034       break;
   2035     default:
   2036       LOG(ERROR) << StringPrintf("Unexpected discovery event");
   2037       break;
   2038   }
   2039 }
   2040 
   2041 /*******************************************************************************
   2042 **
   2043 ** Function         nfa_dm_disc_sm_w4_host_select
   2044 **
   2045 ** Description      Processing discovery events in NFA_DM_RFST_W4_HOST_SELECT
   2046 **                  state
   2047 **
   2048 ** Returns          void
   2049 **
   2050 *******************************************************************************/
   2051 static void nfa_dm_disc_sm_w4_host_select(tNFA_DM_RF_DISC_SM_EVENT event,
   2052                                           tNFA_DM_RF_DISC_DATA* p_data) {
   2053   tNFA_CONN_EVT_DATA conn_evt;
   2054   tNFA_DM_DISC_FLAGS old_sleep_wakeup_flag =
   2055       (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
   2056   bool sleep_wakeup_event = false;
   2057   bool sleep_wakeup_event_processed = false;
   2058   tNFA_STATUS status;
   2059 
   2060   switch (event) {
   2061     case NFA_DM_RF_DISCOVER_SELECT_CMD:
   2062       /* if not waiting to deactivate */
   2063       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
   2064         NFC_DiscoverySelect(p_data->select.rf_disc_id, p_data->select.protocol,
   2065                             p_data->select.rf_interface);
   2066       } else {
   2067         nfa_dm_disc_conn_event_notify(NFA_SELECT_RESULT_EVT, NFA_STATUS_FAILED);
   2068       }
   2069       break;
   2070 
   2071     case NFA_DM_RF_DISCOVER_SELECT_RSP:
   2072       sleep_wakeup_event = true;
   2073       /* notify application status of selection */
   2074       if (p_data->nfc_discover.status == NFC_STATUS_OK) {
   2075         sleep_wakeup_event_processed = true;
   2076         conn_evt.status = NFA_STATUS_OK;
   2077         /* register callback to get interface error NTF */
   2078         NFC_SetStaticRfCback(nfa_dm_disc_data_cback);
   2079       } else
   2080         conn_evt.status = NFA_STATUS_FAILED;
   2081 
   2082       if (!old_sleep_wakeup_flag) {
   2083         nfa_dm_disc_conn_event_notify(NFA_SELECT_RESULT_EVT,
   2084                                       p_data->nfc_discover.status);
   2085       }
   2086       break;
   2087     case NFA_DM_RF_INTF_ACTIVATED_NTF:
   2088       nfa_dm_disc_new_state(NFA_DM_RFST_POLL_ACTIVE);
   2089       /* always call nfa_dm_disc_notify_activation to update protocol/interface
   2090        * information in NFA control blocks */
   2091       status = nfa_dm_disc_notify_activation(&(p_data->nfc_discover));
   2092       if (old_sleep_wakeup_flag) {
   2093         /* Handle sleep wakeup success: notify RW module of sleep wakeup of tag;
   2094          * if deactivation is pending then deactivate  */
   2095         nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_OK);
   2096       } else if (status == NFA_STATUS_FAILED) {
   2097         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2098             "Not matched, restart discovery after receiving deactivate ntf");
   2099 
   2100         /* after receiving deactivate event, restart discovery */
   2101         NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
   2102       }
   2103       break;
   2104     case NFA_DM_RF_DEACTIVATE_CMD:
   2105       if (old_sleep_wakeup_flag) {
   2106         nfa_dm_cb.disc_cb.deact_pending = true;
   2107         nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
   2108       }
   2109       /* if deactivate CMD was not sent to NFCC */
   2110       else if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP)) {
   2111         nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_W4_RSP;
   2112         /* only IDLE mode is allowed */
   2113         NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
   2114       }
   2115       break;
   2116     case NFA_DM_RF_DEACTIVATE_RSP:
   2117       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
   2118       /* notify exiting from host select state */
   2119       nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
   2120                                       &(p_data->nfc_discover));
   2121 
   2122       nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
   2123       nfa_dm_start_rf_discover();
   2124       break;
   2125 
   2126     case NFA_DM_CORE_INTF_ERROR_NTF:
   2127       sleep_wakeup_event = true;
   2128       if (!old_sleep_wakeup_flag) {
   2129         /* target activation failed, upper layer may deactivate or select again
   2130          */
   2131         conn_evt.status = NFA_STATUS_FAILED;
   2132         nfa_dm_conn_cback_event_notify(NFA_SELECT_RESULT_EVT, &conn_evt);
   2133       }
   2134       break;
   2135     default:
   2136       LOG(ERROR) << StringPrintf("Unexpected discovery event");
   2137       break;
   2138   }
   2139 
   2140   if (old_sleep_wakeup_flag && sleep_wakeup_event &&
   2141       !sleep_wakeup_event_processed) {
   2142     /* performing sleep wakeup and exception conditions happened
   2143      * clear sleep wakeup information and report failure */
   2144     nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_FAILED);
   2145   }
   2146 }
   2147 
   2148 /*******************************************************************************
   2149 **
   2150 ** Function         nfa_dm_disc_sm_poll_active
   2151 **
   2152 ** Description      Processing discovery events in NFA_DM_RFST_POLL_ACTIVE state
   2153 **
   2154 ** Returns          void
   2155 **
   2156 *******************************************************************************/
   2157 static void nfa_dm_disc_sm_poll_active(tNFA_DM_RF_DISC_SM_EVENT event,
   2158                                        tNFA_DM_RF_DISC_DATA* p_data) {
   2159   tNFC_STATUS status;
   2160   tNFA_DM_DISC_FLAGS old_sleep_wakeup_flag =
   2161       (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING);
   2162   bool sleep_wakeup_event = false;
   2163   bool sleep_wakeup_event_processed = false;
   2164 
   2165   switch (event) {
   2166     case NFA_DM_RF_DEACTIVATE_CMD:
   2167       if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
   2168         if ((nfa_dm_cb.disc_cb.activated_rf_interface == NFC_INTERFACE_FRAME) &&
   2169             (p_data->deactivate_type == NFC_DEACTIVATE_TYPE_SLEEP)) {
   2170           /* NCI 2.0- DH is responsible for sending deactivation commands before
   2171            * RF_DEACTIVATE_CMD */
   2172           nfa_dm_send_tag_deselect_cmd(nfa_dm_cb.disc_cb.activated_protocol);
   2173         }
   2174       }
   2175 
   2176       if (nfa_dm_cb.disc_cb.activated_protocol == NCI_PROTOCOL_MIFARE) {
   2177         nfa_dm_cb.disc_cb.deact_pending = true;
   2178         nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
   2179         status = nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
   2180         break;
   2181       }
   2182 
   2183       if (old_sleep_wakeup_flag) {
   2184         /* sleep wakeup is already enabled when deactivate cmd is requested,
   2185          * keep the information in control block to issue it later */
   2186         nfa_dm_cb.disc_cb.deact_pending = true;
   2187         nfa_dm_cb.disc_cb.pending_deact_type = p_data->deactivate_type;
   2188       } else {
   2189         status = nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
   2190       }
   2191 
   2192       break;
   2193     case NFA_DM_RF_DEACTIVATE_RSP:
   2194       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
   2195       /* register callback to get interface error NTF */
   2196       NFC_SetStaticRfCback(nfa_dm_disc_data_cback);
   2197 
   2198       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
   2199         /* it's race condition. received deactivate NTF before receiving RSP */
   2200 
   2201         tNFC_DEACTIVATE_DEVT deact;
   2202         deact.status = NFC_STATUS_OK;
   2203         deact.type = NFC_DEACTIVATE_TYPE_IDLE;
   2204         deact.is_ntf = true;
   2205         tNFC_DISCOVER nfc_discover;
   2206         nfc_discover.deactivate = deact;
   2207         nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
   2208                                         &nfc_discover);
   2209 
   2210         /* NFCC is in IDLE state */
   2211         nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
   2212         nfa_dm_start_rf_discover();
   2213       }
   2214       break;
   2215     case NFA_DM_RF_DEACTIVATE_NTF:
   2216       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
   2217 
   2218       nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
   2219 
   2220       if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
   2221         /* it's race condition. received deactivate NTF before receiving RSP */
   2222         /* notify deactivation after receiving deactivate RSP */
   2223         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2224             "Rx deactivate NTF while waiting for deactivate RSP");
   2225         break;
   2226       }
   2227       if (p_data->nfc_discover.deactivate.reason !=
   2228           NFC_DEACTIVATE_REASON_DH_REQ_FAILED) {
   2229         sleep_wakeup_event = true;
   2230         nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
   2231                                         &(p_data->nfc_discover));
   2232       }
   2233       if ((p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP) ||
   2234           (p_data->nfc_discover.deactivate.type ==
   2235            NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
   2236         if (p_data->nfc_discover.deactivate.reason !=
   2237             NFC_DEACTIVATE_REASON_DH_REQ_FAILED) {
   2238           /* count for number of times deactivate cmd sent */
   2239           nfa_dm_cb.deactivate_cmd_retry_count = 0;
   2240         }
   2241         nfa_dm_disc_new_state(NFA_DM_RFST_W4_HOST_SELECT);
   2242         if (old_sleep_wakeup_flag) {
   2243           sleep_wakeup_event_processed = true;
   2244           /* process pending deactivate request */
   2245           if (nfa_dm_cb.disc_cb.deact_pending) {
   2246             /* notify RW module that sleep wakeup is finished */
   2247             /* if deactivation is pending then deactivate  */
   2248             nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_OK);
   2249 
   2250             /* Notify NFA RW sub-systems because NFA_DM_RF_DEACTIVATE_RSP will
   2251              * not call this function */
   2252             nfa_rw_proc_disc_evt(NFA_DM_RF_DISC_DEACTIVATED_EVT, NULL, true);
   2253           } else {
   2254             /* Successfully went to sleep mode for sleep wakeup */
   2255             /* Now wake up the tag to complete the operation */
   2256             NFC_DiscoverySelect(nfa_dm_cb.disc_cb.activated_rf_disc_id,
   2257                                 nfa_dm_cb.disc_cb.activated_protocol,
   2258                                 nfa_dm_cb.disc_cb.activated_rf_interface);
   2259           }
   2260         }
   2261         if (p_data->nfc_discover.deactivate.reason ==
   2262             NFC_DEACTIVATE_REASON_DH_REQ_FAILED) {
   2263           /* in case deactivation is not sucessfull, NFCC shall send
   2264              RF_DEACTIVATE_NTF with DH Req failed due to error.
   2265              MW shall send deactivation cmd again for 3 three times. if
   2266              deactivation is not successfull 3 times also,
   2267              then MW shall send deacivate cmd with deactivate type is
   2268              discovery */
   2269           if (nfa_dm_cb.deactivate_cmd_retry_count == 3) {
   2270             if ((!old_sleep_wakeup_flag) ||
   2271                 (!nfa_dm_cb.disc_cb.deact_pending)) {
   2272               nfa_dm_send_deactivate_cmd(NFA_DEACTIVATE_TYPE_DISCOVERY);
   2273             }
   2274             nfa_dm_cb.deactivate_cmd_retry_count = 0;
   2275           } else {
   2276             nfa_dm_cb.deactivate_cmd_retry_count++;
   2277             nfa_dm_send_deactivate_cmd(p_data->nfc_discover.deactivate.type);
   2278           }
   2279         }
   2280       } else if (p_data->nfc_discover.deactivate.type ==
   2281                  NFC_DEACTIVATE_TYPE_IDLE) {
   2282         nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
   2283         nfa_dm_start_rf_discover();
   2284       } else if (p_data->nfc_discover.deactivate.type ==
   2285                  NFC_DEACTIVATE_TYPE_DISCOVERY) {
   2286         nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
   2287         if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING) {
   2288           /* stop discovery */
   2289           NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
   2290         }
   2291       }
   2292       break;
   2293 
   2294     case NFA_DM_CORE_INTF_ERROR_NTF:
   2295       sleep_wakeup_event = true;
   2296       if ((!old_sleep_wakeup_flag) || (!nfa_dm_cb.disc_cb.deact_pending)) {
   2297         nfa_dm_send_deactivate_cmd(NFA_DEACTIVATE_TYPE_DISCOVERY);
   2298       }
   2299       break;
   2300 
   2301     default:
   2302       LOG(ERROR) << StringPrintf("Unexpected discovery event");
   2303       break;
   2304   }
   2305 
   2306   if (old_sleep_wakeup_flag && sleep_wakeup_event &&
   2307       !sleep_wakeup_event_processed) {
   2308     /* performing sleep wakeup and exception conditions happened
   2309      * clear sleep wakeup information and report failure */
   2310     nfa_dm_disc_end_sleep_wakeup(NFC_STATUS_FAILED);
   2311   }
   2312 }
   2313 
   2314 /*******************************************************************************
   2315 **
   2316 ** Function         nfa_dm_disc_sm_listen_active
   2317 **
   2318 ** Description      Processing discovery events in NFA_DM_RFST_LISTEN_ACTIVE
   2319 **                  state
   2320 **
   2321 ** Returns          void
   2322 **
   2323 *******************************************************************************/
   2324 static void nfa_dm_disc_sm_listen_active(tNFA_DM_RF_DISC_SM_EVENT event,
   2325                                          tNFA_DM_RF_DISC_DATA* p_data) {
   2326   tNFC_DEACTIVATE_DEVT deact;
   2327 
   2328   switch (event) {
   2329     case NFA_DM_RF_DEACTIVATE_CMD:
   2330       nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
   2331       break;
   2332     case NFA_DM_RF_DEACTIVATE_RSP:
   2333       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
   2334       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
   2335         /* it's race condition. received deactivate NTF before receiving RSP */
   2336 
   2337         deact.status = NFC_STATUS_OK;
   2338         deact.type = NFC_DEACTIVATE_TYPE_IDLE;
   2339         deact.is_ntf = true;
   2340         tNFC_DISCOVER nfc_discover;
   2341         nfc_discover.deactivate = deact;
   2342         nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
   2343                                         &nfc_discover);
   2344 
   2345         /* NFCC is in IDLE state */
   2346         nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
   2347         nfa_dm_start_rf_discover();
   2348       }
   2349       break;
   2350     case NFA_DM_RF_DEACTIVATE_NTF:
   2351       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
   2352 
   2353       nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
   2354 
   2355       if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
   2356         /* it's race condition. received deactivate NTF before receiving RSP */
   2357         /* notify deactivation after receiving deactivate RSP */
   2358         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2359             "Rx deactivate NTF while waiting for deactivate RSP");
   2360       } else {
   2361         nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
   2362                                         &(p_data->nfc_discover));
   2363 
   2364         if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) {
   2365           nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
   2366           nfa_dm_start_rf_discover();
   2367         } else if ((p_data->nfc_discover.deactivate.type ==
   2368                     NFC_DEACTIVATE_TYPE_SLEEP) ||
   2369                    (p_data->nfc_discover.deactivate.type ==
   2370                     NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
   2371           nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_SLEEP);
   2372         } else if (p_data->nfc_discover.deactivate.type ==
   2373                    NFC_DEACTIVATE_TYPE_DISCOVERY) {
   2374           /* Discovery */
   2375           nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
   2376           if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_STOPPING) {
   2377             /* stop discovery */
   2378             NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
   2379           }
   2380         }
   2381       }
   2382       break;
   2383 
   2384     case NFA_DM_CORE_INTF_ERROR_NTF:
   2385       break;
   2386     default:
   2387       LOG(ERROR) << StringPrintf("Unexpected discovery event");
   2388       break;
   2389   }
   2390 }
   2391 
   2392 /*******************************************************************************
   2393 **
   2394 ** Function         nfa_dm_disc_sm_listen_sleep
   2395 **
   2396 ** Description      Processing discovery events in NFA_DM_RFST_LISTEN_SLEEP
   2397 **                  state
   2398 **
   2399 ** Returns          void
   2400 **
   2401 *******************************************************************************/
   2402 static void nfa_dm_disc_sm_listen_sleep(tNFA_DM_RF_DISC_SM_EVENT event,
   2403                                         tNFA_DM_RF_DISC_DATA* p_data) {
   2404   switch (event) {
   2405     case NFA_DM_RF_DEACTIVATE_CMD:
   2406       nfa_dm_send_deactivate_cmd(p_data->deactivate_type);
   2407 
   2408       /* if deactivate type is not discovery then NFCC will not sent
   2409        * deactivation NTF */
   2410       if (p_data->deactivate_type != NFA_DEACTIVATE_TYPE_DISCOVERY) {
   2411         nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
   2412         nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
   2413       }
   2414       break;
   2415     case NFA_DM_RF_DEACTIVATE_RSP:
   2416       nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
   2417       /* if deactivate type in CMD was IDLE */
   2418       if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_NTF)) {
   2419         nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
   2420                                         &(p_data->nfc_discover));
   2421 
   2422         nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
   2423         nfa_dm_start_rf_discover();
   2424       }
   2425       break;
   2426     case NFA_DM_RF_DEACTIVATE_NTF:
   2427       /* clear both W4_RSP and W4_NTF because of race condition between
   2428        * deactivat CMD and link loss */
   2429       nfa_dm_cb.disc_cb.disc_flags &=
   2430           ~(NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF);
   2431       nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.tle);
   2432 
   2433       /* there is no active protocol in this state, so broadcast to all by using
   2434        * NFA_DM_RF_DEACTIVATE_RSP */
   2435       nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_RSP,
   2436                                       &(p_data->nfc_discover));
   2437 
   2438       if (p_data->nfc_discover.deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) {
   2439         nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
   2440         nfa_dm_start_rf_discover();
   2441       } else if (p_data->nfc_discover.deactivate.type ==
   2442                  NFA_DEACTIVATE_TYPE_DISCOVERY) {
   2443         nfa_dm_disc_new_state(NFA_DM_RFST_DISCOVERY);
   2444       } else {
   2445         LOG(ERROR) << StringPrintf("Unexpected deactivation type");
   2446         nfa_dm_disc_new_state(NFA_DM_RFST_IDLE);
   2447         nfa_dm_start_rf_discover();
   2448       }
   2449       break;
   2450     case NFA_DM_RF_INTF_ACTIVATED_NTF:
   2451       nfa_dm_disc_new_state(NFA_DM_RFST_LISTEN_ACTIVE);
   2452       if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
   2453           NFA_STATUS_FAILED) {
   2454         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2455             "Not matched, restart discovery after receiving deactivate ntf");
   2456 
   2457         /* after receiving deactivate event, restart discovery */
   2458         NFC_Deactivate(NFA_DEACTIVATE_TYPE_IDLE);
   2459       }
   2460       break;
   2461     default:
   2462       LOG(ERROR) << StringPrintf("Unexpected discovery event");
   2463       break;
   2464   }
   2465 }
   2466 
   2467 /*******************************************************************************
   2468 **
   2469 ** Function         nfa_dm_disc_sm_lp_listen
   2470 **
   2471 ** Description      Processing discovery events in NFA_DM_RFST_LP_LISTEN state
   2472 **
   2473 ** Returns          void
   2474 **
   2475 *******************************************************************************/
   2476 static void nfa_dm_disc_sm_lp_listen(tNFA_DM_RF_DISC_SM_EVENT event,
   2477                                      tNFA_DM_RF_DISC_DATA* p_data) {
   2478   switch (event) {
   2479     case NFA_DM_RF_INTF_ACTIVATED_NTF:
   2480       nfa_dm_disc_new_state(NFA_DM_RFST_LP_ACTIVE);
   2481       nfa_dm_disc_notify_activation(&(p_data->nfc_discover));
   2482       if (nfa_dm_disc_notify_activation(&(p_data->nfc_discover)) ==
   2483           NFA_STATUS_FAILED) {
   2484         DLOG_IF(INFO, nfc_debug_enabled)
   2485             << StringPrintf("Not matched, unexpected activation");
   2486       }
   2487       break;
   2488 
   2489     default:
   2490       LOG(ERROR) << StringPrintf("Unexpected discovery event");
   2491       break;
   2492   }
   2493 }
   2494 
   2495 /*******************************************************************************
   2496 **
   2497 ** Function         nfa_dm_disc_sm_lp_active
   2498 **
   2499 ** Description      Processing discovery events in NFA_DM_RFST_LP_ACTIVE state
   2500 **
   2501 ** Returns          void
   2502 **
   2503 *******************************************************************************/
   2504 static void nfa_dm_disc_sm_lp_active(tNFA_DM_RF_DISC_SM_EVENT event,
   2505                                      tNFA_DM_RF_DISC_DATA* p_data) {
   2506   switch (event) {
   2507     case NFA_DM_RF_DEACTIVATE_NTF:
   2508       nfa_dm_disc_new_state(NFA_DM_RFST_LP_LISTEN);
   2509       nfa_dm_disc_notify_deactivation(NFA_DM_RF_DEACTIVATE_NTF,
   2510                                       &(p_data->nfc_discover));
   2511       break;
   2512     default:
   2513       LOG(ERROR) << StringPrintf("Unexpected discovery event");
   2514       break;
   2515   }
   2516 }
   2517 
   2518 /*******************************************************************************
   2519 **
   2520 ** Function         nfa_dm_disc_sm_execute
   2521 **
   2522 ** Description      Processing discovery related events
   2523 **
   2524 ** Returns          void
   2525 **
   2526 *******************************************************************************/
   2527 void nfa_dm_disc_sm_execute(tNFA_DM_RF_DISC_SM_EVENT event,
   2528                             tNFA_DM_RF_DISC_DATA* p_data) {
   2529   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2530       "state: %s (%d), event: %s(%d) disc_flags: "
   2531       "0x%x",
   2532       nfa_dm_disc_state_2_str(nfa_dm_cb.disc_cb.disc_state).c_str(),
   2533       nfa_dm_cb.disc_cb.disc_state, nfa_dm_disc_event_2_str(event).c_str(),
   2534       event, nfa_dm_cb.disc_cb.disc_flags);
   2535 
   2536   switch (nfa_dm_cb.disc_cb.disc_state) {
   2537     /*  RF Discovery State - Idle */
   2538     case NFA_DM_RFST_IDLE:
   2539       nfa_dm_disc_sm_idle(event, p_data);
   2540       break;
   2541 
   2542     /* RF Discovery State - Discovery */
   2543     case NFA_DM_RFST_DISCOVERY:
   2544       nfa_dm_disc_sm_discovery(event, p_data);
   2545       break;
   2546 
   2547     /*RF Discovery State - Wait for all discoveries */
   2548     case NFA_DM_RFST_W4_ALL_DISCOVERIES:
   2549       nfa_dm_disc_sm_w4_all_discoveries(event, p_data);
   2550       break;
   2551 
   2552     /* RF Discovery State - Wait for host selection */
   2553     case NFA_DM_RFST_W4_HOST_SELECT:
   2554       nfa_dm_disc_sm_w4_host_select(event, p_data);
   2555       break;
   2556 
   2557     /* RF Discovery State - Poll mode activated */
   2558     case NFA_DM_RFST_POLL_ACTIVE:
   2559       nfa_dm_disc_sm_poll_active(event, p_data);
   2560       break;
   2561 
   2562     /* RF Discovery State - listen mode activated */
   2563     case NFA_DM_RFST_LISTEN_ACTIVE:
   2564       nfa_dm_disc_sm_listen_active(event, p_data);
   2565       break;
   2566 
   2567     /* RF Discovery State - listen mode sleep */
   2568     case NFA_DM_RFST_LISTEN_SLEEP:
   2569       nfa_dm_disc_sm_listen_sleep(event, p_data);
   2570       break;
   2571 
   2572     /* Listening in Low Power mode    */
   2573     case NFA_DM_RFST_LP_LISTEN:
   2574       nfa_dm_disc_sm_lp_listen(event, p_data);
   2575       break;
   2576 
   2577     /* Activated in Low Power mode    */
   2578     case NFA_DM_RFST_LP_ACTIVE:
   2579       nfa_dm_disc_sm_lp_active(event, p_data);
   2580       break;
   2581   }
   2582   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2583       "new state: %s (%d), disc_flags: 0x%x",
   2584       nfa_dm_disc_state_2_str(nfa_dm_cb.disc_cb.disc_state).c_str(),
   2585       nfa_dm_cb.disc_cb.disc_state, nfa_dm_cb.disc_cb.disc_flags);
   2586 }
   2587 
   2588 /*******************************************************************************
   2589 **
   2590 ** Function         nfa_dm_add_rf_discover
   2591 **
   2592 ** Description      Add discovery configuration and callback function
   2593 **
   2594 ** Returns          valid handle if success
   2595 **
   2596 *******************************************************************************/
   2597 tNFA_HANDLE nfa_dm_add_rf_discover(tNFA_DM_DISC_TECH_PROTO_MASK disc_mask,
   2598                                    tNFA_DM_DISC_HOST_ID host_id,
   2599                                    tNFA_DISCOVER_CBACK* p_disc_cback) {
   2600   uint8_t xx;
   2601 
   2602   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("disc_mask=0x%x", disc_mask);
   2603 
   2604   for (xx = 0; xx < NFA_DM_DISC_NUM_ENTRIES; xx++) {
   2605     if (!nfa_dm_cb.disc_cb.entry[xx].in_use) {
   2606       nfa_dm_cb.disc_cb.entry[xx].in_use = true;
   2607       nfa_dm_cb.disc_cb.entry[xx].requested_disc_mask = disc_mask;
   2608       nfa_dm_cb.disc_cb.entry[xx].host_id = host_id;
   2609       nfa_dm_cb.disc_cb.entry[xx].p_disc_cback = p_disc_cback;
   2610       nfa_dm_cb.disc_cb.entry[xx].disc_flags = NFA_DM_DISC_FLAGS_NOTIFY;
   2611       return xx;
   2612     }
   2613   }
   2614 
   2615   return NFA_HANDLE_INVALID;
   2616 }
   2617 
   2618 /*******************************************************************************
   2619 **
   2620 ** Function         nfa_dm_start_excl_discovery
   2621 **
   2622 ** Description      Start exclusive RF discovery
   2623 **
   2624 ** Returns          void
   2625 **
   2626 *******************************************************************************/
   2627 void nfa_dm_start_excl_discovery(tNFA_TECHNOLOGY_MASK poll_tech_mask,
   2628                                  tNFA_LISTEN_CFG* p_listen_cfg,
   2629                                  tNFA_DISCOVER_CBACK* p_disc_cback) {
   2630   tNFA_DM_DISC_TECH_PROTO_MASK poll_disc_mask = 0;
   2631 
   2632   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
   2633 
   2634   if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A) {
   2635     poll_disc_mask |= NFA_DM_DISC_MASK_PA_T1T;
   2636     poll_disc_mask |= NFA_DM_DISC_MASK_PA_T2T;
   2637     poll_disc_mask |= NFA_DM_DISC_MASK_PA_ISO_DEP;
   2638     poll_disc_mask |= NFA_DM_DISC_MASK_PA_NFC_DEP;
   2639     poll_disc_mask |= NFA_DM_DISC_MASK_P_LEGACY;
   2640   }
   2641   if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
   2642     if (poll_tech_mask & NFA_TECHNOLOGY_MASK_ACTIVE) {
   2643       poll_disc_mask |= NFA_DM_DISC_MASK_PACM_NFC_DEP;
   2644     }
   2645   } else {
   2646     if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE) {
   2647       poll_disc_mask |= NFA_DM_DISC_MASK_PAA_NFC_DEP;
   2648     }
   2649     if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE) {
   2650       poll_disc_mask |= NFA_DM_DISC_MASK_PFA_NFC_DEP;
   2651     }
   2652   }
   2653 
   2654   if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B) {
   2655     poll_disc_mask |= NFA_DM_DISC_MASK_PB_ISO_DEP;
   2656   }
   2657   if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F) {
   2658     poll_disc_mask |= NFA_DM_DISC_MASK_PF_T3T;
   2659     poll_disc_mask |= NFA_DM_DISC_MASK_PF_NFC_DEP;
   2660   }
   2661   if (poll_tech_mask & NFA_TECHNOLOGY_MASK_V) {
   2662     poll_disc_mask |= NFA_DM_DISC_MASK_P_T5T;
   2663   }
   2664   if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME) {
   2665     poll_disc_mask |= NFA_DM_DISC_MASK_P_B_PRIME;
   2666   }
   2667   if (poll_tech_mask & NFA_TECHNOLOGY_MASK_KOVIO) {
   2668     poll_disc_mask |= NFA_DM_DISC_MASK_P_KOVIO;
   2669   }
   2670 
   2671   nfa_dm_cb.disc_cb.excl_disc_entry.in_use = true;
   2672   nfa_dm_cb.disc_cb.excl_disc_entry.requested_disc_mask = poll_disc_mask;
   2673   nfa_dm_cb.disc_cb.excl_disc_entry.host_id = NFA_DM_DISC_HOST_ID_DH;
   2674   nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback = p_disc_cback;
   2675   nfa_dm_cb.disc_cb.excl_disc_entry.disc_flags = NFA_DM_DISC_FLAGS_NOTIFY;
   2676 
   2677   memcpy(&nfa_dm_cb.disc_cb.excl_listen_config, p_listen_cfg,
   2678          sizeof(tNFA_LISTEN_CFG));
   2679 
   2680   nfa_dm_disc_sm_execute(NFA_DM_RF_DISCOVER_CMD, NULL);
   2681 }
   2682 
   2683 /*******************************************************************************
   2684 **
   2685 ** Function         nfa_dm_stop_excl_discovery
   2686 **
   2687 ** Description      Stop exclusive RF discovery
   2688 **
   2689 ** Returns          void
   2690 **
   2691 *******************************************************************************/
   2692 void nfa_dm_stop_excl_discovery(void) {
   2693   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
   2694 
   2695   nfa_dm_cb.disc_cb.excl_disc_entry.in_use = false;
   2696   nfa_dm_cb.disc_cb.excl_disc_entry.p_disc_cback = NULL;
   2697 }
   2698 
   2699 /*******************************************************************************
   2700 **
   2701 ** Function         nfa_dm_delete_rf_discover
   2702 **
   2703 ** Description      Remove discovery configuration and callback function
   2704 **
   2705 ** Returns          void
   2706 **
   2707 *******************************************************************************/
   2708 void nfa_dm_delete_rf_discover(tNFA_HANDLE handle) {
   2709   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("handle=0x%x", handle);
   2710 
   2711   if (handle < NFA_DM_DISC_NUM_ENTRIES) {
   2712     nfa_dm_cb.disc_cb.entry[handle].in_use = false;
   2713   } else {
   2714     LOG(ERROR) << StringPrintf("Invalid discovery handle");
   2715   }
   2716 }
   2717 
   2718 /*******************************************************************************
   2719 **
   2720 ** Function         nfa_dm_rf_discover_select
   2721 **
   2722 ** Description      Select target, protocol and RF interface
   2723 **
   2724 ** Returns          void
   2725 **
   2726 *******************************************************************************/
   2727 void nfa_dm_rf_discover_select(uint8_t rf_disc_id, tNFA_NFC_PROTOCOL protocol,
   2728                                tNFA_INTF_TYPE rf_interface) {
   2729   tNFA_DM_DISC_SELECT_PARAMS select_params;
   2730   tNFA_CONN_EVT_DATA conn_evt;
   2731 
   2732   DLOG_IF(INFO, nfc_debug_enabled)
   2733       << StringPrintf("rf_disc_id:0x%X, protocol:0x%X, rf_interface:0x%X",
   2734                       rf_disc_id, protocol, rf_interface);
   2735 
   2736   if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT) {
   2737     /* state is OK: notify the status when the response is received from NFCC */
   2738     select_params.rf_disc_id = rf_disc_id;
   2739     select_params.protocol = protocol;
   2740     select_params.rf_interface = rf_interface;
   2741 
   2742     nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_NOTIFY;
   2743     tNFA_DM_RF_DISC_DATA nfa_dm_rf_disc_data;
   2744     nfa_dm_rf_disc_data.select = select_params;
   2745     nfa_dm_disc_sm_execute(NFA_DM_RF_DISCOVER_SELECT_CMD, &nfa_dm_rf_disc_data);
   2746   } else {
   2747     /* Wrong state: notify failed status right away */
   2748     conn_evt.status = NFA_STATUS_FAILED;
   2749     nfa_dm_conn_cback_event_notify(NFA_SELECT_RESULT_EVT, &conn_evt);
   2750   }
   2751 }
   2752 
   2753 /*******************************************************************************
   2754 **
   2755 ** Function         nfa_dm_rf_deactivate
   2756 **
   2757 ** Description      Deactivate NFC link
   2758 **
   2759 ** Returns          NFA_STATUS_OK if success
   2760 **
   2761 *******************************************************************************/
   2762 tNFA_STATUS nfa_dm_rf_deactivate(tNFA_DEACTIVATE_TYPE deactivate_type) {
   2763   DLOG_IF(INFO, nfc_debug_enabled)
   2764       << StringPrintf("deactivate_type:0x%X", deactivate_type);
   2765 
   2766   if (deactivate_type == NFA_DEACTIVATE_TYPE_SLEEP) {
   2767     if (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_NFC_DEP)
   2768       deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP_AF;
   2769     else
   2770       deactivate_type = NFC_DEACTIVATE_TYPE_SLEEP;
   2771   }
   2772 
   2773   if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE) {
   2774     return NFA_STATUS_FAILED;
   2775   } else if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_DISCOVERY) {
   2776     if (deactivate_type == NFA_DEACTIVATE_TYPE_DISCOVERY) {
   2777       if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
   2778         nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
   2779         nfa_dm_disc_kovio_timeout_cback(&nfa_dm_cb.disc_cb.kovio_tle);
   2780         return NFA_STATUS_OK;
   2781       } else {
   2782         /* it could be race condition. */
   2783         DLOG_IF(INFO, nfc_debug_enabled)
   2784             << StringPrintf("already in discovery state");
   2785         return NFA_STATUS_FAILED;
   2786       }
   2787     } else if (deactivate_type == NFA_DEACTIVATE_TYPE_IDLE) {
   2788       if (nfa_dm_cb.disc_cb.kovio_tle.in_use) {
   2789         nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
   2790         nfa_dm_disc_kovio_timeout_cback(&nfa_dm_cb.disc_cb.kovio_tle);
   2791       }
   2792       tNFA_DM_RF_DISC_DATA nfa_dm_rf_disc_data;
   2793       nfa_dm_rf_disc_data.deactivate_type = deactivate_type;
   2794       nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD, &nfa_dm_rf_disc_data);
   2795       return NFA_STATUS_OK;
   2796     } else {
   2797       return NFA_STATUS_FAILED;
   2798     }
   2799   } else {
   2800     tNFA_DM_RF_DISC_DATA nfa_dm_rf_disc_data;
   2801     nfa_dm_rf_disc_data.deactivate_type = deactivate_type;
   2802     nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD, &nfa_dm_rf_disc_data);
   2803     return NFA_STATUS_OK;
   2804   }
   2805 }
   2806 
   2807 /*******************************************************************************
   2808 **
   2809 ** Function         nfa_dm_disc_state_2_str
   2810 **
   2811 ** Description      convert nfc discovery state to string
   2812 **
   2813 *******************************************************************************/
   2814 static std::string nfa_dm_disc_state_2_str(uint8_t state) {
   2815   switch (state) {
   2816     case NFA_DM_RFST_IDLE:
   2817       return "IDLE";
   2818 
   2819     case NFA_DM_RFST_DISCOVERY:
   2820       return "DISCOVERY";
   2821 
   2822     case NFA_DM_RFST_W4_ALL_DISCOVERIES:
   2823       return "W4_ALL_DISCOVERIES";
   2824 
   2825     case NFA_DM_RFST_W4_HOST_SELECT:
   2826       return "W4_HOST_SELECT";
   2827 
   2828     case NFA_DM_RFST_POLL_ACTIVE:
   2829       return "POLL_ACTIVE";
   2830 
   2831     case NFA_DM_RFST_LISTEN_ACTIVE:
   2832       return "LISTEN_ACTIVE";
   2833 
   2834     case NFA_DM_RFST_LISTEN_SLEEP:
   2835       return "LISTEN_SLEEP";
   2836 
   2837     case NFA_DM_RFST_LP_LISTEN:
   2838       return "LP_LISTEN";
   2839 
   2840     case NFA_DM_RFST_LP_ACTIVE:
   2841       return "LP_ACTIVE";
   2842   }
   2843   return "Unknown";
   2844 }
   2845 
   2846 /*******************************************************************************
   2847 **
   2848 ** Function         nfa_dm_disc_event_2_str
   2849 **
   2850 ** Description      convert nfc discovery RSP/NTF to string
   2851 **
   2852 *******************************************************************************/
   2853 static std::string nfa_dm_disc_event_2_str(uint8_t event) {
   2854   switch (event) {
   2855     case NFA_DM_RF_DISCOVER_CMD:
   2856       return "DISCOVER_CMD";
   2857     case NFA_DM_RF_DISCOVER_RSP:
   2858       return "DISCOVER_RSP";
   2859     case NFA_DM_RF_DISCOVER_NTF:
   2860       return "DISCOVER_NTF";
   2861     case NFA_DM_RF_DISCOVER_SELECT_CMD:
   2862       return "SELECT_CMD";
   2863     case NFA_DM_RF_DISCOVER_SELECT_RSP:
   2864       return "SELECT_RSP";
   2865     case NFA_DM_RF_INTF_ACTIVATED_NTF:
   2866       return "ACTIVATED_NTF";
   2867     case NFA_DM_RF_DEACTIVATE_CMD:
   2868       return "DEACTIVATE_CMD";
   2869     case NFA_DM_RF_DEACTIVATE_RSP:
   2870       return "DEACTIVATE_RSP";
   2871     case NFA_DM_RF_DEACTIVATE_NTF:
   2872       return "DEACTIVATE_NTF";
   2873     case NFA_DM_LP_LISTEN_CMD:
   2874       return "NFA_DM_LP_LISTEN_CMD";
   2875     case NFA_DM_CORE_INTF_ERROR_NTF:
   2876       return "INTF_ERROR_NTF";
   2877     default:
   2878       return "Unknown";
   2879   }
   2880 }
   2881 
   2882 /*******************************************************************************
   2883 **
   2884 ** Function         P2P_Prio_Logic
   2885 **
   2886 ** Description      Implements algorithm for NFC-DEP protocol priority over
   2887 **                  ISO-DEP protocol.
   2888 **
   2889 ** Returns          True if success
   2890 **
   2891 *******************************************************************************/
   2892 bool nfa_dm_p2p_prio_logic(uint8_t event, uint8_t* p, uint8_t event_type) {
   2893   if (!nfa_poll_bail_out_mode) {
   2894     DLOG_IF(INFO, nfc_debug_enabled)
   2895         << StringPrintf("p2p priority is running under bail out mode ONLY.");
   2896     return true;
   2897   }
   2898 
   2899   if ((nfa_dm_cb.flags & NFA_DM_FLAGS_P2P_PAUSED) &&
   2900       (nfa_dm_cb.flags & NFA_DM_FLAGS_LISTEN_DISABLED)) {
   2901     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2902         "returning from nfa_dm_p2p_prio_logic  Disable p2p_prio_logic");
   2903     return true;
   2904   }
   2905   if (appl_dta_mode_flag == 0x01) {
   2906     /*Disable the P2P Prio Logic when DTA is running*/
   2907     return TRUE;
   2908   }
   2909   if (event == NCI_MSG_RF_DISCOVER &&
   2910       p2p_prio_logic_data.timer_expired == true &&
   2911       event_type == NFA_DM_P2P_PRIO_RSP) {
   2912     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2913         "nfa_dm_p2p_prio_logic starting a timer for next rf intf activated "
   2914         "ntf");
   2915     nfc_start_quick_timer(&p2p_prio_logic_data.timer_list,
   2916                           NFC_TTYPE_P2P_PRIO_LOGIC_CLEANUP,
   2917                           ((uint32_t)nfa_dm_act_get_rf_disc_duration() *
   2918                            QUICK_TIMER_TICKS_PER_SEC) /
   2919                               1000);
   2920     return true;
   2921   }
   2922 
   2923   if (event == NCI_MSG_RF_INTF_ACTIVATED &&
   2924       p2p_prio_logic_data.timer_expired == true) {
   2925     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2926         "nfa_dm_p2p_prio_logic stopping a timer for next rf intf activated "
   2927         "ntf");
   2928     nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
   2929   }
   2930 
   2931   if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_DISCOVERY) {
   2932     uint8_t rf_disc_id = 0xFF;
   2933     uint8_t type = 0xFF;
   2934     uint8_t protocol = 0xFF;
   2935     uint8_t tech_mode = 0xFF;
   2936 
   2937     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("P2P_Prio_Logic");
   2938 
   2939     if (event == NCI_MSG_RF_INTF_ACTIVATED) {
   2940       rf_disc_id = *p++;
   2941       type = *p++;
   2942       protocol = *p++;
   2943       tech_mode = *p++;
   2944     }
   2945     DLOG_IF(INFO, nfc_debug_enabled)
   2946         << StringPrintf("nfa_dm_p2p_prio_logic event_type = 0x%x", event_type);
   2947 
   2948     if (event == NCI_MSG_RF_INTF_ACTIVATED && tech_mode >= 0x80) {
   2949       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2950           "nfa_dm_p2p_prio_logic listen mode activated reset all the "
   2951           "nfa_dm_p2p_prio_logic variables ");
   2952       nfa_dm_p2p_prio_logic_cleanup();
   2953     }
   2954 
   2955     if ((tech_mode < 0x80) && event == NCI_MSG_RF_INTF_ACTIVATED &&
   2956         protocol == NCI_PROTOCOL_ISO_DEP &&
   2957         p2p_prio_logic_data.isodep_detected == false) {
   2958       nfa_dm_p2p_prio_logic_cleanup();
   2959       p2p_prio_logic_data.isodep_detected = true;
   2960       p2p_prio_logic_data.first_tech_mode = tech_mode;
   2961       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2962           "ISO-DEP Detected First Time  Resume the Polling Loop");
   2963       nci_snd_deactivate_cmd(NFA_DEACTIVATE_TYPE_DISCOVERY);
   2964       return false;
   2965     }
   2966 
   2967     else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
   2968              protocol == NCI_PROTOCOL_ISO_DEP &&
   2969              p2p_prio_logic_data.isodep_detected == true &&
   2970              p2p_prio_logic_data.first_tech_mode != tech_mode) {
   2971       p2p_prio_logic_data.isodep_detected = true;
   2972       p2p_prio_logic_data.timer_expired = false;
   2973       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2974           "ISO-DEP Detected Second Time Other Techmode  Resume the Polling "
   2975           "Loop");
   2976       nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
   2977       nci_snd_deactivate_cmd(NFA_DEACTIVATE_TYPE_DISCOVERY);
   2978       return false;
   2979     }
   2980 
   2981     else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
   2982              protocol == NCI_PROTOCOL_ISO_DEP &&
   2983              p2p_prio_logic_data.isodep_detected == true &&
   2984              p2p_prio_logic_data.timer_expired == true) {
   2985       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2986           "ISO-DEP Detected TimerExpired, Final Notifying the Event");
   2987       nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
   2988       nfa_dm_p2p_prio_logic_cleanup();
   2989     }
   2990 
   2991     else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
   2992              protocol == NCI_PROTOCOL_ISO_DEP &&
   2993              p2p_prio_logic_data.isodep_detected == true &&
   2994              p2p_prio_logic_data.first_tech_mode == tech_mode) {
   2995       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   2996           "ISO-DEP Detected Same Techmode, Final Notifying the Event");
   2997       nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
   2998       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("P2P_Stop_Timer");
   2999       nfa_dm_p2p_prio_logic_cleanup();
   3000     }
   3001 
   3002     else if (event == NCI_MSG_RF_INTF_ACTIVATED &&
   3003              protocol != NCI_PROTOCOL_ISO_DEP &&
   3004              p2p_prio_logic_data.isodep_detected == true) {
   3005       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   3006           "ISO-DEP Not Detected  Giving Priority for other Technology");
   3007       nfc_stop_quick_timer(&p2p_prio_logic_data.timer_list);
   3008       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("P2P_Stop_Timer");
   3009       nfa_dm_p2p_prio_logic_cleanup();
   3010     }
   3011 
   3012     else if (event == NCI_MSG_RF_DEACTIVATE &&
   3013              p2p_prio_logic_data.isodep_detected == true &&
   3014              p2p_prio_logic_data.timer_expired == false &&
   3015              event_type == NFA_DM_P2P_PRIO_RSP) {
   3016       DLOG_IF(INFO, nfc_debug_enabled)
   3017           << StringPrintf("NFA_DM_RF_DEACTIVATE_RSP");
   3018       return false;
   3019     }
   3020 
   3021     else if (event == NCI_MSG_RF_DEACTIVATE &&
   3022              p2p_prio_logic_data.isodep_detected == true &&
   3023              p2p_prio_logic_data.timer_expired == false &&
   3024              event_type == NFA_DM_P2P_PRIO_NTF) {
   3025       DLOG_IF(INFO, nfc_debug_enabled)
   3026           << StringPrintf("NFA_DM_RF_DEACTIVATE_NTF");
   3027 
   3028       nfc_start_quick_timer(&p2p_prio_logic_data.timer_list,
   3029                             NFC_TTYPE_P2P_PRIO_RESPONSE,
   3030                             ((uint32_t)160 * QUICK_TIMER_TICKS_PER_SEC) / 1000);
   3031 
   3032       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("P2P_Start_Timer");
   3033 
   3034       return false;
   3035     }
   3036   }
   3037 
   3038   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("returning TRUE");
   3039   return true;
   3040 }
   3041 
   3042 /*******************************************************************************
   3043 **
   3044 ** Function         p2p_prio_logic_timeout
   3045 **
   3046 ** Description      Callback function for p2p timer
   3047 **
   3048 ** Returns          void
   3049 **
   3050 *******************************************************************************/
   3051 void nfa_dm_p2p_timer_event() {
   3052   DLOG_IF(INFO, nfc_debug_enabled)
   3053       << StringPrintf("P2P_Timer_timeout NFC-DEP Not Discovered!!");
   3054 
   3055   p2p_prio_logic_data.timer_expired = true;
   3056 
   3057   if (p2p_prio_logic_data.isodep_detected == true) {
   3058     DLOG_IF(INFO, nfc_debug_enabled)
   3059         << StringPrintf("Deactivate and Restart RF discovery");
   3060     nci_snd_deactivate_cmd(NFC_DEACTIVATE_TYPE_IDLE);
   3061   }
   3062 }
   3063 
   3064 /*******************************************************************************
   3065 **
   3066 ** Function         nfa_dm_p2p_prio_logic_cleanup
   3067 **
   3068 ** Description      Callback function for p2p prio logic cleanup timer
   3069 **
   3070 ** Returns          void
   3071 **
   3072 *******************************************************************************/
   3073 void nfa_dm_p2p_prio_logic_cleanup() {
   3074   memset(&p2p_prio_logic_data, 0x00, sizeof(nfa_dm_p2p_prio_logic_t));
   3075 }
   3076 
   3077 /*******************************************************************************
   3078 **
   3079 ** Function         nfa_dm_send_tag_deselect_cmd
   3080 **
   3081 ** Description      Send command to send tag in sleep state
   3082 **
   3083 ** Returns          void
   3084 **
   3085 *******************************************************************************/
   3086 static void nfa_dm_send_tag_deselect_cmd(tNFA_NFC_PROTOCOL protocol) {
   3087   NFC_HDR* p_msg;
   3088   uint8_t* p;
   3089 
   3090   DLOG_IF(INFO, nfc_debug_enabled)
   3091       << StringPrintf("nfa_dm_send_tag_deselect_cmd");
   3092   p_msg = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
   3093 
   3094   if (p_msg) {
   3095     if (protocol == NFC_PROTOCOL_ISO_DEP) {
   3096       /* send one byte of 0xc2 as as deselect command to Tag */
   3097       p_msg->len = 1;
   3098       p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
   3099       p = (uint8_t*)(p_msg + 1) + p_msg->offset;
   3100       *p = NFA_RW_TAG_DESELECT_CMD;
   3101     } else if (protocol == NFC_PROTOCOL_T2T) {
   3102       p_msg->len = NFA_RW_TAG_SLP_REQ_LEN;
   3103       p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
   3104       p = (uint8_t*)(p_msg + 1) + p_msg->offset;
   3105       memcpy((uint8_t*)(p_msg + 1) + p_msg->offset, NFA_RW_TAG_SLP_REQ,
   3106              p_msg->len);
   3107     } else {
   3108       GKI_freebuf(p_msg);
   3109       return;
   3110     }
   3111     NFC_SendData(NFC_RF_CONN_ID, p_msg);
   3112   }
   3113 }
   3114