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.field_info(rf::FieldStatus::FieldOff, 255).await?; 1219 self.send_control(nci::RfDeactivateNotificationBuilder { 1220 deactivation_type: cmd.get_deactivation_type(), 1221 deactivation_reason: nci::DeactivationReason::DhRequest, 1222 }) 1223 .await? 1224 } 1225 _ => (), 1226 } 1227 1228 // Deselect the remote device if applicable. 1229 match next_state { 1230 RfState::PollActive { id, rf_protocol, rf_technology, .. } 1231 | RfState::WaitForSelectResponse { id, rf_protocol, rf_technology, .. } => { 1232 self.send_rf(rf::DeactivateNotificationBuilder { 1233 receiver: id, 1234 protocol: rf_protocol, 1235 technology: rf_technology, 1236 power_level: 255, 1237 sender: self.id, 1238 type_: cmd.get_deactivation_type().into(), 1239 reason: rf::DeactivateReason::EndpointRequest, 1240 }) 1241 .await? 1242 } 1243 _ => (), 1244 } 1245 1246 Ok(()) 1247 } 1248 nfcee_discover(&mut self, _cmd: nci::NfceeDiscoverCommand) -> Result<()>1249 async fn nfcee_discover(&mut self, _cmd: nci::NfceeDiscoverCommand) -> Result<()> { 1250 info!("[{}] NFCEE_DISCOVER_CMD", self.id); 1251 1252 self.send_control(nci::NfceeDiscoverResponseBuilder { 1253 status: nci::Status::Ok, 1254 number_of_nfcees: 1, 1255 }) 1256 .await?; 1257 1258 self.send_control(nci::NfceeDiscoverNotificationBuilder { 1259 nfcee_id: nci::NfceeId::hci_nfcee(0x86), 1260 nfcee_status: nci::NfceeStatus::Disabled, 1261 supported_nfcee_protocols: vec![], 1262 nfcee_information: vec![nci::NfceeInformation { 1263 r#type: nci::NfceeInformationType::HostId, 1264 value: vec![0xc0], 1265 }], 1266 nfcee_supply_power: nci::NfceeSupplyPower::NfccHasNoControl, 1267 }) 1268 .await?; 1269 1270 Ok(()) 1271 } 1272 nfcee_mode_set(&mut self, cmd: nci::NfceeModeSetCommand) -> Result<()>1273 async fn nfcee_mode_set(&mut self, cmd: nci::NfceeModeSetCommand) -> Result<()> { 1274 info!("[{}] NFCEE_MODE_SET_CMD", self.id); 1275 info!(" NFCEE ID: {:?}", cmd.get_nfcee_id()); 1276 info!(" NFCEE Mode: {:?}", cmd.get_nfcee_mode()); 1277 1278 if cmd.get_nfcee_id() != nci::NfceeId::hci_nfcee(0x86) { 1279 warn!("[{}] nfcee_mode_set with invalid nfcee_id", self.id); 1280 self.send_control(nci::NfceeModeSetResponseBuilder { status: nci::Status::Ok }).await?; 1281 return Ok(()); 1282 } 1283 1284 self.state.nfcee_state = match cmd.get_nfcee_mode() { 1285 nci::NfceeMode::Enable => NfceeState::Enabled, 1286 nci::NfceeMode::Disable => NfceeState::Disabled, 1287 }; 1288 1289 self.send_control(nci::NfceeModeSetResponseBuilder { status: nci::Status::Ok }).await?; 1290 1291 self.send_control(nci::NfceeModeSetNotificationBuilder { status: nci::Status::Ok }).await?; 1292 1293 if self.state.nfcee_state == NfceeState::Enabled { 1294 // Android host stack expects this notification to know when the 1295 // NFCEE completes start-up. The list of information entries is 1296 // filled with defaults observed on real phones. 1297 self.send_data(nci::DataPacketBuilder { 1298 mt: nci::MessageType::Data, 1299 conn_id: nci::ConnId::StaticHci, 1300 cr: 0, 1301 payload: Some(bytes::Bytes::copy_from_slice(&[0x81, 0x43, 0xc0, 0x01])), 1302 }) 1303 .await?; 1304 1305 self.send_control(nci::RfNfceeDiscoveryReqNotificationBuilder { 1306 information_entries: vec![ 1307 nci::InformationEntry { 1308 r#type: nci::InformationEntryType::AddDiscoveryRequest, 1309 nfcee_id: nci::NfceeId::hci_nfcee(0x86), 1310 rf_technology_and_mode: nci::RfTechnologyAndMode::NfcFPassiveListenMode, 1311 rf_protocol: nci::RfProtocolType::T3t, 1312 }, 1313 nci::InformationEntry { 1314 r#type: nci::InformationEntryType::AddDiscoveryRequest, 1315 nfcee_id: nci::NfceeId::hci_nfcee(0x86), 1316 rf_technology_and_mode: nci::RfTechnologyAndMode::NfcAPassiveListenMode, 1317 rf_protocol: nci::RfProtocolType::IsoDep, 1318 }, 1319 nci::InformationEntry { 1320 r#type: nci::InformationEntryType::AddDiscoveryRequest, 1321 nfcee_id: nci::NfceeId::hci_nfcee(0x86), 1322 rf_technology_and_mode: nci::RfTechnologyAndMode::NfcBPassiveListenMode, 1323 rf_protocol: nci::RfProtocolType::IsoDep, 1324 }, 1325 ], 1326 }) 1327 .await?; 1328 } 1329 1330 Ok(()) 1331 } 1332 android_get_caps(&mut self, _cmd: nci::AndroidGetCapsCommand) -> Result<()>1333 async fn android_get_caps(&mut self, _cmd: nci::AndroidGetCapsCommand) -> Result<()> { 1334 info!("[{}] ANDROID_GET_CAPS_CMD", self.id); 1335 let cap_tlvs = vec![ 1336 nci::CapTlv { t: nci::CapTlvType::PassiveObserverMode, v: vec![1] }, 1337 nci::CapTlv { t: nci::CapTlvType::PollingFrameNotification, v: vec![1] }, 1338 ]; 1339 self.send_control(nci::AndroidGetCapsResponseBuilder { 1340 status: nci::Status::Ok, 1341 android_version: 0, 1342 tlvs: cap_tlvs, 1343 }) 1344 .await?; 1345 Ok(()) 1346 } 1347 android_passive_observe_mode( &mut self, cmd: nci::AndroidPassiveObserveModeCommand, ) -> Result<()>1348 async fn android_passive_observe_mode( 1349 &mut self, 1350 cmd: nci::AndroidPassiveObserveModeCommand, 1351 ) -> Result<()> { 1352 info!("[{}] ANDROID_PASSIVE_OBSERVE_MODE_CMD", self.id); 1353 info!(" Mode: {:?}", cmd.get_passive_observe_mode()); 1354 1355 self.state.passive_observe_mode = cmd.get_passive_observe_mode(); 1356 self.send_control(nci::AndroidPassiveObserveModeResponseBuilder { 1357 status: nci::Status::Ok, 1358 }) 1359 .await?; 1360 Ok(()) 1361 } 1362 android_query_passive_observe_mode( &mut self, _cmd: nci::AndroidQueryPassiveObserveModeCommand, ) -> Result<()>1363 async fn android_query_passive_observe_mode( 1364 &mut self, 1365 _cmd: nci::AndroidQueryPassiveObserveModeCommand, 1366 ) -> Result<()> { 1367 info!("[{}] ANDROID_QUERY_PASSIVE_OBSERVE_MODE_CMD", self.id); 1368 1369 self.send_control(nci::AndroidQueryPassiveObserveModeResponseBuilder { 1370 status: nci::Status::Ok, 1371 passive_observe_mode: self.state.passive_observe_mode, 1372 }) 1373 .await?; 1374 Ok(()) 1375 } 1376 receive_command(&mut self, packet: nci::ControlPacket) -> Result<()>1377 async fn receive_command(&mut self, packet: nci::ControlPacket) -> Result<()> { 1378 use nci::AndroidPacketChild::*; 1379 use nci::ControlPacketChild::*; 1380 use nci::CorePacketChild::*; 1381 use nci::NfceePacketChild::*; 1382 use nci::ProprietaryPacketChild::*; 1383 use nci::RfPacketChild::*; 1384 1385 match packet.specialize() { 1386 CorePacket(packet) => match packet.specialize() { 1387 CoreResetCommand(cmd) => self.core_reset(cmd).await, 1388 CoreInitCommand(cmd) => self.core_init(cmd).await, 1389 CoreSetConfigCommand(cmd) => self.core_set_config(cmd).await, 1390 CoreGetConfigCommand(cmd) => self.core_get_config(cmd).await, 1391 CoreConnCreateCommand(cmd) => self.core_conn_create(cmd).await, 1392 CoreConnCloseCommand(cmd) => self.core_conn_close(cmd).await, 1393 CoreSetPowerSubStateCommand(cmd) => self.core_set_power_sub_state(cmd).await, 1394 _ => unimplemented!("unsupported core oid {:?}", packet.get_oid()), 1395 }, 1396 RfPacket(packet) => match packet.specialize() { 1397 RfDiscoverMapCommand(cmd) => self.rf_discover_map(cmd).await, 1398 RfSetListenModeRoutingCommand(cmd) => self.rf_set_listen_mode_routing(cmd).await, 1399 RfGetListenModeRoutingCommand(cmd) => self.rf_get_listen_mode_routing(cmd).await, 1400 RfDiscoverCommand(cmd) => self.rf_discover(cmd).await, 1401 RfDiscoverSelectCommand(cmd) => self.rf_discover_select(cmd).await, 1402 RfDeactivateCommand(cmd) => self.rf_deactivate(cmd).await, 1403 _ => unimplemented!("unsupported rf oid {:?}", packet.get_oid()), 1404 }, 1405 NfceePacket(packet) => match packet.specialize() { 1406 NfceeDiscoverCommand(cmd) => self.nfcee_discover(cmd).await, 1407 NfceeModeSetCommand(cmd) => self.nfcee_mode_set(cmd).await, 1408 _ => unimplemented!("unsupported nfcee oid {:?}", packet.get_oid()), 1409 }, 1410 ProprietaryPacket(packet) => match packet.specialize() { 1411 AndroidPacket(packet) => match packet.specialize() { 1412 AndroidGetCapsCommand(cmd) => self.android_get_caps(cmd).await, 1413 AndroidPassiveObserveModeCommand(cmd) => { 1414 self.android_passive_observe_mode(cmd).await 1415 } 1416 AndroidQueryPassiveObserveModeCommand(cmd) => { 1417 self.android_query_passive_observe_mode(cmd).await 1418 } 1419 _ => { 1420 unimplemented!("unsupported android oid {:?}", packet.get_android_sub_oid()) 1421 } 1422 }, 1423 _ => unimplemented!("unsupported proprietary oid {:?}", packet.get_oid()), 1424 }, 1425 _ => unimplemented!("unsupported gid {:?}", packet.get_gid()), 1426 } 1427 } 1428 rf_conn_data(&mut self, packet: nci::DataPacket) -> Result<()>1429 async fn rf_conn_data(&mut self, packet: nci::DataPacket) -> Result<()> { 1430 info!("[{}] received data on RF logical connection", self.id); 1431 1432 // TODO(henrichataing) implement credit based control flow. 1433 match self.state.rf_state { 1434 RfState::PollActive { 1435 id, 1436 rf_technology, 1437 rf_protocol: rf::Protocol::IsoDep, 1438 rf_interface: nci::RfInterfaceType::IsoDep, 1439 .. 1440 } 1441 | RfState::ListenActive { 1442 id, 1443 rf_technology, 1444 rf_protocol: rf::Protocol::IsoDep, 1445 rf_interface: nci::RfInterfaceType::IsoDep, 1446 .. 1447 } => { 1448 self.send_rf(rf::DataBuilder { 1449 receiver: id, 1450 sender: self.id, 1451 power_level: 255, 1452 protocol: rf::Protocol::IsoDep, 1453 technology: rf_technology, 1454 data: packet.get_payload().into(), 1455 }) 1456 .await?; 1457 // Resplenish the credit count for the RF Connection. 1458 self.send_control( 1459 nci::CoreConnCreditsNotificationBuilder { 1460 connections: vec![nci::ConnectionCredits { 1461 conn_id: nci::ConnId::StaticRf, 1462 credits: 1, 1463 }], 1464 } 1465 .build(), 1466 ) 1467 .await 1468 } 1469 RfState::PollActive { 1470 rf_protocol: rf::Protocol::IsoDep, 1471 rf_interface: nci::RfInterfaceType::Frame, 1472 .. 1473 } => { 1474 println!("ISO-DEP frame data {:?}", packet.get_payload()); 1475 match packet.get_payload() { 1476 // RATS command 1477 // TODO(henrichataing) Send back the response received from 1478 // the peer in the RF packet. 1479 [0xe0, _] => { 1480 warn!("[{}] frame RATS command", self.id); 1481 self.send_data(nci::DataPacketBuilder { 1482 mt: nci::MessageType::Data, 1483 conn_id: nci::ConnId::StaticRf, 1484 cr: 0, 1485 payload: Some(bytes::Bytes::copy_from_slice( 1486 &self.state.rf_activation_parameters, 1487 )), 1488 }) 1489 .await? 1490 } 1491 // DESELECT command 1492 // TODO(henrichataing) check if the command should be 1493 // forwarded to the peer, and if it warrants a response 1494 [0xc2] => warn!("[{}] unimplemented frame DESELECT command", self.id), 1495 // SLP_REQ command 1496 // No response is expected for this command. 1497 // TODO(henrichataing) forward a deactivation request to 1498 // the peer and deactivate the local interface. 1499 [0x50, 0x00] => warn!("[{}] unimplemented frame SLP_REQ command", self.id), 1500 _ => unimplemented!(), 1501 }; 1502 // Resplenish the credit count for the RF Connection. 1503 self.send_control( 1504 nci::CoreConnCreditsNotificationBuilder { 1505 connections: vec![nci::ConnectionCredits { 1506 conn_id: nci::ConnId::StaticRf, 1507 credits: 1, 1508 }], 1509 } 1510 .build(), 1511 ) 1512 .await 1513 } 1514 RfState::PollActive { rf_protocol, rf_interface, .. } 1515 | RfState::ListenActive { rf_protocol, rf_interface, .. } => unimplemented!( 1516 "unsupported combination of RF protocol {:?} and interface {:?}", 1517 rf_protocol, 1518 rf_interface 1519 ), 1520 _ => { 1521 warn!( 1522 "[{}] ignored RF data packet while not in active listen or poll mode", 1523 self.id 1524 ); 1525 Ok(()) 1526 } 1527 } 1528 } 1529 hci_conn_data(&mut self, packet: nci::DataPacket) -> Result<()>1530 async fn hci_conn_data(&mut self, packet: nci::DataPacket) -> Result<()> { 1531 info!("[{}] received data on HCI logical connection", self.id); 1532 1533 // TODO: parse and understand HCI Control Protocol (HCP) 1534 // to accurately respond to the requests. For now it is sufficient 1535 // to return hardcoded answers to identified requests. 1536 let response = match packet.get_payload() { 1537 // ANY_OPEN_PIPE() 1538 [0x81, 0x03] => vec![0x81, 0x80], 1539 // ANY_GET_PARAMETER(index=1) 1540 [0x81, 0x02, 0x01] => vec![0x81, 0x80, 0xd7, 0xfe, 0x65, 0x66, 0xc7, 0xfe, 0x65, 0x66], 1541 // ANY_GET_PARAMETER(index=4) 1542 [0x81, 0x02, 0x04] => vec![0x81, 0x80, 0x00, 0xc0, 0x01], 1543 // ANY_SET_PARAMETER() 1544 [0x81, 0x01, 0x03, 0x02, 0xc0] 1545 | [0x81, 0x01, 0x03, _, _, _] 1546 | [0x81, 0x01, 0x01, _, 0x00, 0x00, 0x00, _, 0x00, 0x00, 0x00] => vec![0x81, 0x80], 1547 // ADM_CLEAR_ALL_PIPE() 1548 [0x81, 0x14, 0x02, 0x01] => vec![0x81, 0x80], 1549 _ => { 1550 error!("unimplemented HCI command : {:?}", packet.get_payload()); 1551 unimplemented!() 1552 } 1553 }; 1554 1555 self.send_data(nci::DataPacketBuilder { 1556 mt: nci::MessageType::Data, 1557 conn_id: nci::ConnId::StaticHci, 1558 cr: 0, 1559 payload: Some(bytes::Bytes::copy_from_slice(&response)), 1560 }) 1561 .await?; 1562 1563 // Resplenish the credit count for the HCI Connection. 1564 self.send_control( 1565 nci::CoreConnCreditsNotificationBuilder { 1566 connections: vec![nci::ConnectionCredits { 1567 conn_id: nci::ConnId::StaticHci, 1568 credits: 1, 1569 }], 1570 } 1571 .build(), 1572 ) 1573 .await 1574 } 1575 dynamic_conn_data(&self, _conn_id: u8, _packet: nci::DataPacket) -> Result<()>1576 async fn dynamic_conn_data(&self, _conn_id: u8, _packet: nci::DataPacket) -> Result<()> { 1577 info!("[{}] received data on dynamic logical connection", self.id); 1578 todo!() 1579 } 1580 receive_data(&mut self, packet: nci::DataPacket) -> Result<()>1581 async fn receive_data(&mut self, packet: nci::DataPacket) -> Result<()> { 1582 info!("[{}] receive_data({})", self.id, u8::from(packet.get_conn_id())); 1583 1584 match packet.get_conn_id() { 1585 nci::ConnId::StaticRf => self.rf_conn_data(packet).await, 1586 nci::ConnId::StaticHci => self.hci_conn_data(packet).await, 1587 nci::ConnId::Dynamic(id) => self.dynamic_conn_data(*id, packet).await, 1588 } 1589 } 1590 field_info(&mut self, field_status: rf::FieldStatus, power_level: u8) -> Result<()>1591 async fn field_info(&mut self, field_status: rf::FieldStatus, power_level: u8) -> Result<()> { 1592 if self.state.config_parameters.rf_field_info != 0 { 1593 self.send_control(nci::RfFieldInfoNotificationBuilder { 1594 rf_field_status: match field_status { 1595 rf::FieldStatus::FieldOn => nci::RfFieldStatus::FieldDetected, 1596 rf::FieldStatus::FieldOff => nci::RfFieldStatus::NoFieldDetected, 1597 }, 1598 }) 1599 .await?; 1600 } 1601 self.send_control(nci::AndroidPollingLoopNotificationBuilder { 1602 polling_frames: vec![nci::PollingFrame { 1603 frame_type: nci::PollingFrameType::RemoteField, 1604 flags: 0, 1605 timestamp: (self.state.start_time.elapsed().as_micros() as u32).to_be_bytes(), 1606 gain: power_level, 1607 payload: vec![field_status.into()], 1608 }], 1609 }) 1610 .await?; 1611 Ok(()) 1612 } 1613 poll_command(&mut self, cmd: rf::PollCommand) -> Result<()>1614 async fn poll_command(&mut self, cmd: rf::PollCommand) -> Result<()> { 1615 trace!("[{}] poll_command()", self.id); 1616 1617 if self.state.rf_state != RfState::Discovery { 1618 return Ok(()); 1619 } 1620 let technology = cmd.get_technology(); 1621 1622 // Android proprietary extension for polling frame notifications. 1623 // The NFCC should send the NCI_ANDROID_POLLING_FRAME_NTF to the Host 1624 // after each polling loop frame 1625 // This notification is independent of whether Passive Observe Mode is 1626 // active or not. When Passive Observe Mode is active, the NFCC 1627 // should always send this notification before proceeding with the 1628 // transaction. 1629 self.send_control(nci::AndroidPollingLoopNotificationBuilder { 1630 polling_frames: vec![nci::PollingFrame { 1631 frame_type: match technology { 1632 rf::Technology::NfcA => nci::PollingFrameType::Reqa, 1633 rf::Technology::NfcB => nci::PollingFrameType::Reqb, 1634 rf::Technology::NfcF => nci::PollingFrameType::Reqf, 1635 rf::Technology::NfcV => nci::PollingFrameType::Reqv, 1636 rf::Technology::Raw => nci::PollingFrameType::Unknown, 1637 }, 1638 flags: 0, 1639 timestamp: (self.state.start_time.elapsed().as_micros() as u32).to_be_bytes(), 1640 gain: cmd.get_power_level(), 1641 payload: cmd.get_payload().to_vec(), 1642 }], 1643 }) 1644 .await?; 1645 1646 // When the Passive Observe Mode is active, the NFCC shall not respond 1647 // to any poll requests during the polling loop in Listen Mode, until 1648 // explicitly authorized by the Host. 1649 if self.state.passive_observe_mode == nci::PassiveObserveMode::Enable { 1650 return Ok(()); 1651 } 1652 1653 if self.state.discover_configuration.iter().any(|config| { 1654 matches!( 1655 (config.technology_and_mode, technology), 1656 (nci::RfTechnologyAndMode::NfcAPassiveListenMode, rf::Technology::NfcA) 1657 | (nci::RfTechnologyAndMode::NfcBPassiveListenMode, rf::Technology::NfcB) 1658 | (nci::RfTechnologyAndMode::NfcFPassiveListenMode, rf::Technology::NfcF) 1659 ) 1660 }) { 1661 match technology { 1662 rf::Technology::NfcA => { 1663 self.send_rf(rf::NfcAPollResponseBuilder { 1664 protocol: rf::Protocol::Undetermined, 1665 receiver: cmd.get_sender(), 1666 sender: self.id, 1667 power_level: 255, 1668 nfcid1: self.state.nfcid1(), 1669 int_protocol: self.state.config_parameters.la_sel_info >> 5, 1670 bit_frame_sdd: self.state.config_parameters.la_bit_frame_sdd, 1671 }) 1672 .await? 1673 } 1674 // TODO(b/346715736) implement support for NFC-B technology 1675 rf::Technology::NfcB => (), 1676 rf::Technology::NfcF => todo!(), 1677 _ => (), 1678 } 1679 } 1680 1681 Ok(()) 1682 } 1683 nfca_poll_response(&mut self, cmd: rf::NfcAPollResponse) -> Result<()>1684 async fn nfca_poll_response(&mut self, cmd: rf::NfcAPollResponse) -> Result<()> { 1685 info!("[{}] nfca_poll_response()", self.id); 1686 1687 if self.state.rf_state != RfState::Discovery { 1688 return Ok(()); 1689 } 1690 1691 let int_protocol = cmd.get_int_protocol(); 1692 let rf_protocols = match int_protocol { 1693 0b00 => [rf::Protocol::T2t].iter(), 1694 0b01 => [rf::Protocol::IsoDep].iter(), 1695 0b10 => [rf::Protocol::NfcDep].iter(), 1696 0b11 => [rf::Protocol::NfcDep, rf::Protocol::IsoDep].iter(), 1697 _ => return Ok(()), 1698 }; 1699 let sens_res = match cmd.get_nfcid1().len() { 1700 4 => 0x00, 1701 7 => 0x40, 1702 10 => 0x80, 1703 _ => panic!(), 1704 } | cmd.get_bit_frame_sdd() as u16; 1705 let sel_res = int_protocol << 5; 1706 1707 for rf_protocol in rf_protocols { 1708 self.state.add_poll_response(RfPollResponse { 1709 id: cmd.get_sender(), 1710 rf_protocol: *rf_protocol, 1711 rf_technology: rf::Technology::NfcA, 1712 rf_technology_specific_parameters: 1713 nci::NfcAPollModeTechnologySpecificParametersBuilder { 1714 sens_res, 1715 nfcid1: cmd.get_nfcid1().clone(), 1716 sel_res, 1717 } 1718 .build() 1719 .encode_to_vec()?, 1720 }) 1721 } 1722 1723 Ok(()) 1724 } 1725 t4at_select_command(&mut self, cmd: rf::T4ATSelectCommand) -> Result<()>1726 async fn t4at_select_command(&mut self, cmd: rf::T4ATSelectCommand) -> Result<()> { 1727 info!("[{}] t4at_select_command()", self.id); 1728 1729 match self.state.rf_state { 1730 RfState::Discovery => (), 1731 RfState::ListenSleep { id } if id == cmd.get_sender() => (), 1732 _ => return Ok(()), 1733 }; 1734 1735 // TODO(henrichataing): validate that the protocol and technology are 1736 // valid for the current discovery settings. 1737 1738 // TODO(henrichataing): use listen mode routing table to decide which 1739 // interface should be used for the activating device. 1740 1741 self.state.rf_state = RfState::ListenActive { 1742 id: cmd.get_sender(), 1743 rf_technology: rf::Technology::NfcA, 1744 rf_protocol: rf::Protocol::IsoDep, 1745 rf_interface: nci::RfInterfaceType::IsoDep, 1746 }; 1747 1748 // [DIGITAL] 14.6.2 RATS Response (Answer To Select) 1749 // Construct the response from the values passed in the configuration 1750 // parameters. The TL byte is excluded from the response. 1751 let mut rats_response = vec![ 1752 0x78, // TC(1), TB(1), TA(1) transmitted, FSCI=8 1753 0x80, // TA(1) 1754 self.state.config_parameters.li_a_rats_tb1, 1755 self.state.config_parameters.li_a_rats_tc1, 1756 ]; 1757 1758 rats_response.extend_from_slice(&self.state.config_parameters.li_a_hist_by); 1759 1760 self.send_rf(rf::T4ATSelectResponseBuilder { 1761 receiver: cmd.get_sender(), 1762 sender: self.id, 1763 power_level: 255, 1764 rats_response, 1765 }) 1766 .await?; 1767 1768 info!("[{}] RF_INTF_ACTIVATED_NTF", self.id); 1769 info!(" DiscoveryID: {:?}", nci::RfDiscoveryId::from_index(0)); 1770 info!(" Interface: ISO-DEP"); 1771 info!(" Protocol: ISO-DEP"); 1772 info!(" ActivationTechnology: NFC_A_PASSIVE_LISTEN"); 1773 info!(" RATS: {}", cmd.get_param()); 1774 1775 self.send_control(nci::RfIntfActivatedNotificationBuilder { 1776 rf_discovery_id: nci::RfDiscoveryId::from_index(0), 1777 rf_interface: nci::RfInterfaceType::IsoDep, 1778 rf_protocol: nci::RfProtocolType::IsoDep, 1779 activation_rf_technology_and_mode: nci::RfTechnologyAndMode::NfcAPassiveListenMode, 1780 max_data_packet_payload_size: MAX_DATA_PACKET_PAYLOAD_SIZE, 1781 initial_number_of_credits: 1, 1782 // No parameters are currently defined for NFC-A Listen Mode. 1783 rf_technology_specific_parameters: vec![], 1784 data_exchange_rf_technology_and_mode: nci::RfTechnologyAndMode::NfcAPassiveListenMode, 1785 data_exchange_transmit_bit_rate: nci::BitRate::BitRate106KbitS, 1786 data_exchange_receive_bit_rate: nci::BitRate::BitRate106KbitS, 1787 activation_parameters: nci::NfcAIsoDepListenModeActivationParametersBuilder { 1788 param: cmd.get_param(), 1789 } 1790 .build() 1791 .encode_to_vec()?, 1792 }) 1793 .await?; 1794 1795 Ok(()) 1796 } 1797 t4at_select_response(&mut self, cmd: rf::T4ATSelectResponse) -> Result<()>1798 async fn t4at_select_response(&mut self, cmd: rf::T4ATSelectResponse) -> Result<()> { 1799 info!("[{}] t4at_select_response()", self.id); 1800 1801 let (id, rf_discovery_id, rf_interface, rf_protocol) = match self.state.rf_state { 1802 RfState::WaitForSelectResponse { 1803 id, 1804 rf_discovery_id, 1805 rf_interface, 1806 rf_protocol, 1807 .. 1808 } => (id, rf_discovery_id, rf_interface, rf_protocol), 1809 _ => return Ok(()), 1810 }; 1811 1812 if cmd.get_sender() != id { 1813 return Ok(()); 1814 } 1815 1816 self.state.rf_state = RfState::PollActive { 1817 id, 1818 rf_protocol: self.state.rf_poll_responses[rf_discovery_id].rf_protocol, 1819 rf_technology: self.state.rf_poll_responses[rf_discovery_id].rf_technology, 1820 rf_interface, 1821 }; 1822 1823 // Save the activation parameters for the RF frame interface 1824 // implementation. Note: TL is not included in the RATS response 1825 // and needs to be added manually to the activation parameters. 1826 self.state.rf_activation_parameters = vec![cmd.get_rats_response().len() as u8]; 1827 self.state.rf_activation_parameters.extend_from_slice(cmd.get_rats_response()); 1828 1829 info!("[{}] RF_INTF_ACTIVATED_NTF", self.id); 1830 info!(" DiscoveryID: {:?}", nci::RfDiscoveryId::from_index(rf_discovery_id)); 1831 info!(" Interface: {:?}", rf_interface); 1832 info!(" Protocol: {:?}", rf_protocol); 1833 info!(" ActivationTechnology: NFC_A_PASSIVE_POLL"); 1834 info!(" RATS: {:?}", cmd.get_rats_response()); 1835 1836 self.send_control(nci::RfIntfActivatedNotificationBuilder { 1837 rf_discovery_id: nci::RfDiscoveryId::from_index(rf_discovery_id), 1838 rf_interface, 1839 rf_protocol: rf_protocol.into(), 1840 activation_rf_technology_and_mode: nci::RfTechnologyAndMode::NfcAPassivePollMode, 1841 max_data_packet_payload_size: MAX_DATA_PACKET_PAYLOAD_SIZE, 1842 initial_number_of_credits: 1, 1843 rf_technology_specific_parameters: self.state.rf_poll_responses[rf_discovery_id] 1844 .rf_technology_specific_parameters 1845 .clone(), 1846 data_exchange_rf_technology_and_mode: nci::RfTechnologyAndMode::NfcAPassivePollMode, 1847 data_exchange_transmit_bit_rate: nci::BitRate::BitRate106KbitS, 1848 data_exchange_receive_bit_rate: nci::BitRate::BitRate106KbitS, 1849 // TODO(hchataing) the activation parameters should be empty 1850 // when the RF frame interface is used, since the protocol 1851 // activation is managed by the DH. 1852 activation_parameters: nci::NfcAIsoDepPollModeActivationParametersBuilder { 1853 rats_response: cmd.get_rats_response().clone(), 1854 } 1855 .build() 1856 .encode_to_vec()?, 1857 }) 1858 .await?; 1859 1860 Ok(()) 1861 } 1862 data_packet(&mut self, data: rf::Data) -> Result<()>1863 async fn data_packet(&mut self, data: rf::Data) -> Result<()> { 1864 info!("[{}] data_packet()", self.id); 1865 1866 match (self.state.rf_state, data.get_protocol()) { 1867 ( 1868 RfState::PollActive { 1869 id, rf_technology, rf_protocol: rf::Protocol::IsoDep, .. 1870 }, 1871 rf::Protocol::IsoDep, 1872 ) 1873 | ( 1874 RfState::ListenActive { 1875 id, rf_technology, rf_protocol: rf::Protocol::IsoDep, .. 1876 }, 1877 rf::Protocol::IsoDep, 1878 ) if data.get_sender() == id && data.get_technology() == rf_technology => { 1879 self.send_data(nci::DataPacketBuilder { 1880 mt: nci::MessageType::Data, 1881 conn_id: nci::ConnId::StaticRf, 1882 cr: 1, // TODO(henrichataing): credit based control flow 1883 payload: Some(bytes::Bytes::copy_from_slice(data.get_data())), 1884 }) 1885 .await 1886 } 1887 (RfState::PollActive { id, .. }, _) | (RfState::ListenActive { id, .. }, _) 1888 if id != data.get_sender() => 1889 { 1890 warn!("[{}] ignored RF data packet sent from an un-selected device", self.id); 1891 Ok(()) 1892 } 1893 (RfState::PollActive { .. }, _) | (RfState::ListenActive { .. }, _) => { 1894 unimplemented!("unsupported combination of technology and protocol") 1895 } 1896 (_, _) => { 1897 warn!("[{}] ignored RF data packet received in inactive state", self.id); 1898 Ok(()) 1899 } 1900 } 1901 } 1902 deactivate_notification(&mut self, cmd: rf::DeactivateNotification) -> Result<()>1903 async fn deactivate_notification(&mut self, cmd: rf::DeactivateNotification) -> Result<()> { 1904 info!("[{}] deactivate_notification()", self.id); 1905 1906 use rf::DeactivateType::*; 1907 1908 let mut next_state = match (self.state.rf_state, cmd.get_type_()) { 1909 (RfState::PollActive { id, .. }, IdleMode) if id == cmd.get_sender() => RfState::Idle, 1910 (RfState::PollActive { id, .. }, SleepMode | SleepAfMode) if id == cmd.get_sender() => { 1911 RfState::WaitForHostSelect 1912 } 1913 (RfState::PollActive { id, .. }, Discovery) if id == cmd.get_sender() => { 1914 RfState::Discovery 1915 } 1916 (RfState::ListenSleep { id, .. }, IdleMode) if id == cmd.get_sender() => RfState::Idle, 1917 (RfState::ListenSleep { id, .. }, Discovery) if id == cmd.get_sender() => { 1918 RfState::Discovery 1919 } 1920 (RfState::ListenActive { id, .. }, IdleMode) if id == cmd.get_sender() => RfState::Idle, 1921 (RfState::ListenActive { id, .. }, SleepMode | SleepAfMode) 1922 if id == cmd.get_sender() => 1923 { 1924 RfState::ListenSleep { id } 1925 } 1926 (RfState::ListenActive { id, .. }, Discovery) if id == cmd.get_sender() => { 1927 RfState::Discovery 1928 } 1929 (_, _) => self.state.rf_state, 1930 }; 1931 1932 // Update the state now to prevent interface activation from 1933 // completing if a remote device is being selected. 1934 (next_state, self.state.rf_state) = (self.state.rf_state, next_state); 1935 1936 // Deactivate the active RF interface if applicable. 1937 if next_state != self.state.rf_state { 1938 self.field_info(rf::FieldStatus::FieldOff, 255).await?; 1939 self.send_control(nci::RfDeactivateNotificationBuilder { 1940 deactivation_type: cmd.get_type_().into(), 1941 deactivation_reason: cmd.get_reason().into(), 1942 }) 1943 .await? 1944 } 1945 1946 Ok(()) 1947 } 1948 receive_rf(&mut self, packet: rf::RfPacket) -> Result<()>1949 async fn receive_rf(&mut self, packet: rf::RfPacket) -> Result<()> { 1950 use rf::RfPacketChild::*; 1951 1952 match packet.specialize() { 1953 PollCommand(cmd) => self.poll_command(cmd).await, 1954 FieldInfo(cmd) => self.field_info(cmd.get_field_status(), cmd.get_power_level()).await, 1955 NfcAPollResponse(cmd) => self.nfca_poll_response(cmd).await, 1956 // [NCI] 5.2.2 State RFST_DISCOVERY 1957 // If discovered by a Remote NFC Endpoint in Listen mode, once the 1958 // Remote NFC Endpoint has established any underlying protocol(s) needed 1959 // by the configured RF Interface, the NFCC SHALL send 1960 // RF_INTF_ACTIVATED_NTF (Listen Mode) to the DH and the state is 1961 // changed to RFST_LISTEN_ACTIVE. 1962 T4ATSelectCommand(cmd) => self.t4at_select_command(cmd).await, 1963 T4ATSelectResponse(cmd) => self.t4at_select_response(cmd).await, 1964 SelectCommand(_) => unimplemented!(), 1965 DeactivateNotification(cmd) => self.deactivate_notification(cmd).await, 1966 Data(cmd) => self.data_packet(cmd).await, 1967 _ => unimplemented!(), 1968 } 1969 } 1970 1971 /// Activity for activating an RF interface for a discovered device. 1972 /// 1973 /// The method send a notification when the interface is successfully 1974 /// activated, or when the device activation fails. 1975 /// 1976 /// * `rf_discovery_id` - index of the discovered device 1977 /// * `rf_interface` - interface to activate 1978 /// 1979 /// The RF state is changed to WaitForSelectResponse when 1980 /// the select command is successfully sent. activate_poll_interface( &mut self, rf_discovery_id: usize, rf_protocol: nci::RfProtocolType, rf_interface: nci::RfInterfaceType, ) -> Result<()>1981 async fn activate_poll_interface( 1982 &mut self, 1983 rf_discovery_id: usize, 1984 rf_protocol: nci::RfProtocolType, 1985 rf_interface: nci::RfInterfaceType, 1986 ) -> Result<()> { 1987 info!("[{}] activate_poll_interface({:?})", self.id, rf_interface); 1988 1989 let rf_technology = self.state.rf_poll_responses[rf_discovery_id].rf_technology; 1990 match (rf_protocol, rf_technology) { 1991 (nci::RfProtocolType::T2t, rf::Technology::NfcA) => { 1992 self.send_rf(rf::SelectCommandBuilder { 1993 sender: self.id, 1994 receiver: self.state.rf_poll_responses[rf_discovery_id].id, 1995 technology: rf::Technology::NfcA, 1996 power_level: 255, 1997 protocol: rf::Protocol::T2t, 1998 }) 1999 .await? 2000 } 2001 (nci::RfProtocolType::IsoDep, rf::Technology::NfcA) => { 2002 self.send_rf(rf::T4ATSelectCommandBuilder { 2003 sender: self.id, 2004 receiver: self.state.rf_poll_responses[rf_discovery_id].id, 2005 power_level: 255, 2006 // [DIGITAL] 14.6.1.6 The FSD supported by the 2007 // Reader/Writer SHALL be FSD T4AT,MIN 2008 // (set to 256 in Appendix B.6). 2009 param: 0x80, 2010 }) 2011 .await? 2012 } 2013 (nci::RfProtocolType::NfcDep, rf::Technology::NfcA) => { 2014 self.send_rf(rf::NfcDepSelectCommandBuilder { 2015 sender: self.id, 2016 receiver: self.state.rf_poll_responses[rf_discovery_id].id, 2017 power_level: 255, 2018 technology: rf::Technology::NfcA, 2019 lr: 0, 2020 }) 2021 .await? 2022 } 2023 _ => todo!(), 2024 } 2025 2026 self.state.rf_state = RfState::WaitForSelectResponse { 2027 id: self.state.rf_poll_responses[rf_discovery_id].id, 2028 rf_discovery_id, 2029 rf_interface, 2030 rf_protocol: rf_protocol.into(), 2031 rf_technology, 2032 }; 2033 Ok(()) 2034 } 2035 run_until<O>(&mut self, future: impl Future<Output = O>) -> Result<O>2036 async fn run_until<O>(&mut self, future: impl Future<Output = O>) -> Result<O> { 2037 let mut future = pin!(future); 2038 loop { 2039 tokio::select! { 2040 packet = self.nci_stream.next() => { 2041 let packet = packet.ok_or(anyhow::anyhow!("nci channel closed"))??; 2042 let header = nci::PacketHeader::parse(&packet[0..3])?; 2043 match header.get_mt() { 2044 nci::MessageType::Data => { 2045 self.receive_data(nci::DataPacket::parse(&packet)?).await? 2046 } 2047 nci::MessageType::Command => { 2048 self.receive_command(nci::ControlPacket::parse(&packet)?).await? 2049 } 2050 mt => { 2051 return Err(anyhow::anyhow!( 2052 "unexpected message type {:?} in received NCI packet", 2053 mt 2054 )) 2055 } 2056 } 2057 }, 2058 rf_packet = self.rf_rx.recv() => { 2059 self.receive_rf( 2060 rf_packet.ok_or(anyhow::anyhow!("rf_rx channel closed"))?, 2061 ) 2062 .await? 2063 }, 2064 output = &mut future => break Ok(output) 2065 } 2066 } 2067 } 2068 2069 /// Timer handler method. This function is invoked at regular interval 2070 /// on the NFCC instance and is used to drive internal timers. tick(&mut self) -> Result<()>2071 async fn tick(&mut self) -> Result<()> { 2072 if self.state.rf_state != RfState::Discovery { 2073 return Ok(()); 2074 } 2075 2076 //info!("[{}] poll", self.id); 2077 2078 // [NCI] 5.2.2 State RFST_DISCOVERY 2079 // 2080 // In this state the NFCC stays in Poll Mode and/or Listen Mode (based 2081 // on the discovery configuration) until at least one Remote NFC 2082 // Endpoint is detected or the RF Discovery Process is stopped by 2083 // the DH. 2084 // 2085 // The following implements the Poll Mode Discovery, Listen Mode 2086 // Discover is implicitly implemented in response to poll and 2087 // select commands. 2088 2089 // RF Discovery is ongoing and no peer device has been discovered 2090 // so far. Send a RF poll command for all enabled technologies. 2091 self.state.rf_poll_responses.clear(); 2092 for configuration in self.state.discover_configuration.iter() { 2093 self.send_rf(rf::PollCommandBuilder { 2094 sender: self.id, 2095 receiver: u16::MAX, 2096 protocol: rf::Protocol::Undetermined, 2097 technology: match configuration.technology_and_mode { 2098 nci::RfTechnologyAndMode::NfcAPassivePollMode => rf::Technology::NfcA, 2099 nci::RfTechnologyAndMode::NfcBPassivePollMode => rf::Technology::NfcB, 2100 nci::RfTechnologyAndMode::NfcFPassivePollMode => rf::Technology::NfcF, 2101 nci::RfTechnologyAndMode::NfcVPassivePollMode => rf::Technology::NfcV, 2102 _ => continue, 2103 }, 2104 power_level: 255, 2105 payload: Some(bytes::Bytes::new()), 2106 }) 2107 .await? 2108 } 2109 2110 // Wait for poll responses to return. 2111 self.run_until(time::sleep(Duration::from_millis(POLL_RESPONSE_TIMEOUT))).await?; 2112 2113 // Check if device was activated in Listen mode during 2114 // the poll interval, or if the discovery got cancelled. 2115 if self.state.rf_state != RfState::Discovery || self.state.rf_poll_responses.is_empty() { 2116 return Ok(()); 2117 } 2118 2119 // While polling, if the NFCC discovers just one Remote NFC Endpoint 2120 // that supports just one protocol, the NFCC SHALL try to automatically 2121 // activate it. The NFCC SHALL first establish any underlying 2122 // protocol(s) with the Remote NFC Endpoint that are needed by the 2123 // configured RF Interface. On completion, the NFCC SHALL activate the 2124 // RF Interface and send RF_INTF_ACTIVATED_NTF (Poll Mode) to the DH. 2125 // At this point, the state is changed to RFST_POLL_ACTIVE. If the 2126 // protocol activation is not successful, the NFCC SHALL send 2127 // CORE_GENERIC_ERROR_NTF to the DH with status 2128 // DISCOVERY_TARGET_ACTIVATION_FAILED and SHALL stay in the 2129 // RFST_DISCOVERY state. 2130 if self.state.rf_poll_responses.len() == 1 { 2131 let rf_protocol = self.state.rf_poll_responses[0].rf_protocol.into(); 2132 let rf_interface = self.state.select_interface(RfMode::Poll, rf_protocol); 2133 return self.activate_poll_interface(0, rf_protocol, rf_interface).await; 2134 } 2135 2136 debug!("[{}] received {} poll response(s)", self.id, self.state.rf_poll_responses.len()); 2137 2138 // While polling, if the NFCC discovers more than one Remote NFC 2139 // Endpoint, or a Remote NFC Endpoint that supports more than one RF 2140 // Protocol, it SHALL start sending RF_DISCOVER_NTF messages to the DH. 2141 // At this point, the state is changed to RFST_W4_ALL_DISCOVERIES. 2142 self.state.rf_state = RfState::WaitForHostSelect; 2143 let last_index = self.state.rf_poll_responses.len() - 1; 2144 for (index, response) in self.state.rf_poll_responses.clone().iter().enumerate() { 2145 self.send_control(nci::RfDiscoverNotificationBuilder { 2146 rf_discovery_id: nci::RfDiscoveryId::from_index(index), 2147 rf_protocol: response.rf_protocol.into(), 2148 rf_technology_and_mode: match response.rf_technology { 2149 rf::Technology::NfcA => nci::RfTechnologyAndMode::NfcAPassivePollMode, 2150 rf::Technology::NfcB => nci::RfTechnologyAndMode::NfcBPassivePollMode, 2151 _ => todo!(), 2152 }, 2153 rf_technology_specific_parameters: response 2154 .rf_technology_specific_parameters 2155 .clone(), 2156 notification_type: if index == last_index { 2157 nci::DiscoverNotificationType::LastNotification 2158 } else { 2159 nci::DiscoverNotificationType::MoreNotifications 2160 }, 2161 }) 2162 .await? 2163 } 2164 2165 Ok(()) 2166 } 2167 2168 /// 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<()>2169 pub async fn run( 2170 id: u16, 2171 nci_stream: nci::StreamRefMut<'a>, 2172 nci_writer: nci::Writer, 2173 rf_rx: mpsc::UnboundedReceiver<rf::RfPacket>, 2174 rf_tx: mpsc::UnboundedSender<rf::RfPacket>, 2175 ) -> Result<()> { 2176 // Local controller state. 2177 let mut nfcc = Controller::new(id, nci_stream, nci_writer, rf_rx, rf_tx); 2178 2179 // Timer for tick events. 2180 let mut timer = time::interval(Duration::from_millis(1000)); 2181 2182 loop { 2183 nfcc.run_until(timer.tick()).await?; 2184 nfcc.tick().await?; 2185 } 2186 } 2187 } 2188