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