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