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