Home | History | Annotate | Download | only in p2p
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2010-2014 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /******************************************************************************
     20  *
     21  *  This is the main implementation file for the NFA P2P.
     22  *
     23  ******************************************************************************/
     24 #include <string.h>
     25 #include "llcp_api.h"
     26 #include "llcp_defs.h"
     27 #include "nfa_dm_int.h"
     28 #include "nfa_p2p_api.h"
     29 #include "nfa_p2p_int.h"
     30 #include "nfa_sys.h"
     31 #include "nfa_sys_int.h"
     32 #include "nfc_api.h"
     33 
     34 /*****************************************************************************
     35 **  Global Variables
     36 *****************************************************************************/
     37 
     38 /* system manager control block definition */
     39 tNFA_P2P_CB nfa_p2p_cb;
     40 
     41 /*****************************************************************************
     42 **  Static Functions
     43 *****************************************************************************/
     44 
     45 /* event handler function type */
     46 static bool nfa_p2p_evt_hdlr(NFC_HDR* p_msg);
     47 
     48 /* disable function type */
     49 static void nfa_p2p_sys_disable(void);
     50 static void nfa_p2p_update_active_listen(void);
     51 
     52 /* debug functions type */
     53 #if (BT_TRACE_VERBOSE == TRUE)
     54 static char* nfa_p2p_llcp_state_code(tNFA_P2P_LLCP_STATE state_code);
     55 #endif
     56 
     57 /*****************************************************************************
     58 **  Constants
     59 *****************************************************************************/
     60 /* timeout to restore active listen mode if no RF activation on passive mode */
     61 #define NFA_P2P_RESTORE_ACTIVE_LISTEN_TIMEOUT 5000
     62 
     63 static const tNFA_SYS_REG nfa_p2p_sys_reg = {NULL, nfa_p2p_evt_hdlr,
     64                                              nfa_p2p_sys_disable, NULL};
     65 
     66 #define NFA_P2P_NUM_ACTIONS (NFA_P2P_LAST_EVT & 0x00ff)
     67 
     68 /* type for action functions */
     69 typedef bool (*tNFA_P2P_ACTION)(tNFA_P2P_MSG* p_data);
     70 
     71 /* action function list */
     72 const tNFA_P2P_ACTION nfa_p2p_action[] = {
     73     nfa_p2p_reg_server,                  /* NFA_P2P_API_REG_SERVER_EVT       */
     74     nfa_p2p_reg_client,                  /* NFA_P2P_API_REG_CLIENT_EVT       */
     75     nfa_p2p_dereg,                       /* NFA_P2P_API_DEREG_EVT            */
     76     nfa_p2p_accept_connection,           /* NFA_P2P_API_ACCEPT_CONN_EVT      */
     77     nfa_p2p_reject_connection,           /* NFA_P2P_API_REJECT_CONN_EVT      */
     78     nfa_p2p_disconnect,                  /* NFA_P2P_API_DISCONNECT_EVT       */
     79     nfa_p2p_create_data_link_connection, /* NFA_P2P_API_CONNECT_EVT          */
     80     nfa_p2p_send_ui,                     /* NFA_P2P_API_SEND_UI_EVT          */
     81     nfa_p2p_send_data,                   /* NFA_P2P_API_SEND_DATA_EVT        */
     82     nfa_p2p_set_local_busy,              /* NFA_P2P_API_SET_LOCAL_BUSY_EVT   */
     83     nfa_p2p_get_link_info,               /* NFA_P2P_API_GET_LINK_INFO_EVT    */
     84     nfa_p2p_get_remote_sap,              /* NFA_P2P_API_GET_REMOTE_SAP_EVT   */
     85     nfa_p2p_set_llcp_cfg,                /* NFA_P2P_API_SET_LLCP_CFG_EVT     */
     86     nfa_p2p_restart_rf_discovery         /* NFA_P2P_INT_RESTART_RF_DISC_EVT  */
     87 };
     88 
     89 /*******************************************************************************
     90 **
     91 ** Function         nfa_p2p_discovery_cback
     92 **
     93 ** Description      Processing event from discovery callback for listening
     94 **
     95 **
     96 ** Returns          None
     97 **
     98 *******************************************************************************/
     99 void nfa_p2p_discovery_cback(tNFA_DM_RF_DISC_EVT event, tNFC_DISCOVER* p_data) {
    100   tNFA_CONN_EVT_DATA evt_data;
    101 
    102   P2P_TRACE_DEBUG1("nfa_p2p_discovery_cback (): event:0x%02X", event);
    103 
    104   switch (event) {
    105     case NFA_DM_RF_DISC_START_EVT:
    106       if (p_data->status == NFC_STATUS_OK) {
    107         nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_LISTENING;
    108         nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_DISCOVERY;
    109       }
    110       break;
    111 
    112     case NFA_DM_RF_DISC_ACTIVATED_EVT:
    113 
    114       nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_LISTEN_ACTIVE;
    115 
    116       /* notify NFC link activation */
    117       memcpy(&(evt_data.activated.activate_ntf), &(p_data->activate),
    118              sizeof(tNFC_ACTIVATE_DEVT));
    119       nfa_dm_conn_cback_event_notify(NFA_ACTIVATED_EVT, &evt_data);
    120 
    121       if ((p_data->activate.protocol == NFC_PROTOCOL_NFC_DEP) &&
    122           (p_data->activate.intf_param.type == NFC_INTERFACE_NFC_DEP)) {
    123         nfa_p2p_activate_llcp(p_data);
    124 
    125         /* stop timer not to deactivate LLCP link on passive mode */
    126         nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer);
    127       }
    128       break;
    129 
    130     case NFA_DM_RF_DISC_DEACTIVATED_EVT:
    131 
    132       if ((nfa_p2p_cb.rf_disc_state != NFA_DM_RFST_LISTEN_ACTIVE) &&
    133           (nfa_p2p_cb.rf_disc_state != NFA_DM_RFST_LISTEN_SLEEP)) {
    134         /* this is not for P2P listen
    135         ** DM broadcasts deactivaiton event in listen sleep state.
    136         */
    137         break;
    138       }
    139 
    140       /* notify deactivation */
    141       if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP) ||
    142           (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
    143         nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_LISTEN_SLEEP;
    144         evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_SLEEP;
    145       } else {
    146         nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_DISCOVERY;
    147         evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
    148       }
    149       nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data);
    150       break;
    151 
    152     default:
    153       P2P_TRACE_ERROR0("Unexpected event");
    154       break;
    155   }
    156 }
    157 
    158 /*******************************************************************************
    159 **
    160 ** Function         nfa_p2p_update_active_listen_timeout_cback
    161 **
    162 ** Description      Timeout while waiting for passive mode activation
    163 **
    164 ** Returns          void
    165 **
    166 *******************************************************************************/
    167 static void nfa_p2p_update_active_listen_timeout_cback(TIMER_LIST_ENT* p_tle) {
    168   NFA_TRACE_ERROR0("nfa_p2p_update_active_listen_timeout_cback()");
    169 
    170   /* restore active listen mode */
    171   nfa_p2p_update_active_listen();
    172 }
    173 
    174 /*******************************************************************************
    175 **
    176 ** Function         nfa_p2p_update_active_listen
    177 **
    178 ** Description      Remove active listen mode temporarily or restore it
    179 **
    180 **
    181 ** Returns          None
    182 **
    183 *******************************************************************************/
    184 static void nfa_p2p_update_active_listen(void) {
    185   tNFA_DM_DISC_TECH_PROTO_MASK p2p_listen_mask = 0;
    186   NFC_HDR* p_msg;
    187 
    188   P2P_TRACE_DEBUG1(
    189       "nfa_p2p_update_active_listen (): listen_tech_mask_to_restore:0x%x",
    190       nfa_p2p_cb.listen_tech_mask_to_restore);
    191 
    192   /* if active listen mode was removed temporarily */
    193   if (nfa_p2p_cb.listen_tech_mask_to_restore) {
    194     /* restore listen technologies */
    195     nfa_p2p_cb.listen_tech_mask = nfa_p2p_cb.listen_tech_mask_to_restore;
    196     nfa_p2p_cb.listen_tech_mask_to_restore = 0;
    197     nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer);
    198   } else {
    199     /* start timer in case of no passive activation */
    200     nfa_p2p_cb.active_listen_restore_timer.p_cback =
    201         (TIMER_CBACK*)nfa_p2p_update_active_listen_timeout_cback;
    202     nfa_sys_start_timer(&nfa_p2p_cb.active_listen_restore_timer, 0,
    203                         NFA_P2P_RESTORE_ACTIVE_LISTEN_TIMEOUT);
    204 
    205     /* save listen techonologies */
    206     nfa_p2p_cb.listen_tech_mask_to_restore = nfa_p2p_cb.listen_tech_mask;
    207 
    208     /* remove active listen mode */
    209     if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
    210       nfa_p2p_cb.listen_tech_mask &= ~(NFA_TECHNOLOGY_MASK_ACTIVE);
    211     } else {
    212       nfa_p2p_cb.listen_tech_mask &=
    213           ~(NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE);
    214     }
    215   }
    216 
    217   if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) {
    218     nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle);
    219     nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
    220   }
    221 
    222   /* collect listen technologies with NFC-DEP protocol */
    223   if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A)
    224     p2p_listen_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
    225 
    226   if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F)
    227     p2p_listen_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
    228   if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
    229     if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_ACTIVE)
    230       p2p_listen_mask |= NFA_DM_DISC_MASK_LACM_NFC_DEP;
    231   } else {
    232     if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
    233       p2p_listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP;
    234     if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
    235       p2p_listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP;
    236   }
    237 
    238   /* For P2P mode(Default DTA mode) open Raw channel to bypass LLCP layer. For
    239    * LLCP DTA mode activate LLCP Bypassing LLCP is handled in
    240    * nfa_dm_poll_disc_cback */
    241 
    242   if (appl_dta_mode_flag == 1 &&
    243       ((nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_DEFAULT_MODE)) {
    244     // Configure listen technologies and protocols and register callback to DTA
    245 
    246     P2P_TRACE_DEBUG1(
    247         "%s: DTA mode:Registering nfa_dm_poll_disc_cback to avoid LLCP in P2P",
    248         __func__);
    249     nfa_p2p_cb.dm_disc_handle =
    250         nfa_dm_add_rf_discover(p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH,
    251                                nfa_dm_poll_disc_cback_dta_wrapper);
    252   } else {
    253     /* Configure listen technologies and protocols and register callback to NFA
    254      * DM discovery */
    255     nfa_p2p_cb.dm_disc_handle = nfa_dm_add_rf_discover(
    256         p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH, nfa_p2p_discovery_cback);
    257   }
    258 
    259   /* restart RF discovery to update RF technologies */
    260   p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR));
    261   if (p_msg != NULL) {
    262     p_msg->event = NFA_P2P_INT_RESTART_RF_DISC_EVT;
    263     nfa_sys_sendmsg(p_msg);
    264   }
    265 }
    266 
    267 /*******************************************************************************
    268 **
    269 ** Function         nfa_p2p_llcp_link_cback
    270 **
    271 ** Description      Processing event from LLCP link management callback
    272 **
    273 **
    274 ** Returns          None
    275 **
    276 *******************************************************************************/
    277 void nfa_p2p_llcp_link_cback(uint8_t event, uint8_t reason) {
    278   tNFA_LLCP_ACTIVATED llcp_activated;
    279   tNFA_LLCP_DEACTIVATED llcp_deactivated;
    280 
    281   P2P_TRACE_DEBUG2("nfa_p2p_llcp_link_cback () event:0x%x, reason:0x%x", event,
    282                    reason);
    283 
    284   if (event == LLCP_LINK_ACTIVATION_COMPLETE_EVT) {
    285     LLCP_GetLinkMIU(&nfa_p2p_cb.local_link_miu, &nfa_p2p_cb.remote_link_miu);
    286     nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_ACTIVATED;
    287 
    288     if (nfa_p2p_cb.is_initiator) {
    289       /* notify NFA DM to send Activate Event to applicaiton with status  */
    290       nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
    291     }
    292 
    293     llcp_activated.is_initiator = nfa_p2p_cb.is_initiator;
    294     llcp_activated.local_link_miu = nfa_p2p_cb.local_link_miu;
    295     llcp_activated.remote_link_miu = nfa_p2p_cb.remote_link_miu;
    296     llcp_activated.remote_lsc = LLCP_GetRemoteLSC();
    297     llcp_activated.remote_wks = LLCP_GetRemoteWKS();
    298     llcp_activated.remote_version = LLCP_GetRemoteVersion();
    299 
    300     nfa_dm_act_conn_cback_notify(NFA_LLCP_ACTIVATED_EVT,
    301                                  (tNFA_CONN_EVT_DATA*)&llcp_activated);
    302 
    303   } else if (event == LLCP_LINK_ACTIVATION_FAILED_EVT) {
    304     nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE;
    305 
    306     if (nfa_p2p_cb.is_initiator) {
    307       /* notify NFA DM to send Activate Event to applicaiton with status  */
    308       nfa_dm_notify_activation_status(NFA_STATUS_FAILED, NULL);
    309     }
    310 
    311     nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
    312   } else if (event == LLCP_LINK_FIRST_PACKET_RECEIVED_EVT) {
    313     nfa_dm_act_conn_cback_notify(NFA_LLCP_FIRST_PACKET_RECEIVED_EVT, NULL);
    314   } else /* LLCP_LINK_DEACTIVATED_EVT       */
    315   {
    316     nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE;
    317 
    318     /* if got RF link loss without any rx LLC PDU */
    319     if (reason == LLCP_LINK_RF_LINK_LOSS_NO_RX_LLC) {
    320       /* if it was active listen mode */
    321       if ((nfa_p2p_cb.is_active_mode) && (!nfa_p2p_cb.is_initiator)) {
    322         /* if it didn't retry without active listen mode and passive mode is
    323          * available */
    324         if ((nfa_p2p_cb.listen_tech_mask_to_restore == 0x00) &&
    325             (nfa_p2p_cb.listen_tech_mask &
    326              (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F))) {
    327           P2P_TRACE_DEBUG0("Retry without active listen mode");
    328 
    329           /* retry without active listen mode */
    330           nfa_p2p_update_active_listen();
    331         }
    332       } else if (nfa_p2p_cb.listen_tech_mask_to_restore) {
    333         nfa_sys_start_timer(&nfa_p2p_cb.active_listen_restore_timer, 0,
    334                             NFA_P2P_RESTORE_ACTIVE_LISTEN_TIMEOUT);
    335       }
    336 
    337       reason = LLCP_LINK_RF_LINK_LOSS_ERR;
    338     } else {
    339       if (nfa_p2p_cb.listen_tech_mask_to_restore) {
    340         /* restore active listen mode */
    341         nfa_p2p_update_active_listen();
    342       }
    343     }
    344 
    345     llcp_deactivated.reason = reason;
    346     nfa_dm_act_conn_cback_notify(NFA_LLCP_DEACTIVATED_EVT,
    347                                  (tNFA_CONN_EVT_DATA*)&llcp_deactivated);
    348 
    349     if (reason != LLCP_LINK_RF_LINK_LOSS_ERR) /* if NFC link is still up */
    350     {
    351       if (nfa_p2p_cb.is_initiator) {
    352         /*For LLCP DTA test, Deactivate to Sleep is needed to send DSL_REQ*/
    353         if (appl_dta_mode_flag == 1 &&
    354             ((nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_LLCP_MODE)) {
    355           nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_SLEEP);
    356         } else {
    357           nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
    358         }
    359       } else if ((nfa_p2p_cb.is_active_mode) && (reason == LLCP_LINK_TIMEOUT)) {
    360         /*
    361         ** target needs to trun off RF in case of receiving invalid
    362         ** frame from initiator
    363         */
    364         P2P_TRACE_DEBUG0("Got LLCP_LINK_TIMEOUT in active mode on target");
    365         nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
    366       }
    367     }
    368   }
    369 }
    370 
    371 /*******************************************************************************
    372 **
    373 ** Function         nfa_p2p_activate_llcp
    374 **
    375 ** Description      Activate LLCP link
    376 **
    377 **
    378 ** Returns          None
    379 **
    380 *******************************************************************************/
    381 void nfa_p2p_activate_llcp(tNFC_DISCOVER* p_data) {
    382   tLLCP_ACTIVATE_CONFIG config;
    383 
    384   P2P_TRACE_DEBUG0("nfa_p2p_activate_llcp ()");
    385 
    386   if ((p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) ||
    387       (p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_F)) {
    388     config.is_initiator = true;
    389   } else {
    390     config.is_initiator = false;
    391   }
    392   if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
    393     if (p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_ACTIVE) {
    394       config.is_initiator = true;
    395     }
    396   } else {
    397     if ((p_data->activate.rf_tech_param.mode ==
    398          NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
    399         (p_data->activate.rf_tech_param.mode ==
    400          NFC_DISCOVERY_TYPE_POLL_F_ACTIVE)) {
    401       config.is_initiator = true;
    402     }
    403   }
    404   if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
    405     if ((p_data->activate.rf_tech_param.mode ==
    406          NFC_DISCOVERY_TYPE_POLL_ACTIVE) ||
    407         (p_data->activate.rf_tech_param.mode ==
    408          NFC_DISCOVERY_TYPE_LISTEN_ACTIVE)) {
    409       nfa_p2p_cb.is_active_mode = true;
    410     } else {
    411       nfa_p2p_cb.is_active_mode = false;
    412     }
    413   } else {
    414     if ((p_data->activate.rf_tech_param.mode ==
    415          NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
    416         (p_data->activate.rf_tech_param.mode ==
    417          NFC_DISCOVERY_TYPE_POLL_F_ACTIVE) ||
    418         (p_data->activate.rf_tech_param.mode ==
    419          NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) ||
    420         (p_data->activate.rf_tech_param.mode ==
    421          NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE)) {
    422       nfa_p2p_cb.is_active_mode = true;
    423     } else {
    424       nfa_p2p_cb.is_active_mode = false;
    425     }
    426   }
    427 
    428   nfa_p2p_cb.is_initiator = config.is_initiator;
    429 
    430   config.max_payload_size =
    431       p_data->activate.intf_param.intf_param.pa_nfc.max_payload_size;
    432   config.waiting_time =
    433       p_data->activate.intf_param.intf_param.pa_nfc.waiting_time;
    434   config.p_gen_bytes = p_data->activate.intf_param.intf_param.pa_nfc.gen_bytes;
    435   config.gen_bytes_len =
    436       p_data->activate.intf_param.intf_param.pa_nfc.gen_bytes_len;
    437 
    438   LLCP_ActivateLink(config, nfa_p2p_llcp_link_cback);
    439 }
    440 
    441 /*******************************************************************************
    442 **
    443 ** Function         nfa_p2p_deactivate_llcp
    444 **
    445 ** Description      Deactivate LLCP link
    446 **
    447 **
    448 ** Returns          None
    449 **
    450 *******************************************************************************/
    451 void nfa_p2p_deactivate_llcp(void) {
    452   P2P_TRACE_DEBUG0("nfa_p2p_deactivate_llcp ()");
    453 
    454   LLCP_DeactivateLink();
    455 }
    456 
    457 /*******************************************************************************
    458 **
    459 ** Function         nfa_p2p_init
    460 **
    461 ** Description      Initialize NFA P2P
    462 **
    463 **
    464 ** Returns          None
    465 **
    466 *******************************************************************************/
    467 void nfa_p2p_init(void) {
    468   uint8_t xx;
    469 
    470   P2P_TRACE_DEBUG0("nfa_p2p_init ()");
    471 
    472   /* initialize control block */
    473   memset(&nfa_p2p_cb, 0, sizeof(tNFA_P2P_CB));
    474   nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
    475   nfa_p2p_cb.trace_level = APPL_INITIAL_TRACE_LEVEL;
    476 
    477   for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++) {
    478     nfa_p2p_cb.sdp_cb[xx].local_sap = LLCP_INVALID_SAP;
    479   }
    480 
    481   /* register message handler on NFA SYS */
    482   nfa_sys_register(NFA_ID_P2P, &nfa_p2p_sys_reg);
    483 }
    484 
    485 /*******************************************************************************
    486 **
    487 ** Function         nfa_p2p_sys_disable
    488 **
    489 ** Description      Deregister NFA P2P from NFA SYS/DM
    490 **
    491 **
    492 ** Returns          None
    493 **
    494 *******************************************************************************/
    495 static void nfa_p2p_sys_disable(void) {
    496   P2P_TRACE_DEBUG0("nfa_p2p_sys_disable()");
    497 
    498   nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer);
    499 
    500   /* deregister message handler on NFA SYS */
    501   nfa_sys_deregister(NFA_ID_P2P);
    502 }
    503 
    504 /*******************************************************************************
    505 **
    506 ** Function         nfa_p2p_set_config
    507 **
    508 ** Description      Set General bytes and WT parameters for LLCP
    509 **
    510 **
    511 ** Returns          void
    512 **
    513 *******************************************************************************/
    514 void nfa_p2p_set_config(tNFA_DM_DISC_TECH_PROTO_MASK disc_mask) {
    515   uint8_t wt, gen_bytes_len = LLCP_MAX_GEN_BYTES;
    516   uint8_t params[LLCP_MAX_GEN_BYTES + 5], *p, length;
    517 
    518   P2P_TRACE_DEBUG0("nfa_p2p_set_config ()");
    519 
    520   LLCP_GetDiscoveryConfig(&wt, params + 2, &gen_bytes_len);
    521   if (nfa_dm_is_p2p_paused()) {
    522     gen_bytes_len = 0;
    523   }
    524 
    525   if ((disc_mask &
    526        (NFA_DM_DISC_MASK_PA_NFC_DEP | NFA_DM_DISC_MASK_PF_NFC_DEP)) ||
    527       ((NFC_GetNCIVersion() == NCI_VERSION_2_0) &&
    528        (disc_mask & NFA_DM_DISC_MASK_PACM_NFC_DEP)) ||
    529       ((NFC_GetNCIVersion() != NCI_VERSION_2_0) &&
    530        (disc_mask &
    531         (NFA_DM_DISC_MASK_PAA_NFC_DEP | NFA_DM_DISC_MASK_PFA_NFC_DEP)))) {
    532     p = params;
    533 
    534     UINT8_TO_BE_STREAM(p, NFC_PMID_ATR_REQ_GEN_BYTES);
    535     UINT8_TO_BE_STREAM(p, gen_bytes_len);
    536 
    537     p += gen_bytes_len;
    538     length = gen_bytes_len + 2;
    539 
    540     nfa_dm_check_set_config(length, params, false);
    541   }
    542 
    543   if ((disc_mask &
    544        (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LF_NFC_DEP)) ||
    545       ((NFC_GetNCIVersion() == NCI_VERSION_2_0) &&
    546        (disc_mask & NFA_DM_DISC_MASK_LACM_NFC_DEP)) ||
    547       ((NFC_GetNCIVersion() != NCI_VERSION_2_0) &&
    548        (disc_mask &
    549         (NFA_DM_DISC_MASK_LFA_NFC_DEP | NFA_DM_DISC_MASK_LAA_NFC_DEP)))) {
    550     p = params;
    551 
    552     UINT8_TO_BE_STREAM(p, NFC_PMID_ATR_RES_GEN_BYTES);
    553     UINT8_TO_BE_STREAM(p, gen_bytes_len);
    554 
    555     p += gen_bytes_len;
    556     length = gen_bytes_len + 2;
    557 
    558     UINT8_TO_BE_STREAM(p, NFC_PMID_WT);
    559     UINT8_TO_BE_STREAM(p, NCI_PARAM_LEN_WT);
    560     UINT8_TO_BE_STREAM(p, wt);
    561 
    562     length += 3;
    563 
    564     nfa_dm_check_set_config(length, params, false);
    565   }
    566 }
    567 
    568 /*******************************************************************************
    569 **
    570 ** Function         nfa_p2p_enable_listening
    571 **
    572 ** Description      Configure listen technologies and protocols for LLCP
    573 **                  If LLCP WKS is changed then LLCP Gen bytes will be updated.
    574 **
    575 ** Returns          void
    576 **
    577 *******************************************************************************/
    578 void nfa_p2p_enable_listening(tNFA_SYS_ID sys_id, bool update_wks) {
    579   tNFA_DM_DISC_TECH_PROTO_MASK p2p_listen_mask = 0;
    580 
    581   P2P_TRACE_DEBUG2("nfa_p2p_enable_listening () sys_id = %d, update_wks = %d",
    582                    sys_id, update_wks);
    583 
    584   if (sys_id == NFA_ID_P2P)
    585     nfa_p2p_cb.is_p2p_listening = true;
    586   else if (sys_id == NFA_ID_SNEP)
    587     nfa_p2p_cb.is_snep_listening = true;
    588 
    589   if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) {
    590     /* if need to update WKS in LLCP Gen bytes */
    591     if (update_wks) {
    592       /* update LLCP Gen Bytes */
    593       nfa_p2p_set_config(NFA_DM_DISC_MASK_PA_NFC_DEP |
    594                          NFA_DM_DISC_MASK_LA_NFC_DEP);
    595     }
    596     return;
    597   }
    598 
    599   /* collect listen technologies with NFC-DEP protocol */
    600   if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A)
    601     p2p_listen_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
    602 
    603   if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F)
    604     p2p_listen_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
    605 
    606   if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
    607     if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_ACTIVE)
    608       p2p_listen_mask |= NFA_DM_DISC_MASK_LACM_NFC_DEP;
    609   } else {
    610     if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
    611       p2p_listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP;
    612 
    613     if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
    614       p2p_listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP;
    615   }
    616 
    617   if (p2p_listen_mask) {
    618     /* For P2P mode(Default DTA mode) open Raw channel to bypass LLCP layer.
    619      * For LLCP DTA mode activate LLCP Bypassing LLCP is handled in
    620      * nfa_dm_poll_disc_cback */
    621     if (appl_dta_mode_flag == 1 &&
    622         ((nfa_dm_cb.eDtaMode & 0x0F) == NFA_DTA_DEFAULT_MODE)) {
    623       /* Configure listen technologies and protocols and register callback to
    624        * NFA DM discovery */
    625       P2P_TRACE_DEBUG1(
    626           "%s: DTA mode:Registering nfa_dm_poll_disc_cback to avoid LLCP in "
    627           "P2P",
    628           __func__);
    629       nfa_p2p_cb.dm_disc_handle =
    630           nfa_dm_add_rf_discover(p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH,
    631                                  nfa_dm_poll_disc_cback_dta_wrapper);
    632     } else {
    633       /* Configure listen technologies and protocols and register callback to
    634        * NFA DM discovery */
    635       nfa_p2p_cb.dm_disc_handle = nfa_dm_add_rf_discover(
    636           p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH, nfa_p2p_discovery_cback);
    637     }
    638   }
    639 }
    640 
    641 /*******************************************************************************
    642 **
    643 ** Function         nfa_p2p_disable_listening
    644 **
    645 ** Description      Remove listen technologies and protocols for LLCP and
    646 **                  deregister callback from NFA DM discovery if all of
    647 **                  P2P/CHO/SNEP doesn't listen LLCP any more.
    648 **                  If LLCP WKS is changed then ATR_RES will be updated.
    649 **
    650 ** Returns          void
    651 **
    652 *******************************************************************************/
    653 void nfa_p2p_disable_listening(tNFA_SYS_ID sys_id, bool update_wks) {
    654   P2P_TRACE_DEBUG2("nfa_p2p_disable_listening ()  sys_id = %d, update_wks = %d",
    655                    sys_id, update_wks);
    656 
    657   if (sys_id == NFA_ID_P2P)
    658     nfa_p2p_cb.is_p2p_listening = false;
    659   else if (sys_id == NFA_ID_SNEP)
    660     nfa_p2p_cb.is_snep_listening = false;
    661 
    662   if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) {
    663     if ((nfa_p2p_cb.is_p2p_listening == false) &&
    664         (nfa_p2p_cb.is_snep_listening == false)) {
    665       nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE;
    666       nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_IDLE;
    667 
    668       nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle);
    669       nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
    670     } else if (update_wks) {
    671       /* update LLCP Gen Bytes */
    672       nfa_p2p_set_config(NFA_DM_DISC_MASK_PA_NFC_DEP |
    673                          NFA_DM_DISC_MASK_LA_NFC_DEP);
    674     }
    675   }
    676 }
    677 
    678 /*******************************************************************************
    679 **
    680 ** Function         nfa_p2p_update_listen_tech
    681 **
    682 ** Description      Update P2P listen technologies. If there is change then
    683 **                  restart or stop P2P listen.
    684 **
    685 ** Returns          void
    686 **
    687 *******************************************************************************/
    688 void nfa_p2p_update_listen_tech(tNFA_TECHNOLOGY_MASK tech_mask) {
    689   P2P_TRACE_DEBUG1("nfa_p2p_update_listen_tech ()  tech_mask = 0x%x",
    690                    tech_mask);
    691 
    692   if (nfa_p2p_cb.listen_tech_mask_to_restore) {
    693     nfa_p2p_cb.listen_tech_mask_to_restore = 0;
    694     nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer);
    695   }
    696 
    697   if (nfa_p2p_cb.listen_tech_mask != tech_mask) {
    698     nfa_p2p_cb.listen_tech_mask = tech_mask;
    699 
    700     if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) {
    701       nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_IDLE;
    702 
    703       nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle);
    704       nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
    705     }
    706 
    707     /* restart discovery without updating sub-module status */
    708     if (nfa_p2p_cb.is_p2p_listening || appl_dta_mode_flag)
    709       nfa_p2p_enable_listening(NFA_ID_P2P, false);
    710     else if (nfa_p2p_cb.is_snep_listening)
    711       nfa_p2p_enable_listening(NFA_ID_SNEP, false);
    712   }
    713 }
    714 
    715 /*******************************************************************************
    716 **
    717 ** Function         nfa_p2p_evt_hdlr
    718 **
    719 ** Description      Processing event for NFA P2P
    720 **
    721 **
    722 ** Returns          TRUE if p_msg needs to be deallocated
    723 **
    724 *******************************************************************************/
    725 static bool nfa_p2p_evt_hdlr(NFC_HDR* p_hdr) {
    726   bool delete_msg = true;
    727   uint16_t event;
    728 
    729   tNFA_P2P_MSG* p_msg = (tNFA_P2P_MSG*)p_hdr;
    730 
    731 #if (BT_TRACE_VERBOSE == TRUE)
    732   P2P_TRACE_DEBUG2("nfa_p2p_evt_hdlr (): LLCP State [%s], Event [%s]",
    733                    nfa_p2p_llcp_state_code(nfa_p2p_cb.llcp_state),
    734                    nfa_p2p_evt_code(p_msg->hdr.event));
    735 #else
    736   P2P_TRACE_DEBUG2("nfa_p2p_evt_hdlr (): State 0x%02x, Event 0x%02x",
    737                    nfa_p2p_cb.llcp_state, p_msg->hdr.event);
    738 #endif
    739 
    740   event = p_msg->hdr.event & 0x00ff;
    741 
    742   /* execute action functions */
    743   if (event < NFA_P2P_NUM_ACTIONS) {
    744     delete_msg = (*nfa_p2p_action[event])(p_msg);
    745   } else {
    746     P2P_TRACE_ERROR0("Unhandled event");
    747   }
    748 
    749   return delete_msg;
    750 }
    751 
    752 #if (BT_TRACE_VERBOSE == TRUE)
    753 /*******************************************************************************
    754 **
    755 ** Function         nfa_p2p_llcp_state_code
    756 **
    757 ** Description
    758 **
    759 ** Returns          string of state
    760 **
    761 *******************************************************************************/
    762 static char* nfa_p2p_llcp_state_code(tNFA_P2P_LLCP_STATE state_code) {
    763   switch (state_code) {
    764     case NFA_P2P_LLCP_STATE_IDLE:
    765       return "Link IDLE";
    766     case NFA_P2P_LLCP_STATE_LISTENING:
    767       return "Link LISTENING";
    768     case NFA_P2P_LLCP_STATE_ACTIVATED:
    769       return "Link ACTIVATED";
    770     default:
    771       return "Unknown state";
    772   }
    773 }
    774 
    775 /*******************************************************************************
    776 **
    777 ** Function         nfa_p2p_evt_code
    778 **
    779 ** Description
    780 **
    781 ** Returns          string of event
    782 **
    783 *******************************************************************************/
    784 char* nfa_p2p_evt_code(uint16_t evt_code) {
    785   switch (evt_code) {
    786     case NFA_P2P_API_REG_SERVER_EVT:
    787       return "API_REG_SERVER";
    788     case NFA_P2P_API_REG_CLIENT_EVT:
    789       return "API_REG_CLIENT";
    790     case NFA_P2P_API_DEREG_EVT:
    791       return "API_DEREG";
    792     case NFA_P2P_API_ACCEPT_CONN_EVT:
    793       return "API_ACCEPT_CONN";
    794     case NFA_P2P_API_REJECT_CONN_EVT:
    795       return "API_REJECT_CONN";
    796     case NFA_P2P_API_DISCONNECT_EVT:
    797       return "API_DISCONNECT";
    798     case NFA_P2P_API_CONNECT_EVT:
    799       return "API_CONNECT";
    800     case NFA_P2P_API_SEND_UI_EVT:
    801       return "API_SEND_UI";
    802     case NFA_P2P_API_SEND_DATA_EVT:
    803       return "API_SEND_DATA";
    804     case NFA_P2P_API_SET_LOCAL_BUSY_EVT:
    805       return "API_SET_LOCAL_BUSY";
    806     case NFA_P2P_API_GET_LINK_INFO_EVT:
    807       return "API_GET_LINK_INFO";
    808     case NFA_P2P_API_GET_REMOTE_SAP_EVT:
    809       return "API_GET_REMOTE_SAP";
    810     case NFA_P2P_API_SET_LLCP_CFG_EVT:
    811       return "API_SET_LLCP_CFG_EVT";
    812     case NFA_P2P_INT_RESTART_RF_DISC_EVT:
    813       return "RESTART_RF_DISC_EVT";
    814     default:
    815       return "Unknown event";
    816   }
    817 }
    818 #endif /* Debug Functions */
    819