1*7eba2f3bSAndroid Build Coastguard Worker // Copyright 2023, The Android Open Source Project 2*7eba2f3bSAndroid Build Coastguard Worker // 3*7eba2f3bSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*7eba2f3bSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*7eba2f3bSAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*7eba2f3bSAndroid Build Coastguard Worker // 7*7eba2f3bSAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 8*7eba2f3bSAndroid Build Coastguard Worker // 9*7eba2f3bSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*7eba2f3bSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*7eba2f3bSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*7eba2f3bSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*7eba2f3bSAndroid Build Coastguard Worker // limitations under the License. 14*7eba2f3bSAndroid Build Coastguard Worker 15*7eba2f3bSAndroid Build Coastguard Worker //! Packet parsers and serializers. 16*7eba2f3bSAndroid Build Coastguard Worker 17*7eba2f3bSAndroid Build Coastguard Worker /// NCI packet parser and serializer. 18*7eba2f3bSAndroid Build Coastguard Worker pub mod nci { 19*7eba2f3bSAndroid Build Coastguard Worker #![allow(clippy::all)] 20*7eba2f3bSAndroid Build Coastguard Worker #![allow(unused)] 21*7eba2f3bSAndroid Build Coastguard Worker #![allow(missing_docs)] 22*7eba2f3bSAndroid Build Coastguard Worker 23*7eba2f3bSAndroid Build Coastguard Worker include!(concat!(env!("OUT_DIR"), "/nci_packets.rs")); 24*7eba2f3bSAndroid Build Coastguard Worker 25*7eba2f3bSAndroid Build Coastguard Worker impl ConnId { 26*7eba2f3bSAndroid Build Coastguard Worker /// Create a Conn ID with `id` as an offset in the range of dynamic 27*7eba2f3bSAndroid Build Coastguard Worker /// identifiers. from_dynamic(id: u8) -> Self28*7eba2f3bSAndroid Build Coastguard Worker pub fn from_dynamic(id: u8) -> Self { 29*7eba2f3bSAndroid Build Coastguard Worker ConnId::try_from(id as u8 + 2).unwrap() 30*7eba2f3bSAndroid Build Coastguard Worker } 31*7eba2f3bSAndroid Build Coastguard Worker 32*7eba2f3bSAndroid Build Coastguard Worker /// Return the index for a dynamic Conn ID. to_dynamic(id: Private<u8>) -> u833*7eba2f3bSAndroid Build Coastguard Worker pub fn to_dynamic(id: Private<u8>) -> u8 { 34*7eba2f3bSAndroid Build Coastguard Worker *id - 2 35*7eba2f3bSAndroid Build Coastguard Worker } 36*7eba2f3bSAndroid Build Coastguard Worker } 37*7eba2f3bSAndroid Build Coastguard Worker 38*7eba2f3bSAndroid Build Coastguard Worker impl RfDiscoveryId { 39*7eba2f3bSAndroid Build Coastguard Worker /// Create the default reserved RF Discovery ID. reserved() -> Self40*7eba2f3bSAndroid Build Coastguard Worker pub fn reserved() -> Self { 41*7eba2f3bSAndroid Build Coastguard Worker RfDiscoveryId::try_from(0).unwrap() 42*7eba2f3bSAndroid Build Coastguard Worker } 43*7eba2f3bSAndroid Build Coastguard Worker 44*7eba2f3bSAndroid Build Coastguard Worker /// Create an RF Discovery ID with `id` as an offset in the range of 45*7eba2f3bSAndroid Build Coastguard Worker /// non-reserved identifiers. from_index(id: usize) -> Self46*7eba2f3bSAndroid Build Coastguard Worker pub fn from_index(id: usize) -> Self { 47*7eba2f3bSAndroid Build Coastguard Worker RfDiscoveryId::try_from(id as u8 + 1).unwrap() 48*7eba2f3bSAndroid Build Coastguard Worker } 49*7eba2f3bSAndroid Build Coastguard Worker 50*7eba2f3bSAndroid Build Coastguard Worker /// Return the index for a valid RF Discovery ID. to_index(id: Private<u8>) -> usize51*7eba2f3bSAndroid Build Coastguard Worker pub fn to_index(id: Private<u8>) -> usize { 52*7eba2f3bSAndroid Build Coastguard Worker *id as usize - 1 53*7eba2f3bSAndroid Build Coastguard Worker } 54*7eba2f3bSAndroid Build Coastguard Worker } 55*7eba2f3bSAndroid Build Coastguard Worker 56*7eba2f3bSAndroid Build Coastguard Worker impl NfceeId { nfcee(id: u8) -> Self57*7eba2f3bSAndroid Build Coastguard Worker pub fn nfcee(id: u8) -> Self { 58*7eba2f3bSAndroid Build Coastguard Worker NfceeId::try_from(id).unwrap() 59*7eba2f3bSAndroid Build Coastguard Worker } 60*7eba2f3bSAndroid Build Coastguard Worker hci_nfcee(id: u8) -> Self61*7eba2f3bSAndroid Build Coastguard Worker pub fn hci_nfcee(id: u8) -> Self { 62*7eba2f3bSAndroid Build Coastguard Worker NfceeId::try_from(id).unwrap() 63*7eba2f3bSAndroid Build Coastguard Worker } 64*7eba2f3bSAndroid Build Coastguard Worker } 65*7eba2f3bSAndroid Build Coastguard Worker 66*7eba2f3bSAndroid Build Coastguard Worker use futures::stream::{self, Stream}; 67*7eba2f3bSAndroid Build Coastguard Worker use std::pin::Pin; 68*7eba2f3bSAndroid Build Coastguard Worker use tokio::io::{AsyncRead, AsyncWrite}; 69*7eba2f3bSAndroid Build Coastguard Worker use tokio::sync::Mutex; 70*7eba2f3bSAndroid Build Coastguard Worker 71*7eba2f3bSAndroid Build Coastguard Worker /// Read NCI Control and Data packets received on the NCI transport. 72*7eba2f3bSAndroid Build Coastguard Worker /// Performs recombination of the segmented packets. 73*7eba2f3bSAndroid Build Coastguard Worker pub struct Reader { 74*7eba2f3bSAndroid Build Coastguard Worker socket: Pin<Box<dyn AsyncRead>>, 75*7eba2f3bSAndroid Build Coastguard Worker } 76*7eba2f3bSAndroid Build Coastguard Worker 77*7eba2f3bSAndroid Build Coastguard Worker /// Write NCI Control and Data packets received to the NCI transport. 78*7eba2f3bSAndroid Build Coastguard Worker /// Performs segmentation of the packets. 79*7eba2f3bSAndroid Build Coastguard Worker pub struct Writer { 80*7eba2f3bSAndroid Build Coastguard Worker socket: Pin<Box<dyn AsyncWrite>>, 81*7eba2f3bSAndroid Build Coastguard Worker } 82*7eba2f3bSAndroid Build Coastguard Worker 83*7eba2f3bSAndroid Build Coastguard Worker impl Reader { 84*7eba2f3bSAndroid Build Coastguard Worker /// Create an NCI reader from an NCI transport. new<T: AsyncRead + 'static>(rx: T) -> Self85*7eba2f3bSAndroid Build Coastguard Worker pub fn new<T: AsyncRead + 'static>(rx: T) -> Self { 86*7eba2f3bSAndroid Build Coastguard Worker Reader { socket: Box::pin(rx) } 87*7eba2f3bSAndroid Build Coastguard Worker } 88*7eba2f3bSAndroid Build Coastguard Worker 89*7eba2f3bSAndroid Build Coastguard Worker /// Read a single NCI packet from the reader. The packet is automatically 90*7eba2f3bSAndroid Build Coastguard Worker /// re-assembled if segmented on the NCI transport. read(&mut self) -> anyhow::Result<Vec<u8>>91*7eba2f3bSAndroid Build Coastguard Worker pub async fn read(&mut self) -> anyhow::Result<Vec<u8>> { 92*7eba2f3bSAndroid Build Coastguard Worker use tokio::io::AsyncReadExt; 93*7eba2f3bSAndroid Build Coastguard Worker 94*7eba2f3bSAndroid Build Coastguard Worker const HEADER_SIZE: usize = 3; 95*7eba2f3bSAndroid Build Coastguard Worker let mut complete_packet = vec![0; HEADER_SIZE]; 96*7eba2f3bSAndroid Build Coastguard Worker 97*7eba2f3bSAndroid Build Coastguard Worker // Note on reassembly: 98*7eba2f3bSAndroid Build Coastguard Worker // - for each segment of a Control Message, the header of the 99*7eba2f3bSAndroid Build Coastguard Worker // Control Packet SHALL contain the same MT, GID and OID values, 100*7eba2f3bSAndroid Build Coastguard Worker // - for each segment of a Data Message the header of the Data 101*7eba2f3bSAndroid Build Coastguard Worker // Packet SHALL contain the same MT and Conn ID. 102*7eba2f3bSAndroid Build Coastguard Worker // Thus it is correct to keep only the last header of the segmented 103*7eba2f3bSAndroid Build Coastguard Worker // packet. 104*7eba2f3bSAndroid Build Coastguard Worker loop { 105*7eba2f3bSAndroid Build Coastguard Worker // Read the common packet header. 106*7eba2f3bSAndroid Build Coastguard Worker self.socket.read_exact(&mut complete_packet[0..HEADER_SIZE]).await?; 107*7eba2f3bSAndroid Build Coastguard Worker let header = PacketHeader::parse(&complete_packet[0..HEADER_SIZE])?; 108*7eba2f3bSAndroid Build Coastguard Worker 109*7eba2f3bSAndroid Build Coastguard Worker // Read the packet payload. 110*7eba2f3bSAndroid Build Coastguard Worker let payload_length = header.get_payload_length() as usize; 111*7eba2f3bSAndroid Build Coastguard Worker let mut payload_bytes = vec![0; payload_length]; 112*7eba2f3bSAndroid Build Coastguard Worker self.socket.read_exact(&mut payload_bytes).await?; 113*7eba2f3bSAndroid Build Coastguard Worker complete_packet.extend(payload_bytes); 114*7eba2f3bSAndroid Build Coastguard Worker 115*7eba2f3bSAndroid Build Coastguard Worker // Check the Packet Boundary Flag. 116*7eba2f3bSAndroid Build Coastguard Worker match header.get_pbf() { 117*7eba2f3bSAndroid Build Coastguard Worker PacketBoundaryFlag::CompleteOrFinal => return Ok(complete_packet), 118*7eba2f3bSAndroid Build Coastguard Worker PacketBoundaryFlag::Incomplete => (), 119*7eba2f3bSAndroid Build Coastguard Worker } 120*7eba2f3bSAndroid Build Coastguard Worker } 121*7eba2f3bSAndroid Build Coastguard Worker } 122*7eba2f3bSAndroid Build Coastguard Worker into_stream(self) -> impl Stream<Item = anyhow::Result<Vec<u8>>>123*7eba2f3bSAndroid Build Coastguard Worker pub fn into_stream(self) -> impl Stream<Item = anyhow::Result<Vec<u8>>> { 124*7eba2f3bSAndroid Build Coastguard Worker stream::try_unfold(self, |mut reader| async move { 125*7eba2f3bSAndroid Build Coastguard Worker Ok(Some((reader.read().await?, reader))) 126*7eba2f3bSAndroid Build Coastguard Worker }) 127*7eba2f3bSAndroid Build Coastguard Worker } 128*7eba2f3bSAndroid Build Coastguard Worker } 129*7eba2f3bSAndroid Build Coastguard Worker 130*7eba2f3bSAndroid Build Coastguard Worker /// A mutable reference to the stream returned by into_stream 131*7eba2f3bSAndroid Build Coastguard Worker pub type StreamRefMut<'a> = Pin<&'a mut dyn Stream<Item = anyhow::Result<Vec<u8>>>>; 132*7eba2f3bSAndroid Build Coastguard Worker 133*7eba2f3bSAndroid Build Coastguard Worker impl Writer { 134*7eba2f3bSAndroid Build Coastguard Worker /// Create an NCI writer from an NCI transport. new<T: AsyncWrite + 'static>(rx: T) -> Self135*7eba2f3bSAndroid Build Coastguard Worker pub fn new<T: AsyncWrite + 'static>(rx: T) -> Self { 136*7eba2f3bSAndroid Build Coastguard Worker Writer { socket: Box::pin(rx) } 137*7eba2f3bSAndroid Build Coastguard Worker } 138*7eba2f3bSAndroid Build Coastguard Worker 139*7eba2f3bSAndroid Build Coastguard Worker /// Write a single NCI packet to the writer. The packet is automatically 140*7eba2f3bSAndroid Build Coastguard Worker /// segmented if the payload exceeds the maximum size limit. write(&mut self, mut packet: &[u8]) -> anyhow::Result<()>141*7eba2f3bSAndroid Build Coastguard Worker pub async fn write(&mut self, mut packet: &[u8]) -> anyhow::Result<()> { 142*7eba2f3bSAndroid Build Coastguard Worker use tokio::io::AsyncWriteExt; 143*7eba2f3bSAndroid Build Coastguard Worker 144*7eba2f3bSAndroid Build Coastguard Worker let mut header_bytes = [packet[0], packet[1], 0]; 145*7eba2f3bSAndroid Build Coastguard Worker packet = &packet[3..]; 146*7eba2f3bSAndroid Build Coastguard Worker 147*7eba2f3bSAndroid Build Coastguard Worker loop { 148*7eba2f3bSAndroid Build Coastguard Worker // Update header with framing information. 149*7eba2f3bSAndroid Build Coastguard Worker let chunk_length = std::cmp::min(255, packet.len()); 150*7eba2f3bSAndroid Build Coastguard Worker let pbf = if chunk_length < packet.len() { 151*7eba2f3bSAndroid Build Coastguard Worker PacketBoundaryFlag::Incomplete 152*7eba2f3bSAndroid Build Coastguard Worker } else { 153*7eba2f3bSAndroid Build Coastguard Worker PacketBoundaryFlag::CompleteOrFinal 154*7eba2f3bSAndroid Build Coastguard Worker }; 155*7eba2f3bSAndroid Build Coastguard Worker const PBF_MASK: u8 = 0x10; 156*7eba2f3bSAndroid Build Coastguard Worker header_bytes[0] &= !PBF_MASK; 157*7eba2f3bSAndroid Build Coastguard Worker header_bytes[0] |= (pbf as u8) << 4; 158*7eba2f3bSAndroid Build Coastguard Worker header_bytes[2] = chunk_length as u8; 159*7eba2f3bSAndroid Build Coastguard Worker 160*7eba2f3bSAndroid Build Coastguard Worker // Write the header and payload segment bytes. 161*7eba2f3bSAndroid Build Coastguard Worker self.socket.write_all(&header_bytes).await?; 162*7eba2f3bSAndroid Build Coastguard Worker self.socket.write_all(&packet[..chunk_length]).await?; 163*7eba2f3bSAndroid Build Coastguard Worker packet = &packet[chunk_length..]; 164*7eba2f3bSAndroid Build Coastguard Worker 165*7eba2f3bSAndroid Build Coastguard Worker if packet.is_empty() { 166*7eba2f3bSAndroid Build Coastguard Worker return Ok(()); 167*7eba2f3bSAndroid Build Coastguard Worker } 168*7eba2f3bSAndroid Build Coastguard Worker } 169*7eba2f3bSAndroid Build Coastguard Worker } 170*7eba2f3bSAndroid Build Coastguard Worker } 171*7eba2f3bSAndroid Build Coastguard Worker } 172*7eba2f3bSAndroid Build Coastguard Worker 173*7eba2f3bSAndroid Build Coastguard Worker /// RF packet parser and serializer. 174*7eba2f3bSAndroid Build Coastguard Worker pub mod rf { 175*7eba2f3bSAndroid Build Coastguard Worker #![allow(clippy::all)] 176*7eba2f3bSAndroid Build Coastguard Worker #![allow(unused)] 177*7eba2f3bSAndroid Build Coastguard Worker #![allow(missing_docs)] 178*7eba2f3bSAndroid Build Coastguard Worker 179*7eba2f3bSAndroid Build Coastguard Worker include!(concat!(env!("OUT_DIR"), "/rf_packets.rs")); 180*7eba2f3bSAndroid Build Coastguard Worker } 181*7eba2f3bSAndroid Build Coastguard Worker 182*7eba2f3bSAndroid Build Coastguard Worker impl From<rf::Protocol> for nci::RfProtocolType { from(protocol: rf::Protocol) -> Self183*7eba2f3bSAndroid Build Coastguard Worker fn from(protocol: rf::Protocol) -> Self { 184*7eba2f3bSAndroid Build Coastguard Worker match protocol { 185*7eba2f3bSAndroid Build Coastguard Worker rf::Protocol::Undetermined => nci::RfProtocolType::Undetermined, 186*7eba2f3bSAndroid Build Coastguard Worker rf::Protocol::T1t => nci::RfProtocolType::T1t, 187*7eba2f3bSAndroid Build Coastguard Worker rf::Protocol::T2t => nci::RfProtocolType::T2t, 188*7eba2f3bSAndroid Build Coastguard Worker rf::Protocol::T3t => nci::RfProtocolType::T3t, 189*7eba2f3bSAndroid Build Coastguard Worker rf::Protocol::IsoDep => nci::RfProtocolType::IsoDep, 190*7eba2f3bSAndroid Build Coastguard Worker rf::Protocol::NfcDep => nci::RfProtocolType::NfcDep, 191*7eba2f3bSAndroid Build Coastguard Worker rf::Protocol::T5t => nci::RfProtocolType::T5t, 192*7eba2f3bSAndroid Build Coastguard Worker rf::Protocol::Ndef => nci::RfProtocolType::Ndef, 193*7eba2f3bSAndroid Build Coastguard Worker } 194*7eba2f3bSAndroid Build Coastguard Worker } 195*7eba2f3bSAndroid Build Coastguard Worker } 196*7eba2f3bSAndroid Build Coastguard Worker 197*7eba2f3bSAndroid Build Coastguard Worker impl From<nci::RfProtocolType> for rf::Protocol { from(protocol: nci::RfProtocolType) -> Self198*7eba2f3bSAndroid Build Coastguard Worker fn from(protocol: nci::RfProtocolType) -> Self { 199*7eba2f3bSAndroid Build Coastguard Worker match protocol { 200*7eba2f3bSAndroid Build Coastguard Worker nci::RfProtocolType::Undetermined => rf::Protocol::Undetermined, 201*7eba2f3bSAndroid Build Coastguard Worker nci::RfProtocolType::T1t => rf::Protocol::T1t, 202*7eba2f3bSAndroid Build Coastguard Worker nci::RfProtocolType::T2t => rf::Protocol::T2t, 203*7eba2f3bSAndroid Build Coastguard Worker nci::RfProtocolType::T3t => rf::Protocol::T3t, 204*7eba2f3bSAndroid Build Coastguard Worker nci::RfProtocolType::IsoDep => rf::Protocol::IsoDep, 205*7eba2f3bSAndroid Build Coastguard Worker nci::RfProtocolType::NfcDep => rf::Protocol::NfcDep, 206*7eba2f3bSAndroid Build Coastguard Worker nci::RfProtocolType::T5t => rf::Protocol::T5t, 207*7eba2f3bSAndroid Build Coastguard Worker nci::RfProtocolType::Ndef => rf::Protocol::Ndef, 208*7eba2f3bSAndroid Build Coastguard Worker } 209*7eba2f3bSAndroid Build Coastguard Worker } 210*7eba2f3bSAndroid Build Coastguard Worker } 211*7eba2f3bSAndroid Build Coastguard Worker 212*7eba2f3bSAndroid Build Coastguard Worker impl TryFrom<nci::RfTechnologyAndMode> for rf::Technology { 213*7eba2f3bSAndroid Build Coastguard Worker type Error = nci::RfTechnologyAndMode; try_from(protocol: nci::RfTechnologyAndMode) -> Result<Self, Self::Error>214*7eba2f3bSAndroid Build Coastguard Worker fn try_from(protocol: nci::RfTechnologyAndMode) -> Result<Self, Self::Error> { 215*7eba2f3bSAndroid Build Coastguard Worker Ok(match protocol { 216*7eba2f3bSAndroid Build Coastguard Worker nci::RfTechnologyAndMode::NfcAPassivePollMode 217*7eba2f3bSAndroid Build Coastguard Worker | nci::RfTechnologyAndMode::NfcAPassiveListenMode => rf::Technology::NfcA, 218*7eba2f3bSAndroid Build Coastguard Worker nci::RfTechnologyAndMode::NfcBPassivePollMode 219*7eba2f3bSAndroid Build Coastguard Worker | nci::RfTechnologyAndMode::NfcBPassiveListenMode => rf::Technology::NfcB, 220*7eba2f3bSAndroid Build Coastguard Worker nci::RfTechnologyAndMode::NfcFPassivePollMode 221*7eba2f3bSAndroid Build Coastguard Worker | nci::RfTechnologyAndMode::NfcFPassiveListenMode => rf::Technology::NfcF, 222*7eba2f3bSAndroid Build Coastguard Worker nci::RfTechnologyAndMode::NfcVPassivePollMode => rf::Technology::NfcV, 223*7eba2f3bSAndroid Build Coastguard Worker _ => return Err(protocol), 224*7eba2f3bSAndroid Build Coastguard Worker }) 225*7eba2f3bSAndroid Build Coastguard Worker } 226*7eba2f3bSAndroid Build Coastguard Worker } 227*7eba2f3bSAndroid Build Coastguard Worker 228*7eba2f3bSAndroid Build Coastguard Worker impl From<rf::DeactivateType> for nci::DeactivationType { from(type_: rf::DeactivateType) -> Self229*7eba2f3bSAndroid Build Coastguard Worker fn from(type_: rf::DeactivateType) -> Self { 230*7eba2f3bSAndroid Build Coastguard Worker match type_ { 231*7eba2f3bSAndroid Build Coastguard Worker rf::DeactivateType::IdleMode => nci::DeactivationType::IdleMode, 232*7eba2f3bSAndroid Build Coastguard Worker rf::DeactivateType::SleepMode => nci::DeactivationType::SleepMode, 233*7eba2f3bSAndroid Build Coastguard Worker rf::DeactivateType::SleepAfMode => nci::DeactivationType::SleepAfMode, 234*7eba2f3bSAndroid Build Coastguard Worker rf::DeactivateType::Discovery => nci::DeactivationType::Discovery, 235*7eba2f3bSAndroid Build Coastguard Worker } 236*7eba2f3bSAndroid Build Coastguard Worker } 237*7eba2f3bSAndroid Build Coastguard Worker } 238*7eba2f3bSAndroid Build Coastguard Worker 239*7eba2f3bSAndroid Build Coastguard Worker impl From<nci::DeactivationType> for rf::DeactivateType { from(type_: nci::DeactivationType) -> Self240*7eba2f3bSAndroid Build Coastguard Worker fn from(type_: nci::DeactivationType) -> Self { 241*7eba2f3bSAndroid Build Coastguard Worker match type_ { 242*7eba2f3bSAndroid Build Coastguard Worker nci::DeactivationType::IdleMode => rf::DeactivateType::IdleMode, 243*7eba2f3bSAndroid Build Coastguard Worker nci::DeactivationType::SleepMode => rf::DeactivateType::SleepMode, 244*7eba2f3bSAndroid Build Coastguard Worker nci::DeactivationType::SleepAfMode => rf::DeactivateType::SleepAfMode, 245*7eba2f3bSAndroid Build Coastguard Worker nci::DeactivationType::Discovery => rf::DeactivateType::Discovery, 246*7eba2f3bSAndroid Build Coastguard Worker } 247*7eba2f3bSAndroid Build Coastguard Worker } 248*7eba2f3bSAndroid Build Coastguard Worker } 249*7eba2f3bSAndroid Build Coastguard Worker 250*7eba2f3bSAndroid Build Coastguard Worker impl From<rf::DeactivateReason> for nci::DeactivationReason { from(reason: rf::DeactivateReason) -> Self251*7eba2f3bSAndroid Build Coastguard Worker fn from(reason: rf::DeactivateReason) -> Self { 252*7eba2f3bSAndroid Build Coastguard Worker match reason { 253*7eba2f3bSAndroid Build Coastguard Worker rf::DeactivateReason::DhRequest => nci::DeactivationReason::DhRequest, 254*7eba2f3bSAndroid Build Coastguard Worker rf::DeactivateReason::EndpointRequest => nci::DeactivationReason::EndpointRequest, 255*7eba2f3bSAndroid Build Coastguard Worker rf::DeactivateReason::RfLinkLoss => nci::DeactivationReason::RfLinkLoss, 256*7eba2f3bSAndroid Build Coastguard Worker rf::DeactivateReason::NfcBBadAfi => nci::DeactivationReason::NfcBBadAfi, 257*7eba2f3bSAndroid Build Coastguard Worker rf::DeactivateReason::DhRequestFailed => nci::DeactivationReason::DhRequestFailed, 258*7eba2f3bSAndroid Build Coastguard Worker } 259*7eba2f3bSAndroid Build Coastguard Worker } 260*7eba2f3bSAndroid Build Coastguard Worker } 261