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