• 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  *  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 *******************************************************************************/
nfa_p2p_discovery_cback(tNFA_DM_RF_DISC_EVT event,tNFC_DISCOVER * p_data)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 *******************************************************************************/
nfa_p2p_update_active_listen_timeout_cback(TIMER_LIST_ENT * p_tle)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 *******************************************************************************/
nfa_p2p_update_active_listen(void)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     nfa_p2p_cb.listen_tech_mask &=
210         ~(NFA_TECHNOLOGY_MASK_A_ACTIVE | NFA_TECHNOLOGY_MASK_F_ACTIVE);
211   }
212 
213   if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) {
214     nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle);
215     nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
216   }
217 
218   /* collect listen technologies with NFC-DEP protocol */
219   if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A)
220     p2p_listen_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
221 
222   if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F)
223     p2p_listen_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
224 
225   if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
226     p2p_listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP;
227 
228   if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
229     p2p_listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP;
230 
231   /* Configure listen technologies and protocols and register callback to NFA DM
232    * discovery */
233   nfa_p2p_cb.dm_disc_handle = nfa_dm_add_rf_discover(
234       p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH, nfa_p2p_discovery_cback);
235 
236   /* restart RF discovery to update RF technologies */
237   p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR));
238   if (p_msg != NULL) {
239     p_msg->event = NFA_P2P_INT_RESTART_RF_DISC_EVT;
240     nfa_sys_sendmsg(p_msg);
241   }
242 }
243 
244 /*******************************************************************************
245 **
246 ** Function         nfa_p2p_llcp_link_cback
247 **
248 ** Description      Processing event from LLCP link management callback
249 **
250 **
251 ** Returns          None
252 **
253 *******************************************************************************/
nfa_p2p_llcp_link_cback(uint8_t event,uint8_t reason)254 void nfa_p2p_llcp_link_cback(uint8_t event, uint8_t reason) {
255   tNFA_LLCP_ACTIVATED llcp_activated;
256   tNFA_LLCP_DEACTIVATED llcp_deactivated;
257 
258   P2P_TRACE_DEBUG2("nfa_p2p_llcp_link_cback () event:0x%x, reason:0x%x", event,
259                    reason);
260 
261   if (event == LLCP_LINK_ACTIVATION_COMPLETE_EVT) {
262     LLCP_GetLinkMIU(&nfa_p2p_cb.local_link_miu, &nfa_p2p_cb.remote_link_miu);
263     nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_ACTIVATED;
264 
265     if (nfa_p2p_cb.is_initiator) {
266       /* notify NFA DM to send Activate Event to applicaiton with status  */
267       nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
268     }
269 
270     llcp_activated.is_initiator = nfa_p2p_cb.is_initiator;
271     llcp_activated.local_link_miu = nfa_p2p_cb.local_link_miu;
272     llcp_activated.remote_link_miu = nfa_p2p_cb.remote_link_miu;
273     llcp_activated.remote_lsc = LLCP_GetRemoteLSC();
274     llcp_activated.remote_wks = LLCP_GetRemoteWKS();
275     llcp_activated.remote_version = LLCP_GetRemoteVersion();
276 
277     nfa_dm_act_conn_cback_notify(NFA_LLCP_ACTIVATED_EVT,
278                                  (tNFA_CONN_EVT_DATA*)&llcp_activated);
279 
280   } else if (event == LLCP_LINK_ACTIVATION_FAILED_EVT) {
281     nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE;
282 
283     if (nfa_p2p_cb.is_initiator) {
284       /* notify NFA DM to send Activate Event to applicaiton with status  */
285       nfa_dm_notify_activation_status(NFA_STATUS_FAILED, NULL);
286     }
287 
288     nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
289   } else if (event == LLCP_LINK_FIRST_PACKET_RECEIVED_EVT) {
290     nfa_dm_act_conn_cback_notify(NFA_LLCP_FIRST_PACKET_RECEIVED_EVT, NULL);
291   } else /* LLCP_LINK_DEACTIVATED_EVT       */
292   {
293     nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE;
294 
295     /* if got RF link loss without any rx LLC PDU */
296     if (reason == LLCP_LINK_RF_LINK_LOSS_NO_RX_LLC) {
297       /* if it was active listen mode */
298       if ((nfa_p2p_cb.is_active_mode) && (!nfa_p2p_cb.is_initiator)) {
299         /* if it didn't retry without active listen mode and passive mode is
300          * available */
301         if ((nfa_p2p_cb.listen_tech_mask_to_restore == 0x00) &&
302             (nfa_p2p_cb.listen_tech_mask &
303              (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F))) {
304           P2P_TRACE_DEBUG0("Retry without active listen mode");
305 
306           /* retry without active listen mode */
307           nfa_p2p_update_active_listen();
308         }
309       } else if (nfa_p2p_cb.listen_tech_mask_to_restore) {
310         nfa_sys_start_timer(&nfa_p2p_cb.active_listen_restore_timer, 0,
311                             NFA_P2P_RESTORE_ACTIVE_LISTEN_TIMEOUT);
312       }
313 
314       reason = LLCP_LINK_RF_LINK_LOSS_ERR;
315     } else {
316       if (nfa_p2p_cb.listen_tech_mask_to_restore) {
317         /* restore active listen mode */
318         nfa_p2p_update_active_listen();
319       }
320     }
321 
322     llcp_deactivated.reason = reason;
323     nfa_dm_act_conn_cback_notify(NFA_LLCP_DEACTIVATED_EVT,
324                                  (tNFA_CONN_EVT_DATA*)&llcp_deactivated);
325 
326     if (reason != LLCP_LINK_RF_LINK_LOSS_ERR) /* if NFC link is still up */
327     {
328       if (nfa_p2p_cb.is_initiator) {
329         nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
330       } else if ((nfa_p2p_cb.is_active_mode) && (reason == LLCP_LINK_TIMEOUT)) {
331         /*
332         ** target needs to trun off RF in case of receiving invalid
333         ** frame from initiator
334         */
335         P2P_TRACE_DEBUG0("Got LLCP_LINK_TIMEOUT in active mode on target");
336         nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
337       }
338     }
339   }
340 }
341 
342 /*******************************************************************************
343 **
344 ** Function         nfa_p2p_activate_llcp
345 **
346 ** Description      Activate LLCP link
347 **
348 **
349 ** Returns          None
350 **
351 *******************************************************************************/
nfa_p2p_activate_llcp(tNFC_DISCOVER * p_data)352 void nfa_p2p_activate_llcp(tNFC_DISCOVER* p_data) {
353   tLLCP_ACTIVATE_CONFIG config;
354 
355   P2P_TRACE_DEBUG0("nfa_p2p_activate_llcp ()");
356 
357   if ((p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) ||
358       (p_data->activate.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_F) ||
359       (p_data->activate.rf_tech_param.mode ==
360        NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
361       (p_data->activate.rf_tech_param.mode ==
362        NFC_DISCOVERY_TYPE_POLL_F_ACTIVE)) {
363     config.is_initiator = true;
364   } else {
365     config.is_initiator = false;
366   }
367 
368   if ((p_data->activate.rf_tech_param.mode ==
369        NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
370       (p_data->activate.rf_tech_param.mode ==
371        NFC_DISCOVERY_TYPE_POLL_F_ACTIVE) ||
372       (p_data->activate.rf_tech_param.mode ==
373        NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) ||
374       (p_data->activate.rf_tech_param.mode ==
375        NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE)) {
376     nfa_p2p_cb.is_active_mode = true;
377   } else {
378     nfa_p2p_cb.is_active_mode = false;
379   }
380 
381   nfa_p2p_cb.is_initiator = config.is_initiator;
382 
383   config.max_payload_size =
384       p_data->activate.intf_param.intf_param.pa_nfc.max_payload_size;
385   config.waiting_time =
386       p_data->activate.intf_param.intf_param.pa_nfc.waiting_time;
387   config.p_gen_bytes = p_data->activate.intf_param.intf_param.pa_nfc.gen_bytes;
388   config.gen_bytes_len =
389       p_data->activate.intf_param.intf_param.pa_nfc.gen_bytes_len;
390 
391   LLCP_ActivateLink(config, nfa_p2p_llcp_link_cback);
392 }
393 
394 /*******************************************************************************
395 **
396 ** Function         nfa_p2p_deactivate_llcp
397 **
398 ** Description      Deactivate LLCP link
399 **
400 **
401 ** Returns          None
402 **
403 *******************************************************************************/
nfa_p2p_deactivate_llcp(void)404 void nfa_p2p_deactivate_llcp(void) {
405   P2P_TRACE_DEBUG0("nfa_p2p_deactivate_llcp ()");
406 
407   LLCP_DeactivateLink();
408 }
409 
410 /*******************************************************************************
411 **
412 ** Function         nfa_p2p_init
413 **
414 ** Description      Initialize NFA P2P
415 **
416 **
417 ** Returns          None
418 **
419 *******************************************************************************/
nfa_p2p_init(void)420 void nfa_p2p_init(void) {
421   uint8_t xx;
422 
423   P2P_TRACE_DEBUG0("nfa_p2p_init ()");
424 
425   /* initialize control block */
426   memset(&nfa_p2p_cb, 0, sizeof(tNFA_P2P_CB));
427   nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
428   nfa_p2p_cb.trace_level = APPL_INITIAL_TRACE_LEVEL;
429 
430   for (xx = 0; xx < LLCP_MAX_SDP_TRANSAC; xx++) {
431     nfa_p2p_cb.sdp_cb[xx].local_sap = LLCP_INVALID_SAP;
432   }
433 
434   /* register message handler on NFA SYS */
435   nfa_sys_register(NFA_ID_P2P, &nfa_p2p_sys_reg);
436 }
437 
438 /*******************************************************************************
439 **
440 ** Function         nfa_p2p_sys_disable
441 **
442 ** Description      Deregister NFA P2P from NFA SYS/DM
443 **
444 **
445 ** Returns          None
446 **
447 *******************************************************************************/
nfa_p2p_sys_disable(void)448 static void nfa_p2p_sys_disable(void) {
449   P2P_TRACE_DEBUG0("nfa_p2p_sys_disable()");
450 
451   nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer);
452 
453   /* deregister message handler on NFA SYS */
454   nfa_sys_deregister(NFA_ID_P2P);
455 }
456 
457 /*******************************************************************************
458 **
459 ** Function         nfa_p2p_set_config
460 **
461 ** Description      Set General bytes and WT parameters for LLCP
462 **
463 **
464 ** Returns          void
465 **
466 *******************************************************************************/
nfa_p2p_set_config(tNFA_DM_DISC_TECH_PROTO_MASK disc_mask)467 void nfa_p2p_set_config(tNFA_DM_DISC_TECH_PROTO_MASK disc_mask) {
468   uint8_t wt, gen_bytes_len = LLCP_MAX_GEN_BYTES;
469   uint8_t params[LLCP_MAX_GEN_BYTES + 5], *p, length;
470 
471   P2P_TRACE_DEBUG0("nfa_p2p_set_config ()");
472 
473   LLCP_GetDiscoveryConfig(&wt, params + 2, &gen_bytes_len);
474   if (nfa_dm_is_p2p_paused()) {
475     gen_bytes_len = 0;
476   }
477 
478   if (disc_mask &
479       (NFA_DM_DISC_MASK_PA_NFC_DEP | NFA_DM_DISC_MASK_PF_NFC_DEP |
480        NFA_DM_DISC_MASK_PAA_NFC_DEP | NFA_DM_DISC_MASK_PFA_NFC_DEP)) {
481     p = params;
482 
483     UINT8_TO_BE_STREAM(p, NFC_PMID_ATR_REQ_GEN_BYTES);
484     UINT8_TO_BE_STREAM(p, gen_bytes_len);
485 
486     p += gen_bytes_len;
487     length = gen_bytes_len + 2;
488 
489     nfa_dm_check_set_config(length, params, false);
490   }
491 
492   if (disc_mask &
493       (NFA_DM_DISC_MASK_LA_NFC_DEP | NFA_DM_DISC_MASK_LF_NFC_DEP |
494        NFA_DM_DISC_MASK_LAA_NFC_DEP | NFA_DM_DISC_MASK_LFA_NFC_DEP)) {
495     p = params;
496 
497     UINT8_TO_BE_STREAM(p, NFC_PMID_ATR_RES_GEN_BYTES);
498     UINT8_TO_BE_STREAM(p, gen_bytes_len);
499 
500     p += gen_bytes_len;
501     length = gen_bytes_len + 2;
502 
503     UINT8_TO_BE_STREAM(p, NFC_PMID_WT);
504     UINT8_TO_BE_STREAM(p, NCI_PARAM_LEN_WT);
505     UINT8_TO_BE_STREAM(p, wt);
506 
507     length += 3;
508 
509     nfa_dm_check_set_config(length, params, false);
510   }
511 }
512 
513 /*******************************************************************************
514 **
515 ** Function         nfa_p2p_enable_listening
516 **
517 ** Description      Configure listen technologies and protocols for LLCP
518 **                  If LLCP WKS is changed then LLCP Gen bytes will be updated.
519 **
520 ** Returns          void
521 **
522 *******************************************************************************/
nfa_p2p_enable_listening(tNFA_SYS_ID sys_id,bool update_wks)523 void nfa_p2p_enable_listening(tNFA_SYS_ID sys_id, bool update_wks) {
524   tNFA_DM_DISC_TECH_PROTO_MASK p2p_listen_mask = 0;
525 
526   P2P_TRACE_DEBUG2("nfa_p2p_enable_listening () sys_id = %d, update_wks = %d",
527                    sys_id, update_wks);
528 
529   if (sys_id == NFA_ID_P2P)
530     nfa_p2p_cb.is_p2p_listening = true;
531   else if (sys_id == NFA_ID_SNEP)
532     nfa_p2p_cb.is_snep_listening = true;
533 
534   if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) {
535     /* if need to update WKS in LLCP Gen bytes */
536     if (update_wks) {
537       /* update LLCP Gen Bytes */
538       nfa_p2p_set_config(NFA_DM_DISC_MASK_PA_NFC_DEP |
539                          NFA_DM_DISC_MASK_LA_NFC_DEP);
540     }
541     return;
542   }
543 
544   /* collect listen technologies with NFC-DEP protocol */
545   if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A)
546     p2p_listen_mask |= NFA_DM_DISC_MASK_LA_NFC_DEP;
547 
548   if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F)
549     p2p_listen_mask |= NFA_DM_DISC_MASK_LF_NFC_DEP;
550 
551   if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE)
552     p2p_listen_mask |= NFA_DM_DISC_MASK_LAA_NFC_DEP;
553 
554   if (nfa_p2p_cb.listen_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE)
555     p2p_listen_mask |= NFA_DM_DISC_MASK_LFA_NFC_DEP;
556 
557   if (p2p_listen_mask) {
558     /* Configure listen technologies and protocols and register callback to NFA
559      * DM discovery */
560     nfa_p2p_cb.dm_disc_handle = nfa_dm_add_rf_discover(
561         p2p_listen_mask, NFA_DM_DISC_HOST_ID_DH, nfa_p2p_discovery_cback);
562   }
563 }
564 
565 /*******************************************************************************
566 **
567 ** Function         nfa_p2p_disable_listening
568 **
569 ** Description      Remove listen technologies and protocols for LLCP and
570 **                  deregister callback from NFA DM discovery if all of
571 **                  P2P/CHO/SNEP doesn't listen LLCP any more.
572 **                  If LLCP WKS is changed then ATR_RES will be updated.
573 **
574 ** Returns          void
575 **
576 *******************************************************************************/
nfa_p2p_disable_listening(tNFA_SYS_ID sys_id,bool update_wks)577 void nfa_p2p_disable_listening(tNFA_SYS_ID sys_id, bool update_wks) {
578   P2P_TRACE_DEBUG2("nfa_p2p_disable_listening ()  sys_id = %d, update_wks = %d",
579                    sys_id, update_wks);
580 
581   if (sys_id == NFA_ID_P2P)
582     nfa_p2p_cb.is_p2p_listening = false;
583   else if (sys_id == NFA_ID_SNEP)
584     nfa_p2p_cb.is_snep_listening = false;
585 
586   if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) {
587     if ((nfa_p2p_cb.is_p2p_listening == false) &&
588         (nfa_p2p_cb.is_snep_listening == false)) {
589       nfa_p2p_cb.llcp_state = NFA_P2P_LLCP_STATE_IDLE;
590       nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_IDLE;
591 
592       nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle);
593       nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
594     } else if (update_wks) {
595       /* update LLCP Gen Bytes */
596       nfa_p2p_set_config(NFA_DM_DISC_MASK_PA_NFC_DEP |
597                          NFA_DM_DISC_MASK_LA_NFC_DEP);
598     }
599   }
600 }
601 
602 /*******************************************************************************
603 **
604 ** Function         nfa_p2p_update_listen_tech
605 **
606 ** Description      Update P2P listen technologies. If there is change then
607 **                  restart or stop P2P listen.
608 **
609 ** Returns          void
610 **
611 *******************************************************************************/
nfa_p2p_update_listen_tech(tNFA_TECHNOLOGY_MASK tech_mask)612 void nfa_p2p_update_listen_tech(tNFA_TECHNOLOGY_MASK tech_mask) {
613   P2P_TRACE_DEBUG1("nfa_p2p_update_listen_tech ()  tech_mask = 0x%x",
614                    tech_mask);
615 
616   if (nfa_p2p_cb.listen_tech_mask_to_restore) {
617     nfa_p2p_cb.listen_tech_mask_to_restore = 0;
618     nfa_sys_stop_timer(&nfa_p2p_cb.active_listen_restore_timer);
619   }
620 
621   if (nfa_p2p_cb.listen_tech_mask != tech_mask) {
622     nfa_p2p_cb.listen_tech_mask = tech_mask;
623 
624     if (nfa_p2p_cb.dm_disc_handle != NFA_HANDLE_INVALID) {
625       nfa_p2p_cb.rf_disc_state = NFA_DM_RFST_IDLE;
626 
627       nfa_dm_delete_rf_discover(nfa_p2p_cb.dm_disc_handle);
628       nfa_p2p_cb.dm_disc_handle = NFA_HANDLE_INVALID;
629     }
630 
631     /* restart discovery without updating sub-module status */
632     if (nfa_p2p_cb.is_p2p_listening)
633       nfa_p2p_enable_listening(NFA_ID_P2P, false);
634     else if (nfa_p2p_cb.is_snep_listening)
635       nfa_p2p_enable_listening(NFA_ID_SNEP, false);
636   }
637 }
638 
639 /*******************************************************************************
640 **
641 ** Function         nfa_p2p_evt_hdlr
642 **
643 ** Description      Processing event for NFA P2P
644 **
645 **
646 ** Returns          TRUE if p_msg needs to be deallocated
647 **
648 *******************************************************************************/
nfa_p2p_evt_hdlr(NFC_HDR * p_hdr)649 static bool nfa_p2p_evt_hdlr(NFC_HDR* p_hdr) {
650   bool delete_msg = true;
651   uint16_t event;
652 
653   tNFA_P2P_MSG* p_msg = (tNFA_P2P_MSG*)p_hdr;
654 
655 #if (BT_TRACE_VERBOSE == TRUE)
656   P2P_TRACE_DEBUG2("nfa_p2p_evt_hdlr (): LLCP State [%s], Event [%s]",
657                    nfa_p2p_llcp_state_code(nfa_p2p_cb.llcp_state),
658                    nfa_p2p_evt_code(p_msg->hdr.event));
659 #else
660   P2P_TRACE_DEBUG2("nfa_p2p_evt_hdlr (): State 0x%02x, Event 0x%02x",
661                    nfa_p2p_cb.llcp_state, p_msg->hdr.event);
662 #endif
663 
664   event = p_msg->hdr.event & 0x00ff;
665 
666   /* execute action functions */
667   if (event < NFA_P2P_NUM_ACTIONS) {
668     delete_msg = (*nfa_p2p_action[event])(p_msg);
669   } else {
670     P2P_TRACE_ERROR0("Unhandled event");
671   }
672 
673   return delete_msg;
674 }
675 
676 #if (BT_TRACE_VERBOSE == TRUE)
677 /*******************************************************************************
678 **
679 ** Function         nfa_p2p_llcp_state_code
680 **
681 ** Description
682 **
683 ** Returns          string of state
684 **
685 *******************************************************************************/
nfa_p2p_llcp_state_code(tNFA_P2P_LLCP_STATE state_code)686 static char* nfa_p2p_llcp_state_code(tNFA_P2P_LLCP_STATE state_code) {
687   switch (state_code) {
688     case NFA_P2P_LLCP_STATE_IDLE:
689       return "Link IDLE";
690     case NFA_P2P_LLCP_STATE_LISTENING:
691       return "Link LISTENING";
692     case NFA_P2P_LLCP_STATE_ACTIVATED:
693       return "Link ACTIVATED";
694     default:
695       return "Unknown state";
696   }
697 }
698 
699 /*******************************************************************************
700 **
701 ** Function         nfa_p2p_evt_code
702 **
703 ** Description
704 **
705 ** Returns          string of event
706 **
707 *******************************************************************************/
nfa_p2p_evt_code(uint16_t evt_code)708 char* nfa_p2p_evt_code(uint16_t evt_code) {
709   switch (evt_code) {
710     case NFA_P2P_API_REG_SERVER_EVT:
711       return "API_REG_SERVER";
712     case NFA_P2P_API_REG_CLIENT_EVT:
713       return "API_REG_CLIENT";
714     case NFA_P2P_API_DEREG_EVT:
715       return "API_DEREG";
716     case NFA_P2P_API_ACCEPT_CONN_EVT:
717       return "API_ACCEPT_CONN";
718     case NFA_P2P_API_REJECT_CONN_EVT:
719       return "API_REJECT_CONN";
720     case NFA_P2P_API_DISCONNECT_EVT:
721       return "API_DISCONNECT";
722     case NFA_P2P_API_CONNECT_EVT:
723       return "API_CONNECT";
724     case NFA_P2P_API_SEND_UI_EVT:
725       return "API_SEND_UI";
726     case NFA_P2P_API_SEND_DATA_EVT:
727       return "API_SEND_DATA";
728     case NFA_P2P_API_SET_LOCAL_BUSY_EVT:
729       return "API_SET_LOCAL_BUSY";
730     case NFA_P2P_API_GET_LINK_INFO_EVT:
731       return "API_GET_LINK_INFO";
732     case NFA_P2P_API_GET_REMOTE_SAP_EVT:
733       return "API_GET_REMOTE_SAP";
734     case NFA_P2P_API_SET_LLCP_CFG_EVT:
735       return "API_SET_LLCP_CFG_EVT";
736     case NFA_P2P_INT_RESTART_RF_DISC_EVT:
737       return "RESTART_RF_DISC_EVT";
738     default:
739       return "Unknown event";
740   }
741 }
742 #endif /* Debug Functions */
743