• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  *
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
41 tNFA_P2P_CB nfa_p2p_cb;
42 #endif
43 
44 /*****************************************************************************
45 **  Static Functions
46 *****************************************************************************/
47 
48 /* event handler function type */
49 static BOOLEAN nfa_p2p_evt_hdlr (BT_HDR *p_msg);
50 
51 /* disable function type */
52 static void nfa_p2p_sys_disable (void);
53 static void nfa_p2p_update_active_listen (void);
54 
55 /* debug functions type */
56 #if (BT_TRACE_VERBOSE == TRUE)
57 static 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 
66 static 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 */
77 typedef BOOLEAN (*tNFA_P2P_ACTION) (tNFA_P2P_MSG *p_data);
78 
79 /* action function list */
80 const 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 *******************************************************************************/
nfa_p2p_discovery_cback(tNFA_DM_RF_DISC_EVT event,tNFC_DISCOVER * p_data)108 void 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 *******************************************************************************/
nfa_p2p_update_active_listen_timeout_cback(TIMER_LIST_ENT * p_tle)185 static 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 *******************************************************************************/
nfa_p2p_update_active_listen(void)203 static 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 *******************************************************************************/
nfa_p2p_llcp_link_cback(UINT8 event,UINT8 reason)274 void 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 *******************************************************************************/
nfa_p2p_activate_llcp(tNFC_DISCOVER * p_data)386 void 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 *******************************************************************************/
nfa_p2p_deactivate_llcp(void)436 void 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 *******************************************************************************/
nfa_p2p_init(void)453 void 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 *******************************************************************************/
nfa_p2p_sys_disable(void)484 static 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 *******************************************************************************/
nfa_p2p_set_config(tNFA_DM_DISC_TECH_PROTO_MASK disc_mask)504 void 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     if (nfa_dm_is_p2p_paused ())
513     {
514         gen_bytes_len = 0;
515     }
516 
517     if (disc_mask & ( NFA_DM_DISC_MASK_PA_NFC_DEP
518                      |NFA_DM_DISC_MASK_PF_NFC_DEP
519                      |NFA_DM_DISC_MASK_PAA_NFC_DEP
520                      |NFA_DM_DISC_MASK_PFA_NFC_DEP) )
521     {
522         p = params;
523 
524         UINT8_TO_BE_STREAM (p, NFC_PMID_ATR_REQ_GEN_BYTES);
525         UINT8_TO_BE_STREAM (p, gen_bytes_len);
526 
527         p += gen_bytes_len;
528         length = gen_bytes_len + 2;
529 
530         nfa_dm_check_set_config (length, params, FALSE);
531     }
532 
533     if (disc_mask & ( NFA_DM_DISC_MASK_LA_NFC_DEP
534                      |NFA_DM_DISC_MASK_LF_NFC_DEP
535                      |NFA_DM_DISC_MASK_LAA_NFC_DEP
536                      |NFA_DM_DISC_MASK_LFA_NFC_DEP) )
537     {
538         p = params;
539 
540         UINT8_TO_BE_STREAM (p, NFC_PMID_ATR_RES_GEN_BYTES);
541         UINT8_TO_BE_STREAM (p, gen_bytes_len);
542 
543         p += gen_bytes_len;
544         length = gen_bytes_len + 2;
545 
546         UINT8_TO_BE_STREAM (p, NFC_PMID_WT);
547         UINT8_TO_BE_STREAM (p, NCI_PARAM_LEN_WT);
548         UINT8_TO_BE_STREAM (p, wt);
549 
550         length += 3;
551 
552         nfa_dm_check_set_config (length, params, FALSE);
553     }
554 }
555 
556 /*******************************************************************************
557 **
558 ** Function         nfa_p2p_enable_listening
559 **
560 ** Description      Configure listen technologies and protocols for LLCP
561 **                  If LLCP WKS is changed then LLCP Gen bytes will be updated.
562 **
563 ** Returns          void
564 **
565 *******************************************************************************/
nfa_p2p_enable_listening(tNFA_SYS_ID sys_id,BOOLEAN update_wks)566 void nfa_p2p_enable_listening (tNFA_SYS_ID sys_id, BOOLEAN update_wks)
567 {
568     tNFA_DM_DISC_TECH_PROTO_MASK p2p_listen_mask = 0;
569 
570     P2P_TRACE_DEBUG2 ("nfa_p2p_enable_listening () sys_id = %d, update_wks = %d",
571                        sys_id, update_wks);
572 
573     if (sys_id == NFA_ID_P2P)
574         nfa_p2p_cb.is_p2p_listening = TRUE;
575     else if (sys_id == NFA_ID_CHO)
576         nfa_p2p_cb.is_cho_listening = TRUE;
577     else if (sys_id == NFA_ID_SNEP)
578         nfa_p2p_cb.is_snep_listening = TRUE;
579 
580     if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID)
581     {
582         /* if need to update WKS in LLCP Gen bytes */
583         if (update_wks)
584         {
585             /* update LLCP Gen Bytes */
586             nfa_p2p_set_config (NFA_DM_DISC_MASK_PA_NFC_DEP|NFA_DM_DISC_MASK_LA_NFC_DEP);
587         }
588         return;
589     }
590 
591     /* collect listen technologies with NFC-DEP protocol */
592     if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A)
593         p2p_listen_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
594 
595     if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F)
596         p2p_listen_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
597 
598     if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
599         p2p_listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP;
600 
601     if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
602         p2p_listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP;
603 
604     if (p2p_listen_mask)
605     {
606         /* Configure listen technologies and protocols and register callback to NFA DM discovery */
607         nfa_p2p_cb.dm_disc_handle = nfa_dm_add_rf_discover (p2p_listen_mask,
608                                                             NFA_DM_DISC_HOST_ID_DH,
609                                                             nfa_p2p_discovery_cback);
610     }
611 }
612 
613 /*******************************************************************************
614 **
615 ** Function         nfa_p2p_disable_listening
616 **
617 ** Description      Remove listen technologies and protocols for LLCP and
618 **                  deregister callback from NFA DM discovery if all of P2P/CHO/SNEP
619 **                  doesn't listen LLCP any more.
620 **                  If LLCP WKS is changed then ATR_RES will be updated.
621 **
622 ** Returns          void
623 **
624 *******************************************************************************/
nfa_p2p_disable_listening(tNFA_SYS_ID sys_id,BOOLEAN update_wks)625 void nfa_p2p_disable_listening (tNFA_SYS_ID sys_id, BOOLEAN update_wks)
626 {
627 
628     P2P_TRACE_DEBUG2 ("nfa_p2p_disable_listening ()  sys_id = %d, update_wks = %d",
629                        sys_id, update_wks);
630 
631     if (sys_id == NFA_ID_P2P)
632         nfa_p2p_cb.is_p2p_listening = FALSE;
633     else if (sys_id == NFA_ID_CHO)
634         nfa_p2p_cb.is_cho_listening = FALSE;
635     else if (sys_id == NFA_ID_SNEP)
636         nfa_p2p_cb.is_snep_listening = FALSE;
637 
638     if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID)
639     {
640         if (  (nfa_p2p_cb.is_p2p_listening == FALSE)
641             &&(nfa_p2p_cb.is_cho_listening == FALSE)
642             &&(nfa_p2p_cb.is_snep_listening == FALSE)  )
643         {
644             nfa_p2p_cb.llcp_state    = NFA_P2P_LLCP_STATE_IDLE;
645             nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_IDLE;
646 
647             nfa_dm_delete_rf_discover (nfa_p2p_cb.dm_disc_handle);
648             nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
649         }
650         else if (update_wks)
651         {
652             /* update LLCP Gen Bytes */
653             nfa_p2p_set_config (NFA_DM_DISC_MASK_PA_NFC_DEP|NFA_DM_DISC_MASK_LA_NFC_DEP);
654         }
655     }
656 }
657 
658 /*******************************************************************************
659 **
660 ** Function         nfa_p2p_update_listen_tech
661 **
662 ** Description      Update P2P listen technologies. If there is change then
663 **                  restart or stop P2P listen.
664 **
665 ** Returns          void
666 **
667 *******************************************************************************/
nfa_p2p_update_listen_tech(tNFA_TECHNOLOGY_MASK tech_mask)668 void nfa_p2p_update_listen_tech (tNFA_TECHNOLOGY_MASK tech_mask)
669 {
670     P2P_TRACE_DEBUG1 ("nfa_p2p_update_listen_tech ()  tech_mask = 0x%x", tech_mask);
671 
672     if (nfa_p2p_cb.listen_tech_mask_to_restore)
673     {
674         nfa_p2p_cb.listen_tech_mask_to_restore = 0;
675         nfa_sys_stop_timer (&nfa_p2p_cb.active_listen_restore_timer);
676     }
677 
678     if (nfa_p2p_cb.listen_tech_mask != tech_mask)
679     {
680         nfa_p2p_cb.listen_tech_mask = tech_mask;
681 
682         if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID)
683         {
684             nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_IDLE;
685 
686             nfa_dm_delete_rf_discover (nfa_p2p_cb.dm_disc_handle);
687             nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
688         }
689 
690         /* restart discovery without updating sub-module status */
691         if (nfa_p2p_cb.is_p2p_listening)
692             nfa_p2p_enable_listening (NFA_ID_P2P, FALSE);
693         else if (nfa_p2p_cb.is_cho_listening)
694             nfa_p2p_enable_listening (NFA_ID_CHO, FALSE);
695         else if (nfa_p2p_cb.is_snep_listening)
696             nfa_p2p_enable_listening (NFA_ID_SNEP, FALSE);
697     }
698 }
699 
700 /*******************************************************************************
701 **
702 ** Function         nfa_p2p_evt_hdlr
703 **
704 ** Description      Processing event for NFA P2P
705 **
706 **
707 ** Returns          TRUE if p_msg needs to be deallocated
708 **
709 *******************************************************************************/
nfa_p2p_evt_hdlr(BT_HDR * p_hdr)710 static BOOLEAN nfa_p2p_evt_hdlr (BT_HDR *p_hdr)
711 {
712     BOOLEAN delete_msg = TRUE;
713     UINT16  event;
714 
715     tNFA_P2P_MSG *p_msg = (tNFA_P2P_MSG *)p_hdr;
716 
717 #if (BT_TRACE_VERBOSE == TRUE)
718     P2P_TRACE_DEBUG2 ("nfa_p2p_evt_hdlr (): LLCP State [%s], Event [%s]",
719                        nfa_p2p_llcp_state_code (nfa_p2p_cb.llcp_state),
720                        nfa_p2p_evt_code (p_msg->hdr.event));
721 #else
722     P2P_TRACE_DEBUG2 ("nfa_p2p_evt_hdlr (): State 0x%02x, Event 0x%02x",
723                        nfa_p2p_cb.llcp_state, p_msg->hdr.event);
724 #endif
725 
726     event = p_msg->hdr.event & 0x00ff;
727 
728     /* execute action functions */
729     if (event < NFA_P2P_NUM_ACTIONS)
730     {
731         delete_msg = (*nfa_p2p_action[event]) (p_msg);
732     }
733     else
734     {
735         P2P_TRACE_ERROR0 ("Unhandled event");
736     }
737 
738     return delete_msg;
739 }
740 
741 
742 #if (BT_TRACE_VERBOSE == TRUE)
743 /*******************************************************************************
744 **
745 ** Function         nfa_p2p_llcp_state_code
746 **
747 ** Description
748 **
749 ** Returns          string of state
750 **
751 *******************************************************************************/
nfa_p2p_llcp_state_code(tNFA_P2P_LLCP_STATE state_code)752 static char *nfa_p2p_llcp_state_code (tNFA_P2P_LLCP_STATE state_code)
753 {
754     switch (state_code)
755     {
756     case NFA_P2P_LLCP_STATE_IDLE:
757         return "Link IDLE";
758     case NFA_P2P_LLCP_STATE_LISTENING:
759         return "Link LISTENING";
760     case NFA_P2P_LLCP_STATE_ACTIVATED:
761         return "Link ACTIVATED";
762     default:
763         return "Unknown state";
764     }
765 }
766 
767 /*******************************************************************************
768 **
769 ** Function         nfa_p2p_evt_code
770 **
771 ** Description
772 **
773 ** Returns          string of event
774 **
775 *******************************************************************************/
nfa_p2p_evt_code(UINT16 evt_code)776 char *nfa_p2p_evt_code (UINT16 evt_code)
777 {
778     switch (evt_code)
779     {
780     case NFA_P2P_API_REG_SERVER_EVT:
781         return "API_REG_SERVER";
782     case NFA_P2P_API_REG_CLIENT_EVT:
783         return "API_REG_CLIENT";
784     case NFA_P2P_API_DEREG_EVT:
785         return "API_DEREG";
786     case NFA_P2P_API_ACCEPT_CONN_EVT:
787         return "API_ACCEPT_CONN";
788     case NFA_P2P_API_REJECT_CONN_EVT:
789         return "API_REJECT_CONN";
790     case NFA_P2P_API_DISCONNECT_EVT:
791         return "API_DISCONNECT";
792     case NFA_P2P_API_CONNECT_EVT:
793         return "API_CONNECT";
794     case NFA_P2P_API_SEND_UI_EVT:
795         return "API_SEND_UI";
796     case NFA_P2P_API_SEND_DATA_EVT:
797         return "API_SEND_DATA";
798     case NFA_P2P_API_SET_LOCAL_BUSY_EVT:
799         return "API_SET_LOCAL_BUSY";
800     case NFA_P2P_API_GET_LINK_INFO_EVT:
801         return "API_GET_LINK_INFO";
802     case NFA_P2P_API_GET_REMOTE_SAP_EVT:
803         return "API_GET_REMOTE_SAP";
804     case NFA_P2P_API_SET_LLCP_CFG_EVT:
805         return "API_SET_LLCP_CFG_EVT";
806     case NFA_P2P_INT_RESTART_RF_DISC_EVT:
807         return "RESTART_RF_DISC_EVT";
808     default:
809         return "Unknown event";
810     }
811 }
812 #endif  /* Debug Functions */
813