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