1/******************************************************************************
2 *
3 *  Copyright (C) 2009-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 functions that interface with the NFC NCI transport.
22 *  On the receive side, it routes events to the appropriate handler
23 *  (callback). On the transmit side, it manages the command transmission.
24 *
25******************************************************************************/
26#include <string.h>
27#include "bt_types.h"
28#include "nfc_target.h"
29
30#include "nci_hmsgs.h"
31#include "nfc_api.h"
32#include "rw_api.h"
33#include "rw_int.h"
34
35tRW_CB rw_cb;
36/*******************************************************************************
37*******************************************************************************/
38void rw_init(void) {
39  memset(&rw_cb, 0, sizeof(tRW_CB));
40  rw_cb.trace_level = NFC_INITIAL_TRACE_LEVEL;
41}
42
43#if (RW_STATS_INCLUDED == TRUE)
44/*******************************************************************************
45* Internal functions for statistics
46*******************************************************************************/
47/*******************************************************************************
48**
49** Function         rw_main_reset_stats
50**
51** Description      Reset counters for statistics
52**
53** Returns          void
54**
55*******************************************************************************/
56void rw_main_reset_stats(void) {
57  memset(&rw_cb.stats, 0, sizeof(tRW_STATS));
58
59  /* Get current tick count */
60  rw_cb.stats.start_tick = GKI_get_tick_count();
61}
62
63/*******************************************************************************
64**
65** Function         rw_main_update_tx_stats
66**
67** Description      Update stats for tx
68**
69** Returns          void
70**
71*******************************************************************************/
72void rw_main_update_tx_stats(uint32_t num_bytes, bool is_retry) {
73  rw_cb.stats.bytes_sent += num_bytes;
74  rw_cb.stats.num_ops++;
75
76  if (is_retry) rw_cb.stats.num_retries++;
77}
78
79/*******************************************************************************
80**
81** Function         rw_main_update_fail_stats
82**
83** Description      Increment failure count
84**
85** Returns          void
86**
87*******************************************************************************/
88void rw_main_update_fail_stats(void) { rw_cb.stats.num_fail++; }
89
90/*******************************************************************************
91**
92** Function         rw_main_update_crc_error_stats
93**
94** Description      Increment crc error count
95**
96** Returns          void
97**
98*******************************************************************************/
99void rw_main_update_crc_error_stats(void) { rw_cb.stats.num_crc++; }
100
101/*******************************************************************************
102**
103** Function         rw_main_update_trans_error_stats
104**
105** Description      Increment trans error count
106**
107** Returns          void
108**
109*******************************************************************************/
110void rw_main_update_trans_error_stats(void) { rw_cb.stats.num_trans_err++; }
111
112/*******************************************************************************
113**
114** Function         rw_main_update_rx_stats
115**
116** Description      Update stats for rx
117**
118** Returns          void
119**
120*******************************************************************************/
121void rw_main_update_rx_stats(uint32_t num_bytes) {
122  rw_cb.stats.bytes_received += num_bytes;
123}
124
125/*******************************************************************************
126**
127** Function         rw_main_log_stats
128**
129** Description      Dump stats
130**
131** Returns          void
132**
133*******************************************************************************/
134void rw_main_log_stats(void) {
135  uint32_t ticks, elapsed_ms;
136
137  ticks = GKI_get_tick_count() - rw_cb.stats.start_tick;
138  elapsed_ms = GKI_TICKS_TO_MS(ticks);
139
140  RW_TRACE_DEBUG5(
141      "NFC tx stats: cmds:%i, retries:%i, aborted: %i, tx_errs: %i, bytes "
142      "sent:%i",
143      rw_cb.stats.num_ops, rw_cb.stats.num_retries, rw_cb.stats.num_fail,
144      rw_cb.stats.num_trans_err, rw_cb.stats.bytes_sent);
145  RW_TRACE_DEBUG2("    rx stats: rx-crc errors %i, bytes received: %i",
146                  rw_cb.stats.num_crc, rw_cb.stats.bytes_received);
147  RW_TRACE_DEBUG1("    time activated %i ms", elapsed_ms);
148}
149#endif /* RW_STATS_INCLUDED */
150
151/*******************************************************************************
152**
153** Function         RW_SendRawFrame
154**
155** Description      This function sends a raw frame to the peer device.
156**
157** Returns          tNFC_STATUS
158**
159*******************************************************************************/
160tNFC_STATUS RW_SendRawFrame(uint8_t* p_raw_data, uint16_t data_len) {
161  tNFC_STATUS status = NFC_STATUS_FAILED;
162  NFC_HDR* p_data;
163  uint8_t* p;
164
165  if (rw_cb.p_cback) {
166    /* a valid opcode for RW - remove */
167    p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
168    if (p_data) {
169      p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
170      p = (uint8_t*)(p_data + 1) + p_data->offset;
171      memcpy(p, p_raw_data, data_len);
172      p_data->len = data_len;
173
174      RW_TRACE_EVENT1("RW SENT raw frame (0x%x)", data_len);
175      status = NFC_SendData(NFC_RF_CONN_ID, p_data);
176    }
177  }
178  return status;
179}
180
181/*******************************************************************************
182**
183** Function         RW_SetActivatedTagType
184**
185** Description      This function selects the tag type for Reader/Writer mode.
186**
187** Returns          tNFC_STATUS
188**
189*******************************************************************************/
190tNFC_STATUS RW_SetActivatedTagType(tNFC_ACTIVATE_DEVT* p_activate_params,
191                                   tRW_CBACK* p_cback) {
192  tNFC_STATUS status = NFC_STATUS_FAILED;
193
194  /* check for null cback here / remove checks from rw_t?t */
195  RW_TRACE_DEBUG3("RW_SetActivatedTagType protocol:%d, technology:%d, SAK:%d",
196                  p_activate_params->protocol,
197                  p_activate_params->rf_tech_param.mode,
198                  p_activate_params->rf_tech_param.param.pa.sel_rsp);
199
200  if (p_cback == NULL) {
201    RW_TRACE_ERROR0("RW_SetActivatedTagType called with NULL callback");
202    return (NFC_STATUS_FAILED);
203  }
204
205  /* Reset tag-specific area of control block */
206  memset(&rw_cb.tcb, 0, sizeof(tRW_TCB));
207
208#if (RW_STATS_INCLUDED == TRUE)
209  /* Reset RW stats */
210  rw_main_reset_stats();
211#endif /* RW_STATS_INCLUDED */
212
213  rw_cb.p_cback = p_cback;
214  /* not a tag NFC_PROTOCOL_NFCIP1:   NFCDEP/LLCP - NFC-A or NFC-F */
215  if (NFC_PROTOCOL_T1T == p_activate_params->protocol) {
216    /* Type1Tag    - NFC-A */
217    if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) {
218      status = rw_t1t_select(p_activate_params->rf_tech_param.param.pa.hr,
219                             p_activate_params->rf_tech_param.param.pa.nfcid1);
220    }
221  } else if (NFC_PROTOCOL_T2T == p_activate_params->protocol) {
222    /* Type2Tag    - NFC-A */
223    if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) {
224      if (p_activate_params->rf_tech_param.param.pa.sel_rsp ==
225          NFC_SEL_RES_NFC_FORUM_T2T)
226        status = rw_t2t_select();
227    }
228  } else if (NFC_PROTOCOL_T3T == p_activate_params->protocol) {
229    /* Type3Tag    - NFC-F */
230    if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_F) {
231      status =
232          rw_t3t_select(p_activate_params->rf_tech_param.param.pf.nfcid2,
233                        p_activate_params->rf_tech_param.param.pf.mrti_check,
234                        p_activate_params->rf_tech_param.param.pf.mrti_update);
235    }
236  } else if (NFC_PROTOCOL_ISO_DEP == p_activate_params->protocol) {
237    /* ISODEP/4A,4B- NFC-A or NFC-B */
238    if ((p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B) ||
239        (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A)) {
240      status = rw_t4t_select();
241    }
242  } else if (NFC_PROTOCOL_T5T == p_activate_params->protocol) {
243    /* T5T */
244    if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_V) {
245      status = rw_i93_select(p_activate_params->rf_tech_param.param.pi93.uid);
246    }
247  }
248  /* TODO set up callback for proprietary protocol */
249  else {
250    RW_TRACE_ERROR0("RW_SetActivatedTagType Invalid protocol");
251  }
252
253  if (status != NFC_STATUS_OK) rw_cb.p_cback = NULL;
254  return status;
255}
256
257/*******************************************************************************
258**
259** Function         RW_SetTraceLevel
260**
261** Description      This function sets the trace level for Reader/Writer mode.
262**                  If called with a value of 0xFF,
263**                  it simply returns the current trace level.
264**
265** Returns          The new or current trace level
266**
267*******************************************************************************/
268uint8_t RW_SetTraceLevel(uint8_t new_level) {
269  if (new_level != 0xFF) rw_cb.trace_level = new_level;
270
271  return (rw_cb.trace_level);
272}
273