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