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