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