1 // Copyright 2023, The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //! Implementation of the NFCC. 16 17 use crate::crc; 18 use crate::packets::{nci, rf}; 19 use anyhow::Result; 20 use core::time::Duration; 21 use futures::StreamExt; 22 use log::{debug, info, trace, warn}; 23 use pdl_runtime::Packet; 24 use std::convert::TryFrom; 25 use std::future::Future; 26 use std::pin::pin; 27 use std::time::Instant; 28 use tokio::sync::mpsc; 29 use tokio::time; 30 31 const NCI_VERSION: nci::NciVersion = nci::NciVersion::Version20; 32 const MANUFACTURER_ID: u8 = 0x02; 33 const MANUFACTURER_SPECIFIC_INFORMATION: [u8; 26] = 34 [5, 3, 3, 19, 4, 25, 1, 7, 0, 0, 68, 100, 214, 0, 0, 90, 172, 0, 0, 0, 1, 44, 176, 153, 243, 0]; 35 36 /// Read-only configuration parameters 37 const PB_ATTRIB_PARAM1: u8 = 0x00; 38 const LF_T3T_MAX: u8 = 16; 39 const LLCP_VERSION: u8 = 0x00; 40 41 /// Writable configuration parameters with default 42 /// value defined by the NFCC. 43 const TOTAL_DURATION: u16 = 1000; 44 const PA_DEVICES_LIMIT: u8 = 255; 45 const PB_DEVICES_LIMIT: u8 = 255; 46 const PF_DEVICES_LIMIT: u8 = 255; 47 const PV_DEVICES_LIMIT: u8 = 255; 48 const LA_BIT_FRAME_SDD: u8 = 0x10; 49 const LA_PLATFORM_CONFIG: u8 = 0x0c; 50 const LA_SEL_INFO: u8 = 0x60; // Supports ISO-DEP and NFC-DEP. 51 const LB_SENSB_INFO: u8 = 0x1; // Supports ISO-DEP. 52 const LB_SFGI: u8 = 0; 53 const LB_FWI_ADC_FO: u8 = 0x00; 54 const LF_PROTOCOL_TYPE: u8 = 0x02; // Supports NFC-DEP. 55 const LI_A_RATS_TB1: u8 = 0x70; 56 const LI_A_RATS_TC1: u8 = 0x02; 57 58 const MAX_LOGICAL_CONNECTIONS: u8 = 2; 59 const MAX_ROUTING_TABLE_SIZE: u16 = 512; 60 const MAX_CONTROL_PACKET_PAYLOAD_SIZE: u8 = 255; 61 const MAX_DATA_PACKET_PAYLOAD_SIZE: u8 = 255; 62 const NUMBER_OF_CREDITS: u8 = 1; 63 const MAX_NFCV_RF_FRAME_SIZE: u16 = 512; 64 const NUMBER_OF_SUPPORTED_EXIT_FRAMES: u8 = 5; 65 const EXIT_FRAME_QUALIFIER_TECHNOLOGY_MASK: u8 = 0b00000011; 66 const EXIT_FRAME_QUALIFIER_PREFIX_MATCHING_MASK: u8 = 0b00010000; 67 68 /// Time in milliseconds that Casimir waits for poll responses after 69 /// sending a poll command. 70 const POLL_RESPONSE_TIMEOUT: u64 = 200; 71 72 /// All configuration parameters of the NFCC. 73 /// The configuration is filled with default values from the specification 74 /// See [NCI] Table 46: Common Parameters for Discovery Configuration 75 /// for the format of each parameter and the default value. 76 #[derive(Clone, Debug, PartialEq, Eq)] 77 #[allow(missing_docs)] 78 pub struct ConfigParameters { 79 total_duration: u16, 80 /// [NCI] Table 47: Values for CON_DISCOVERY_PARAM. 81 con_discovery_param: u8, 82 power_state: u8, 83 pa_bail_out: u8, 84 pa_devices_limit: u8, 85 pb_afi: u8, 86 pb_bail_out: u8, 87 pb_attrib_param1: u8, 88 /// [NCI] Table 26: Values for PB_SENSB_REQ_PARAM. 89 pb_sensb_req_param: u8, 90 pb_devices_limit: u8, 91 pf_bit_rate: u8, 92 pf_bail_out: u8, 93 pf_devices_limit: u8, 94 pi_b_h_info: Vec<u8>, 95 pi_bit_rate: u8, 96 pn_nfc_dep_psl: u8, 97 pn_atr_req_gen_bytes: Vec<u8>, 98 /// [NCI] Table 30: Values for PN_ATR_REQ_CONFIG. 99 pn_atr_req_config: u8, 100 pv_devices_limit: u8, 101 la_bit_frame_sdd: u8, 102 la_platform_config: u8, 103 /// [NCI] Table 34: LA_SEL_INFO Coding. 104 la_sel_info: u8, 105 la_nfcid1: Vec<u8>, 106 /// [NCI] Table 36: LB_SENSB_INFO Values. 107 lb_sensb_info: u8, 108 lb_nfcid0: [u8; 4], 109 lb_application_data: u32, 110 lb_sfgi: u8, 111 /// [NCI] Table 37: LB_FWI_ADC_FO Values. 112 lb_fwi_adc_fo: u8, 113 lb_bit_rate: u8, 114 lf_t3t_identifiers_1: [u8; 18], 115 lf_t3t_identifiers_2: [u8; 18], 116 lf_t3t_identifiers_3: [u8; 18], 117 lf_t3t_identifiers_4: [u8; 18], 118 lf_t3t_identifiers_5: [u8; 18], 119 lf_t3t_identifiers_6: [u8; 18], 120 lf_t3t_identifiers_7: [u8; 18], 121 lf_t3t_identifiers_8: [u8; 18], 122 lf_t3t_identifiers_9: [u8; 18], 123 lf_t3t_identifiers_10: [u8; 18], 124 lf_t3t_identifiers_11: [u8; 18], 125 lf_t3t_identifiers_12: [u8; 18], 126 lf_t3t_identifiers_13: [u8; 18], 127 lf_t3t_identifiers_14: [u8; 18], 128 lf_t3t_identifiers_15: [u8; 18], 129 lf_t3t_identifiers_16: [u8; 18], 130 lf_t3t_pmm_default: [u8; 8], 131 lf_t3t_max: u8, 132 lf_t3t_flags: u16, 133 lf_t3t_rd_allowed: u8, 134 /// [NCI] Table 39: Supported Protocols for Listen F. 135 lf_protocol_type: u8, 136 li_a_rats_tb1: u8, 137 li_a_hist_by: Vec<u8>, 138 li_b_h_info_resp: Vec<u8>, 139 li_a_bit_rate: u8, 140 li_a_rats_tc1: u8, 141 ln_wt: u8, 142 ln_atr_res_gen_bytes: Vec<u8>, 143 ln_atr_res_config: u8, 144 pacm_bit_rate: u8, 145 /// [NCI] Table 23: RF Field Information Configuration Parameter. 146 rf_field_info: u8, 147 rf_nfcee_action: u8, 148 nfcdep_op: u8, 149 /// [NCI] Table 115: LLCP Version Parameter. 150 llcp_version: u8, 151 /// [NCI] Table 65: Value Field for NFCC Configuration Control. 152 nfcc_config_control: u8, 153 } 154 155 /// State of an NFCC logical connection with the DH. 156 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 157 #[allow(missing_docs)] 158 pub enum LogicalConnection { 159 RemoteNfcEndpoint { rf_discovery_id: u8, rf_protocol_type: nci::RfProtocolType }, 160 } 161 162 /// State of the RF Discovery of an NFCC instance. 163 /// The state WaitForAllDiscoveries is not represented as it is implied 164 /// by the discovery routine. 165 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 166 #[allow(missing_docs)] 167 pub enum RfState { 168 Idle, 169 Discovery, 170 PollActive { 171 id: u16, 172 rf_interface: nci::RfInterfaceType, 173 rf_technology: rf::Technology, 174 rf_protocol: rf::Protocol, 175 }, 176 ListenSleep { 177 id: u16, 178 }, 179 ListenActive { 180 id: u16, 181 rf_interface: nci::RfInterfaceType, 182 rf_technology: rf::Technology, 183 rf_protocol: rf::Protocol, 184 }, 185 WaitForHostSelect, 186 WaitForSelectResponse { 187 id: u16, 188 rf_discovery_id: usize, 189 rf_interface: nci::RfInterfaceType, 190 rf_technology: rf::Technology, 191 rf_protocol: rf::Protocol, 192 }, 193 } 194 195 /// State of the emulated eSE (ST) NFCEE. 196 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 197 #[allow(missing_docs)] 198 pub enum NfceeState { 199 Enabled, 200 Disabled, 201 } 202 203 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 204 #[allow(missing_docs)] 205 pub enum RfMode { 206 Poll, 207 Listen, 208 } 209 210 /// Poll responses received in the context of RF discovery in active 211 /// Listen mode. 212 #[derive(Clone, Debug, PartialEq, Eq)] 213 pub struct RfPollResponse { 214 id: u16, 215 rf_protocol: rf::Protocol, 216 rf_technology: rf::Technology, 217 rf_technology_specific_parameters: Vec<u8>, 218 } 219 220 /// Exit frame data received by the Set exit frame command. 221 #[derive(Clone, Debug, PartialEq, Eq)] 222 pub struct RfExitFrame { 223 is_prefix_matching_allowed: bool, 224 rf_technology: rf::Technology, 225 power_states: u8, 226 data: Vec<u8>, 227 mask: Vec<u8>, 228 } 229 230 /// State of an NFCC instance. 231 #[allow(missing_docs)] 232 pub struct State { 233 pub config_parameters: ConfigParameters, 234 pub logical_connections: [Option<LogicalConnection>; MAX_LOGICAL_CONNECTIONS as usize], 235 pub discover_configuration: Vec<nci::DiscoverConfiguration>, 236 pub discover_map: Vec<nci::MappingConfiguration>, 237 pub nfcee_state: NfceeState, 238 pub rf_state: RfState, 239 pub rf_poll_responses: Vec<RfPollResponse>, 240 pub rf_activation_parameters: Vec<u8>, 241 // TODO(johnrjohn) Use bitflags here 242 pub passive_observe_mode: u8, 243 pub last_observe_mode_state: Option<u8>, 244 pub start_time: std::time::Instant, 245 pub remote_field_status: rf::FieldStatus, 246 pub exit_frame_timeout: Duration, 247 pub exit_frame_start_time: Option<std::time::Instant>, 248 pub exit_frames: Vec<RfExitFrame>, 249 } 250 251 /// State of an NFCC instance. 252 pub struct Controller<'a> { 253 id: u16, 254 nci_stream: nci::StreamRefMut<'a>, 255 nci_writer: nci::Writer, 256 rf_rx: mpsc::UnboundedReceiver<rf::RfPacket>, 257 rf_tx: mpsc::UnboundedSender<rf::RfPacket>, 258 state: State, 259 } 260 261 impl ConfigParameters { get(&self, id: nci::ConfigParameterId) -> Result<Vec<u8>>262 fn get(&self, id: nci::ConfigParameterId) -> Result<Vec<u8>> { 263 match id { 264 nci::ConfigParameterId::TotalDuration => Ok(self.total_duration.to_le_bytes().to_vec()), 265 nci::ConfigParameterId::ConDiscoveryParam => { 266 Ok(self.con_discovery_param.to_le_bytes().to_vec()) 267 } 268 nci::ConfigParameterId::PowerState => Ok(vec![self.power_state]), 269 nci::ConfigParameterId::PaBailOut => Ok(vec![self.pa_bail_out]), 270 nci::ConfigParameterId::PaDevicesLimit => Ok(vec![self.pa_devices_limit]), 271 nci::ConfigParameterId::PbAfi => Ok(vec![self.pb_afi]), 272 nci::ConfigParameterId::PbBailOut => Ok(vec![self.pb_bail_out]), 273 nci::ConfigParameterId::PbAttribParam1 => Ok(vec![self.pb_attrib_param1]), 274 nci::ConfigParameterId::PbSensbReqParam => Ok(vec![self.pb_sensb_req_param]), 275 nci::ConfigParameterId::PbDevicesLimit => Ok(vec![self.pb_devices_limit]), 276 nci::ConfigParameterId::PfBitRate => Ok(vec![self.pf_bit_rate]), 277 nci::ConfigParameterId::PfBailOut => Ok(vec![self.pf_bail_out]), 278 nci::ConfigParameterId::PfDevicesLimit => Ok(vec![self.pf_devices_limit]), 279 nci::ConfigParameterId::PiBHInfo => Ok(self.pi_b_h_info.clone()), 280 nci::ConfigParameterId::PiBitRate => Ok(vec![self.pi_bit_rate]), 281 nci::ConfigParameterId::PnNfcDepPsl => Ok(vec![self.pn_nfc_dep_psl]), 282 nci::ConfigParameterId::PnAtrReqGenBytes => Ok(self.pn_atr_req_gen_bytes.clone()), 283 nci::ConfigParameterId::PnAtrReqConfig => Ok(vec![self.pn_atr_req_config]), 284 nci::ConfigParameterId::PvDevicesLimit => Ok(vec![self.pv_devices_limit]), 285 nci::ConfigParameterId::LaBitFrameSdd => Ok(vec![self.la_bit_frame_sdd]), 286 nci::ConfigParameterId::LaPlatformConfig => Ok(vec![self.la_platform_config]), 287 nci::ConfigParameterId::LaSelInfo => Ok(vec![self.la_sel_info]), 288 nci::ConfigParameterId::LaNfcid1 => Ok(self.la_nfcid1.clone()), 289 nci::ConfigParameterId::LbSensbInfo => Ok(vec![self.lb_sensb_info]), 290 nci::ConfigParameterId::LbNfcid0 => Ok(self.lb_nfcid0.to_vec()), 291 nci::ConfigParameterId::LbApplicationData => { 292 Ok(self.lb_application_data.to_le_bytes().to_vec()) 293 } 294 nci::ConfigParameterId::LbSfgi => Ok(vec![self.lb_sfgi]), 295 nci::ConfigParameterId::LbFwiAdcFo => Ok(vec![self.lb_fwi_adc_fo]), 296 nci::ConfigParameterId::LbBitRate => Ok(vec![self.lb_bit_rate]), 297 nci::ConfigParameterId::LfT3tIdentifiers1 => Ok(self.lf_t3t_identifiers_1.to_vec()), 298 nci::ConfigParameterId::LfT3tIdentifiers2 => Ok(self.lf_t3t_identifiers_2.to_vec()), 299 nci::ConfigParameterId::LfT3tIdentifiers3 => Ok(self.lf_t3t_identifiers_3.to_vec()), 300 nci::ConfigParameterId::LfT3tIdentifiers4 => Ok(self.lf_t3t_identifiers_4.to_vec()), 301 nci::ConfigParameterId::LfT3tIdentifiers5 => Ok(self.lf_t3t_identifiers_5.to_vec()), 302 nci::ConfigParameterId::LfT3tIdentifiers6 => Ok(self.lf_t3t_identifiers_6.to_vec()), 303 nci::ConfigParameterId::LfT3tIdentifiers7 => Ok(self.lf_t3t_identifiers_7.to_vec()), 304 nci::ConfigParameterId::LfT3tIdentifiers8 => Ok(self.lf_t3t_identifiers_8.to_vec()), 305 nci::ConfigParameterId::LfT3tIdentifiers9 => Ok(self.lf_t3t_identifiers_9.to_vec()), 306 nci::ConfigParameterId::LfT3tIdentifiers10 => Ok(self.lf_t3t_identifiers_10.to_vec()), 307 nci::ConfigParameterId::LfT3tIdentifiers11 => Ok(self.lf_t3t_identifiers_11.to_vec()), 308 nci::ConfigParameterId::LfT3tIdentifiers12 => Ok(self.lf_t3t_identifiers_12.to_vec()), 309 nci::ConfigParameterId::LfT3tIdentifiers13 => Ok(self.lf_t3t_identifiers_13.to_vec()), 310 nci::ConfigParameterId::LfT3tIdentifiers14 => Ok(self.lf_t3t_identifiers_14.to_vec()), 311 nci::ConfigParameterId::LfT3tIdentifiers15 => Ok(self.lf_t3t_identifiers_15.to_vec()), 312 nci::ConfigParameterId::LfT3tIdentifiers16 => Ok(self.lf_t3t_identifiers_16.to_vec()), 313 nci::ConfigParameterId::LfT3tPmmDefault => Ok(self.lf_t3t_pmm_default.to_vec()), 314 nci::ConfigParameterId::LfT3tMax => Ok(vec![self.lf_t3t_max]), 315 nci::ConfigParameterId::LfT3tFlags => Ok(self.lf_t3t_flags.to_le_bytes().to_vec()), 316 nci::ConfigParameterId::LfT3tRdAllowed => Ok(vec![self.lf_t3t_rd_allowed]), 317 nci::ConfigParameterId::LfProtocolType => Ok(vec![self.lf_protocol_type]), 318 nci::ConfigParameterId::LiARatsTb1 => Ok(vec![self.li_a_rats_tb1]), 319 nci::ConfigParameterId::LiAHistBy => Ok(self.li_a_hist_by.clone()), 320 nci::ConfigParameterId::LiBHInfoResp => Ok(self.li_b_h_info_resp.clone()), 321 nci::ConfigParameterId::LiABitRate => Ok(vec![self.li_a_bit_rate]), 322 nci::ConfigParameterId::LiARatsTc1 => Ok(vec![self.li_a_rats_tc1]), 323 nci::ConfigParameterId::LnWt => Ok(vec![self.ln_wt]), 324 nci::ConfigParameterId::LnAtrResGenBytes => Ok(self.ln_atr_res_gen_bytes.clone()), 325 nci::ConfigParameterId::LnAtrResConfig => Ok(vec![self.ln_atr_res_config]), 326 nci::ConfigParameterId::PacmBitRate => Ok(vec![self.pacm_bit_rate]), 327 nci::ConfigParameterId::RfFieldInfo => Ok(vec![self.rf_field_info]), 328 nci::ConfigParameterId::RfNfceeAction => Ok(vec![self.rf_nfcee_action]), 329 nci::ConfigParameterId::NfcdepOp => Ok(vec![self.nfcdep_op]), 330 nci::ConfigParameterId::LlcpVersion => Ok(vec![self.llcp_version]), 331 nci::ConfigParameterId::NfccConfigControl => Ok(vec![self.nfcc_config_control]), 332 _ => Err(anyhow::anyhow!("unknown config parameter ID")), 333 } 334 } 335 set(&mut self, id: nci::ConfigParameterId, value: &[u8]) -> Result<()>336 fn set(&mut self, id: nci::ConfigParameterId, value: &[u8]) -> Result<()> { 337 match id { 338 nci::ConfigParameterId::TotalDuration => { 339 self.total_duration = u16::from_le_bytes(value.try_into()?); 340 Ok(()) 341 } 342 nci::ConfigParameterId::ConDiscoveryParam => { 343 self.con_discovery_param = u8::from_le_bytes(value.try_into()?); 344 Ok(()) 345 } 346 nci::ConfigParameterId::PowerState => { 347 self.power_state = u8::from_le_bytes(value.try_into()?); 348 Ok(()) 349 } 350 nci::ConfigParameterId::PaBailOut => { 351 self.pa_bail_out = u8::from_le_bytes(value.try_into()?); 352 Ok(()) 353 } 354 nci::ConfigParameterId::PaDevicesLimit => { 355 self.pa_devices_limit = u8::from_le_bytes(value.try_into()?); 356 Ok(()) 357 } 358 nci::ConfigParameterId::PbAfi => { 359 self.pb_afi = u8::from_le_bytes(value.try_into()?); 360 Ok(()) 361 } 362 nci::ConfigParameterId::PbBailOut => { 363 self.pb_bail_out = u8::from_le_bytes(value.try_into()?); 364 Ok(()) 365 } 366 nci::ConfigParameterId::PbAttribParam1 => { 367 self.pb_attrib_param1 = u8::from_le_bytes(value.try_into()?); 368 Ok(()) 369 } 370 nci::ConfigParameterId::PbSensbReqParam => { 371 self.pb_sensb_req_param = u8::from_le_bytes(value.try_into()?); 372 Ok(()) 373 } 374 nci::ConfigParameterId::PbDevicesLimit => { 375 self.pb_devices_limit = u8::from_le_bytes(value.try_into()?); 376 Ok(()) 377 } 378 nci::ConfigParameterId::PfBitRate => { 379 self.pf_bit_rate = u8::from_le_bytes(value.try_into()?); 380 Ok(()) 381 } 382 nci::ConfigParameterId::PfBailOut => { 383 self.pf_bail_out = u8::from_le_bytes(value.try_into()?); 384 Ok(()) 385 } 386 nci::ConfigParameterId::PfDevicesLimit => { 387 self.pf_devices_limit = u8::from_le_bytes(value.try_into()?); 388 Ok(()) 389 } 390 nci::ConfigParameterId::PiBHInfo => { 391 self.pi_b_h_info = value.to_vec(); 392 Ok(()) 393 } 394 nci::ConfigParameterId::PiBitRate => { 395 self.pi_bit_rate = u8::from_le_bytes(value.try_into()?); 396 Ok(()) 397 } 398 nci::ConfigParameterId::PnNfcDepPsl => { 399 self.pn_nfc_dep_psl = u8::from_le_bytes(value.try_into()?); 400 Ok(()) 401 } 402 nci::ConfigParameterId::PnAtrReqGenBytes => { 403 self.pn_atr_req_gen_bytes = value.to_vec(); 404 Ok(()) 405 } 406 nci::ConfigParameterId::PnAtrReqConfig => { 407 self.pn_atr_req_config = u8::from_le_bytes(value.try_into()?); 408 Ok(()) 409 } 410 nci::ConfigParameterId::PvDevicesLimit => { 411 self.pv_devices_limit = u8::from_le_bytes(value.try_into()?); 412 Ok(()) 413 } 414 nci::ConfigParameterId::LaBitFrameSdd => { 415 self.la_bit_frame_sdd = u8::from_le_bytes(value.try_into()?); 416 Ok(()) 417 } 418 nci::ConfigParameterId::LaPlatformConfig => { 419 self.la_platform_config = u8::from_le_bytes(value.try_into()?); 420 Ok(()) 421 } 422 nci::ConfigParameterId::LaSelInfo => { 423 self.la_sel_info = u8::from_le_bytes(value.try_into()?); 424 Ok(()) 425 } 426 nci::ConfigParameterId::LaNfcid1 => { 427 self.la_nfcid1 = value.to_vec(); 428 Ok(()) 429 } 430 nci::ConfigParameterId::LbSensbInfo => { 431 self.lb_sensb_info = u8::from_le_bytes(value.try_into()?); 432 Ok(()) 433 } 434 nci::ConfigParameterId::LbNfcid0 => { 435 self.lb_nfcid0 = value.try_into()?; 436 Ok(()) 437 } 438 nci::ConfigParameterId::LbApplicationData => { 439 self.lb_application_data = u32::from_le_bytes(value.try_into()?); 440 Ok(()) 441 } 442 nci::ConfigParameterId::LbSfgi => { 443 self.lb_sfgi = u8::from_le_bytes(value.try_into()?); 444 Ok(()) 445 } 446 nci::ConfigParameterId::LbFwiAdcFo => { 447 self.lb_fwi_adc_fo = u8::from_le_bytes(value.try_into()?); 448 Ok(()) 449 } 450 nci::ConfigParameterId::LbBitRate => { 451 self.lb_bit_rate = u8::from_le_bytes(value.try_into()?); 452 Ok(()) 453 } 454 nci::ConfigParameterId::LfT3tIdentifiers1 => { 455 self.lf_t3t_identifiers_1 = value.try_into()?; 456 Ok(()) 457 } 458 nci::ConfigParameterId::LfT3tIdentifiers2 => { 459 self.lf_t3t_identifiers_2 = value.try_into()?; 460 Ok(()) 461 } 462 nci::ConfigParameterId::LfT3tIdentifiers3 => { 463 self.lf_t3t_identifiers_3 = value.try_into()?; 464 Ok(()) 465 } 466 nci::ConfigParameterId::LfT3tIdentifiers4 => { 467 self.lf_t3t_identifiers_4 = value.try_into()?; 468 Ok(()) 469 } 470 nci::ConfigParameterId::LfT3tIdentifiers5 => { 471 self.lf_t3t_identifiers_5 = value.try_into()?; 472 Ok(()) 473 } 474 nci::ConfigParameterId::LfT3tIdentifiers6 => { 475 self.lf_t3t_identifiers_6 = value.try_into()?; 476 Ok(()) 477 } 478 nci::ConfigParameterId::LfT3tIdentifiers7 => { 479 self.lf_t3t_identifiers_7 = value.try_into()?; 480 Ok(()) 481 } 482 nci::ConfigParameterId::LfT3tIdentifiers8 => { 483 self.lf_t3t_identifiers_8 = value.try_into()?; 484 Ok(()) 485 } 486 nci::ConfigParameterId::LfT3tIdentifiers9 => { 487 self.lf_t3t_identifiers_9 = value.try_into()?; 488 Ok(()) 489 } 490 nci::ConfigParameterId::LfT3tIdentifiers10 => { 491 self.lf_t3t_identifiers_10 = value.try_into()?; 492 Ok(()) 493 } 494 nci::ConfigParameterId::LfT3tIdentifiers11 => { 495 self.lf_t3t_identifiers_11 = value.try_into()?; 496 Ok(()) 497 } 498 nci::ConfigParameterId::LfT3tIdentifiers12 => { 499 self.lf_t3t_identifiers_12 = value.try_into()?; 500 Ok(()) 501 } 502 nci::ConfigParameterId::LfT3tIdentifiers13 => { 503 self.lf_t3t_identifiers_13 = value.try_into()?; 504 Ok(()) 505 } 506 nci::ConfigParameterId::LfT3tIdentifiers14 => { 507 self.lf_t3t_identifiers_14 = value.try_into()?; 508 Ok(()) 509 } 510 nci::ConfigParameterId::LfT3tIdentifiers15 => { 511 self.lf_t3t_identifiers_15 = value.try_into()?; 512 Ok(()) 513 } 514 nci::ConfigParameterId::LfT3tIdentifiers16 => { 515 self.lf_t3t_identifiers_16 = value.try_into()?; 516 Ok(()) 517 } 518 nci::ConfigParameterId::LfT3tPmmDefault => { 519 self.lf_t3t_pmm_default = value.try_into()?; 520 Ok(()) 521 } 522 nci::ConfigParameterId::LfT3tMax => Err(anyhow::anyhow!("read-only config parameter")), 523 nci::ConfigParameterId::LfT3tFlags => { 524 self.lf_t3t_flags = u16::from_le_bytes(value.try_into()?); 525 Ok(()) 526 } 527 nci::ConfigParameterId::LfT3tRdAllowed => { 528 self.lf_t3t_rd_allowed = u8::from_le_bytes(value.try_into()?); 529 Ok(()) 530 } 531 nci::ConfigParameterId::LfProtocolType => { 532 self.lf_protocol_type = u8::from_le_bytes(value.try_into()?); 533 Ok(()) 534 } 535 nci::ConfigParameterId::LiARatsTb1 => { 536 self.li_a_rats_tb1 = u8::from_le_bytes(value.try_into()?); 537 Ok(()) 538 } 539 nci::ConfigParameterId::LiAHistBy => { 540 self.li_a_hist_by = value.to_vec(); 541 Ok(()) 542 } 543 nci::ConfigParameterId::LiBHInfoResp => { 544 self.li_b_h_info_resp = value.to_vec(); 545 Ok(()) 546 } 547 nci::ConfigParameterId::LiABitRate => { 548 self.li_a_bit_rate = u8::from_le_bytes(value.try_into()?); 549 Ok(()) 550 } 551 nci::ConfigParameterId::LiARatsTc1 => { 552 self.li_a_rats_tc1 = u8::from_le_bytes(value.try_into()?); 553 Ok(()) 554 } 555 nci::ConfigParameterId::LnWt => { 556 self.ln_wt = u8::from_le_bytes(value.try_into()?); 557 Ok(()) 558 } 559 nci::ConfigParameterId::LnAtrResGenBytes => { 560 self.ln_atr_res_gen_bytes = value.to_vec(); 561 Ok(()) 562 } 563 nci::ConfigParameterId::LnAtrResConfig => { 564 self.ln_atr_res_config = u8::from_le_bytes(value.try_into()?); 565 Ok(()) 566 } 567 nci::ConfigParameterId::PacmBitRate => { 568 self.pacm_bit_rate = u8::from_le_bytes(value.try_into()?); 569 Ok(()) 570 } 571 nci::ConfigParameterId::RfFieldInfo => { 572 self.rf_field_info = u8::from_le_bytes(value.try_into()?); 573 Ok(()) 574 } 575 nci::ConfigParameterId::RfNfceeAction => { 576 self.rf_nfcee_action = u8::from_le_bytes(value.try_into()?); 577 Ok(()) 578 } 579 nci::ConfigParameterId::NfcdepOp => { 580 self.nfcdep_op = u8::from_le_bytes(value.try_into()?); 581 Ok(()) 582 } 583 nci::ConfigParameterId::LlcpVersion => { 584 self.llcp_version = u8::from_le_bytes(value.try_into()?); 585 Ok(()) 586 } 587 nci::ConfigParameterId::NfccConfigControl => { 588 self.nfcc_config_control = u8::from_le_bytes(value.try_into()?); 589 Ok(()) 590 } 591 _ => Err(anyhow::anyhow!("unknown config parameter ID")), 592 } 593 } 594 } 595 596 impl Default for ConfigParameters { default() -> Self597 fn default() -> Self { 598 ConfigParameters { 599 total_duration: TOTAL_DURATION, 600 con_discovery_param: 0x01, 601 power_state: 0x02, 602 pa_bail_out: 0x00, 603 pa_devices_limit: PA_DEVICES_LIMIT, 604 pb_afi: 0x00, 605 pb_bail_out: 0x00, 606 pb_attrib_param1: PB_ATTRIB_PARAM1, 607 pb_sensb_req_param: 0x00, 608 pb_devices_limit: PB_DEVICES_LIMIT, 609 pf_bit_rate: 0x01, 610 pf_bail_out: 0x00, 611 pf_devices_limit: PF_DEVICES_LIMIT, 612 pi_b_h_info: vec![], 613 pi_bit_rate: 0x00, 614 pn_nfc_dep_psl: 0x00, 615 pn_atr_req_gen_bytes: vec![], 616 pn_atr_req_config: 0x30, 617 pv_devices_limit: PV_DEVICES_LIMIT, 618 la_bit_frame_sdd: LA_BIT_FRAME_SDD, 619 la_platform_config: LA_PLATFORM_CONFIG, 620 la_sel_info: LA_SEL_INFO, 621 la_nfcid1: vec![0x08, 0x00, 0x00, 0x00], 622 lb_sensb_info: LB_SENSB_INFO, 623 lb_nfcid0: [0x08, 0x00, 0x00, 0x00], 624 lb_application_data: 0x00000000, 625 lb_sfgi: LB_SFGI, 626 lb_fwi_adc_fo: LB_FWI_ADC_FO, 627 lb_bit_rate: 0x00, 628 lf_t3t_identifiers_1: [0; 18], 629 lf_t3t_identifiers_2: [0; 18], 630 lf_t3t_identifiers_3: [0; 18], 631 lf_t3t_identifiers_4: [0; 18], 632 lf_t3t_identifiers_5: [0; 18], 633 lf_t3t_identifiers_6: [0; 18], 634 lf_t3t_identifiers_7: [0; 18], 635 lf_t3t_identifiers_8: [0; 18], 636 lf_t3t_identifiers_9: [0; 18], 637 lf_t3t_identifiers_10: [0; 18], 638 lf_t3t_identifiers_11: [0; 18], 639 lf_t3t_identifiers_12: [0; 18], 640 lf_t3t_identifiers_13: [0; 18], 641 lf_t3t_identifiers_14: [0; 18], 642 lf_t3t_identifiers_15: [0; 18], 643 lf_t3t_identifiers_16: [0; 18], 644 lf_t3t_pmm_default: [0xff; 8], 645 lf_t3t_max: LF_T3T_MAX, 646 lf_t3t_flags: 0x0000, 647 lf_t3t_rd_allowed: 0x00, 648 lf_protocol_type: LF_PROTOCOL_TYPE, 649 li_a_rats_tb1: LI_A_RATS_TB1, 650 li_a_hist_by: vec![], 651 li_b_h_info_resp: vec![], 652 li_a_bit_rate: 0x00, 653 li_a_rats_tc1: LI_A_RATS_TC1, 654 ln_wt: 10, 655 ln_atr_res_gen_bytes: vec![], 656 ln_atr_res_config: 0x30, 657 pacm_bit_rate: 0x01, 658 rf_field_info: 0x00, 659 rf_nfcee_action: 0x01, 660 // [NCI] Table 101: NFC-DEP Operation Parameter. 661 nfcdep_op: 0x1f, 662 llcp_version: LLCP_VERSION, 663 nfcc_config_control: 0x00, 664 } 665 } 666 } 667 668 impl State { 669 /// Craft the NFCID1 used by this instance in NFC-A poll responses. 670 /// Returns a dynamically generated NFCID1 (4 byte long and starts with 08h). nfcid1(&self) -> Vec<u8>671 fn nfcid1(&self) -> Vec<u8> { 672 if self.config_parameters.la_nfcid1.len() == 4 673 && self.config_parameters.la_nfcid1[0] == 0x08 674 { 675 vec![0x08, 186, 7, 99] // TODO(hchataing) pseudo random 676 } else { 677 self.config_parameters.la_nfcid1.clone() 678 } 679 } 680 681 /// Select the interface to be preferably used for the selected protocol. select_interface( &self, mode: RfMode, rf_protocol: nci::RfProtocolType, ) -> nci::RfInterfaceType682 fn select_interface( 683 &self, 684 mode: RfMode, 685 rf_protocol: nci::RfProtocolType, 686 ) -> nci::RfInterfaceType { 687 for config in self.discover_map.iter() { 688 match (mode, config.mode.poll_mode, config.mode.listen_mode) { 689 _ if config.rf_protocol != rf_protocol => (), 690 (RfMode::Poll, nci::FeatureFlag::Enabled, _) 691 | (RfMode::Listen, _, nci::FeatureFlag::Enabled) => return config.rf_interface, 692 _ => (), 693 } 694 } 695 696 // [NCI] 6.2 RF Interface Mapping Configuration 697 // 698 // The NFCC SHALL set the default mapping of RF Interface to RF Protocols / 699 // Modes to the following values: 700 // 701 // • If the NFCC supports the ISO-DEP RF interface, the NFCC SHALL map the 702 // ISO-DEP RF Protocol to the ISO-DEP RF Interface for Poll Mode and 703 // Listen Mode. 704 // • If the NFCC supports the NFC-DEP RF interface, the NFCC SHALL map the 705 // NFC-DEP RF Protocol to the NFC-DEP RF Interface for Poll Mode and 706 // Listen Mode. 707 // • If the NFCC supports the NDEF RF interface, the NFCC SHALL map the 708 // NDEF RF Protocol to the NDEF RF Interface for Poll Mode. 709 // • Otherwise, the NFCC SHALL map to the Frame RF Interface by default 710 match rf_protocol { 711 nci::RfProtocolType::IsoDep => nci::RfInterfaceType::IsoDep, 712 nci::RfProtocolType::NfcDep => nci::RfInterfaceType::NfcDep, 713 nci::RfProtocolType::Ndef if mode == RfMode::Poll => nci::RfInterfaceType::Ndef, 714 _ => nci::RfInterfaceType::Frame, 715 } 716 } 717 718 /// Insert a poll response into the discovery list. 719 /// The response is not inserted if the device was already discovered 720 /// with the same parameters. add_poll_response(&mut self, poll_response: RfPollResponse)721 fn add_poll_response(&mut self, poll_response: RfPollResponse) { 722 if !self.rf_poll_responses.contains(&poll_response) { 723 self.rf_poll_responses.push(poll_response); 724 } 725 } 726 } 727 728 impl<'a> Controller<'a> { 729 /// Create a new NFCC instance with default configuration. new( id: u16, nci_stream: nci::StreamRefMut<'a>, nci_writer: nci::Writer, rf_rx: mpsc::UnboundedReceiver<rf::RfPacket>, rf_tx: mpsc::UnboundedSender<rf::RfPacket>, ) -> Controller<'a>730 pub fn new( 731 id: u16, 732 nci_stream: nci::StreamRefMut<'a>, 733 nci_writer: nci::Writer, 734 rf_rx: mpsc::UnboundedReceiver<rf::RfPacket>, 735 rf_tx: mpsc::UnboundedSender<rf::RfPacket>, 736 ) -> Controller<'a> { 737 Controller { 738 id, 739 nci_stream, 740 nci_writer, 741 rf_rx, 742 rf_tx, 743 state: State { 744 config_parameters: Default::default(), 745 logical_connections: [None; MAX_LOGICAL_CONNECTIONS as usize], 746 discover_map: vec![], 747 discover_configuration: vec![], 748 nfcee_state: NfceeState::Disabled, 749 rf_state: RfState::Idle, 750 rf_poll_responses: vec![], 751 rf_activation_parameters: vec![], 752 passive_observe_mode: nci::PassiveObserveMode::Disable.into(), 753 last_observe_mode_state: None, 754 start_time: Instant::now(), 755 remote_field_status: rf::FieldStatus::FieldOff, 756 exit_frame_timeout: Duration::from_millis(0), 757 exit_frame_start_time: None, 758 exit_frames: vec![], 759 }, 760 } 761 } 762 send_control(&mut self, packet: impl Into<nci::ControlPacket>) -> Result<()>763 async fn send_control(&mut self, packet: impl Into<nci::ControlPacket>) -> Result<()> { 764 self.nci_writer.write(&packet.into().encode_to_vec()?).await 765 } 766 send_data(&mut self, packet: impl Into<nci::DataPacket>) -> Result<()>767 async fn send_data(&mut self, packet: impl Into<nci::DataPacket>) -> Result<()> { 768 self.nci_writer.write(&packet.into().encode_to_vec()?).await 769 } 770 send_rf(&self, packet: impl Into<rf::RfPacket>) -> Result<()>771 async fn send_rf(&self, packet: impl Into<rf::RfPacket>) -> Result<()> { 772 self.rf_tx.send(packet.into())?; 773 Ok(()) 774 } 775 core_reset(&mut self, cmd: nci::CoreResetCommand) -> Result<()>776 async fn core_reset(&mut self, cmd: nci::CoreResetCommand) -> Result<()> { 777 info!("[{}] CORE_RESET_CMD", self.id); 778 info!(" ResetType: {:?}", cmd.get_reset_type()); 779 780 match cmd.get_reset_type() { 781 nci::ResetType::KeepConfig => (), 782 nci::ResetType::ResetConfig => self.state.config_parameters = Default::default(), 783 } 784 785 for i in 0..MAX_LOGICAL_CONNECTIONS { 786 self.state.logical_connections[i as usize] = None; 787 } 788 789 self.state.discover_map.clear(); 790 self.state.discover_configuration.clear(); 791 self.state.rf_state = RfState::Idle; 792 self.state.rf_poll_responses.clear(); 793 794 self.send_control(nci::CoreResetResponseBuilder { status: nci::Status::Ok }).await?; 795 796 self.send_control(nci::CoreResetNotificationBuilder { 797 trigger: nci::ResetTrigger::ResetCommand, 798 config_status: match cmd.get_reset_type() { 799 nci::ResetType::KeepConfig => nci::ConfigStatus::ConfigKept, 800 nci::ResetType::ResetConfig => nci::ConfigStatus::ConfigReset, 801 }, 802 nci_version: NCI_VERSION, 803 manufacturer_id: MANUFACTURER_ID, 804 manufacturer_specific_information: MANUFACTURER_SPECIFIC_INFORMATION.to_vec(), 805 }) 806 .await?; 807 808 Ok(()) 809 } 810 core_init(&mut self, _cmd: nci::CoreInitCommand) -> Result<()>811 async fn core_init(&mut self, _cmd: nci::CoreInitCommand) -> Result<()> { 812 info!("[{}] CORE_INIT_CMD", self.id); 813 814 self.send_control(nci::CoreInitResponseBuilder { 815 status: nci::Status::Ok, 816 nfcc_features: nci::NfccFeatures { 817 discovery_frequency_configuration: nci::FeatureFlag::Disabled, 818 discovery_configuration_mode: nci::DiscoveryConfigurationMode::DhOnly, 819 hci_network_support: nci::FeatureFlag::Enabled, 820 active_communication_mode: nci::FeatureFlag::Enabled, 821 technology_based_routing: nci::FeatureFlag::Enabled, 822 protocol_based_routing: nci::FeatureFlag::Enabled, 823 aid_based_routing: nci::FeatureFlag::Enabled, 824 system_code_based_routing: nci::FeatureFlag::Enabled, 825 apdu_pattern_based_routing: nci::FeatureFlag::Enabled, 826 forced_nfcee_routing: nci::FeatureFlag::Enabled, 827 battery_off_state: nci::FeatureFlag::Disabled, 828 switched_off_state: nci::FeatureFlag::Enabled, 829 switched_on_substates: nci::FeatureFlag::Enabled, 830 rf_configuration_in_switched_off_state: nci::FeatureFlag::Disabled, 831 proprietary_capabilities: 0, 832 }, 833 max_logical_connections: MAX_LOGICAL_CONNECTIONS, 834 max_routing_table_size: MAX_ROUTING_TABLE_SIZE, 835 max_control_packet_payload_size: MAX_CONTROL_PACKET_PAYLOAD_SIZE, 836 max_data_packet_payload_size: MAX_DATA_PACKET_PAYLOAD_SIZE, 837 number_of_credits: NUMBER_OF_CREDITS, 838 max_nfcv_rf_frame_size: MAX_NFCV_RF_FRAME_SIZE, 839 supported_rf_interfaces: vec![ 840 nci::RfInterface { interface: nci::RfInterfaceType::Frame, extensions: vec![] }, 841 nci::RfInterface { interface: nci::RfInterfaceType::IsoDep, extensions: vec![] }, 842 nci::RfInterface { interface: nci::RfInterfaceType::NfcDep, extensions: vec![] }, 843 nci::RfInterface { 844 interface: nci::RfInterfaceType::NfceeDirect, 845 extensions: vec![], 846 }, 847 ], 848 }) 849 .await?; 850 851 Ok(()) 852 } 853 core_set_config(&mut self, cmd: nci::CoreSetConfigCommand) -> Result<()>854 async fn core_set_config(&mut self, cmd: nci::CoreSetConfigCommand) -> Result<()> { 855 info!("[{}] CORE_SET_CONFIG_CMD", self.id); 856 857 let mut invalid_parameters = vec![]; 858 for parameter in cmd.get_parameters().iter() { 859 info!(" Type: {:?}", parameter.id); 860 info!(" Value: {:?}", parameter.value); 861 match parameter.id { 862 nci::ConfigParameterId::Rfu(_) => invalid_parameters.push(parameter.id), 863 // TODO(henrichataing): 864 // [NCI] 5.2.1 State RFST_IDLE 865 // Unless otherwise specified, discovery related configuration 866 // defined in Sections 6.1, 6.2, 6.3 and 7.1 SHALL only be set 867 // while in IDLE state. 868 // 869 // Respond with Semantic Error as indicated by 870 // [NCI] 3.2.2 Exception Handling for Control Messages 871 // An unexpected Command SHALL NOT cause any action by the NFCC. 872 // Unless otherwise specified, the NFCC SHALL send a Response 873 // with a Status value of STATUS_SEMANTIC_ERROR and no 874 // additional fields. 875 _ => { 876 if self.state.config_parameters.set(parameter.id, ¶meter.value).is_err() { 877 invalid_parameters.push(parameter.id) 878 } 879 } 880 } 881 } 882 883 self.send_control(nci::CoreSetConfigResponseBuilder { 884 status: if invalid_parameters.is_empty() { 885 // A Status of STATUS_OK SHALL indicate that all configuration parameters 886 // have been set to these new values in the NFCC. 887 nci::Status::Ok 888 } else { 889 // If the DH tries to set a parameter that is not applicable for the NFCC, 890 // the NFCC SHALL respond with a CORE_SET_CONFIG_RSP with a Status field 891 // of STATUS_INVALID_PARAM and including one or more invalid Parameter ID(s). 892 // All other configuration parameters SHALL have been set to the new values 893 // in the NFCC. 894 warn!( 895 "[{}] rejecting unknown configuration parameter ids: {:?}", 896 self.id, invalid_parameters 897 ); 898 nci::Status::InvalidParam 899 }, 900 parameters: invalid_parameters, 901 }) 902 .await?; 903 904 Ok(()) 905 } 906 core_get_config(&mut self, cmd: nci::CoreGetConfigCommand) -> Result<()>907 async fn core_get_config(&mut self, cmd: nci::CoreGetConfigCommand) -> Result<()> { 908 info!("[{}] CORE_GET_CONFIG_CMD", self.id); 909 910 let mut valid_parameters = vec![]; 911 let mut invalid_parameters = vec![]; 912 for id in cmd.get_parameters() { 913 info!(" ID: {:?}", id); 914 match self.state.config_parameters.get(*id) { 915 Ok(value) => { 916 valid_parameters.push(nci::ConfigParameter { id: *id, value: value.to_vec() }) 917 } 918 Err(_) => invalid_parameters.push(nci::ConfigParameter { id: *id, value: vec![] }), 919 } 920 } 921 922 self.send_control(if invalid_parameters.is_empty() { 923 // If the NFCC is able to respond with all requested parameters, the 924 // NFCC SHALL respond with the CORE_GET_CONFIG_RSP with a Status 925 // of STATUS_OK. 926 nci::CoreGetConfigResponseBuilder { 927 status: nci::Status::Ok, 928 parameters: valid_parameters, 929 } 930 } else { 931 // If the DH tries to retrieve any parameter(s) that are not available 932 // in the NFCC, the NFCC SHALL respond with a CORE_GET_CONFIG_RSP with 933 // a Status field of STATUS_INVALID_PARAM, containing each unavailable 934 // Parameter ID with a Parameter Len field of value zero. 935 nci::CoreGetConfigResponseBuilder { 936 status: nci::Status::InvalidParam, 937 parameters: invalid_parameters, 938 } 939 }) 940 .await?; 941 942 Ok(()) 943 } 944 core_conn_create(&mut self, cmd: nci::CoreConnCreateCommand) -> Result<()>945 async fn core_conn_create(&mut self, cmd: nci::CoreConnCreateCommand) -> Result<()> { 946 info!("[{}] CORE_CONN_CREATE_CMD", self.id); 947 948 let result: std::result::Result<u8, nci::Status> = (|| { 949 // Retrieve an unused connection ID for the logical connection. 950 let conn_id = { 951 (0..MAX_LOGICAL_CONNECTIONS) 952 .find(|conn_id| self.state.logical_connections[*conn_id as usize].is_none()) 953 .ok_or(nci::Status::Rejected)? 954 }; 955 956 // Check that the selected destination type is supported and validate 957 // the destination specific parameters. 958 let logical_connection = match cmd.get_destination_type() { 959 // If the value of Destination Type is that of a Remote NFC 960 // Endpoint (0x02), then only the Destination-specific Parameter 961 // with Type 0x00 or proprietary parameters (as defined in Table 16) 962 // SHALL be present. 963 nci::DestinationType::RemoteNfcEndpoint => { 964 let mut rf_discovery_id: Option<u8> = None; 965 let mut rf_protocol_type: Option<nci::RfProtocolType> = None; 966 967 for parameter in cmd.get_parameters() { 968 match parameter.id { 969 nci::DestinationSpecificParameterId::RfDiscovery => { 970 rf_discovery_id = parameter.value.first().cloned(); 971 rf_protocol_type = parameter 972 .value 973 .get(1) 974 .and_then(|t| nci::RfProtocolType::try_from(*t).ok()); 975 } 976 _ => return Err(nci::Status::Rejected), 977 } 978 } 979 980 LogicalConnection::RemoteNfcEndpoint { 981 rf_discovery_id: rf_discovery_id.ok_or(nci::Status::Rejected)?, 982 rf_protocol_type: rf_protocol_type.ok_or(nci::Status::Rejected)?, 983 } 984 } 985 nci::DestinationType::NfccLoopback | nci::DestinationType::Nfcee => { 986 return Err(nci::Status::Rejected) 987 } 988 }; 989 990 // The combination of Destination Type and Destination Specific 991 // Parameters SHALL uniquely identify a single destination for the 992 // Logical Connection. 993 if self 994 .state 995 .logical_connections 996 .iter() 997 .any(|c| c.as_ref() == Some(&logical_connection)) 998 { 999 return Err(nci::Status::Rejected); 1000 } 1001 1002 // Create the connection. 1003 self.state.logical_connections[conn_id as usize] = Some(logical_connection); 1004 1005 Ok(conn_id) 1006 })(); 1007 1008 self.send_control(match result { 1009 Ok(conn_id) => nci::CoreConnCreateResponseBuilder { 1010 status: nci::Status::Ok, 1011 max_data_packet_payload_size: MAX_DATA_PACKET_PAYLOAD_SIZE, 1012 initial_number_of_credits: 0xff, 1013 conn_id: nci::ConnId::from_dynamic(conn_id), 1014 }, 1015 Err(status) => nci::CoreConnCreateResponseBuilder { 1016 status, 1017 max_data_packet_payload_size: 0, 1018 initial_number_of_credits: 0xff, 1019 conn_id: 0.try_into().unwrap(), 1020 }, 1021 }) 1022 .await?; 1023 1024 Ok(()) 1025 } 1026 core_conn_close(&mut self, cmd: nci::CoreConnCloseCommand) -> Result<()>1027 async fn core_conn_close(&mut self, cmd: nci::CoreConnCloseCommand) -> Result<()> { 1028 info!("[{}] CORE_CONN_CLOSE_CMD", self.id); 1029 1030 let conn_id = match cmd.get_conn_id() { 1031 nci::ConnId::StaticRf | nci::ConnId::StaticHci => { 1032 warn!("[{}] core_conn_close called with static conn_id", self.id); 1033 self.send_control(nci::CoreConnCloseResponseBuilder { 1034 status: nci::Status::Rejected, 1035 }) 1036 .await?; 1037 return Ok(()); 1038 } 1039 nci::ConnId::Dynamic(id) => nci::ConnId::to_dynamic(id), 1040 }; 1041 1042 let status = if conn_id >= MAX_LOGICAL_CONNECTIONS 1043 || self.state.logical_connections[conn_id as usize].is_none() 1044 { 1045 // If there is no connection associated to the Conn ID in the CORE_CONN_CLOSE_CMD, the 1046 // NFCC SHALL reject the connection closure request by sending a CORE_CONN_CLOSE_RSP 1047 // with a Status of STATUS_REJECTED. 1048 nci::Status::Rejected 1049 } else { 1050 // When it receives a CORE_CONN_CLOSE_CMD for an existing connection, the NFCC SHALL 1051 // accept the connection closure request by sending a CORE_CONN_CLOSE_RSP with a Status of 1052 // STATUS_OK, and the Logical Connection is closed. 1053 self.state.logical_connections[conn_id as usize] = None; 1054 nci::Status::Ok 1055 }; 1056 1057 self.send_control(nci::CoreConnCloseResponseBuilder { status }).await?; 1058 1059 Ok(()) 1060 } 1061 core_set_power_sub_state( &mut self, cmd: nci::CoreSetPowerSubStateCommand, ) -> Result<()>1062 async fn core_set_power_sub_state( 1063 &mut self, 1064 cmd: nci::CoreSetPowerSubStateCommand, 1065 ) -> Result<()> { 1066 info!("[{}] CORE_SET_POWER_SUB_STATE_CMD", self.id); 1067 info!(" State: {:?}", cmd.get_power_state()); 1068 1069 self.send_control(nci::CoreSetPowerSubStateResponseBuilder { status: nci::Status::Ok }) 1070 .await?; 1071 1072 Ok(()) 1073 } 1074 rf_discover_map(&mut self, cmd: nci::RfDiscoverMapCommand) -> Result<()>1075 async fn rf_discover_map(&mut self, cmd: nci::RfDiscoverMapCommand) -> Result<()> { 1076 info!("[{}] RF_DISCOVER_MAP_CMD", self.id); 1077 1078 self.state.discover_map.clone_from(cmd.get_mapping_configurations()); 1079 self.send_control(nci::RfDiscoverMapResponseBuilder { status: nci::Status::Ok }).await?; 1080 1081 Ok(()) 1082 } 1083 rf_set_listen_mode_routing( &mut self, _cmd: nci::RfSetListenModeRoutingCommand, ) -> Result<()>1084 async fn rf_set_listen_mode_routing( 1085 &mut self, 1086 _cmd: nci::RfSetListenModeRoutingCommand, 1087 ) -> Result<()> { 1088 info!("[{}] RF_SET_LISTEN_MODE_ROUTING_CMD", self.id); 1089 1090 self.send_control(nci::RfSetListenModeRoutingResponseBuilder { status: nci::Status::Ok }) 1091 .await?; 1092 1093 Ok(()) 1094 } 1095 rf_get_listen_mode_routing( &mut self, _cmd: nci::RfGetListenModeRoutingCommand, ) -> Result<()>1096 async fn rf_get_listen_mode_routing( 1097 &mut self, 1098 _cmd: nci::RfGetListenModeRoutingCommand, 1099 ) -> Result<()> { 1100 info!("[{}] RF_GET_LISTEN_MODE_ROUTING_CMD", self.id); 1101 1102 self.send_control(nci::RfGetListenModeRoutingResponseBuilder { 1103 status: nci::Status::Ok, 1104 more_to_follow: 0, 1105 routing_entries: vec![], 1106 }) 1107 .await?; 1108 1109 Ok(()) 1110 } 1111 rf_discover(&mut self, cmd: nci::RfDiscoverCommand) -> Result<()>1112 async fn rf_discover(&mut self, cmd: nci::RfDiscoverCommand) -> Result<()> { 1113 info!("[{}] RF_DISCOVER_CMD", self.id); 1114 for config in cmd.get_configurations() { 1115 info!(" TechMode: {:?}", config.technology_and_mode); 1116 } 1117 1118 if self.state.rf_state != RfState::Idle { 1119 warn!("[{}] rf_discover received in {:?} state", self.id, self.state.rf_state); 1120 self.send_control(nci::RfDiscoverResponseBuilder { 1121 status: nci::Status::SemanticError, 1122 }) 1123 .await?; 1124 return Ok(()); 1125 } 1126 1127 self.state.discover_configuration.clone_from(cmd.get_configurations()); 1128 self.state.rf_state = RfState::Discovery; 1129 1130 self.send_control(nci::RfDiscoverResponseBuilder { status: nci::Status::Ok }).await?; 1131 1132 Ok(()) 1133 } 1134 rf_discover_select(&mut self, cmd: nci::RfDiscoverSelectCommand) -> Result<()>1135 async fn rf_discover_select(&mut self, cmd: nci::RfDiscoverSelectCommand) -> Result<()> { 1136 info!("[{}] RF_DISCOVER_SELECT_CMD", self.id); 1137 info!(" DiscoveryID: {:?}", cmd.get_rf_discovery_id()); 1138 info!(" Protocol: {:?}", cmd.get_rf_protocol()); 1139 info!(" Interface: {:?}", cmd.get_rf_interface()); 1140 1141 if self.state.rf_state != RfState::WaitForHostSelect { 1142 warn!("[{}] rf_discover_select received in {:?} state", self.id, self.state.rf_state); 1143 self.send_control(nci::RfDiscoverSelectResponseBuilder { 1144 status: nci::Status::SemanticError, 1145 }) 1146 .await?; 1147 return Ok(()); 1148 } 1149 1150 let rf_discovery_id = match cmd.get_rf_discovery_id() { 1151 nci::RfDiscoveryId::Rfu(_) => { 1152 warn!("[{}] rf_discover_select with reserved rf_discovery_id", self.id); 1153 self.send_control(nci::RfDiscoverSelectResponseBuilder { 1154 status: nci::Status::Rejected, 1155 }) 1156 .await?; 1157 return Ok(()); 1158 } 1159 nci::RfDiscoveryId::Id(id) => nci::RfDiscoveryId::to_index(id), 1160 }; 1161 1162 // If the RF Discovery ID, RF Protocol or RF Interface is not valid, 1163 // the NFCC SHALL respond with RF_DISCOVER_SELECT_RSP with a Status of 1164 // STATUS_REJECTED. 1165 if rf_discovery_id >= self.state.rf_poll_responses.len() { 1166 warn!("[{}] rf_discover_select with invalid rf_discovery_id", self.id); 1167 self.send_control(nci::RfDiscoverSelectResponseBuilder { 1168 status: nci::Status::Rejected, 1169 }) 1170 .await?; 1171 return Ok(()); 1172 } 1173 1174 if cmd.get_rf_protocol() != self.state.rf_poll_responses[rf_discovery_id].rf_protocol.into() 1175 { 1176 warn!("[{}] rf_discover_select with invalid rf_protocol", self.id); 1177 self.send_control(nci::RfDiscoverSelectResponseBuilder { 1178 status: nci::Status::Rejected, 1179 }) 1180 .await?; 1181 return Ok(()); 1182 } 1183 1184 self.send_control(nci::RfDiscoverSelectResponseBuilder { status: nci::Status::Ok }).await?; 1185 1186 // Send RF select command to the peer to activate the device. 1187 // The command has varying parameters based on the activated protocol. 1188 self.activate_poll_interface( 1189 rf_discovery_id, 1190 cmd.get_rf_protocol(), 1191 cmd.get_rf_interface(), 1192 ) 1193 .await?; 1194 1195 Ok(()) 1196 } 1197 rf_deactivate(&mut self, cmd: nci::RfDeactivateCommand) -> Result<()>1198 async fn rf_deactivate(&mut self, cmd: nci::RfDeactivateCommand) -> Result<()> { 1199 info!("[{}] RF_DEACTIVATE_CMD", self.id); 1200 info!(" Type: {:?}", cmd.get_deactivation_type()); 1201 1202 use nci::DeactivationType::*; 1203 1204 let (status, mut next_state) = match (self.state.rf_state, cmd.get_deactivation_type()) { 1205 (RfState::Idle, _) => (nci::Status::SemanticError, RfState::Idle), 1206 (RfState::Discovery, IdleMode) => (nci::Status::Ok, RfState::Idle), 1207 (RfState::Discovery, _) => (nci::Status::SemanticError, RfState::Discovery), 1208 (RfState::PollActive { .. }, IdleMode) => (nci::Status::Ok, RfState::Idle), 1209 (RfState::PollActive { .. }, SleepMode | SleepAfMode) => { 1210 (nci::Status::Ok, RfState::WaitForHostSelect) 1211 } 1212 (RfState::PollActive { .. }, Discovery) => (nci::Status::Ok, RfState::Discovery), 1213 (RfState::ListenSleep { .. }, IdleMode) => (nci::Status::Ok, RfState::Idle), 1214 (RfState::ListenSleep { .. }, _) => (nci::Status::SemanticError, self.state.rf_state), 1215 (RfState::ListenActive { .. }, IdleMode) => (nci::Status::Ok, RfState::Idle), 1216 (RfState::ListenActive { id, .. }, SleepMode | SleepAfMode) => { 1217 (nci::Status::Ok, RfState::ListenSleep { id }) 1218 } 1219 (RfState::ListenActive { .. }, Discovery) => (nci::Status::Ok, RfState::Discovery), 1220 (RfState::WaitForHostSelect, IdleMode) => (nci::Status::Ok, RfState::Idle), 1221 (RfState::WaitForHostSelect, _) => { 1222 (nci::Status::SemanticError, RfState::WaitForHostSelect) 1223 } 1224 (RfState::WaitForSelectResponse { .. }, IdleMode) => (nci::Status::Ok, RfState::Idle), 1225 (RfState::WaitForSelectResponse { .. }, _) => { 1226 (nci::Status::SemanticError, self.state.rf_state) 1227 } 1228 }; 1229 1230 // Update the state now to prevent interface activation from 1231 // completing if a remote device is being selected. 1232 (next_state, self.state.rf_state) = (self.state.rf_state, next_state); 1233 1234 self.send_control(nci::RfDeactivateResponseBuilder { status }).await?; 1235 1236 // Deactivate the active RF interface if applicable 1237 // (next_state is the previous state in this context). 1238 match next_state { 1239 RfState::PollActive { .. } | RfState::ListenActive { .. } => { 1240 info!("[{}] RF_DEACTIVATE_NTF", self.id); 1241 info!(" Type: {:?}", cmd.get_deactivation_type()); 1242 info!(" Reason: DH_Request"); 1243 self.field_info(rf::FieldStatus::FieldOff, 255).await?; 1244 self.send_control(nci::RfDeactivateNotificationBuilder { 1245 deactivation_type: cmd.get_deactivation_type(), 1246 deactivation_reason: nci::DeactivationReason::DhRequest, 1247 }) 1248 .await? 1249 } 1250 _ => (), 1251 } 1252 1253 // Deselect the remote device if applicable. 1254 match next_state { 1255 RfState::PollActive { id, rf_protocol, rf_technology, .. } 1256 | RfState::WaitForSelectResponse { id, rf_protocol, rf_technology, .. } => { 1257 self.send_rf(rf::DeactivateNotificationBuilder { 1258 receiver: id, 1259 protocol: rf_protocol, 1260 technology: rf_technology, 1261 bitrate: rf::BitRate::BitRate106KbitS, 1262 power_level: 255, 1263 sender: self.id, 1264 type_: cmd.get_deactivation_type().into(), 1265 reason: rf::DeactivateReason::EndpointRequest, 1266 }) 1267 .await? 1268 } 1269 _ => (), 1270 } 1271 1272 Ok(()) 1273 } 1274 nfcee_discover(&mut self, _cmd: nci::NfceeDiscoverCommand) -> Result<()>1275 async fn nfcee_discover(&mut self, _cmd: nci::NfceeDiscoverCommand) -> Result<()> { 1276 info!("[{}] NFCEE_DISCOVER_CMD", self.id); 1277 1278 self.send_control(nci::NfceeDiscoverResponseBuilder { 1279 status: nci::Status::Ok, 1280 number_of_nfcees: 1, 1281 }) 1282 .await?; 1283 1284 self.send_control(nci::NfceeDiscoverNotificationBuilder { 1285 nfcee_id: nci::NfceeId::hci_nfcee(0x86), 1286 nfcee_status: nci::NfceeStatus::Disabled, 1287 supported_nfcee_protocols: vec![], 1288 nfcee_information: vec![nci::NfceeInformation { 1289 r#type: nci::NfceeInformationType::HostId, 1290 value: vec![0xc0], 1291 }], 1292 nfcee_supply_power: nci::NfceeSupplyPower::NfccHasNoControl, 1293 }) 1294 .await?; 1295 1296 Ok(()) 1297 } 1298 nfcee_mode_set(&mut self, cmd: nci::NfceeModeSetCommand) -> Result<()>1299 async fn nfcee_mode_set(&mut self, cmd: nci::NfceeModeSetCommand) -> Result<()> { 1300 info!("[{}] NFCEE_MODE_SET_CMD", self.id); 1301 info!(" NFCEE ID: {:?}", cmd.get_nfcee_id()); 1302 info!(" NFCEE Mode: {:?}", cmd.get_nfcee_mode()); 1303 1304 if cmd.get_nfcee_id() != nci::NfceeId::hci_nfcee(0x86) { 1305 warn!("[{}] nfcee_mode_set with invalid nfcee_id", self.id); 1306 self.send_control(nci::NfceeModeSetResponseBuilder { status: nci::Status::Ok }).await?; 1307 return Ok(()); 1308 } 1309 1310 self.state.nfcee_state = match cmd.get_nfcee_mode() { 1311 nci::NfceeMode::Enable => NfceeState::Enabled, 1312 nci::NfceeMode::Disable => NfceeState::Disabled, 1313 }; 1314 1315 self.send_control(nci::NfceeModeSetResponseBuilder { status: nci::Status::Ok }).await?; 1316 1317 self.send_control(nci::NfceeModeSetNotificationBuilder { status: nci::Status::Ok }).await?; 1318 1319 if self.state.nfcee_state == NfceeState::Enabled { 1320 // Android host stack expects this notification to know when the 1321 // NFCEE completes start-up. The list of information entries is 1322 // filled with defaults observed on real phones. 1323 self.send_data(nci::DataPacketBuilder { 1324 mt: nci::MessageType::Data, 1325 conn_id: nci::ConnId::StaticHci, 1326 cr: 0, 1327 payload: Some(bytes::Bytes::copy_from_slice(&[0x81, 0x43, 0xc0, 0x01])), 1328 }) 1329 .await?; 1330 1331 self.send_control(nci::RfNfceeDiscoveryReqNotificationBuilder { 1332 information_entries: vec![ 1333 nci::InformationEntry { 1334 r#type: nci::InformationEntryType::AddDiscoveryRequest, 1335 nfcee_id: nci::NfceeId::hci_nfcee(0x86), 1336 rf_technology_and_mode: nci::RfTechnologyAndMode::NfcFPassiveListenMode, 1337 rf_protocol: nci::RfProtocolType::T3t, 1338 }, 1339 nci::InformationEntry { 1340 r#type: nci::InformationEntryType::AddDiscoveryRequest, 1341 nfcee_id: nci::NfceeId::hci_nfcee(0x86), 1342 rf_technology_and_mode: nci::RfTechnologyAndMode::NfcAPassiveListenMode, 1343 rf_protocol: nci::RfProtocolType::IsoDep, 1344 }, 1345 nci::InformationEntry { 1346 r#type: nci::InformationEntryType::AddDiscoveryRequest, 1347 nfcee_id: nci::NfceeId::hci_nfcee(0x86), 1348 rf_technology_and_mode: nci::RfTechnologyAndMode::NfcBPassiveListenMode, 1349 rf_protocol: nci::RfProtocolType::IsoDep, 1350 }, 1351 ], 1352 }) 1353 .await?; 1354 } 1355 1356 Ok(()) 1357 } 1358 android_get_caps(&mut self, _cmd: nci::AndroidGetCapsCommand) -> Result<()>1359 async fn android_get_caps(&mut self, _cmd: nci::AndroidGetCapsCommand) -> Result<()> { 1360 info!("[{}] ANDROID_GET_CAPS_CMD", self.id); 1361 let cap_tlvs = vec![ 1362 nci::CapTlv { t: nci::CapTlvType::PassiveObserverMode, v: vec![2] }, 1363 nci::CapTlv { t: nci::CapTlvType::PollingFrameNotification, v: vec![1] }, 1364 nci::CapTlv { t: nci::CapTlvType::AutotransactPollingLoopFilter, v: vec![1] }, 1365 nci::CapTlv { 1366 t: nci::CapTlvType::NumberOfExitFramesSupported, 1367 v: vec![NUMBER_OF_SUPPORTED_EXIT_FRAMES], 1368 }, 1369 ]; 1370 self.send_control(nci::AndroidGetCapsResponseBuilder { 1371 status: nci::Status::Ok, 1372 android_version: 0, 1373 tlvs: cap_tlvs, 1374 }) 1375 .await?; 1376 Ok(()) 1377 } 1378 android_passive_observe_mode( &mut self, cmd: nci::AndroidPassiveObserveModeCommand, ) -> Result<()>1379 async fn android_passive_observe_mode( 1380 &mut self, 1381 cmd: nci::AndroidPassiveObserveModeCommand, 1382 ) -> Result<()> { 1383 info!("[{}] ANDROID_PASSIVE_OBSERVE_MODE_CMD", self.id); 1384 info!(" Mode: {:?}", cmd.get_passive_observe_mode()); 1385 1386 self.state.passive_observe_mode = 1387 if cmd.get_passive_observe_mode() == nci::PassiveObserveMode::Disable { 1388 u8::from(nci::PassiveObserveMode::Disable) 1389 } else { 1390 u8::from(nci::TechnologyMask::AllOn) 1391 }; 1392 self.state.last_observe_mode_state = None; 1393 self.state.exit_frame_start_time = None; 1394 self.send_control(nci::AndroidPassiveObserveModeResponseBuilder { 1395 status: nci::Status::Ok, 1396 }) 1397 .await?; 1398 Ok(()) 1399 } 1400 android_set_passive_observer_tech( &mut self, cmd: nci::AndroidSetPassiveObserverTechCommand, ) -> Result<()>1401 async fn android_set_passive_observer_tech( 1402 &mut self, 1403 cmd: nci::AndroidSetPassiveObserverTechCommand, 1404 ) -> Result<()> { 1405 info!("[{}] ANDROID_SET_PASSIVE_OBSERVER_TECH_CMD", self.id); 1406 info!(" Mask: {:#b}", cmd.get_tech_mask()); 1407 1408 self.state.passive_observe_mode = cmd.get_tech_mask(); 1409 self.state.last_observe_mode_state = None; 1410 self.state.exit_frame_start_time = None; 1411 1412 self.send_control(nci::AndroidPassiveObserveModeResponseBuilder { 1413 status: nci::Status::Ok, 1414 }) 1415 .await?; 1416 Ok(()) 1417 } 1418 android_query_passive_observe_mode( &mut self, _cmd: nci::AndroidQueryPassiveObserveModeCommand, ) -> Result<()>1419 async fn android_query_passive_observe_mode( 1420 &mut self, 1421 _cmd: nci::AndroidQueryPassiveObserveModeCommand, 1422 ) -> Result<()> { 1423 info!("[{}] ANDROID_QUERY_PASSIVE_OBSERVE_MODE_CMD", self.id); 1424 info!(" Observe mode state: {:#b}", self.state.passive_observe_mode); 1425 1426 self.send_control(nci::AndroidQueryPassiveObserveModeResponseBuilder { 1427 status: nci::Status::Ok, 1428 passive_observe_mode: self.state.passive_observe_mode, 1429 }) 1430 .await?; 1431 Ok(()) 1432 } 1433 android_set_passive_observer_exit_frames( &mut self, cmd: nci::AndroidSetPassiveObserverExitFrameCommand, ) -> Result<()>1434 async fn android_set_passive_observer_exit_frames( 1435 &mut self, 1436 cmd: nci::AndroidSetPassiveObserverExitFrameCommand, 1437 ) -> Result<()> { 1438 info!("[{}] ANDROID_SET_PASSIVE_OBSERVER_EXIT_FRAMES_CMD", self.id); 1439 1440 if self.state.rf_state == RfState::Idle || self.state.rf_state == RfState::Discovery { 1441 self.state.exit_frames.clear(); 1442 self.state.exit_frame_timeout = 1443 Duration::from_millis(u16::from_le(cmd.get_timeout()) as u64); 1444 let exit_frame_count = cmd.get_exit_frames().len(); 1445 info!("number of exit frames {:?}", exit_frame_count); 1446 let incoming_frames = cmd.get_exit_frames(); 1447 for frame in incoming_frames.iter() { 1448 let data_length = frame.field_value[1..].len() / 2; 1449 let power_states = frame.field_value[0]; 1450 let mut data: Vec<u8> = vec![]; 1451 data.clone_from(&frame.field_value[1..1 + data_length].to_vec()); 1452 let mut mask: Vec<u8> = vec![]; 1453 mask.clone_from(&frame.field_value[1 + data_length..].to_vec()); 1454 1455 self.state.exit_frames.push(RfExitFrame { 1456 power_states, 1457 data, 1458 mask, 1459 rf_technology: rf::Technology::from_u8( 1460 frame.qualifier_type & EXIT_FRAME_QUALIFIER_TECHNOLOGY_MASK, 1461 ), 1462 is_prefix_matching_allowed: frame.qualifier_type 1463 & EXIT_FRAME_QUALIFIER_PREFIX_MATCHING_MASK 1464 != 0, 1465 }); 1466 info!("Added exit frame {:?}", self.state.exit_frames.last().unwrap()) 1467 } 1468 1469 self.send_control(nci::AndroidSetPassiveObserverExitFrameResponseBuilder { 1470 status: nci::Status::Ok, 1471 }) 1472 .await?; 1473 return Ok(()); 1474 } 1475 self.send_control(nci::AndroidSetPassiveObserverExitFrameResponseBuilder { 1476 status: nci::Status::SemanticError, 1477 }) 1478 .await?; 1479 Ok(()) 1480 } 1481 receive_command(&mut self, packet: nci::ControlPacket) -> Result<()>1482 async fn receive_command(&mut self, packet: nci::ControlPacket) -> Result<()> { 1483 use nci::AndroidPacketChild::*; 1484 use nci::ControlPacketChild::*; 1485 use nci::CorePacketChild::*; 1486 use nci::NfceePacketChild::*; 1487 use nci::ProprietaryPacketChild::*; 1488 use nci::RfPacketChild::*; 1489 1490 match packet.specialize() { 1491 CorePacket(packet) => match packet.specialize() { 1492 CoreResetCommand(cmd) => self.core_reset(cmd).await, 1493 CoreInitCommand(cmd) => self.core_init(cmd).await, 1494 CoreSetConfigCommand(cmd) => self.core_set_config(cmd).await, 1495 CoreGetConfigCommand(cmd) => self.core_get_config(cmd).await, 1496 CoreConnCreateCommand(cmd) => self.core_conn_create(cmd).await, 1497 CoreConnCloseCommand(cmd) => self.core_conn_close(cmd).await, 1498 CoreSetPowerSubStateCommand(cmd) => self.core_set_power_sub_state(cmd).await, 1499 _ => unimplemented!("unsupported core oid {:?}", packet.get_oid()), 1500 }, 1501 RfPacket(packet) => match packet.specialize() { 1502 RfDiscoverMapCommand(cmd) => self.rf_discover_map(cmd).await, 1503 RfSetListenModeRoutingCommand(cmd) => self.rf_set_listen_mode_routing(cmd).await, 1504 RfGetListenModeRoutingCommand(cmd) => self.rf_get_listen_mode_routing(cmd).await, 1505 RfDiscoverCommand(cmd) => self.rf_discover(cmd).await, 1506 RfDiscoverSelectCommand(cmd) => self.rf_discover_select(cmd).await, 1507 RfDeactivateCommand(cmd) => self.rf_deactivate(cmd).await, 1508 _ => unimplemented!("unsupported rf oid {:?}", packet.get_oid()), 1509 }, 1510 NfceePacket(packet) => match packet.specialize() { 1511 NfceeDiscoverCommand(cmd) => self.nfcee_discover(cmd).await, 1512 NfceeModeSetCommand(cmd) => self.nfcee_mode_set(cmd).await, 1513 _ => unimplemented!("unsupported nfcee oid {:?}", packet.get_oid()), 1514 }, 1515 ProprietaryPacket(packet) => match packet.specialize() { 1516 AndroidPacket(packet) => match packet.specialize() { 1517 AndroidGetCapsCommand(cmd) => self.android_get_caps(cmd).await, 1518 AndroidPassiveObserveModeCommand(cmd) => { 1519 self.android_passive_observe_mode(cmd).await 1520 } 1521 AndroidSetPassiveObserverTechCommand(cmd) => { 1522 self.android_set_passive_observer_tech(cmd).await 1523 } 1524 AndroidQueryPassiveObserveModeCommand(cmd) => { 1525 self.android_query_passive_observe_mode(cmd).await 1526 } 1527 AndroidSetPassiveObserverExitFrameCommand(cmd) => { 1528 self.android_set_passive_observer_exit_frames(cmd).await 1529 } 1530 _ => { 1531 unimplemented!("unsupported android oid {:?}", packet.get_android_sub_oid()) 1532 } 1533 }, 1534 _ => unimplemented!("unsupported proprietary oid {:?}", packet.get_oid()), 1535 }, 1536 _ => unimplemented!("unsupported gid {:?}", packet.get_gid()), 1537 } 1538 } 1539 rf_conn_data(&mut self, packet: nci::DataPacket) -> Result<()>1540 async fn rf_conn_data(&mut self, packet: nci::DataPacket) -> Result<()> { 1541 info!("[{}] received data on RF logical connection", self.id); 1542 1543 // TODO(henrichataing) implement credit based control flow. 1544 match self.state.rf_state { 1545 RfState::PollActive { 1546 id, 1547 rf_technology, 1548 rf_protocol: rf::Protocol::IsoDep, 1549 rf_interface: nci::RfInterfaceType::IsoDep, 1550 .. 1551 } 1552 | RfState::ListenActive { 1553 id, 1554 rf_technology, 1555 rf_protocol: rf::Protocol::IsoDep, 1556 rf_interface: nci::RfInterfaceType::IsoDep, 1557 .. 1558 } => { 1559 self.send_rf(rf::DataBuilder { 1560 receiver: id, 1561 sender: self.id, 1562 bitrate: rf::BitRate::BitRate106KbitS, 1563 power_level: 255, 1564 protocol: rf::Protocol::IsoDep, 1565 technology: rf_technology, 1566 data: packet.get_payload().into(), 1567 }) 1568 .await?; 1569 // Resplenish the credit count for the RF Connection. 1570 self.send_control( 1571 nci::CoreConnCreditsNotificationBuilder { 1572 connections: vec![nci::ConnectionCredits { 1573 conn_id: nci::ConnId::StaticRf, 1574 credits: 1, 1575 }], 1576 } 1577 .build(), 1578 ) 1579 .await 1580 } 1581 RfState::PollActive { 1582 rf_protocol: rf::Protocol::IsoDep, 1583 rf_interface: nci::RfInterfaceType::Frame, 1584 .. 1585 } => { 1586 println!("ISO-DEP frame data {:?}", packet.get_payload()); 1587 match packet.get_payload() { 1588 // RATS command 1589 // TODO(henrichataing) Send back the response received from 1590 // the peer in the RF packet. 1591 [0xe0, _] => { 1592 warn!("[{}] frame RATS command", self.id); 1593 self.send_data(nci::DataPacketBuilder { 1594 mt: nci::MessageType::Data, 1595 conn_id: nci::ConnId::StaticRf, 1596 cr: 0, 1597 payload: Some(bytes::Bytes::copy_from_slice( 1598 &self.state.rf_activation_parameters, 1599 )), 1600 }) 1601 .await? 1602 } 1603 // DESELECT command 1604 // TODO(henrichataing) check if the command should be 1605 // forwarded to the peer, and if it warrants a response 1606 [0xc2] => warn!("[{}] unimplemented frame DESELECT command", self.id), 1607 // SLP_REQ command 1608 // No response is expected for this command. 1609 // TODO(henrichataing) forward a deactivation request to 1610 // the peer and deactivate the local interface. 1611 [0x50, 0x00] => warn!("[{}] unimplemented frame SLP_REQ command", self.id), 1612 _ => unimplemented!(), 1613 }; 1614 // Resplenish the credit count for the RF Connection. 1615 self.send_control( 1616 nci::CoreConnCreditsNotificationBuilder { 1617 connections: vec![nci::ConnectionCredits { 1618 conn_id: nci::ConnId::StaticRf, 1619 credits: 1, 1620 }], 1621 } 1622 .build(), 1623 ) 1624 .await 1625 } 1626 RfState::PollActive { rf_protocol, rf_interface, .. } 1627 | RfState::ListenActive { rf_protocol, rf_interface, .. } => unimplemented!( 1628 "unsupported combination of RF protocol {:?} and interface {:?}", 1629 rf_protocol, 1630 rf_interface 1631 ), 1632 _ => { 1633 warn!( 1634 "[{}] ignored RF data packet while not in active listen or poll mode", 1635 self.id 1636 ); 1637 Ok(()) 1638 } 1639 } 1640 } 1641 hci_conn_data(&mut self, _packet: nci::DataPacket) -> Result<()>1642 async fn hci_conn_data(&mut self, _packet: nci::DataPacket) -> Result<()> { 1643 info!("[{}] received data on HCI logical connection", self.id); 1644 Ok(()) 1645 } 1646 dynamic_conn_data(&mut self, conn_id: u8, packet: nci::DataPacket) -> Result<()>1647 async fn dynamic_conn_data(&mut self, conn_id: u8, packet: nci::DataPacket) -> Result<()> { 1648 info!("[{}] received data on dynamic logical connection", self.id); 1649 let response = packet.get_payload(); 1650 1651 self.send_data(nci::DataPacketBuilder { 1652 mt: nci::MessageType::Data, 1653 conn_id: nci::ConnId::from_dynamic(conn_id), 1654 cr: 0, 1655 payload: Some(bytes::Bytes::copy_from_slice(response)), 1656 }) 1657 .await?; 1658 1659 // Resplenish the credit count for the HCI Connection. 1660 self.send_control( 1661 nci::CoreConnCreditsNotificationBuilder { 1662 connections: vec![nci::ConnectionCredits { 1663 conn_id: nci::ConnId::from_dynamic(conn_id), 1664 credits: 1, 1665 }], 1666 } 1667 .build(), 1668 ) 1669 .await 1670 } 1671 receive_data(&mut self, packet: nci::DataPacket) -> Result<()>1672 async fn receive_data(&mut self, packet: nci::DataPacket) -> Result<()> { 1673 info!("[{}] receive_data({})", self.id, u8::from(packet.get_conn_id())); 1674 1675 match packet.get_conn_id() { 1676 nci::ConnId::StaticRf => self.rf_conn_data(packet).await, 1677 nci::ConnId::StaticHci => self.hci_conn_data(packet).await, 1678 nci::ConnId::Dynamic(id) => self.dynamic_conn_data(*id, packet).await, 1679 } 1680 } 1681 field_info(&mut self, field_status: rf::FieldStatus, power_level: u8) -> Result<()>1682 async fn field_info(&mut self, field_status: rf::FieldStatus, power_level: u8) -> Result<()> { 1683 if self.state.remote_field_status != field_status { 1684 if self.state.config_parameters.rf_field_info != 0 { 1685 self.send_control(nci::RfFieldInfoNotificationBuilder { 1686 rf_field_status: match field_status { 1687 rf::FieldStatus::FieldOn => nci::RfFieldStatus::FieldDetected, 1688 rf::FieldStatus::FieldOff => nci::RfFieldStatus::NoFieldDetected, 1689 }, 1690 }) 1691 .await?; 1692 } 1693 self.send_control(nci::AndroidPollingLoopNotificationBuilder { 1694 polling_frames: vec![nci::PollingFrame { 1695 frame_type: nci::PollingFrameType::RemoteField, 1696 flags: nci::PollingFrameFlags { format: nci::PollingFrameFormat::Short }, 1697 timestamp: (self.state.start_time.elapsed().as_micros() as u32).to_be_bytes(), 1698 gain: power_level, 1699 payload: vec![field_status.into()], 1700 }], 1701 }) 1702 .await?; 1703 self.state.remote_field_status = field_status; 1704 } 1705 Ok(()) 1706 } 1707 poll_command(&mut self, cmd: rf::PollCommand) -> Result<()>1708 async fn poll_command(&mut self, cmd: rf::PollCommand) -> Result<()> { 1709 trace!("[{}] poll_command()", self.id); 1710 1711 if self.state.rf_state != RfState::Discovery { 1712 return Ok(()); 1713 } 1714 let technology = cmd.get_technology(); 1715 1716 // Android proprietary extension for polling frame notifications. 1717 // The NFCC should send the NCI_ANDROID_POLLING_FRAME_NTF to the Host 1718 // after each polling loop frame 1719 // This notification is independent of whether Passive Observe Mode is 1720 // active or not. When Passive Observe Mode is active, the NFCC 1721 // should always send this notification before proceeding with the 1722 // transaction. 1723 1724 let data = cmd.get_payload(); 1725 let format = cmd.get_format(); 1726 1727 let (crc_valid, data) = match technology { 1728 // If frame longer than 2 bytes has valid CRC 1729 // cut it (2 last bytes) out of result 1730 rf::Technology::NfcA | rf::Technology::NfcB 1731 if data.len() > 2 1732 && format == rf::PollingFrameFormat::Long 1733 && crc::verify_crc(technology, data).is_ok() => 1734 { 1735 (true, data[0..data.len() - 2].to_vec()) 1736 } 1737 // If length of data is less than 2 bytes, 1738 // or the last byte does not contain 8 bits, there can be no CRC 1739 // Frames without or with invalid CRC are returned in full 1740 _ => (false, data.to_vec()), 1741 }; 1742 1743 if self.has_exit_frame(&data, technology) { 1744 self.state.last_observe_mode_state = Some(self.state.passive_observe_mode); 1745 self.state.passive_observe_mode = nci::PassiveObserveMode::Disable.into(); 1746 self.state.exit_frame_start_time = Some(Instant::now()); 1747 1748 self.send_control(nci::PassiveObserverSuspendedNotificationBuilder { 1749 exit_frame_type: match technology { 1750 rf::Technology::NfcA => 0x00, 1751 rf::Technology::NfcB => 0x01, 1752 _ => panic!(), 1753 }, 1754 payload: Some(data.clone().into()), 1755 }) 1756 .await?; 1757 } 1758 1759 self.send_control(nci::AndroidPollingLoopNotificationBuilder { 1760 polling_frames: vec![nci::PollingFrame { 1761 frame_type: match technology { 1762 rf::Technology::NfcA => { 1763 // WUPA/REQA 1764 // Musn't have CRC 1765 if !crc_valid 1766 // have short format (7 bits in last byte) 1767 && format == rf::PollingFrameFormat::Short 1768 // 1 byte long in total 1769 && data.len() == 1 1770 // start with 0x52 (WUPA) or 0x26 (REQA) 1771 && (data[0] == 0x52 || data[0] == 0x26) 1772 { 1773 nci::PollingFrameType::Reqa 1774 } else { 1775 // Other are considered as polling loop annotations 1776 nci::PollingFrameType::Unknown 1777 } 1778 } 1779 rf::Technology::NfcB => { 1780 // REQB/WUPB 1781 // Must have valid CRC 1782 if crc_valid 1783 // have long format (8 bits in last byte) 1784 && format == rf::PollingFrameFormat::Long 1785 // 3 bytes long (APf, AFI and PARAM) 1786 && data.len() == 3 1787 // start with 0x05 (APf) 1788 && data[0] == 0x05 1789 { 1790 nci::PollingFrameType::Reqb 1791 } else { 1792 // Other are considered as polling loop annotations 1793 nci::PollingFrameType::Unknown 1794 } 1795 } 1796 // Type F frames cannot serve as polling loop annotations 1797 rf::Technology::NfcF => nci::PollingFrameType::Reqf, 1798 // Type V frames cannot serve as polling loop annotations 1799 rf::Technology::NfcV => nci::PollingFrameType::Reqv, 1800 rf::Technology::Raw => nci::PollingFrameType::Unknown, 1801 }, 1802 // NCI_ANDROID_POLLING_FRAME_NTF Flags 1803 // b0: 0 - short frame; 1 - long frame 1804 flags: nci::PollingFrameFlags { 1805 format: match format { 1806 rf::PollingFrameFormat::Long => nci::PollingFrameFormat::Long, 1807 rf::PollingFrameFormat::Short => nci::PollingFrameFormat::Short, 1808 }, 1809 }, 1810 timestamp: (self.state.start_time.elapsed().as_micros() as u32).to_be_bytes(), 1811 gain: cmd.get_power_level(), 1812 payload: data, 1813 }], 1814 }) 1815 .await?; 1816 1817 // When the Passive Observe Mode is active, the NFCC shall not respond 1818 // to any poll requests during the polling loop in Listen Mode, until 1819 // explicitly authorized by the Host. 1820 let mask: u8 = match technology { 1821 rf::Technology::NfcA => nci::TechnologyMask::NfcA.into(), 1822 rf::Technology::NfcB => nci::TechnologyMask::NfcB.into(), 1823 rf::Technology::NfcF => nci::TechnologyMask::NfcF.into(), 1824 rf::Technology::NfcV => nci::TechnologyMask::NfcV.into(), 1825 _ => 0, 1826 }; 1827 if self.state.passive_observe_mode & mask != 0 { 1828 return Ok(()); 1829 } 1830 1831 if self.state.discover_configuration.iter().any(|config| { 1832 matches!( 1833 (config.technology_and_mode, technology), 1834 (nci::RfTechnologyAndMode::NfcAPassiveListenMode, rf::Technology::NfcA) 1835 | (nci::RfTechnologyAndMode::NfcBPassiveListenMode, rf::Technology::NfcB) 1836 | (nci::RfTechnologyAndMode::NfcFPassiveListenMode, rf::Technology::NfcF) 1837 ) 1838 }) { 1839 match technology { 1840 rf::Technology::NfcA => { 1841 self.send_rf(rf::NfcAPollResponseBuilder { 1842 protocol: rf::Protocol::Undetermined, 1843 receiver: cmd.get_sender(), 1844 sender: self.id, 1845 bitrate: rf::BitRate::BitRate106KbitS, 1846 power_level: 255, 1847 nfcid1: self.state.nfcid1(), 1848 int_protocol: self.state.config_parameters.la_sel_info >> 5, 1849 bit_frame_sdd: self.state.config_parameters.la_bit_frame_sdd, 1850 }) 1851 .await? 1852 } 1853 // TODO(b/346715736) implement support for NFC-B technology 1854 rf::Technology::NfcB => (), 1855 rf::Technology::NfcF => (), 1856 _ => (), 1857 } 1858 } 1859 1860 Ok(()) 1861 } 1862 has_exit_frame(&mut self, polling_frame_data: &[u8], rf_technology: rf::Technology) -> bool1863 fn has_exit_frame(&mut self, polling_frame_data: &[u8], rf_technology: rf::Technology) -> bool { 1864 'frame_loop: for exit_frame in self.state.exit_frames.iter() { 1865 if rf_technology != exit_frame.rf_technology { 1866 continue; 1867 } 1868 1869 let exit_frame_len = exit_frame.data.len(); 1870 // This checks if the data in the exit frame matches the polling frame. 1871 for n in 0..exit_frame_len { 1872 if n >= polling_frame_data.len() 1873 || exit_frame.data[n] != (polling_frame_data[n] & exit_frame.mask[n]) 1874 { 1875 continue 'frame_loop; 1876 } 1877 } 1878 // TODO(johnrjohn) Check if power state matches. 1879 1880 // If the lengths do not match, or if prefix matching is not allowed, it means there 1881 // is unmatched data in the polling frame and this isn't a match. 1882 if exit_frame.data.len() == polling_frame_data.len() 1883 || exit_frame.is_prefix_matching_allowed 1884 { 1885 info!( 1886 "Exit frame matched! PollingFrame: {:?}, ExitFrame {:?}", 1887 polling_frame_data, exit_frame 1888 ); 1889 return true; 1890 } 1891 } 1892 false 1893 } 1894 nfca_poll_response(&mut self, cmd: rf::NfcAPollResponse) -> Result<()>1895 async fn nfca_poll_response(&mut self, cmd: rf::NfcAPollResponse) -> Result<()> { 1896 info!("[{}] nfca_poll_response()", self.id); 1897 1898 if self.state.rf_state != RfState::Discovery { 1899 return Ok(()); 1900 } 1901 1902 let int_protocol = cmd.get_int_protocol(); 1903 let rf_protocols = match int_protocol { 1904 0b00 => [rf::Protocol::T2t].iter(), 1905 0b01 => [rf::Protocol::IsoDep].iter(), 1906 0b10 => [rf::Protocol::NfcDep].iter(), 1907 0b11 => [rf::Protocol::NfcDep, rf::Protocol::IsoDep].iter(), 1908 _ => return Ok(()), 1909 }; 1910 let sens_res = match cmd.get_nfcid1().len() { 1911 4 => 0x00, 1912 7 => 0x40, 1913 10 => 0x80, 1914 _ => panic!(), 1915 } | cmd.get_bit_frame_sdd() as u16; 1916 let sel_res = int_protocol << 5; 1917 1918 for rf_protocol in rf_protocols { 1919 self.state.add_poll_response(RfPollResponse { 1920 id: cmd.get_sender(), 1921 rf_protocol: *rf_protocol, 1922 rf_technology: rf::Technology::NfcA, 1923 rf_technology_specific_parameters: 1924 nci::NfcAPollModeTechnologySpecificParametersBuilder { 1925 sens_res, 1926 nfcid1: cmd.get_nfcid1().clone(), 1927 sel_res, 1928 } 1929 .build() 1930 .encode_to_vec()?, 1931 }) 1932 } 1933 1934 Ok(()) 1935 } 1936 t4at_select_command(&mut self, cmd: rf::T4ATSelectCommand) -> Result<()>1937 async fn t4at_select_command(&mut self, cmd: rf::T4ATSelectCommand) -> Result<()> { 1938 info!("[{}] t4at_select_command()", self.id); 1939 1940 match self.state.rf_state { 1941 RfState::Discovery => (), 1942 RfState::ListenSleep { id } if id == cmd.get_sender() => (), 1943 _ => return Ok(()), 1944 }; 1945 1946 // TODO(henrichataing): validate that the protocol and technology are 1947 // valid for the current discovery settings. 1948 1949 // TODO(henrichataing): use listen mode routing table to decide which 1950 // interface should be used for the activating device. 1951 1952 self.state.rf_state = RfState::ListenActive { 1953 id: cmd.get_sender(), 1954 rf_technology: rf::Technology::NfcA, 1955 rf_protocol: rf::Protocol::IsoDep, 1956 rf_interface: nci::RfInterfaceType::IsoDep, 1957 }; 1958 1959 // [DIGITAL] 14.6.2 RATS Response (Answer To Select) 1960 // Construct the response from the values passed in the configuration 1961 // parameters. The TL byte is excluded from the response. 1962 let mut rats_response = vec![ 1963 0x78, // TC(1), TB(1), TA(1) transmitted, FSCI=8 1964 0x80, // TA(1) 1965 self.state.config_parameters.li_a_rats_tb1, 1966 self.state.config_parameters.li_a_rats_tc1, 1967 ]; 1968 1969 rats_response.extend_from_slice(&self.state.config_parameters.li_a_hist_by); 1970 1971 self.send_rf(rf::T4ATSelectResponseBuilder { 1972 receiver: cmd.get_sender(), 1973 sender: self.id, 1974 bitrate: rf::BitRate::BitRate106KbitS, 1975 power_level: 255, 1976 rats_response, 1977 }) 1978 .await?; 1979 1980 info!("[{}] RF_INTF_ACTIVATED_NTF", self.id); 1981 info!(" DiscoveryID: {:?}", nci::RfDiscoveryId::from_index(0)); 1982 info!(" Interface: ISO-DEP"); 1983 info!(" Protocol: ISO-DEP"); 1984 info!(" ActivationTechnology: NFC_A_PASSIVE_LISTEN"); 1985 info!(" RATS: {}", cmd.get_param()); 1986 1987 self.send_control(nci::RfIntfActivatedNotificationBuilder { 1988 rf_discovery_id: nci::RfDiscoveryId::from_index(0), 1989 rf_interface: nci::RfInterfaceType::IsoDep, 1990 rf_protocol: nci::RfProtocolType::IsoDep, 1991 activation_rf_technology_and_mode: nci::RfTechnologyAndMode::NfcAPassiveListenMode, 1992 max_data_packet_payload_size: MAX_DATA_PACKET_PAYLOAD_SIZE, 1993 initial_number_of_credits: 1, 1994 // No parameters are currently defined for NFC-A Listen Mode. 1995 rf_technology_specific_parameters: vec![], 1996 data_exchange_rf_technology_and_mode: nci::RfTechnologyAndMode::NfcAPassiveListenMode, 1997 data_exchange_transmit_bit_rate: nci::BitRate::BitRate106KbitS, 1998 data_exchange_receive_bit_rate: nci::BitRate::BitRate106KbitS, 1999 activation_parameters: nci::NfcAIsoDepListenModeActivationParametersBuilder { 2000 param: cmd.get_param(), 2001 } 2002 .build() 2003 .encode_to_vec()?, 2004 }) 2005 .await?; 2006 2007 Ok(()) 2008 } 2009 t4at_select_response(&mut self, cmd: rf::T4ATSelectResponse) -> Result<()>2010 async fn t4at_select_response(&mut self, cmd: rf::T4ATSelectResponse) -> Result<()> { 2011 info!("[{}] t4at_select_response()", self.id); 2012 2013 let (id, rf_discovery_id, rf_interface, rf_protocol) = match self.state.rf_state { 2014 RfState::WaitForSelectResponse { 2015 id, 2016 rf_discovery_id, 2017 rf_interface, 2018 rf_protocol, 2019 .. 2020 } => (id, rf_discovery_id, rf_interface, rf_protocol), 2021 _ => return Ok(()), 2022 }; 2023 2024 if cmd.get_sender() != id { 2025 return Ok(()); 2026 } 2027 2028 self.state.rf_state = RfState::PollActive { 2029 id, 2030 rf_protocol: self.state.rf_poll_responses[rf_discovery_id].rf_protocol, 2031 rf_technology: self.state.rf_poll_responses[rf_discovery_id].rf_technology, 2032 rf_interface, 2033 }; 2034 2035 // Save the activation parameters for the RF frame interface 2036 // implementation. Note: TL is not included in the RATS response 2037 // and needs to be added manually to the activation parameters. 2038 self.state.rf_activation_parameters = vec![cmd.get_rats_response().len() as u8]; 2039 self.state.rf_activation_parameters.extend_from_slice(cmd.get_rats_response()); 2040 2041 info!("[{}] RF_INTF_ACTIVATED_NTF", self.id); 2042 info!(" DiscoveryID: {:?}", nci::RfDiscoveryId::from_index(rf_discovery_id)); 2043 info!(" Interface: {:?}", rf_interface); 2044 info!(" Protocol: {:?}", rf_protocol); 2045 info!(" ActivationTechnology: NFC_A_PASSIVE_POLL"); 2046 info!(" RATS: {:?}", cmd.get_rats_response()); 2047 2048 self.send_control(nci::RfIntfActivatedNotificationBuilder { 2049 rf_discovery_id: nci::RfDiscoveryId::from_index(rf_discovery_id), 2050 rf_interface, 2051 rf_protocol: rf_protocol.into(), 2052 activation_rf_technology_and_mode: nci::RfTechnologyAndMode::NfcAPassivePollMode, 2053 max_data_packet_payload_size: MAX_DATA_PACKET_PAYLOAD_SIZE, 2054 initial_number_of_credits: 1, 2055 rf_technology_specific_parameters: self.state.rf_poll_responses[rf_discovery_id] 2056 .rf_technology_specific_parameters 2057 .clone(), 2058 data_exchange_rf_technology_and_mode: nci::RfTechnologyAndMode::NfcAPassivePollMode, 2059 data_exchange_transmit_bit_rate: nci::BitRate::BitRate106KbitS, 2060 data_exchange_receive_bit_rate: nci::BitRate::BitRate106KbitS, 2061 // TODO(hchataing) the activation parameters should be empty 2062 // when the RF frame interface is used, since the protocol 2063 // activation is managed by the DH. 2064 activation_parameters: nci::NfcAIsoDepPollModeActivationParametersBuilder { 2065 rats_response: cmd.get_rats_response().clone(), 2066 } 2067 .build() 2068 .encode_to_vec()?, 2069 }) 2070 .await?; 2071 2072 Ok(()) 2073 } 2074 data_packet(&mut self, data: rf::Data) -> Result<()>2075 async fn data_packet(&mut self, data: rf::Data) -> Result<()> { 2076 info!("[{}] data_packet()", self.id); 2077 2078 match (self.state.rf_state, data.get_protocol()) { 2079 ( 2080 RfState::PollActive { 2081 id, rf_technology, rf_protocol: rf::Protocol::IsoDep, .. 2082 }, 2083 rf::Protocol::IsoDep, 2084 ) 2085 | ( 2086 RfState::ListenActive { 2087 id, rf_technology, rf_protocol: rf::Protocol::IsoDep, .. 2088 }, 2089 rf::Protocol::IsoDep, 2090 ) if data.get_sender() == id && data.get_technology() == rf_technology => { 2091 self.send_data(nci::DataPacketBuilder { 2092 mt: nci::MessageType::Data, 2093 conn_id: nci::ConnId::StaticRf, 2094 cr: 1, // TODO(henrichataing): credit based control flow 2095 payload: Some(bytes::Bytes::copy_from_slice(data.get_data())), 2096 }) 2097 .await 2098 } 2099 (RfState::PollActive { id, .. }, _) | (RfState::ListenActive { id, .. }, _) 2100 if id != data.get_sender() => 2101 { 2102 warn!("[{}] ignored RF data packet sent from an un-selected device", self.id); 2103 Ok(()) 2104 } 2105 (RfState::PollActive { .. }, _) | (RfState::ListenActive { .. }, _) => { 2106 unimplemented!("unsupported combination of technology and protocol") 2107 } 2108 (_, _) => { 2109 warn!("[{}] ignored RF data packet received in inactive state", self.id); 2110 Ok(()) 2111 } 2112 } 2113 } 2114 deactivate_notification(&mut self, cmd: rf::DeactivateNotification) -> Result<()>2115 async fn deactivate_notification(&mut self, cmd: rf::DeactivateNotification) -> Result<()> { 2116 info!("[{}] deactivate_notification()", self.id); 2117 2118 use rf::DeactivateType::*; 2119 2120 let mut next_state = match (self.state.rf_state, cmd.get_type_()) { 2121 (RfState::PollActive { id, .. }, IdleMode) if id == cmd.get_sender() => RfState::Idle, 2122 (RfState::PollActive { id, .. }, SleepMode | SleepAfMode) if id == cmd.get_sender() => { 2123 RfState::WaitForHostSelect 2124 } 2125 (RfState::PollActive { id, .. }, Discovery) if id == cmd.get_sender() => { 2126 RfState::Discovery 2127 } 2128 (RfState::ListenSleep { id, .. }, IdleMode) if id == cmd.get_sender() => RfState::Idle, 2129 (RfState::ListenSleep { id, .. }, Discovery) if id == cmd.get_sender() => { 2130 RfState::Discovery 2131 } 2132 (RfState::ListenActive { id, .. }, IdleMode) if id == cmd.get_sender() => RfState::Idle, 2133 (RfState::ListenActive { id, .. }, SleepMode | SleepAfMode) 2134 if id == cmd.get_sender() => 2135 { 2136 RfState::ListenSleep { id } 2137 } 2138 (RfState::ListenActive { id, .. }, Discovery) if id == cmd.get_sender() => { 2139 RfState::Discovery 2140 } 2141 (_, _) => self.state.rf_state, 2142 }; 2143 2144 // Update the state now to prevent interface activation from 2145 // completing if a remote device is being selected. 2146 (next_state, self.state.rf_state) = (self.state.rf_state, next_state); 2147 2148 // Deactivate the active RF interface if applicable. 2149 if next_state != self.state.rf_state { 2150 self.field_info(rf::FieldStatus::FieldOff, 255).await?; 2151 self.send_control(nci::RfDeactivateNotificationBuilder { 2152 deactivation_type: cmd.get_type_().into(), 2153 deactivation_reason: cmd.get_reason().into(), 2154 }) 2155 .await? 2156 } 2157 2158 Ok(()) 2159 } 2160 receive_rf(&mut self, packet: rf::RfPacket) -> Result<()>2161 async fn receive_rf(&mut self, packet: rf::RfPacket) -> Result<()> { 2162 use rf::RfPacketChild::*; 2163 2164 match packet.specialize() { 2165 PollCommand(cmd) => self.poll_command(cmd).await, 2166 FieldInfo(cmd) => self.field_info(cmd.get_field_status(), cmd.get_power_level()).await, 2167 NfcAPollResponse(cmd) => self.nfca_poll_response(cmd).await, 2168 // [NCI] 5.2.2 State RFST_DISCOVERY 2169 // If discovered by a Remote NFC Endpoint in Listen mode, once the 2170 // Remote NFC Endpoint has established any underlying protocol(s) needed 2171 // by the configured RF Interface, the NFCC SHALL send 2172 // RF_INTF_ACTIVATED_NTF (Listen Mode) to the DH and the state is 2173 // changed to RFST_LISTEN_ACTIVE. 2174 T4ATSelectCommand(cmd) => self.t4at_select_command(cmd).await, 2175 T4ATSelectResponse(cmd) => self.t4at_select_response(cmd).await, 2176 SelectCommand(_) => unimplemented!(), 2177 DeactivateNotification(cmd) => self.deactivate_notification(cmd).await, 2178 Data(cmd) => self.data_packet(cmd).await, 2179 _ => unimplemented!(), 2180 } 2181 } 2182 2183 /// Activity for activating an RF interface for a discovered device. 2184 /// 2185 /// The method send a notification when the interface is successfully 2186 /// activated, or when the device activation fails. 2187 /// 2188 /// * `rf_discovery_id` - index of the discovered device 2189 /// * `rf_interface` - interface to activate 2190 /// 2191 /// The RF state is changed to WaitForSelectResponse when 2192 /// the select command is successfully sent. activate_poll_interface( &mut self, rf_discovery_id: usize, rf_protocol: nci::RfProtocolType, rf_interface: nci::RfInterfaceType, ) -> Result<()>2193 async fn activate_poll_interface( 2194 &mut self, 2195 rf_discovery_id: usize, 2196 rf_protocol: nci::RfProtocolType, 2197 rf_interface: nci::RfInterfaceType, 2198 ) -> Result<()> { 2199 info!("[{}] activate_poll_interface({:?})", self.id, rf_interface); 2200 2201 let rf_technology = self.state.rf_poll_responses[rf_discovery_id].rf_technology; 2202 match (rf_protocol, rf_technology) { 2203 (nci::RfProtocolType::T2t, rf::Technology::NfcA) => { 2204 self.send_rf(rf::SelectCommandBuilder { 2205 sender: self.id, 2206 receiver: self.state.rf_poll_responses[rf_discovery_id].id, 2207 technology: rf::Technology::NfcA, 2208 bitrate: rf::BitRate::BitRate106KbitS, 2209 power_level: 255, 2210 protocol: rf::Protocol::T2t, 2211 }) 2212 .await? 2213 } 2214 (nci::RfProtocolType::IsoDep, rf::Technology::NfcA) => { 2215 self.send_rf(rf::T4ATSelectCommandBuilder { 2216 sender: self.id, 2217 receiver: self.state.rf_poll_responses[rf_discovery_id].id, 2218 bitrate: rf::BitRate::BitRate106KbitS, 2219 power_level: 255, 2220 // [DIGITAL] 14.6.1.6 The FSD supported by the 2221 // Reader/Writer SHALL be FSD T4AT,MIN 2222 // (set to 256 in Appendix B.6). 2223 param: 0x80, 2224 }) 2225 .await? 2226 } 2227 (nci::RfProtocolType::NfcDep, rf::Technology::NfcA) => { 2228 self.send_rf(rf::NfcDepSelectCommandBuilder { 2229 sender: self.id, 2230 receiver: self.state.rf_poll_responses[rf_discovery_id].id, 2231 bitrate: rf::BitRate::BitRate106KbitS, 2232 power_level: 255, 2233 technology: rf::Technology::NfcA, 2234 lr: 0, 2235 }) 2236 .await? 2237 } 2238 _ => todo!(), 2239 } 2240 2241 self.state.rf_state = RfState::WaitForSelectResponse { 2242 id: self.state.rf_poll_responses[rf_discovery_id].id, 2243 rf_discovery_id, 2244 rf_interface, 2245 rf_protocol: rf_protocol.into(), 2246 rf_technology, 2247 }; 2248 Ok(()) 2249 } 2250 run_until<O>(&mut self, future: impl Future<Output = O>) -> Result<O>2251 async fn run_until<O>(&mut self, future: impl Future<Output = O>) -> Result<O> { 2252 let mut future = pin!(future); 2253 loop { 2254 tokio::select! { 2255 packet = self.nci_stream.next() => { 2256 let packet = packet.ok_or(anyhow::anyhow!("nci channel closed"))??; 2257 let header = nci::PacketHeader::parse(&packet[0..3])?; 2258 match header.get_mt() { 2259 nci::MessageType::Data => { 2260 self.receive_data(nci::DataPacket::parse(&packet)?).await? 2261 } 2262 nci::MessageType::Command => { 2263 self.receive_command(nci::ControlPacket::parse(&packet)?).await? 2264 } 2265 mt => { 2266 return Err(anyhow::anyhow!( 2267 "unexpected message type {:?} in received NCI packet", 2268 mt 2269 )) 2270 } 2271 } 2272 }, 2273 rf_packet = self.rf_rx.recv() => { 2274 self.receive_rf( 2275 rf_packet.ok_or(anyhow::anyhow!("rf_rx channel closed"))?, 2276 ) 2277 .await? 2278 }, 2279 output = &mut future => break Ok(output) 2280 } 2281 } 2282 } 2283 2284 /// Timer handler method. This function is invoked at regular interval 2285 /// on the NFCC instance and is used to drive internal timers. tick(&mut self) -> Result<()>2286 async fn tick(&mut self) -> Result<()> { 2287 if self.state.rf_state != RfState::Discovery { 2288 return Ok(()); 2289 } 2290 2291 if self.state.exit_frame_start_time.is_some() { 2292 let elapsed_ms = self.state.exit_frame_start_time.unwrap().elapsed().as_millis(); 2293 if elapsed_ms > self.state.exit_frame_timeout.as_millis() { 2294 self.state.exit_frame_start_time = None; 2295 self.state.passive_observe_mode = 2296 self.state.last_observe_mode_state.unwrap_or(nci::TechnologyMask::AllOn.into()); 2297 info!("Turning observe mode back on, exit frame timeout has passed."); 2298 self.send_control(nci::PassiveObserverResumedNotificationBuilder {}).await?; 2299 } 2300 } 2301 2302 //info!("[{}] poll", self.id); 2303 2304 // [NCI] 5.2.2 State RFST_DISCOVERY 2305 // 2306 // In this state the NFCC stays in Poll Mode and/or Listen Mode (based 2307 // on the discovery configuration) until at least one Remote NFC 2308 // Endpoint is detected or the RF Discovery Process is stopped by 2309 // the DH. 2310 // 2311 // The following implements the Poll Mode Discovery, Listen Mode 2312 // Discover is implicitly implemented in response to poll and 2313 // select commands. 2314 2315 // RF Discovery is ongoing and no peer device has been discovered 2316 // so far. Send a RF poll command for all enabled technologies. 2317 self.state.rf_poll_responses.clear(); 2318 for configuration in self.state.discover_configuration.iter() { 2319 self.send_rf(rf::PollCommandBuilder { 2320 sender: self.id, 2321 receiver: u16::MAX, 2322 protocol: rf::Protocol::Undetermined, 2323 technology: match configuration.technology_and_mode { 2324 nci::RfTechnologyAndMode::NfcAPassivePollMode => rf::Technology::NfcA, 2325 nci::RfTechnologyAndMode::NfcBPassivePollMode => rf::Technology::NfcB, 2326 nci::RfTechnologyAndMode::NfcFPassivePollMode => rf::Technology::NfcF, 2327 nci::RfTechnologyAndMode::NfcVPassivePollMode => rf::Technology::NfcV, 2328 _ => continue, 2329 }, 2330 format: match configuration.technology_and_mode { 2331 nci::RfTechnologyAndMode::NfcAPassivePollMode => rf::PollingFrameFormat::Short, 2332 _ => rf::PollingFrameFormat::Long, 2333 }, 2334 bitrate: match configuration.technology_and_mode { 2335 nci::RfTechnologyAndMode::NfcFPassivePollMode => rf::BitRate::BitRate212KbitS, 2336 nci::RfTechnologyAndMode::NfcVPassivePollMode => rf::BitRate::BitRate26KbitS, 2337 _ => rf::BitRate::BitRate106KbitS, 2338 }, 2339 power_level: 255, 2340 payload: Some(bytes::Bytes::new()), 2341 }) 2342 .await? 2343 } 2344 2345 // Wait for poll responses to return. 2346 self.run_until(time::sleep(Duration::from_millis(POLL_RESPONSE_TIMEOUT))).await?; 2347 2348 // Check if device was activated in Listen mode during 2349 // the poll interval, or if the discovery got cancelled. 2350 if self.state.rf_state != RfState::Discovery || self.state.rf_poll_responses.is_empty() { 2351 return Ok(()); 2352 } 2353 2354 // While polling, if the NFCC discovers just one Remote NFC Endpoint 2355 // that supports just one protocol, the NFCC SHALL try to automatically 2356 // activate it. The NFCC SHALL first establish any underlying 2357 // protocol(s) with the Remote NFC Endpoint that are needed by the 2358 // configured RF Interface. On completion, the NFCC SHALL activate the 2359 // RF Interface and send RF_INTF_ACTIVATED_NTF (Poll Mode) to the DH. 2360 // At this point, the state is changed to RFST_POLL_ACTIVE. If the 2361 // protocol activation is not successful, the NFCC SHALL send 2362 // CORE_GENERIC_ERROR_NTF to the DH with status 2363 // DISCOVERY_TARGET_ACTIVATION_FAILED and SHALL stay in the 2364 // RFST_DISCOVERY state. 2365 if self.state.rf_poll_responses.len() == 1 { 2366 let rf_protocol = self.state.rf_poll_responses[0].rf_protocol.into(); 2367 let rf_interface = self.state.select_interface(RfMode::Poll, rf_protocol); 2368 return self.activate_poll_interface(0, rf_protocol, rf_interface).await; 2369 } 2370 2371 debug!("[{}] received {} poll response(s)", self.id, self.state.rf_poll_responses.len()); 2372 2373 // While polling, if the NFCC discovers more than one Remote NFC 2374 // Endpoint, or a Remote NFC Endpoint that supports more than one RF 2375 // Protocol, it SHALL start sending RF_DISCOVER_NTF messages to the DH. 2376 // At this point, the state is changed to RFST_W4_ALL_DISCOVERIES. 2377 self.state.rf_state = RfState::WaitForHostSelect; 2378 let last_index = self.state.rf_poll_responses.len() - 1; 2379 for (index, response) in self.state.rf_poll_responses.clone().iter().enumerate() { 2380 self.send_control(nci::RfDiscoverNotificationBuilder { 2381 rf_discovery_id: nci::RfDiscoveryId::from_index(index), 2382 rf_protocol: response.rf_protocol.into(), 2383 rf_technology_and_mode: match response.rf_technology { 2384 rf::Technology::NfcA => nci::RfTechnologyAndMode::NfcAPassivePollMode, 2385 rf::Technology::NfcB => nci::RfTechnologyAndMode::NfcBPassivePollMode, 2386 _ => todo!(), 2387 }, 2388 rf_technology_specific_parameters: response 2389 .rf_technology_specific_parameters 2390 .clone(), 2391 notification_type: if index == last_index { 2392 nci::DiscoverNotificationType::LastNotification 2393 } else { 2394 nci::DiscoverNotificationType::MoreNotifications 2395 }, 2396 }) 2397 .await? 2398 } 2399 2400 Ok(()) 2401 } 2402 2403 /// Main NFCC instance routine. run( id: u16, nci_stream: nci::StreamRefMut<'a>, nci_writer: nci::Writer, rf_rx: mpsc::UnboundedReceiver<rf::RfPacket>, rf_tx: mpsc::UnboundedSender<rf::RfPacket>, ) -> Result<()>2404 pub async fn run( 2405 id: u16, 2406 nci_stream: nci::StreamRefMut<'a>, 2407 nci_writer: nci::Writer, 2408 rf_rx: mpsc::UnboundedReceiver<rf::RfPacket>, 2409 rf_tx: mpsc::UnboundedSender<rf::RfPacket>, 2410 ) -> Result<()> { 2411 // Local controller state. 2412 let mut nfcc = Controller::new(id, nci_stream, nci_writer, rf_rx, rf_tx); 2413 2414 // Timer for tick events. 2415 let mut timer = time::interval(Duration::from_millis(1000)); 2416 2417 loop { 2418 nfcc.run_until(timer.tick()).await?; 2419 nfcc.tick().await?; 2420 } 2421 } 2422 } 2423