• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <android-base/logging.h>
27 #include <android-base/stringprintf.h>
28 #include <log/log.h>
29 #include <string.h>
30 
31 #include "bt_types.h"
32 #include "nci_hmsgs.h"
33 #include "nfc_api.h"
34 #include "nfc_int.h"
35 #include "nfc_target.h"
36 #include "rw_api.h"
37 #include "rw_int.h"
38 
39 using android::base::StringPrintf;
40 
41 tRW_CB rw_cb;
42 
43 /*******************************************************************************
44 *******************************************************************************/
rw_init(void)45 void rw_init(void) { memset(&rw_cb, 0, sizeof(tRW_CB)); }
46 
47 #if (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 *******************************************************************************/
rw_main_reset_stats(void)60 void rw_main_reset_stats(void) {
61   memset(&rw_cb.stats, 0, sizeof(tRW_STATS));
62 
63   /* Get current tick count */
64   rw_cb.stats.start_tick = GKI_get_tick_count();
65 }
66 
67 /*******************************************************************************
68 **
69 ** Function         rw_main_update_tx_stats
70 **
71 ** Description      Update stats for tx
72 **
73 ** Returns          void
74 **
75 *******************************************************************************/
rw_main_update_tx_stats(uint32_t num_bytes,bool is_retry)76 void rw_main_update_tx_stats(uint32_t num_bytes, bool is_retry) {
77   rw_cb.stats.bytes_sent += num_bytes;
78   rw_cb.stats.num_ops++;
79 
80   if (is_retry) rw_cb.stats.num_retries++;
81 }
82 
83 /*******************************************************************************
84 **
85 ** Function         rw_main_update_fail_stats
86 **
87 ** Description      Increment failure count
88 **
89 ** Returns          void
90 **
91 *******************************************************************************/
rw_main_update_fail_stats(void)92 void rw_main_update_fail_stats(void) { rw_cb.stats.num_fail++; }
93 
94 /*******************************************************************************
95 **
96 ** Function         rw_main_update_crc_error_stats
97 **
98 ** Description      Increment crc error count
99 **
100 ** Returns          void
101 **
102 *******************************************************************************/
rw_main_update_crc_error_stats(void)103 void rw_main_update_crc_error_stats(void) { rw_cb.stats.num_crc++; }
104 
105 /*******************************************************************************
106 **
107 ** Function         rw_main_update_trans_error_stats
108 **
109 ** Description      Increment trans error count
110 **
111 ** Returns          void
112 **
113 *******************************************************************************/
rw_main_update_trans_error_stats(void)114 void rw_main_update_trans_error_stats(void) { rw_cb.stats.num_trans_err++; }
115 
116 /*******************************************************************************
117 **
118 ** Function         rw_main_update_rx_stats
119 **
120 ** Description      Update stats for rx
121 **
122 ** Returns          void
123 **
124 *******************************************************************************/
rw_main_update_rx_stats(uint32_t num_bytes)125 void rw_main_update_rx_stats(uint32_t num_bytes) {
126   rw_cb.stats.bytes_received += num_bytes;
127 }
128 
129 /*******************************************************************************
130 **
131 ** Function         rw_main_log_stats
132 **
133 ** Description      Dump stats
134 **
135 ** Returns          void
136 **
137 *******************************************************************************/
rw_main_log_stats(void)138 void rw_main_log_stats(void) {
139   uint32_t ticks, elapsed_ms;
140 
141   ticks = GKI_get_tick_count() - rw_cb.stats.start_tick;
142   elapsed_ms = GKI_TICKS_TO_MS(ticks);
143 
144   LOG(VERBOSE) << StringPrintf(
145       "NFC tx stats: cmds:%i, retries:%i, aborted: %i, tx_errs: %i, bytes "
146       "sent:%i",
147       rw_cb.stats.num_ops, rw_cb.stats.num_retries, rw_cb.stats.num_fail,
148       rw_cb.stats.num_trans_err, rw_cb.stats.bytes_sent);
149   LOG(VERBOSE) << StringPrintf(
150       "    rx stats: rx-crc errors %i, bytes received: %i", rw_cb.stats.num_crc,
151       rw_cb.stats.bytes_received);
152   LOG(VERBOSE) << StringPrintf("    time activated %i ms", elapsed_ms);
153 }
154 #endif /* RW_STATS_INCLUDED */
155 
156 /*******************************************************************************
157 **
158 ** Function         RW_SendRawFrame
159 **
160 ** Description      This function sends a raw frame to the peer device.
161 **
162 ** Returns          tNFC_STATUS
163 **
164 *******************************************************************************/
RW_SendRawFrame(uint8_t * p_raw_data,uint16_t data_len)165 tNFC_STATUS RW_SendRawFrame(uint8_t* p_raw_data, uint16_t data_len) {
166   tNFC_STATUS status = NFC_STATUS_FAILED;
167   NFC_HDR* p_data;
168   uint8_t* p;
169 
170   if (rw_cb.p_cback) {
171     if (data_len > GKI_get_pool_bufsize(NFC_RW_POOL_ID) - NCI_MSG_OFFSET_SIZE -
172                        NCI_DATA_HDR_SIZE - 1) {
173       android_errorWriteLog(0x534e4554, "157650117");
174       return NFC_STATUS_FAILED;
175     }
176     /* a valid opcode for RW - remove */
177     p_data = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
178     if (p_data) {
179       p_data->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
180       p = (uint8_t*)(p_data + 1) + p_data->offset;
181       memcpy(p, p_raw_data, data_len);
182       p_data->len = data_len;
183 
184       LOG(VERBOSE) << StringPrintf("RW SENT raw frame (0x%x)", data_len);
185       status = NFC_SendData(NFC_RF_CONN_ID, p_data);
186     }
187   }
188   return status;
189 }
190 
191 /*******************************************************************************
192 **
193 ** Function         RW_SetActivatedTagType
194 **
195 ** Description      This function selects the tag type for Reader/Writer mode.
196 **
197 ** Returns          tNFC_STATUS
198 **
199 *******************************************************************************/
RW_SetActivatedTagType(tNFC_ACTIVATE_DEVT * p_activate_params,tRW_CBACK * p_cback)200 tNFC_STATUS RW_SetActivatedTagType(tNFC_ACTIVATE_DEVT* p_activate_params,
201                                    tRW_CBACK* p_cback) {
202   tNFC_STATUS status = NFC_STATUS_FAILED;
203 
204   /* check for null cback here / remove checks from rw_t?t */
205   LOG(VERBOSE) << StringPrintf(
206       "RW_SetActivatedTagType protocol:%d, technology:%d, SAK:%d",
207       p_activate_params->protocol, p_activate_params->rf_tech_param.mode,
208       p_activate_params->rf_tech_param.param.pa.sel_rsp);
209 
210   if (p_cback == nullptr) {
211     LOG(ERROR) << StringPrintf(
212         "RW_SetActivatedTagType called with NULL callback");
213     return (NFC_STATUS_FAILED);
214   }
215 
216   switch (rw_cb.tcb_type) {
217     case RW_CB_TYPE_T1T: {
218       nfc_stop_quick_timer(&rw_cb.tcb.t1t.timer);
219       break;
220     }
221     case RW_CB_TYPE_T2T: {
222       nfc_stop_quick_timer(&rw_cb.tcb.t2t.t2_timer);
223       break;
224     }
225     case RW_CB_TYPE_T3T: {
226       nfc_stop_quick_timer(&rw_cb.tcb.t3t.timer);
227       nfc_stop_quick_timer(&rw_cb.tcb.t3t.poll_timer);
228       break;
229     }
230     case RW_CB_TYPE_T4T: {
231       nfc_stop_quick_timer(&rw_cb.tcb.t4t.timer);
232       break;
233     }
234     case RW_CB_TYPE_T5T: {
235       nfc_stop_quick_timer(&rw_cb.tcb.i93.timer);
236       break;
237     }
238     case RW_CB_TYPE_MIFARE: {
239       nfc_stop_quick_timer(&rw_cb.tcb.mfc.timer);
240       nfc_stop_quick_timer(&rw_cb.tcb.mfc.mfc_timer);
241       break;
242     }
243     case RW_CB_TYPE_UNKNOWN: {
244       break;
245     }
246   }
247 
248   /* Reset tag-specific area of control block */
249   memset(&rw_cb.tcb, 0, sizeof(tRW_TCB));
250 
251 #if (RW_STATS_INCLUDED == TRUE)
252   /* Reset RW stats */
253   rw_main_reset_stats();
254 #endif /* RW_STATS_INCLUDED */
255 
256   rw_cb.p_cback = p_cback;
257   /* not a tag NFC_PROTOCOL_NFCIP1:   NFCDEP/LLCP - NFC-A or NFC-F */
258   if (NFC_PROTOCOL_T1T == p_activate_params->protocol) {
259     /* Type1Tag    - NFC-A */
260     if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) {
261       rw_cb.tcb_type = RW_CB_TYPE_T1T;
262       status = rw_t1t_select(p_activate_params->rf_tech_param.param.pa.hr,
263                              p_activate_params->rf_tech_param.param.pa.nfcid1);
264     }
265   } else if (NFC_PROTOCOL_T2T == p_activate_params->protocol) {
266     /* Type2Tag    - NFC-A */
267     if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) {
268       rw_cb.tcb_type = RW_CB_TYPE_T2T;
269       if (p_activate_params->rf_tech_param.param.pa.sel_rsp ==
270           NFC_SEL_RES_NFC_FORUM_T2T)
271         status = rw_t2t_select();
272     }
273   } else if (NFC_PROTOCOL_T3T == p_activate_params->protocol) {
274     /* Type3Tag    - NFC-F */
275     if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_F) {
276       rw_cb.tcb_type = RW_CB_TYPE_T3T;
277       status =
278           rw_t3t_select(p_activate_params->rf_tech_param.param.pf.nfcid2,
279                         p_activate_params->rf_tech_param.param.pf.mrti_check,
280                         p_activate_params->rf_tech_param.param.pf.mrti_update);
281     }
282   } else if (NFC_PROTOCOL_ISO_DEP == p_activate_params->protocol) {
283     /* ISODEP/4A,4B- NFC-A or NFC-B */
284     if ((p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B) ||
285         (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A)) {
286       rw_cb.tcb_type = RW_CB_TYPE_T4T;
287       status = rw_t4t_select();
288     }
289   } else if (NFC_PROTOCOL_T5T == p_activate_params->protocol) {
290     /* T5T */
291     if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_V) {
292       rw_cb.tcb_type = RW_CB_TYPE_T5T;
293       status = rw_i93_select(p_activate_params->rf_tech_param.param.pi93.uid);
294     }
295   } else if (NFC_PROTOCOL_MIFARE == p_activate_params->protocol) {
296     /* Mifare Classic*/
297     if (p_activate_params->rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) {
298       rw_cb.tcb_type = RW_CB_TYPE_MIFARE;
299       status = rw_mfc_select(
300           p_activate_params->rf_tech_param.param.pa.sel_rsp,
301           p_activate_params->rf_tech_param.param.pa.nfcid1 +
302               p_activate_params->rf_tech_param.param.pa.nfcid1_len - 4);
303     }
304   }
305   /* TODO set up callback for proprietary protocol */
306   else {
307     rw_cb.tcb_type = RW_CB_TYPE_UNKNOWN;
308     LOG(ERROR) << StringPrintf("RW_SetActivatedTagType Invalid protocol");
309   }
310 
311   if (status != NFC_STATUS_OK) rw_cb.p_cback = nullptr;
312   return status;
313 }
314