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 file contains the action functions for device manager state
22 *  machine.
23 *
24 ******************************************************************************/
25#include <string.h>
26#include "nci_hmsgs.h"
27#include "nfa_api.h"
28#include "nfa_ce_int.h"
29#include "nfa_dm_int.h"
30#include "nfa_p2p_int.h"
31#include "nfa_rw_api.h"
32#include "nfa_rw_int.h"
33#include "nfa_sys.h"
34#include "nfa_sys_int.h"
35#include "nfc_api.h"
36
37#if (NFC_NFCEE_INCLUDED == TRUE)
38#include "nfa_ee_int.h"
39#include "nfa_hci_int.h"
40#endif
41
42#if (NFA_SNEP_INCLUDED == TRUE)
43#include "nfa_snep_int.h"
44#endif
45
46/* This is the timeout value to guarantee disable is performed within reasonable
47 * amount of time */
48#ifndef NFA_DM_DISABLE_TIMEOUT_VAL
49#define NFA_DM_DISABLE_TIMEOUT_VAL 1000
50#endif
51
52static void nfa_dm_set_init_nci_params(void);
53static tNFA_STATUS nfa_dm_start_polling(void);
54static bool nfa_dm_deactivate_polling(void);
55static void nfa_dm_excl_disc_cback(tNFA_DM_RF_DISC_EVT event,
56                                   tNFC_DISCOVER* p_data);
57static void nfa_dm_poll_disc_cback(tNFA_DM_RF_DISC_EVT event,
58                                   tNFC_DISCOVER* p_data);
59
60/*******************************************************************************
61**
62** Function         nfa_dm_module_init_cback
63**
64** Description      Processing initialization complete event from sub-modules
65**
66** Returns          None
67**
68*******************************************************************************/
69static void nfa_dm_module_init_cback(void) {
70  tNFA_DM_CBACK_DATA dm_cback_data;
71
72  nfa_dm_cb.flags &= ~NFA_DM_FLAGS_ENABLE_EVT_PEND;
73
74  /* All subsystem are initialized */
75  dm_cback_data.status = NFA_STATUS_OK;
76  (*nfa_dm_cb.p_dm_cback)(NFA_DM_ENABLE_EVT, &dm_cback_data);
77}
78
79/*******************************************************************************
80**
81** Function         nfa_dm_nfcc_power_mode_proc_complete_cback
82**
83** Description      Processing complete of processing NFCC power state change
84**                  from all sub-modules
85**
86** Returns          None
87**
88*******************************************************************************/
89static void nfa_dm_nfcc_power_mode_proc_complete_cback(void) {
90  tNFA_DM_PWR_MODE_CHANGE power_mode_change;
91
92  NFA_TRACE_DEBUG1(
93      "nfa_dm_nfcc_power_mode_proc_complete_cback () nfcc_pwr_mode = 0x%x",
94      nfa_dm_cb.nfcc_pwr_mode);
95
96  /* if NFCC power state is change to full power */
97  if (nfa_dm_cb.nfcc_pwr_mode != NFA_DM_PWR_MODE_OFF_SLEEP) {
98    nfa_dm_cb.flags &= ~NFA_DM_FLAGS_NFCC_IS_RESTORING;
99
100    /* reconfigure BRCM NFCC */
101    nfa_dm_disc_sm_execute(NFA_DM_RF_DISCOVER_CMD, NULL);
102  }
103
104  nfa_dm_cb.flags &= ~NFA_DM_FLAGS_SETTING_PWR_MODE;
105
106  power_mode_change.status = NFA_STATUS_OK;
107  power_mode_change.power_mode = nfa_dm_cb.nfcc_pwr_mode;
108  (*nfa_dm_cb.p_dm_cback)(NFA_DM_PWR_MODE_CHANGE_EVT,
109                          (tNFA_DM_CBACK_DATA*)&power_mode_change);
110}
111/*******************************************************************************
112**
113** Function         nfa_dm_sys_enable
114**
115** Description      This function on enable
116**
117** Returns          void
118**
119*******************************************************************************/
120void nfa_dm_sys_enable(void) { nfa_dm_set_init_nci_params(); }
121
122/*******************************************************************************
123**
124** Function         nfa_dm_set_init_nci_params
125**
126** Description      Set initial NCI configuration parameters
127**
128** Returns          void
129**
130*******************************************************************************/
131static void nfa_dm_set_init_nci_params(void) {
132  uint8_t xx;
133
134  /* set NCI default value if other than zero */
135
136  /* LF_T3T_IDENTIFIERS_1/2/.../16 */
137  for (xx = 0; xx < NFA_CE_LISTEN_INFO_MAX; xx++) {
138    nfa_dm_cb.params.lf_t3t_id[xx][0] = 0xFF;
139    nfa_dm_cb.params.lf_t3t_id[xx][1] = 0xFF;
140    nfa_dm_cb.params.lf_t3t_id[xx][2] = 0x02;
141    nfa_dm_cb.params.lf_t3t_id[xx][3] = 0xFE;
142  }
143
144  /* LF_T3T_PMM */
145  for (xx = 0; xx < NCI_PARAM_LEN_LF_T3T_PMM; xx++) {
146    nfa_dm_cb.params.lf_t3t_pmm[xx] = 0xFF;
147  }
148
149  /* LF_T3T_FLAGS:
150  ** DH needs to set this configuration, even if default value (not listening)
151  ** is used, to let NFCC know of intention (not listening) of DH.
152  */
153
154  /* FWI */
155  nfa_dm_cb.params.fwi[0] = 0x04;
156
157  /* WT */
158  nfa_dm_cb.params.wt[0] = 14;
159
160  /* Set CE default configuration */
161  if (p_nfa_dm_ce_cfg[0]) {
162    nfa_dm_check_set_config(p_nfa_dm_ce_cfg[0], &p_nfa_dm_ce_cfg[1], false);
163  }
164
165  /* Set optional general default configuration */
166  if (p_nfa_dm_gen_cfg && p_nfa_dm_gen_cfg[0]) {
167    nfa_dm_check_set_config(p_nfa_dm_gen_cfg[0], &p_nfa_dm_gen_cfg[1], false);
168  }
169
170  if (p_nfa_dm_interface_mapping && nfa_dm_num_dm_interface_mapping) {
171    NFC_DiscoveryMap(nfa_dm_num_dm_interface_mapping,
172                     p_nfa_dm_interface_mapping, NULL);
173  }
174}
175
176/*******************************************************************************
177**
178** Function         nfa_dm_proc_nfcc_power_mode
179**
180** Description      Processing NFCC power mode changes
181**
182** Returns          None
183**
184*******************************************************************************/
185void nfa_dm_proc_nfcc_power_mode(uint8_t nfcc_power_mode) {
186  NFA_TRACE_DEBUG1("nfa_dm_proc_nfcc_power_mode (): nfcc_power_mode=%d",
187                   nfcc_power_mode);
188
189  /* if NFCC power mode is change to full power */
190  if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL) {
191    memset(&nfa_dm_cb.params, 0x00, sizeof(tNFA_DM_PARAMS));
192    NFA_TRACE_DEBUG2("setcfg_pending_mask=0x%x, setcfg_pending_num=%d",
193                     nfa_dm_cb.setcfg_pending_mask,
194                     nfa_dm_cb.setcfg_pending_num);
195    nfa_dm_cb.setcfg_pending_mask = 0;
196    nfa_dm_cb.setcfg_pending_num = 0;
197
198    nfa_dm_set_init_nci_params();
199    nfa_dm_cb.flags &= ~NFA_DM_FLAGS_POWER_OFF_SLEEP;
200  } else if (nfcc_power_mode == NFA_DM_PWR_MODE_OFF_SLEEP) {
201    nfa_dm_cb.flags |= NFA_DM_FLAGS_POWER_OFF_SLEEP;
202  }
203
204  nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_DM);
205}
206
207/*******************************************************************************
208**
209** Function         nfa_dm_disable_event
210**
211** Description      report disable event
212**
213** Returns          void
214**
215*******************************************************************************/
216static void nfa_dm_disable_event(void) {
217  /* Deregister DM from sys */
218  nfa_sys_deregister(NFA_ID_DM);
219
220  /* Notify app */
221  nfa_dm_cb.flags &=
222      ~(NFA_DM_FLAGS_DM_IS_ACTIVE | NFA_DM_FLAGS_DM_DISABLING_NFC |
223        NFA_DM_FLAGS_ENABLE_EVT_PEND);
224  (*nfa_dm_cb.p_dm_cback)(NFA_DM_DISABLE_EVT, NULL);
225}
226
227/*******************************************************************************
228**
229** Function         nfa_dm_nfc_response_cback
230**
231** Description      Call DM event hanlder with NFC response callback data
232**
233** Returns          void
234**
235*******************************************************************************/
236static void nfa_dm_nfc_response_cback(tNFC_RESPONSE_EVT event,
237                                      tNFC_RESPONSE* p_data) {
238  tNFA_DM_CBACK_DATA dm_cback_data;
239  tNFA_GET_CONFIG* p_nfa_get_confg;
240  tNFA_CONN_EVT_DATA conn_evt;
241  uint8_t dm_cback_evt;
242  uint8_t max_ee = 0;
243
244#if (BT_TRACE_VERBOSE == TRUE)
245  NFA_TRACE_DEBUG2("nfa_dm_nfc_response_cback () %s(0x%x)",
246                   nfa_dm_nfc_revt_2_str(event), event);
247#else
248  NFA_TRACE_DEBUG1("nfa_dm_nfc_response_cback () event=0x%x", event);
249#endif
250
251  switch (event) {
252    case NFC_ENABLE_REVT: /* 0  Enable event */
253
254      /* NFC stack enabled. Enable nfa sub-systems */
255      if (p_data->enable.status == NFC_STATUS_OK) {
256        if (nfa_ee_max_ee_cfg != 0) {
257          if (nfa_dm_cb.get_max_ee) {
258            max_ee = nfa_dm_cb.get_max_ee();
259            if (max_ee) {
260              nfa_ee_max_ee_cfg = max_ee;
261            }
262          }
263        }
264        /* Initialize NFA subsystems */
265        nfa_sys_enable_subsystems();
266      } else if (nfa_dm_cb.flags & NFA_DM_FLAGS_ENABLE_EVT_PEND) {
267        /* Notify app */
268        nfa_dm_cb.flags &=
269            ~(NFA_DM_FLAGS_ENABLE_EVT_PEND | NFA_DM_FLAGS_DM_IS_ACTIVE);
270        dm_cback_data.status = p_data->enable.status;
271        (*nfa_dm_cb.p_dm_cback)(NFA_DM_ENABLE_EVT, &dm_cback_data);
272      }
273      break;
274
275    case NFC_DISABLE_REVT: /* 1  Disable event */
276      nfa_dm_disable_event();
277      break;
278
279    case NFC_SET_CONFIG_REVT: /* 2  Set Config Response */
280      /* If this setconfig was due to NFA_SetConfig, then notify the app */
281      /* lsb=whether last NCI_SET_CONFIG was due to NFA_SetConfig */
282      if (nfa_dm_cb.setcfg_pending_mask & 1) {
283        dm_cback_data.set_config.status = p_data->set_config.status;
284        dm_cback_data.set_config.num_param_id = p_data->set_config.num_param_id;
285        memcpy(dm_cback_data.set_config.param_ids, p_data->set_config.param_ids,
286               p_data->set_config.num_param_id);
287        (*nfa_dm_cb.p_dm_cback)(NFA_DM_SET_CONFIG_EVT, &dm_cback_data);
288      }
289
290      /* Update the pending mask */
291      if (nfa_dm_cb.setcfg_pending_num > 0) {
292        nfa_dm_cb.setcfg_pending_mask >>= 1;
293        nfa_dm_cb.setcfg_pending_num--;
294      } else {
295        /* This should not occur (means we got a SET_CONFIG_NTF that's
296         * unaccounted for */
297        NFA_TRACE_ERROR0("NFA received unexpected NFC_SET_CONFIG_REVT");
298      }
299      break;
300
301    case NFC_GET_CONFIG_REVT: /* 3  Get Config Response */
302      if (p_data->get_config.status == NFC_STATUS_OK) {
303        p_nfa_get_confg = (tNFA_GET_CONFIG*)GKI_getbuf(
304            (uint16_t)(sizeof(tNFA_GET_CONFIG) + p_data->get_config.tlv_size));
305        if (p_nfa_get_confg != NULL) {
306          p_nfa_get_confg->status = NFA_STATUS_OK;
307          p_nfa_get_confg->tlv_size = p_data->get_config.tlv_size;
308          memcpy(p_nfa_get_confg->param_tlvs, p_data->get_config.p_param_tlvs,
309                 p_data->get_config.tlv_size);
310          (*nfa_dm_cb.p_dm_cback)(NFA_DM_GET_CONFIG_EVT,
311                                  (tNFA_DM_CBACK_DATA*)p_nfa_get_confg);
312
313          GKI_freebuf(p_nfa_get_confg);
314          return;
315        } else {
316          NFA_TRACE_DEBUG0(
317              "nfa_dm_nfc_response_cback unable to allocate buffer");
318        }
319      }
320
321      /* Return result of getconfig to the app */
322      dm_cback_data.get_config.status = NFA_STATUS_FAILED;
323      (*nfa_dm_cb.p_dm_cback)(NFA_DM_GET_CONFIG_EVT, &dm_cback_data);
324      break;
325
326#if (NFC_NFCEE_INCLUDED == TRUE)
327    case NFC_NFCEE_DISCOVER_REVT: /* NFCEE Discover response */
328    case NFC_NFCEE_INFO_REVT:     /* NFCEE Discover Notification */
329    case NFC_EE_ACTION_REVT:      /* EE Action notification */
330    case NFC_NFCEE_MODE_SET_REVT: /* NFCEE Mode Set response */
331    case NFC_SET_ROUTING_REVT:    /* Configure Routing response */
332      nfa_ee_proc_evt(event, p_data);
333      break;
334
335    case NFC_EE_DISCOVER_REQ_REVT: /* EE Discover Req notification */
336      if (nfa_dm_is_active() &&
337          (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_DISCOVERY)) {
338        nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
339      }
340      nfa_ee_proc_evt(event, p_data);
341      break;
342
343    case NFC_GET_ROUTING_REVT: /* Retrieve Routing response */
344      break;
345#endif
346
347    case NFC_RF_FIELD_REVT: /* RF Field information            */
348      dm_cback_data.rf_field.status = NFA_STATUS_OK;
349      dm_cback_data.rf_field.rf_field_status = p_data->rf_field.rf_field;
350      (*nfa_dm_cb.p_dm_cback)(NFA_DM_RF_FIELD_EVT, &dm_cback_data);
351      break;
352
353    case NFC_GEN_ERROR_REVT: /* generic error command or notification */
354      break;
355
356    case NFC_NFCC_RESTART_REVT: /* NFCC has been re-initialized */
357
358      if (p_data->status == NFC_STATUS_OK) {
359        nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_FULL;
360        nfa_dm_cb.flags |= NFA_DM_FLAGS_NFCC_IS_RESTORING;
361
362        /* NFCC will start from IDLE when turned on again */
363        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_RSP;
364        nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_W4_NTF;
365        nfa_dm_cb.disc_cb.disc_state = NFA_DM_RFST_IDLE;
366      } else {
367        nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_OFF_SLEEP;
368      }
369      /* Notify NFA submodules change of NFCC power mode */
370      nfa_sys_cback_reg_nfcc_power_mode_proc_complete(
371          nfa_dm_nfcc_power_mode_proc_complete_cback);
372      nfa_sys_notify_nfcc_power_mode(nfa_dm_cb.nfcc_pwr_mode);
373      break;
374
375    case NFC_NFCC_TIMEOUT_REVT:
376    case NFC_NFCC_TRANSPORT_ERR_REVT:
377      NFA_TRACE_DEBUG1("flags:0x%08x", nfa_dm_cb.flags);
378      dm_cback_evt = (event == NFC_NFCC_TIMEOUT_REVT)
379                         ? NFA_DM_NFCC_TIMEOUT_EVT
380                         : NFA_DM_NFCC_TRANSPORT_ERR_EVT;
381      (*nfa_dm_cb.p_dm_cback)(dm_cback_evt, NULL);
382      break;
383
384    case NFC_NFCC_POWER_OFF_REVT:
385      nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_OFF_SLEEP;
386
387      /* Notify NFA submodules change of NFCC power mode */
388      nfa_sys_cback_reg_nfcc_power_mode_proc_complete(
389          nfa_dm_nfcc_power_mode_proc_complete_cback);
390      nfa_sys_notify_nfcc_power_mode(NFA_DM_PWR_MODE_OFF_SLEEP);
391      break;
392
393    case NFC_RF_COMM_PARAMS_UPDATE_REVT:
394      conn_evt.status = p_data->status;
395      nfa_dm_conn_cback_event_notify(NFA_UPDATE_RF_PARAM_RESULT_EVT, &conn_evt);
396      break;
397
398    default:
399      break;
400  }
401}
402
403/*******************************************************************************
404**
405** Function         nfa_dm_enable
406**
407** Description      Initialises the NFC device manager
408**
409** Returns          TRUE (message buffer to be freed by caller)
410**
411*******************************************************************************/
412bool nfa_dm_enable(tNFA_DM_MSG* p_data) {
413  tNFA_DM_CBACK_DATA dm_cback_data;
414  NFA_TRACE_DEBUG0("nfa_dm_enable ()");
415
416  /* Check if NFA is already enabled */
417  if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_DM_IS_ACTIVE)) {
418    /* Initialize BRCM control block, it musb be called before setting any flags
419     */
420    nfa_dm_cb.flags |=
421        (NFA_DM_FLAGS_DM_IS_ACTIVE | NFA_DM_FLAGS_ENABLE_EVT_PEND);
422    nfa_sys_cback_reg_enable_complete(nfa_dm_module_init_cback);
423
424    /* Store Enable parameters */
425    nfa_dm_cb.p_dm_cback = p_data->enable.p_dm_cback;
426    nfa_dm_cb.p_conn_cback = p_data->enable.p_conn_cback;
427
428    /* Enable NFC stack */
429    NFC_Enable(nfa_dm_nfc_response_cback);
430  } else {
431    NFA_TRACE_ERROR0("nfa_dm_enable: ERROR ALREADY ENABLED.");
432    dm_cback_data.status = NFA_STATUS_ALREADY_STARTED;
433    (*(p_data->enable.p_dm_cback))(NFA_DM_ENABLE_EVT, &dm_cback_data);
434  }
435
436  return true;
437}
438
439/*******************************************************************************
440**
441** Function         nfa_dm_disable
442**
443** Description      Disables the NFC device manager
444**
445** Returns          TRUE (message buffer to be freed by caller)
446**
447*******************************************************************************/
448bool nfa_dm_disable(tNFA_DM_MSG* p_data) {
449  tNFC_DEACT_TYPE deactivate_type = NFA_DEACTIVATE_TYPE_IDLE;
450
451  NFA_TRACE_DEBUG1("nfa_dm_disable (): graceful:%d", p_data->disable.graceful);
452
453  if (p_data->disable.graceful) {
454    /* if RF discovery is enabled */
455    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED) {
456      nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;
457
458      if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE) {
459        /* if waiting RSP in idle state */
460        if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
461          nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_DISABLING;
462        }
463      } else {
464        nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_DISABLING;
465        nfa_dm_disc_sm_execute(NFA_DM_RF_DEACTIVATE_CMD,
466                               (tNFA_DM_RF_DISC_DATA*)&deactivate_type);
467        if ((nfa_dm_cb.disc_cb.disc_flags &
468             (NFA_DM_DISC_FLAGS_W4_RSP | NFA_DM_DISC_FLAGS_W4_NTF)) == 0) {
469          /* not waiting to deactivate, clear the flag now */
470          nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_DISABLING;
471        }
472      }
473    }
474    /* Start timeout for graceful shutdown. If timer expires, then force an
475     * ungraceful shutdown */
476    nfa_sys_start_timer(&nfa_dm_cb.tle, NFA_DM_TIMEOUT_DISABLE_EVT,
477                        NFA_DM_DISABLE_TIMEOUT_VAL);
478  }
479
480  /* Disable all subsystems other than DM (DM will be disabled after all  */
481  /* the other subsystem have been disabled)                              */
482  nfa_sys_disable_subsystems(p_data->disable.graceful);
483  return true;
484}
485
486/*******************************************************************************
487**
488** Function         nfa_dm_disable_complete
489**
490** Description      Called when all NFA subsytems are disabled.
491**
492**                  NFC core stack can now be disabled.
493**
494** Returns          void
495**
496*******************************************************************************/
497void nfa_dm_disable_complete(void) {
498  NFA_TRACE_DEBUG0("nfa_dm_disable_complete ()");
499
500  if ((nfa_dm_cb.flags & NFA_DM_FLAGS_DM_DISABLING_NFC) == 0) {
501    NFA_TRACE_DEBUG0(
502        "nfa_dm_disable_complete (): proceeding with nfc core shutdown.");
503
504    nfa_dm_cb.flags |= NFA_DM_FLAGS_DM_DISABLING_NFC;
505
506    nfa_sys_stop_timer(&nfa_dm_cb.tle);
507
508    /* Free all buffers for NDEF handlers */
509    nfa_dm_ndef_dereg_all();
510
511    /* Disable nfc core stack */
512    NFC_Disable();
513  }
514}
515
516/*******************************************************************************
517**
518** Function         nfa_dm_set_config
519**
520** Description      Process set config command
521**
522** Returns          TRUE (message buffer to be freed by caller)
523**
524*******************************************************************************/
525bool nfa_dm_set_config(tNFA_DM_MSG* p_data) {
526  tNFC_STATUS status;
527  uint8_t buff[255];
528  uint8_t* p = buff;
529
530  tNFA_DM_CBACK_DATA dm_cback_data;
531
532  if (p_data->setconfig.length + 2 > 255) {
533    /* Total length of TLV must be less than 256 (1 byte) */
534    status = NFC_STATUS_FAILED;
535  } else {
536    UINT8_TO_STREAM(p, p_data->setconfig.param_id);
537    UINT8_TO_STREAM(p, p_data->setconfig.length);
538    ARRAY_TO_STREAM(p, p_data->setconfig.p_data, p_data->setconfig.length)
539    status = nfa_dm_check_set_config((uint8_t)(p_data->setconfig.length + 2),
540                                     buff, true);
541  }
542
543  if (status != NFC_STATUS_OK) {
544    dm_cback_data.set_config.status = NFA_STATUS_INVALID_PARAM;
545    (*nfa_dm_cb.p_dm_cback)(NFA_DM_SET_CONFIG_EVT, &dm_cback_data);
546  }
547
548  return true;
549}
550
551/*******************************************************************************
552**
553** Function         nfa_dm_get_config
554**
555** Description      Process get config command
556**
557** Returns          TRUE (message buffer to be freed by caller)
558**
559*******************************************************************************/
560bool nfa_dm_get_config(tNFA_DM_MSG* p_data) {
561  NFC_GetConfig(p_data->getconfig.num_ids, p_data->getconfig.p_pmids);
562
563  return true;
564}
565
566/*******************************************************************************
567**
568** Function         nfa_dm_conn_cback_event_notify
569**
570** Description      Notify application of CONN_CBACK event, using appropriate
571**                  callback
572**
573** Returns          nothing
574**
575*******************************************************************************/
576void nfa_dm_conn_cback_event_notify(uint8_t event, tNFA_CONN_EVT_DATA* p_data) {
577  if (nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) {
578    /* Use exclusive RF mode callback */
579    if (nfa_dm_cb.p_excl_conn_cback)
580      (*nfa_dm_cb.p_excl_conn_cback)(event, p_data);
581  } else {
582    (*nfa_dm_cb.p_conn_cback)(event, p_data);
583  }
584}
585
586/*******************************************************************************
587**
588** Function         nfa_dm_rel_excl_rf_control_and_notify
589**
590** Description      Stop exclusive RF control and notify app of
591**                  NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT
592**
593** Returns          void
594**
595*******************************************************************************/
596void nfa_dm_rel_excl_rf_control_and_notify(void) {
597  tNFA_CONN_EVT_DATA conn_evt;
598
599  NFA_TRACE_DEBUG0("nfa_dm_rel_excl_rf_control_and_notify ()");
600
601  /* Exclusive RF control stopped. Notify app */
602  nfa_dm_cb.flags &= ~NFA_DM_FLAGS_EXCL_RF_ACTIVE;
603
604  /* Stop exclusive RF discovery for exclusive RF mode */
605  nfa_dm_stop_excl_discovery();
606
607  /* Notify app that exclusive RF control has stopped */
608  conn_evt.status = NFA_STATUS_OK;
609  (*nfa_dm_cb.p_excl_conn_cback)(NFA_EXCLUSIVE_RF_CONTROL_STOPPED_EVT,
610                                 &conn_evt);
611  nfa_dm_cb.p_excl_conn_cback = NULL;
612  nfa_dm_cb.p_excl_ndef_cback = NULL;
613}
614
615/*******************************************************************************
616**
617** Function         nfa_dm_act_request_excl_rf_ctrl
618**
619** Description      Request exclusive RF control
620**
621** Returns          TRUE (message buffer to be freed by caller)
622**
623*******************************************************************************/
624bool nfa_dm_act_request_excl_rf_ctrl(tNFA_DM_MSG* p_data) {
625  tNFA_CONN_EVT_DATA conn_evt;
626
627  NFA_TRACE_DEBUG0("nfa_dm_act_request_excl_rf_ctrl ()");
628
629  if (!nfa_dm_cb.p_excl_conn_cback) {
630    if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_IDLE) {
631      conn_evt.status = NFA_STATUS_FAILED;
632      (*p_data->req_excl_rf_ctrl.p_conn_cback)(
633          NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &conn_evt);
634      return true;
635    }
636
637    /* Store callbacks */
638    nfa_dm_cb.p_excl_conn_cback = p_data->req_excl_rf_ctrl.p_conn_cback;
639    nfa_dm_cb.p_excl_ndef_cback = p_data->req_excl_rf_ctrl.p_ndef_cback;
640
641    nfa_dm_cb.flags |= NFA_DM_FLAGS_EXCL_RF_ACTIVE;
642
643    /* start exclusive RF discovery */
644    nfa_dm_start_excl_discovery(p_data->req_excl_rf_ctrl.poll_mask,
645                                &p_data->req_excl_rf_ctrl.listen_cfg,
646                                nfa_dm_excl_disc_cback);
647  } else {
648    NFA_TRACE_ERROR0("Exclusive rf control already requested");
649
650    conn_evt.status = NFA_STATUS_FAILED;
651    (*p_data->req_excl_rf_ctrl.p_conn_cback)(
652        NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT, &conn_evt);
653  }
654
655  return true;
656}
657
658/*******************************************************************************
659**
660** Function         nfa_dm_act_release_excl_rf_ctrl
661**
662** Description      Release exclusive RF control
663**
664** Returns          TRUE (message buffer to be freed by caller)
665**
666*******************************************************************************/
667bool nfa_dm_act_release_excl_rf_ctrl(tNFA_DM_MSG* p_data) {
668  NFA_TRACE_DEBUG0("nfa_dm_act_release_excl_rf_ctrl ()");
669
670  /* nfa_dm_rel_excl_rf_control_and_notify() is called when discovery state goes
671   * IDLE */
672  nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;
673
674  /* if discover command has been sent in IDLE state and waiting for response
675  ** then just wait for responose. Otherwise initiate deactivating.
676  */
677  if (!((nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE) &&
678        (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP))) {
679    nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
680  }
681
682  if (nfa_dm_cb.disc_cb.kovio_tle.in_use)
683    nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
684
685  return true;
686}
687
688/*******************************************************************************
689**
690** Function         nfa_dm_act_deactivate
691**
692** Description      Process deactivate command
693**
694** Returns          TRUE (message buffer to be freed by caller)
695**
696*******************************************************************************/
697bool nfa_dm_act_deactivate(tNFA_DM_MSG* p_data) {
698  tNFA_CONN_EVT_DATA conn_evt;
699  tNFA_DEACTIVATE_TYPE deact_type;
700
701  NFA_TRACE_DEBUG0("nfa_dm_act_deactivate ()");
702
703  /* Always allow deactivate to IDLE */
704  /* Do not allow deactivate to SLEEP for T1T,NFCDEP, ISO15693 */
705  if ((p_data->deactivate.sleep_mode == false) ||
706      ((nfa_dm_cb.disc_cb.activated_protocol != NFA_PROTOCOL_T1T) &&
707       (nfa_dm_cb.disc_cb.activated_protocol != NFA_PROTOCOL_NFC_DEP) &&
708       (nfa_dm_cb.disc_cb.activated_protocol != NFA_PROTOCOL_ISO15693) &&
709       (nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_KOVIO))) {
710    deact_type = NFA_DEACTIVATE_TYPE_DISCOVERY;
711    if (p_data->deactivate.sleep_mode) {
712      if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT) {
713        /* Deactivate to sleep mode not allowed in this state. */
714        deact_type = NFA_DEACTIVATE_TYPE_IDLE;
715      } else if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_LISTEN_SLEEP) {
716        deact_type = NFA_DEACTIVATE_TYPE_SLEEP;
717      }
718    }
719    if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_ALL_DISCOVERIES) {
720      /* Only deactivate to IDLE is allowed in this state. */
721      deact_type = NFA_DEACTIVATE_TYPE_IDLE;
722    }
723
724    if ((nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_NFC_DEP) &&
725        ((nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) == 0x00)) {
726      /* Exclusive RF control doesn't use NFA P2P */
727      /* NFA P2P will deactivate NFC link after deactivating LLCP link */
728      if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_P2P_PAUSED)) {
729        nfa_p2p_deactivate_llcp();
730      } else {
731        nfa_dm_rf_deactivate(deact_type);
732      }
733      return true;
734    } else {
735      if (nfa_dm_rf_deactivate(deact_type) == NFA_STATUS_OK) {
736        if (nfa_dm_cb.disc_cb.kovio_tle.in_use)
737          nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
738        nfa_rw_stop_presence_check_timer();
739        return true;
740      }
741    }
742  }
743
744  NFA_TRACE_ERROR0("nfa_dm_act_deactivate (): invalid protocol, mode or state");
745
746  /* Notify error to application */
747  conn_evt.status = NFA_STATUS_FAILED;
748  nfa_dm_conn_cback_event_notify(NFA_DEACTIVATE_FAIL_EVT, &conn_evt);
749
750  return true;
751}
752
753/*******************************************************************************
754**
755** Function         nfa_dm_act_power_off_sleep
756**
757** Description      Process power off sleep mode request
758**
759** Returns          TRUE (message buffer to be freed by caller)
760**
761*******************************************************************************/
762bool nfa_dm_act_power_off_sleep(tNFA_DM_MSG* p_data) {
763  NFA_TRACE_DEBUG0("nfa_dm_act_power_off_sleep ()");
764
765  NFC_SetPowerOffSleep((bool)(p_data->hdr.layer_specific));
766
767  return true;
768}
769
770/*******************************************************************************
771**
772** Function         nfa_dm_act_reg_vsc
773**
774** Description      Process registers VSC callback
775**
776** Returns          TRUE (message buffer to be freed by caller)
777**
778*******************************************************************************/
779bool nfa_dm_act_reg_vsc(tNFA_DM_MSG* p_data) {
780  if (NFC_RegVSCback(p_data->reg_vsc.is_register, p_data->reg_vsc.p_cback) !=
781      NFC_STATUS_OK) {
782    NFA_TRACE_ERROR0("NFC_RegVSCback failed");
783  }
784  return true;
785}
786
787/*******************************************************************************
788**
789** Function         nfa_dm_act_send_vsc
790**
791** Description      Send the NCI Vendor Specific command to the NCI command
792**                  queue
793**
794** Returns          FALSE (message buffer is NOT freed by caller)
795**
796*******************************************************************************/
797bool nfa_dm_act_send_vsc(tNFA_DM_MSG* p_data) {
798  NFC_HDR* p_cmd = (NFC_HDR*)p_data;
799
800  p_cmd->offset = sizeof(tNFA_DM_API_SEND_VSC) - NFC_HDR_SIZE;
801  p_cmd->len = p_data->send_vsc.cmd_params_len;
802  NFC_SendVsCommand(p_data->send_vsc.oid, p_cmd, p_data->send_vsc.p_cback);
803
804  /* Most dm action functions return TRUE, so nfa-sys frees the GKI buffer
805   * carrying the message,
806   * This action function re-use the GKI buffer to send the VSC, so the GKI
807   * buffer can not be freed by nfa-sys */
808  return false;
809}
810
811/*******************************************************************************
812**
813** Function         nfa_dm_start_polling
814**
815** Description      Start polling
816**
817** Returns          tNFA_STATUS
818**
819*******************************************************************************/
820tNFA_STATUS nfa_dm_start_polling(void) {
821  tNFA_STATUS status;
822  tNFA_TECHNOLOGY_MASK poll_tech_mask;
823  tNFA_DM_DISC_TECH_PROTO_MASK poll_disc_mask = 0;
824
825  NFA_TRACE_DEBUG0("nfa_dm_start_polling ()");
826
827  poll_tech_mask = nfa_dm_cb.poll_mask;
828
829  /* start RF discovery with discovery callback */
830  if (nfa_dm_cb.poll_disc_handle == NFA_HANDLE_INVALID) {
831    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A) {
832      poll_disc_mask |= NFA_DM_DISC_MASK_PA_T1T;
833      poll_disc_mask |= NFA_DM_DISC_MASK_PA_T2T;
834      poll_disc_mask |= NFA_DM_DISC_MASK_PA_ISO_DEP;
835      poll_disc_mask |= NFA_DM_DISC_MASK_PA_NFC_DEP;
836      poll_disc_mask |= NFA_DM_DISC_MASK_P_LEGACY;
837    }
838    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_A_ACTIVE) {
839      poll_disc_mask |= NFA_DM_DISC_MASK_PAA_NFC_DEP;
840    }
841    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B) {
842      poll_disc_mask |= NFA_DM_DISC_MASK_PB_ISO_DEP;
843    }
844    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F) {
845      poll_disc_mask |= NFA_DM_DISC_MASK_PF_T3T;
846      poll_disc_mask |= NFA_DM_DISC_MASK_PF_NFC_DEP;
847    }
848    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_F_ACTIVE) {
849      poll_disc_mask |= NFA_DM_DISC_MASK_PFA_NFC_DEP;
850    }
851    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_ISO15693) {
852      poll_disc_mask |= NFA_DM_DISC_MASK_P_ISO15693;
853    }
854    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_B_PRIME) {
855      poll_disc_mask |= NFA_DM_DISC_MASK_P_B_PRIME;
856    }
857    if (poll_tech_mask & NFA_TECHNOLOGY_MASK_KOVIO) {
858      poll_disc_mask |= NFA_DM_DISC_MASK_P_KOVIO;
859    }
860
861    nfa_dm_cb.poll_disc_handle = nfa_dm_add_rf_discover(
862        poll_disc_mask, NFA_DM_DISC_HOST_ID_DH, nfa_dm_poll_disc_cback);
863
864    if (nfa_dm_cb.poll_disc_handle != NFA_HANDLE_INVALID)
865      status = NFA_STATUS_OK;
866    else
867      status = NFA_STATUS_FAILED;
868  } else {
869    status = NFA_STATUS_OK;
870  }
871
872  return (status);
873}
874
875/*******************************************************************************
876**
877** Function         nfa_dm_act_enable_polling
878**
879** Description      Process enable polling command
880**
881** Returns          TRUE (message buffer to be freed by caller)
882**
883*******************************************************************************/
884bool nfa_dm_act_enable_polling(tNFA_DM_MSG* p_data) {
885  tNFA_CONN_EVT_DATA evt_data;
886
887  NFA_TRACE_DEBUG0("nfa_dm_act_enable_polling ()");
888
889  if ((!(nfa_dm_cb.flags & NFA_DM_FLAGS_POLLING_ENABLED)) &&
890      (!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE))) {
891    nfa_dm_cb.poll_mask = p_data->enable_poll.poll_mask;
892
893    if (nfa_dm_start_polling() == NFA_STATUS_OK) {
894      nfa_dm_cb.flags |= NFA_DM_FLAGS_POLLING_ENABLED;
895
896      evt_data.status = NFA_STATUS_OK;
897      nfa_dm_conn_cback_event_notify(NFA_POLL_ENABLED_EVT, &evt_data);
898      return true;
899    }
900  } else {
901    NFA_TRACE_ERROR0("nfa_dm_act_enable_polling (): already started");
902  }
903
904  /* send NFA_POLL_ENABLED_EVT with NFA_STATUS_FAILED */
905  evt_data.status = NFA_STATUS_FAILED;
906  nfa_dm_conn_cback_event_notify(NFA_POLL_ENABLED_EVT, &evt_data);
907
908  return true;
909}
910
911/*******************************************************************************
912**
913** Function         nfa_dm_deactivate_polling
914**
915** Description      Deactivate any polling state
916**
917** Returns          TRUE if need to wait for deactivation
918**
919*******************************************************************************/
920static bool nfa_dm_deactivate_polling(void) {
921  NFA_TRACE_DEBUG0("nfa_dm_deactivate_polling ()");
922
923  if ((nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_ALL_DISCOVERIES) ||
924      (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_W4_HOST_SELECT)) {
925    nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
926    return false;
927  } else if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) {
928    if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_NFC_DEP) {
929      /* NFA P2P will deactivate NFC link after deactivating LLCP link */
930      nfa_p2p_deactivate_llcp();
931    } else {
932      nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE);
933    }
934    return true;
935  } else {
936    return false;
937  }
938}
939
940/*******************************************************************************
941**
942** Function         nfa_dm_act_disable_polling
943**
944** Description      Process disable polling command
945**
946** Returns          TRUE (message buffer to be freed by caller)
947**
948*******************************************************************************/
949bool nfa_dm_act_disable_polling(tNFA_DM_MSG* p_data) {
950  tNFA_CONN_EVT_DATA evt_data;
951
952  NFA_TRACE_DEBUG0("nfa_dm_act_disable_polling ()");
953
954  if (nfa_dm_cb.poll_disc_handle != NFA_HANDLE_INVALID) {
955    nfa_dm_cb.flags &= ~NFA_DM_FLAGS_POLLING_ENABLED;
956
957    if (nfa_dm_deactivate_polling() == false) {
958      nfa_dm_delete_rf_discover(nfa_dm_cb.poll_disc_handle);
959      nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID;
960
961      evt_data.status = NFA_STATUS_OK;
962      nfa_dm_conn_cback_event_notify(NFA_POLL_DISABLED_EVT, &evt_data);
963    } else {
964      nfa_dm_cb.flags |= NFA_DM_FLAGS_SEND_POLL_STOP_EVT;
965    }
966  } else {
967    evt_data.status = NFA_STATUS_FAILED;
968    nfa_dm_conn_cback_event_notify(NFA_POLL_DISABLED_EVT, &evt_data);
969  }
970
971  return true;
972}
973
974/*******************************************************************************
975**
976** Function         nfa_dm_act_enable_listening
977**
978** Description      Process enable listening command
979**
980** Returns          TRUE (message buffer to be freed by caller)
981**
982*******************************************************************************/
983bool nfa_dm_act_enable_listening(tNFA_DM_MSG* p_data) {
984  tNFA_CONN_EVT_DATA evt_data;
985
986  NFA_TRACE_DEBUG0("nfa_dm_act_enable_listening ()");
987
988  nfa_dm_cb.flags &= ~NFA_DM_FLAGS_LISTEN_DISABLED;
989  evt_data.status = NFA_STATUS_OK;
990  nfa_dm_conn_cback_event_notify(NFA_LISTEN_ENABLED_EVT, &evt_data);
991
992  return true;
993}
994
995/*******************************************************************************
996**
997** Function         nfa_dm_act_disable_listening
998**
999** Description      Process disable listening command
1000**
1001** Returns          TRUE (message buffer to be freed by caller)
1002**
1003*******************************************************************************/
1004bool nfa_dm_act_disable_listening(tNFA_DM_MSG* p_data) {
1005  tNFA_CONN_EVT_DATA evt_data;
1006
1007  NFA_TRACE_DEBUG0("nfa_dm_act_disable_listening ()");
1008
1009  nfa_dm_cb.flags |= NFA_DM_FLAGS_LISTEN_DISABLED;
1010  evt_data.status = NFA_STATUS_OK;
1011  nfa_dm_conn_cback_event_notify(NFA_LISTEN_DISABLED_EVT, &evt_data);
1012
1013  return true;
1014}
1015
1016/*******************************************************************************
1017**
1018** Function         nfa_dm_act_pause_p2p
1019**
1020** Description      Process Pause P2P command
1021**
1022** Returns          TRUE (message buffer to be freed by caller)
1023**
1024*******************************************************************************/
1025bool nfa_dm_act_pause_p2p(tNFA_DM_MSG* p_data) {
1026  tNFA_CONN_EVT_DATA evt_data;
1027
1028  NFA_TRACE_DEBUG0("nfa_dm_act_pause_p2p ()");
1029
1030  nfa_dm_cb.flags |= NFA_DM_FLAGS_P2P_PAUSED;
1031  evt_data.status = NFA_STATUS_OK;
1032  nfa_dm_conn_cback_event_notify(NFA_P2P_PAUSED_EVT, &evt_data);
1033
1034  return true;
1035}
1036
1037/*******************************************************************************
1038**
1039** Function         nfa_dm_act_resume_p2p
1040**
1041** Description      Process resume P2P command
1042**
1043** Returns          TRUE (message buffer to be freed by caller)
1044**
1045*******************************************************************************/
1046bool nfa_dm_act_resume_p2p(tNFA_DM_MSG* p_data) {
1047  tNFA_CONN_EVT_DATA evt_data;
1048
1049  NFA_TRACE_DEBUG0("nfa_dm_act_resume_p2p ()");
1050
1051  nfa_dm_cb.flags &= ~NFA_DM_FLAGS_P2P_PAUSED;
1052  evt_data.status = NFA_STATUS_OK;
1053  nfa_dm_conn_cback_event_notify(NFA_P2P_RESUMED_EVT, &evt_data);
1054
1055  return true;
1056}
1057
1058/*******************************************************************************
1059**
1060** Function         nfa_dm_act_send_raw_frame
1061**
1062** Description      Send an raw frame on RF link
1063**
1064** Returns          TRUE (message buffer to be freed by caller)
1065**
1066*******************************************************************************/
1067bool nfa_dm_act_send_raw_frame(tNFA_DM_MSG* p_data) {
1068  tNFC_STATUS status = NFC_STATUS_FAILED;
1069
1070  NFA_TRACE_DEBUG0("nfa_dm_act_send_raw_frame ()");
1071
1072  /* If NFC link is activated */
1073  if ((nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_POLL_ACTIVE) ||
1074      (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE)) {
1075    nfa_dm_cb.flags |= NFA_DM_FLAGS_RAW_FRAME;
1076    NFC_SetReassemblyFlag(false);
1077    /* If not in exclusive mode, and not activated for LISTEN, then forward raw
1078     * data to NFA_RW to send */
1079    if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE) &&
1080        !(nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE) &&
1081        ((nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_T1T) ||
1082         (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_T2T) ||
1083         (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_T3T) ||
1084         (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_ISO_DEP) ||
1085         (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_ISO15693))) {
1086      /* if RW is checking presence then it will put into pending queue */
1087      status = nfa_rw_send_raw_frame((NFC_HDR*)p_data);
1088    } else {
1089      status = NFC_SendData(NFC_RF_CONN_ID, (NFC_HDR*)p_data);
1090      if (status != NFC_STATUS_OK) {
1091        NFC_SetReassemblyFlag(true);
1092      }
1093      /* Already freed or NCI layer will free buffer */
1094      return false;
1095    }
1096  }
1097
1098  if (status == NFC_STATUS_FAILED) {
1099    NFC_SetReassemblyFlag(true);
1100    /* free the buffer */
1101    return true;
1102  } else {
1103    /* NCI layer will free buffer */
1104    return false;
1105  }
1106}
1107
1108/*******************************************************************************
1109**
1110** Function         nfa_dm_set_p2p_listen_tech
1111**
1112** Description      Notify change of P2P listen technologies to NFA P2P
1113**
1114** Returns          TRUE (message buffer to be freed by caller)
1115**
1116*******************************************************************************/
1117bool nfa_dm_set_p2p_listen_tech(tNFA_DM_MSG* p_data) {
1118  NFA_TRACE_DEBUG1("nfa_dm_set_p2p_listen_tech ()  tech_mask = %d",
1119                   p_data->set_p2p_listen_tech.tech_mask);
1120
1121  nfa_p2p_update_listen_tech(p_data->set_p2p_listen_tech.tech_mask);
1122  nfa_dm_conn_cback_event_notify(NFA_SET_P2P_LISTEN_TECH_EVT, NULL);
1123
1124  return true;
1125}
1126
1127/*******************************************************************************
1128**
1129** Function         nfa_dm_act_start_rf_discovery
1130**
1131** Description      Process start RF discovery command
1132**
1133** Returns          TRUE (message buffer to be freed by caller)
1134**
1135*******************************************************************************/
1136bool nfa_dm_act_start_rf_discovery(tNFA_DM_MSG* p_data) {
1137  tNFA_CONN_EVT_DATA evt_data;
1138
1139  NFA_TRACE_DEBUG0("nfa_dm_act_start_rf_discovery ()");
1140
1141  if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED) {
1142    evt_data.status = NFA_STATUS_OK;
1143    nfa_dm_conn_cback_event_notify(NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
1144  } else if (nfa_dm_cb.disc_cb.disc_state != NFA_DM_RFST_IDLE) {
1145    evt_data.status = NFA_STATUS_SEMANTIC_ERROR;
1146    nfa_dm_conn_cback_event_notify(NFA_RF_DISCOVERY_STARTED_EVT, &evt_data);
1147  } else {
1148    nfa_dm_cb.disc_cb.disc_flags |=
1149        (NFA_DM_DISC_FLAGS_ENABLED | NFA_DM_DISC_FLAGS_NOTIFY);
1150    nfa_dm_start_rf_discover();
1151  }
1152
1153  return true;
1154}
1155
1156/*******************************************************************************
1157**
1158** Function         nfa_dm_act_stop_rf_discovery
1159**
1160** Description      Process stop RF discovery command
1161**
1162** Returns          TRUE (message buffer to be freed by caller)
1163**
1164*******************************************************************************/
1165bool nfa_dm_act_stop_rf_discovery(tNFA_DM_MSG* p_data) {
1166  tNFA_CONN_EVT_DATA evt_data;
1167
1168  NFA_TRACE_DEBUG0("nfa_dm_act_stop_rf_discovery ()");
1169
1170  if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_ENABLED) ||
1171      (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_IDLE)) {
1172    nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;
1173
1174    /* if discover command has been sent in IDLE state and waiting for response
1175     */
1176    if (nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_W4_RSP) {
1177      nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;
1178    } else {
1179      evt_data.status = NFA_STATUS_OK;
1180      nfa_dm_conn_cback_event_notify(NFA_RF_DISCOVERY_STOPPED_EVT, &evt_data);
1181    }
1182  } else {
1183    nfa_dm_cb.disc_cb.disc_flags &= ~NFA_DM_DISC_FLAGS_ENABLED;
1184    nfa_dm_cb.disc_cb.disc_flags |= NFA_DM_DISC_FLAGS_STOPPING;
1185
1186    if (nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_IDLE) == NFA_STATUS_OK) {
1187      if (nfa_dm_cb.disc_cb.kovio_tle.in_use)
1188        nfa_sys_stop_timer(&nfa_dm_cb.disc_cb.kovio_tle);
1189      nfa_rw_stop_presence_check_timer();
1190    }
1191  }
1192  return true;
1193}
1194
1195/*******************************************************************************
1196**
1197** Function         nfa_dm_act_set_rf_disc_duration
1198**
1199** Description      Set duration for RF discovery
1200**
1201** Returns          TRUE (message buffer to be freed by caller)
1202**
1203*******************************************************************************/
1204bool nfa_dm_act_set_rf_disc_duration(tNFA_DM_MSG* p_data) {
1205  nfa_dm_cb.disc_cb.disc_duration = p_data->disc_duration.rf_disc_dur_ms;
1206  return true;
1207}
1208
1209/*******************************************************************************
1210**
1211** Function         nfa_dm_act_get_rf_disc_duration
1212**
1213** Description      Get duration for RF discovery
1214**
1215** Returns          uint16_t
1216**
1217*******************************************************************************/
1218uint16_t nfa_dm_act_get_rf_disc_duration() {
1219  return (nfa_dm_cb.disc_cb.disc_duration);
1220}
1221/*******************************************************************************
1222**
1223** Function         nfa_dm_act_select
1224**
1225** Description      Process RF select command
1226**
1227** Returns          TRUE (message buffer to be freed by caller)
1228**
1229*******************************************************************************/
1230bool nfa_dm_act_select(tNFA_DM_MSG* p_data) {
1231  NFA_TRACE_DEBUG0("nfa_dm_act_select ()");
1232
1233  nfa_dm_rf_discover_select(p_data->select.rf_disc_id, p_data->select.protocol,
1234                            p_data->select.rf_interface);
1235  return true;
1236}
1237
1238/*******************************************************************************
1239**
1240** Function         nfa_dm_act_update_rf_params
1241**
1242** Description      Process update RF communication parameters command
1243**
1244** Returns          TRUE (message buffer to be freed by caller)
1245**
1246*******************************************************************************/
1247bool nfa_dm_act_update_rf_params(tNFA_DM_MSG* p_data) {
1248  tNFA_CONN_EVT_DATA conn_evt;
1249
1250  NFA_TRACE_DEBUG0("nfa_dm_act_update_rf_params ()");
1251
1252  if (NFC_UpdateRFCommParams(&p_data->update_rf_params.params) !=
1253      NFC_STATUS_OK) {
1254    conn_evt.status = NFA_STATUS_FAILED;
1255    nfa_dm_conn_cback_event_notify(NFA_UPDATE_RF_PARAM_RESULT_EVT, &conn_evt);
1256  }
1257
1258  return true;
1259}
1260
1261/*******************************************************************************
1262**
1263** Function         nfa_dm_act_disable_timeout
1264**
1265** Description      timeout on disable process. Shutdown immediately
1266**
1267** Returns          TRUE (message buffer to be freed by caller)
1268**
1269*******************************************************************************/
1270bool nfa_dm_act_disable_timeout(tNFA_DM_MSG* p_data) {
1271  tNFA_DM_API_DISABLE disable;
1272
1273  disable.graceful = false;
1274  nfa_dm_disable((tNFA_DM_MSG*)&disable);
1275  return true;
1276}
1277
1278/*******************************************************************************
1279**
1280** Function         nfa_dm_act_conn_cback_notify
1281**
1282** Description      Notify app of reader/writer/ndef events
1283**
1284** Returns          nothing
1285**
1286*******************************************************************************/
1287void nfa_dm_act_conn_cback_notify(uint8_t event, tNFA_CONN_EVT_DATA* p_data) {
1288  NFA_TRACE_DEBUG1("nfa_dm_act_conn_cback_notify (): event:0x%X", event);
1289
1290  /* Notify event using appropriate CONN_CBACK */
1291  nfa_dm_conn_cback_event_notify(event, p_data);
1292
1293  /* If not in exclusive RF mode, then read NDEF message from tag (if automatic
1294   * reading is enabled) */
1295  if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)) {
1296    if ((event == NFA_NDEF_DETECT_EVT) &&
1297        (nfa_dm_cb.flags & NFA_DM_FLAGS_AUTO_READING_NDEF)) {
1298      /* read NDEF message from tag */
1299      if (p_data->ndef_detect.status == NFA_STATUS_OK) {
1300        NFA_RwReadNDef();
1301      } else if (p_data->ndef_detect.status == NFA_STATUS_FAILED) {
1302        nfa_dm_cb.flags &= ~NFA_DM_FLAGS_AUTO_READING_NDEF;
1303      }
1304      /* ignore NFA_STATUS_BUSY */
1305    } else if ((event == NFA_READ_CPLT_EVT) &&
1306               (nfa_dm_cb.flags & NFA_DM_FLAGS_AUTO_READING_NDEF)) {
1307      /* reading NDEF message is done */
1308      nfa_dm_cb.flags &= ~NFA_DM_FLAGS_AUTO_READING_NDEF;
1309    }
1310  }
1311}
1312
1313/*******************************************************************************
1314**
1315** Function         nfa_dm_act_data_cback
1316**
1317** Description      Processing data from RF link
1318**
1319** Returns          None
1320**
1321*******************************************************************************/
1322static void nfa_dm_act_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
1323                                  tNFC_CONN* p_data) {
1324  NFC_HDR* p_msg;
1325  tNFA_CONN_EVT_DATA evt_data;
1326
1327  NFA_TRACE_DEBUG1("nfa_dm_act_data_cback (): event = 0x%X", event);
1328
1329  if (event == NFC_DATA_CEVT) {
1330    p_msg = (NFC_HDR*)p_data->data.p_data;
1331
1332    if (p_msg) {
1333      evt_data.data.status = p_data->data.status;
1334      evt_data.data.p_data = (uint8_t*)(p_msg + 1) + p_msg->offset;
1335      evt_data.data.len = p_msg->len;
1336
1337      nfa_dm_conn_cback_event_notify(NFA_DATA_EVT, &evt_data);
1338
1339      GKI_freebuf(p_msg);
1340    } else {
1341      NFA_TRACE_ERROR0(
1342          "nfa_dm_act_data_cback (): received NFC_DATA_CEVT with NULL data "
1343          "pointer");
1344    }
1345  } else if (event == NFC_DEACTIVATE_CEVT) {
1346    NFC_SetStaticRfCback(NULL);
1347  }
1348}
1349
1350/*******************************************************************************
1351**
1352** Function         nfa_dm_excl_disc_cback
1353**
1354** Description      Processing event from discovery callback
1355**
1356** Returns          None
1357**
1358*******************************************************************************/
1359static void nfa_dm_excl_disc_cback(tNFA_DM_RF_DISC_EVT event,
1360                                   tNFC_DISCOVER* p_data) {
1361  tNFA_CONN_EVT_DATA evt_data;
1362
1363  NFA_TRACE_DEBUG1("nfa_dm_excl_disc_cback (): event:0x%02X", event);
1364
1365  switch (event) {
1366    case NFA_DM_RF_DISC_START_EVT:
1367      evt_data.status = NFA_STATUS_OK;
1368      nfa_dm_conn_cback_event_notify(NFA_EXCLUSIVE_RF_CONTROL_STARTED_EVT,
1369                                     &evt_data);
1370      break;
1371
1372    case NFA_DM_RF_DISC_ACTIVATED_EVT:
1373      if (nfa_dm_cb.disc_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A) {
1374        /* store SEL_RES response */
1375        nfa_dm_cb.disc_cb.activated_sel_res =
1376            p_data->activate.rf_tech_param.param.pa.sel_rsp;
1377      }
1378
1379      if (nfa_dm_cb.disc_cb.disc_state == NFA_DM_RFST_LISTEN_ACTIVE) {
1380        /* Set data callback to receive raw frame */
1381        NFC_SetStaticRfCback(nfa_dm_act_data_cback);
1382
1383        memset(&(evt_data.activated.params), 0x00, sizeof(tNFA_TAG_PARAMS));
1384        memcpy(&(evt_data.activated.activate_ntf), &(p_data->activate),
1385               sizeof(tNFC_ACTIVATE_DEVT));
1386
1387        nfa_dm_conn_cback_event_notify(NFA_ACTIVATED_EVT, &evt_data);
1388      } else {
1389        /* holding activation notification until sub-module is ready */
1390        nfa_dm_cb.p_activate_ntf =
1391            (uint8_t*)GKI_getbuf(sizeof(tNFC_ACTIVATE_DEVT));
1392
1393        if (nfa_dm_cb.p_activate_ntf) {
1394          memcpy(nfa_dm_cb.p_activate_ntf, &(p_data->activate),
1395                 sizeof(tNFC_ACTIVATE_DEVT));
1396
1397          if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T1T) ||
1398              (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T2T) ||
1399              (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T3T) ||
1400              (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_ISO_DEP) ||
1401              (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_ISO15693) ||
1402              (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_KOVIO)) {
1403            /* Notify NFA tag sub-system */
1404            nfa_rw_proc_disc_evt(NFA_DM_RF_DISC_ACTIVATED_EVT, p_data, false);
1405          } else /* if NFC-DEP, ISO-DEP with frame interface or others */
1406          {
1407            /* Set data callback to receive raw frame */
1408            NFC_SetStaticRfCback(nfa_dm_act_data_cback);
1409            nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
1410          }
1411        } else {
1412          /* deactivate and restart RF discovery */
1413          nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
1414        }
1415      }
1416      break;
1417
1418    case NFA_DM_RF_DISC_DEACTIVATED_EVT:
1419
1420      /* if deactivated to idle or discovery */
1421      if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) ||
1422          (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)) {
1423        /* clear stored NFCID/UID/KOVIO bar code */
1424        nfa_dm_cb.activated_nfcid_len = 0;
1425      }
1426
1427      if (nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_NFC_DEP) {
1428        /* Notify NFA RW sub-systems */
1429        nfa_rw_proc_disc_evt(NFA_DM_RF_DISC_DEACTIVATED_EVT, NULL, false);
1430      }
1431
1432      /* if deactivated as sleep mode */
1433      if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP) ||
1434          (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
1435        evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_SLEEP;
1436      } else {
1437        evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
1438      }
1439
1440      /* notify deactivation to upper layer */
1441      nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data);
1442
1443      /* clean up SEL_RES response */
1444      nfa_dm_cb.disc_cb.activated_sel_res = 0;
1445      break;
1446
1447    default:
1448      NFA_TRACE_ERROR0("Unexpected event");
1449      break;
1450  }
1451}
1452
1453/*******************************************************************************
1454**
1455** Function         nfa_dm_poll_disc_cback
1456**
1457** Description      Processing event from discovery callback
1458**
1459** Returns          None
1460**
1461*******************************************************************************/
1462static void nfa_dm_poll_disc_cback(tNFA_DM_RF_DISC_EVT event,
1463                                   tNFC_DISCOVER* p_data) {
1464  tNFA_CONN_EVT_DATA evt_data;
1465
1466  NFA_TRACE_DEBUG1("nfa_dm_poll_disc_cback (): event:0x%02X", event);
1467
1468  switch (event) {
1469    case NFA_DM_RF_DISC_START_EVT:
1470      break;
1471
1472    case NFA_DM_RF_DISC_ACTIVATED_EVT:
1473
1474      if (nfa_dm_cb.disc_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A) {
1475        /* store SEL_RES response */
1476        nfa_dm_cb.disc_cb.activated_sel_res =
1477            p_data->activate.rf_tech_param.param.pa.sel_rsp;
1478      }
1479
1480      /* holding activation notification until sub-module is ready */
1481      nfa_dm_cb.p_activate_ntf =
1482          (uint8_t*)GKI_getbuf(sizeof(tNFC_ACTIVATE_DEVT));
1483
1484      if (nfa_dm_cb.p_activate_ntf) {
1485        memcpy(nfa_dm_cb.p_activate_ntf, &(p_data->activate),
1486               sizeof(tNFC_ACTIVATE_DEVT));
1487
1488        if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_NFC_DEP) &&
1489            (nfa_dm_cb.disc_cb.activated_rf_interface ==
1490             NFC_INTERFACE_NFC_DEP)) {
1491          if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_P2P_PAUSED)) {
1492            /* activate LLCP */
1493            nfa_p2p_activate_llcp(p_data);
1494            if (nfa_dm_cb.p_activate_ntf) {
1495              GKI_freebuf(nfa_dm_cb.p_activate_ntf);
1496              nfa_dm_cb.p_activate_ntf = NULL;
1497            }
1498          } else {
1499            NFA_TRACE_DEBUG0("P2P is paused");
1500            nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
1501          }
1502        } else if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T1T) ||
1503                   (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T2T) ||
1504                   (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T3T) ||
1505                   (nfa_dm_cb.disc_cb.activated_protocol ==
1506                    NFC_PROTOCOL_ISO_DEP) ||
1507                   (nfa_dm_cb.disc_cb.activated_protocol ==
1508                    NFC_PROTOCOL_15693) ||
1509                   (nfa_dm_cb.disc_cb.activated_protocol ==
1510                    NFC_PROTOCOL_KOVIO) ||
1511                   (nfa_dm_cb.disc_cb.activated_protocol ==
1512                    NFC_PROTOCOL_MIFARE)) {
1513          /* Notify NFA tag sub-system */
1514          nfa_rw_proc_disc_evt(NFA_DM_RF_DISC_ACTIVATED_EVT, p_data, true);
1515        } else /* if NFC-DEP/ISO-DEP with frame interface */
1516        {
1517          /* Set data callback to receive raw frame */
1518          NFC_SetStaticRfCback(nfa_dm_act_data_cback);
1519          nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
1520        }
1521      } else {
1522        /* deactivate and restart RF discovery */
1523        nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
1524      }
1525      break;
1526
1527    case NFA_DM_RF_DISC_DEACTIVATED_EVT:
1528
1529      /* if deactivated to idle or discovery */
1530      if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_IDLE) ||
1531          (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_DISCOVERY)) {
1532        /* clear stored NFCID/UID/KOVIO bar code */
1533        nfa_dm_cb.activated_nfcid_len = 0;
1534      }
1535
1536      if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_NFC_DEP) &&
1537          (nfa_dm_cb.disc_cb.activated_rf_interface == NFC_INTERFACE_NFC_DEP)) {
1538        /*
1539        ** If LLCP link is not deactivated yet,
1540        ** LLCP will receive deactivation ntf through data callback.
1541        ** NFA P2P will receive callback event from LLCP.
1542        */
1543      } else {
1544        /* Notify NFA RW sub-systems */
1545        nfa_rw_proc_disc_evt(NFA_DM_RF_DISC_DEACTIVATED_EVT, NULL, true);
1546      }
1547
1548      /* if NFA sent NFA_ACTIVATED_EVT earlier */
1549      if (nfa_dm_cb.flags & NFA_DM_FLAGS_SEND_DEACTIVATED_EVT) {
1550        nfa_dm_cb.flags &= ~NFA_DM_FLAGS_SEND_DEACTIVATED_EVT;
1551
1552        /* if deactivated as sleep mode */
1553        if ((p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP) ||
1554            (p_data->deactivate.type == NFC_DEACTIVATE_TYPE_SLEEP_AF)) {
1555          evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_SLEEP;
1556        } else {
1557          evt_data.deactivated.type = NFA_DEACTIVATE_TYPE_IDLE;
1558        }
1559        /* notify deactivation to application */
1560        nfa_dm_conn_cback_event_notify(NFA_DEACTIVATED_EVT, &evt_data);
1561      }
1562
1563      /* clean up SEL_RES response */
1564      nfa_dm_cb.disc_cb.activated_sel_res = 0;
1565
1566      if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_POLLING_ENABLED)) {
1567        /* deregister discovery callback from NFA DM Discovery */
1568        nfa_dm_delete_rf_discover(nfa_dm_cb.poll_disc_handle);
1569        nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID;
1570
1571        /* this is for disable polling */
1572        if (nfa_dm_cb.flags & NFA_DM_FLAGS_SEND_POLL_STOP_EVT) {
1573          nfa_dm_cb.flags &= ~NFA_DM_FLAGS_SEND_POLL_STOP_EVT;
1574
1575          evt_data.status = NFA_STATUS_OK;
1576          nfa_dm_conn_cback_event_notify(NFA_POLL_DISABLED_EVT, &evt_data);
1577        }
1578      }
1579      break;
1580  }
1581}
1582
1583/*******************************************************************************
1584**
1585** Function         nfa_dm_notify_activation_status
1586**
1587** Description      Processing activation status from sub-modules
1588**
1589** Returns          None
1590**
1591*******************************************************************************/
1592void nfa_dm_notify_activation_status(tNFA_STATUS status,
1593                                     tNFA_TAG_PARAMS* p_params) {
1594  tNFA_CONN_EVT_DATA evt_data;
1595  tNFC_RF_TECH_PARAMS* p_tech_params;
1596  uint8_t *p_nfcid = NULL, nfcid_len;
1597
1598  NFA_TRACE_DEBUG1("nfa_dm_notify_activation_status (): status:0x%X", status);
1599
1600  if (!nfa_dm_cb.p_activate_ntf) {
1601    /* this is for NFA P2P listen */
1602    return;
1603  }
1604
1605  if (status == NFA_STATUS_OK) {
1606    /* notify NFC link activation */
1607    memcpy(&(evt_data.activated.activate_ntf), nfa_dm_cb.p_activate_ntf,
1608           sizeof(tNFC_ACTIVATE_DEVT));
1609
1610    p_tech_params = &evt_data.activated.activate_ntf.rf_tech_param;
1611
1612    memset(&(evt_data.activated.params), 0x00, sizeof(tNFA_TAG_PARAMS));
1613    if (p_params) {
1614      memcpy(&(evt_data.activated.params), p_params, sizeof(tNFA_TAG_PARAMS));
1615    }
1616
1617    /* get length of NFCID and location */
1618    if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_A) {
1619      if ((p_tech_params->param.pa.nfcid1_len == 0) && (p_params != NULL)) {
1620        nfcid_len = sizeof(p_params->t1t.uid);
1621        p_nfcid = p_params->t1t.uid;
1622        evt_data.activated.activate_ntf.rf_tech_param.param.pa.nfcid1_len =
1623            nfcid_len;
1624        memcpy(evt_data.activated.activate_ntf.rf_tech_param.param.pa.nfcid1,
1625               p_nfcid, nfcid_len);
1626      } else {
1627        nfcid_len = p_tech_params->param.pa.nfcid1_len;
1628        p_nfcid = p_tech_params->param.pa.nfcid1;
1629      }
1630    } else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_B) {
1631      nfcid_len = NFC_NFCID0_MAX_LEN;
1632      p_nfcid = p_tech_params->param.pb.nfcid0;
1633    } else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_F) {
1634      nfcid_len = NFC_NFCID2_LEN;
1635      p_nfcid = p_tech_params->param.pf.nfcid2;
1636    } else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_ISO15693) {
1637      nfcid_len = NFC_ISO15693_UID_LEN;
1638      p_nfcid = p_tech_params->param.pi93.uid;
1639    } else if (p_tech_params->mode == NFC_DISCOVERY_TYPE_POLL_KOVIO) {
1640      nfcid_len = p_tech_params->param.pk.uid_len;
1641      p_nfcid = p_tech_params->param.pk.uid;
1642    } else {
1643      nfcid_len = 0;
1644    }
1645
1646    /*
1647    ** If not in exlusive RF mode, and
1648    **      P2P activation, then push default NDEF message through SNEP
1649    **      TAG activation, then read NDEF message
1650    */
1651    if (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_NFC_DEP) {
1652      /*
1653      ** Default NDEF message will be put to NFC Forum defualt SNEP server
1654      ** after receiving NFA_LLCP_ACTIVATED_EVT.
1655      */
1656    } else if (!(nfa_dm_cb.flags & NFA_DM_FLAGS_EXCL_RF_ACTIVE)) {
1657      /*
1658      ** if the same tag is activated then do not perform auto NDEF
1659      ** detection. Application may put a tag into sleep mode and
1660      ** reactivate the same tag.
1661      */
1662
1663      if ((p_tech_params->mode != nfa_dm_cb.activated_tech_mode) ||
1664          (nfcid_len != nfa_dm_cb.activated_nfcid_len) ||
1665          (memcmp(p_nfcid, nfa_dm_cb.activated_nfcid, nfcid_len))) {
1666        if ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T1T) ||
1667            (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T2T) ||
1668            (nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_T3T) ||
1669            ((nfa_dm_cb.disc_cb.activated_protocol == NFC_PROTOCOL_ISO_DEP) &&
1670             (nfa_dm_cb.disc_cb.activated_rf_interface ==
1671              NFC_INTERFACE_ISO_DEP)) ||
1672            (nfa_dm_cb.disc_cb.activated_protocol == NFA_PROTOCOL_ISO15693)) {
1673          if (p_nfa_dm_cfg->auto_detect_ndef) {
1674            if (p_nfa_dm_cfg->auto_read_ndef) {
1675              nfa_dm_cb.flags |= NFA_DM_FLAGS_AUTO_READING_NDEF;
1676            }
1677            NFA_RwDetectNDef();
1678          } else if (p_nfa_dm_cfg->auto_read_ndef) {
1679            NFA_RwReadNDef();
1680          }
1681        }
1682      }
1683    }
1684
1685    /* store activated tag information */
1686    nfa_dm_cb.activated_tech_mode = p_tech_params->mode;
1687    nfa_dm_cb.activated_nfcid_len = nfcid_len;
1688    if (nfcid_len) memcpy(nfa_dm_cb.activated_nfcid, p_nfcid, nfcid_len);
1689
1690    nfa_dm_cb.flags |= NFA_DM_FLAGS_SEND_DEACTIVATED_EVT;
1691    if (!(nfa_dm_cb.disc_cb.disc_flags & NFA_DM_DISC_FLAGS_CHECKING))
1692      nfa_dm_conn_cback_event_notify(NFA_ACTIVATED_EVT, &evt_data);
1693  } else {
1694    /* if NFC_DEP, NFA P2P will deactivate */
1695    if (nfa_dm_cb.disc_cb.activated_protocol != NFC_PROTOCOL_NFC_DEP) {
1696      nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
1697    }
1698  }
1699
1700  GKI_freebuf(nfa_dm_cb.p_activate_ntf);
1701  nfa_dm_cb.p_activate_ntf = NULL;
1702}
1703
1704#if (BT_TRACE_VERBOSE == TRUE)
1705/*******************************************************************************
1706**
1707** Function         nfa_dm_nfc_revt_2_str
1708**
1709** Description      convert nfc revt to string
1710**
1711*******************************************************************************/
1712char* nfa_dm_nfc_revt_2_str(tNFC_RESPONSE_EVT event) {
1713  switch (event) {
1714    case NFC_ENABLE_REVT:
1715      return "NFC_ENABLE_REVT";
1716
1717    case NFC_DISABLE_REVT:
1718      return "NFC_DISABLE_REVT";
1719
1720    case NFC_SET_CONFIG_REVT:
1721      return "NFC_SET_CONFIG_REVT";
1722
1723    case NFC_GET_CONFIG_REVT:
1724      return "NFC_GET_CONFIG_REVT";
1725
1726    case NFC_NFCEE_DISCOVER_REVT:
1727      return "NFC_NFCEE_DISCOVER_REVT";
1728
1729    case NFC_NFCEE_INFO_REVT:
1730      return "NFC_NFCEE_INFO_REVT";
1731
1732    case NFC_NFCEE_MODE_SET_REVT:
1733      return "NFC_NFCEE_MODE_SET_REVT";
1734
1735    case NFC_RF_FIELD_REVT:
1736      return "NFC_RF_FIELD_REVT";
1737
1738    case NFC_EE_ACTION_REVT:
1739      return "NFC_EE_ACTION_REVT";
1740
1741    case NFC_EE_DISCOVER_REQ_REVT:
1742      return "NFC_EE_DISCOVER_REQ_REVT";
1743
1744    case NFC_SET_ROUTING_REVT:
1745      return "NFC_SET_ROUTING_REVT";
1746
1747    case NFC_GET_ROUTING_REVT:
1748      return "NFC_GET_ROUTING_REVT";
1749
1750    case NFC_GEN_ERROR_REVT:
1751      return "NFC_GEN_ERROR_REVT";
1752
1753    case NFC_NFCC_RESTART_REVT:
1754      return "NFC_NFCC_RESTART_REVT";
1755
1756    case NFC_NFCC_TIMEOUT_REVT:
1757      return "NFC_NFCC_TIMEOUT_REVT";
1758
1759    case NFC_NFCC_TRANSPORT_ERR_REVT:
1760      return "NFC_NFCC_TRANSPORT_ERR_REVT";
1761
1762    case NFC_NFCC_POWER_OFF_REVT:
1763      return "NFC_NFCC_POWER_OFF_REVT";
1764
1765    default:
1766      return "unknown revt";
1767      break;
1768  }
1769}
1770#endif /* BT_VERBOSE */
1771