diff options
Diffstat (limited to 'src/rust/uwb_uci_packets')
-rw-r--r-- | src/rust/uwb_uci_packets/build.rs | 4 | ||||
-rw-r--r-- | src/rust/uwb_uci_packets/src/lib.rs | 169 | ||||
-rw-r--r-- | src/rust/uwb_uci_packets/uci_packets.pdl | 255 |
3 files changed, 310 insertions, 118 deletions
diff --git a/src/rust/uwb_uci_packets/build.rs b/src/rust/uwb_uci_packets/build.rs index f001de5..240c3f2 100644 --- a/src/rust/uwb_uci_packets/build.rs +++ b/src/rust/uwb_uci_packets/build.rs @@ -27,9 +27,9 @@ fn main() { return; } - // The binary should be compiled by `m pdl` before calling cargo. + // The binary should be compiled by `m pdlc` before calling cargo. let output = Command::new("env") - .arg("pdl") + .arg("pdlc") .arg("--output-format") .arg("rust") .arg("uci_packets.pdl") diff --git a/src/rust/uwb_uci_packets/src/lib.rs b/src/rust/uwb_uci_packets/src/lib.rs index bc95bc3..38b0910 100644 --- a/src/rust/uwb_uci_packets/src/lib.rs +++ b/src/rust/uwb_uci_packets/src/lib.rs @@ -22,6 +22,8 @@ use std::cmp; use log::error; +use num_derive::FromPrimitive; +use num_traits::FromPrimitive; use zeroize::Zeroize; include!(concat!(env!("OUT_DIR"), "/uci_packets.rs")); @@ -37,8 +39,19 @@ pub const UCI_PACKET_HEADER_LEN: usize = 7; const UCI_DATA_SND_PACKET_HEADER_LEN: usize = 6; // Opcode field byte position (within UCI packet header) and mask (of bits to be used). -const UCI_CONTROL_PACKET_HEADER_OPCODE_BYTE_POSITION: usize = 1; -const UCI_CONTROL_PACKET_HEADER_OPCODE_MASK: u8 = 0x3F; +const UCI_HEADER_MT_BYTE_POSITION: usize = 0; +const UCI_HEADER_MT_BIT_SHIFT: u8 = 5; +const UCI_HEADER_MT_MASK: u8 = 0x7; + +const UCI_HEADER_PBF_BYTE_POSITION: usize = 0; +const UCI_HEADER_PBF_BIT_SHIFT: u8 = 4; +const UCI_HEADER_PBF_MASK: u8 = 0x1; + +const UCI_CONTROL_HEADER_GID_BYTE_POSITION: usize = 0; +const UCI_CONTROL_HEADER_GID_MASK: u8 = 0xF; + +const UCI_CONTROL_HEADER_OID_BYTE_POSITION: usize = 1; +const UCI_CONTROL_HEADER_OID_MASK: u8 = 0x3F; #[derive(Debug, Clone, PartialEq, FromPrimitive)] pub enum TimeStampLength { @@ -246,19 +259,19 @@ generate_extract_func!(extract_u64, u64); // keep the two enums in sync, for any additional values defined in the UCI spec). impl From<GroupId> for GroupIdOrDataPacketFormat { fn from(gid: GroupId) -> Self { - GroupIdOrDataPacketFormat::from_u8(gid.to_u8().unwrap()).unwrap() + GroupIdOrDataPacketFormat::try_from(u8::from(gid)).unwrap() } } impl From<GroupIdOrDataPacketFormat> for GroupId { fn from(gid_or_dpf: GroupIdOrDataPacketFormat) -> Self { - GroupId::from_u8(gid_or_dpf.to_u8().unwrap()).unwrap() + GroupId::try_from(u8::from(gid_or_dpf)).unwrap() } } impl From<DataPacketFormat> for GroupIdOrDataPacketFormat { fn from(dpf: DataPacketFormat) -> Self { - GroupIdOrDataPacketFormat::from_u8(dpf.to_u8().unwrap()).unwrap() + GroupIdOrDataPacketFormat::try_from(u8::from(dpf)).unwrap() } } @@ -268,7 +281,7 @@ impl TryFrom<GroupIdOrDataPacketFormat> for DataPacketFormat { type Error = Error; fn try_from(gid_or_dpf: GroupIdOrDataPacketFormat) -> Result<Self> { - DataPacketFormat::from_u8(gid_or_dpf.to_u8().unwrap()).ok_or(Error::InvalidPacketError) + DataPacketFormat::try_from(u8::from(gid_or_dpf)).or(Err(Error::InvalidPacketError)) } } @@ -293,12 +306,28 @@ impl UciControlPacketHeader { } } +// Helper methods to extract the UCI Packet header fields. +fn get_mt_from_uci_packet(packet: &[u8]) -> u8 { + (packet[UCI_HEADER_MT_BYTE_POSITION] >> UCI_HEADER_MT_BIT_SHIFT) & UCI_HEADER_MT_MASK +} + +fn get_pbf_from_uci_packet(packet: &[u8]) -> u8 { + (packet[UCI_HEADER_PBF_BYTE_POSITION] >> UCI_HEADER_PBF_BIT_SHIFT) & UCI_HEADER_PBF_MASK +} + +fn get_gid_from_uci_control_packet(packet: &[u8]) -> u8 { + packet[UCI_CONTROL_HEADER_GID_BYTE_POSITION] & UCI_CONTROL_HEADER_GID_MASK +} + +fn get_oid_from_uci_control_packet(packet: &[u8]) -> u8 { + packet[UCI_CONTROL_HEADER_OID_BYTE_POSITION] & UCI_CONTROL_HEADER_OID_MASK +} + // This function parses the packet bytes to return the Control Packet Opcode (OID) field. The // caller should check that the packet bytes represent a UCI control packet. The code will not // panic because UciPacketHal::to_bytes() should always be larger then the place we access. fn get_opcode_from_uci_control_packet(packet: &UciPacketHal) -> u8 { - packet.clone().to_bytes()[UCI_CONTROL_PACKET_HEADER_OPCODE_BYTE_POSITION] - & UCI_CONTROL_PACKET_HEADER_OPCODE_MASK + get_oid_from_uci_control_packet(&packet.clone().to_bytes()) } fn is_uci_control_packet(message_type: MessageType) -> bool { @@ -384,6 +413,25 @@ impl TryFrom<Vec<UciPacketHal>> for UciControlPacket { } } +#[derive(Debug, Clone)] +pub struct RawUciControlPacket { + pub mt: u8, + pub gid: u8, + pub oid: u8, + pub payload: Vec<u8>, +} + +impl RawUciControlPacket { + // Match the GID and OID to confirm the UCI packet (represented by header) is + // the same as the stored signature. We don't match the MT because they can be + // different (eg: CMD/RSP pair). + pub fn is_same_signature_bytes(&self, header: &[u8]) -> bool { + let gid = get_gid_from_uci_control_packet(header); + let oid = get_oid_from_uci_control_packet(header); + gid == self.gid && oid == self.oid + } +} + // UCI Data packet functions. fn is_uci_data_rcv_packet(message_type: MessageType, data_packet_format: DataPacketFormat) -> bool { message_type == MessageType::Data && data_packet_format == DataPacketFormat::DataRcv @@ -541,15 +589,42 @@ pub struct PacketDefrager { control_fragment_cache: Vec<UciPacketHal>, // TODO(b/261762781): Prefer this to be UciDataPacketHal data_fragment_cache: Vec<UciPacketHal>, + // Raw packet payload bytes cache + raw_fragment_cache: Vec<u8>, } pub enum UciDefragPacket { Control(UciControlPacket), Data(UciDataPacket), + Raw(Result<()>, RawUciControlPacket), } impl PacketDefrager { - pub fn defragment_packet(&mut self, msg: &[u8]) -> Option<UciDefragPacket> { + pub fn defragment_packet( + &mut self, + msg: &[u8], + last_raw_cmd: Option<RawUciControlPacket>, + ) -> Option<UciDefragPacket> { + if let Some(raw_cmd) = last_raw_cmd { + let mt_u8 = get_mt_from_uci_packet(msg); + match MessageType::try_from(u8::from(mt_u8)) { + Ok(mt) => match mt { + // Parse only a UCI response packet as a Raw packet. + MessageType::Response => { + return self.defragment_raw_uci_response_packet(msg, raw_cmd); + } + _ => { /* Fallthrough to de-frag as a normal UCI packet below */ } + }, + Err(_) => { + error!("Rx packet from HAL has unrecognized MT={}", mt_u8); + return Some(UciDefragPacket::Raw( + Err(Error::InvalidPacketError), + RawUciControlPacket { mt: mt_u8, gid: 0, oid: 0, payload: Vec::new() }, + )); + } + }; + } + let packet = UciPacketHal::parse(msg) .or_else(|e| { error!("Failed to parse packet: {:?}", e); @@ -596,12 +671,52 @@ impl PacketDefrager { } } } + + fn defragment_raw_uci_response_packet( + &mut self, + msg: &[u8], + raw_cmd: RawUciControlPacket, + ) -> Option<UciDefragPacket> { + let mt_u8 = get_mt_from_uci_packet(msg); + let pbf = get_pbf_from_uci_packet(msg); + let gid = get_gid_from_uci_control_packet(msg); + let oid = get_oid_from_uci_control_packet(msg); + if raw_cmd.is_same_signature_bytes(msg) { + // Store only the packet payload bytes (UCI header should not be stored). + self.raw_fragment_cache.extend_from_slice(&msg[UCI_PACKET_HAL_HEADER_LEN..]); + + if pbf == u8::from(PacketBoundaryFlag::NotComplete) { + return None; + } + + // All fragments received, defragment and return the Raw packet's payload bytes. + return Some(UciDefragPacket::Raw( + Ok(()), + RawUciControlPacket { + mt: mt_u8, + gid, + oid, + payload: self.raw_fragment_cache.drain(..).collect(), + }, + )); + } else { + error!( + "Rx packet from HAL (MT={}, PBF={}, GID={}, OID={}) has non-matching\ + RawCmd signature", + mt_u8, pbf, gid, oid + ); + return Some(UciDefragPacket::Raw( + Err(Error::InvalidPacketError), + RawUciControlPacket { mt: mt_u8, gid, oid, payload: Vec::new() }, + )); + } + } } #[allow(dead_code)] #[derive(Debug, Clone)] pub struct ParsedDiagnosticNtfPacket { - session_id: u32, + session_token: u32, sequence_number: u32, frame_reports: Vec<ParsedFrameReport>, } @@ -618,7 +733,7 @@ pub struct ParsedFrameReport { } pub fn parse_diagnostics_ntf(evt: AndroidRangeDiagnosticsNtf) -> Result<ParsedDiagnosticNtfPacket> { - let session_id = evt.get_session_id(); + let session_token = evt.get_session_token(); let sequence_number = evt.get_sequence_number(); let mut parsed_frame_reports = Vec::new(); for report in evt.get_frame_reports() { @@ -658,7 +773,7 @@ pub fn parse_diagnostics_ntf(evt: AndroidRangeDiagnosticsNtf) -> Result<ParsedDi }); } Ok(ParsedDiagnosticNtfPacket { - session_id, + session_token, sequence_number, frame_reports: parsed_frame_reports, }) @@ -674,8 +789,7 @@ pub enum Controlees { // TODO(ziyiw): Replace these functions after making uwb_uci_packets::Controlee::write_to() public. pub fn write_controlee(controlee: &Controlee) -> BytesMut { let mut buffer = BytesMut::new(); - let short_address = controlee.short_address; - buffer.extend_from_slice(&short_address.to_le_bytes()[0..2]); + buffer.extend_from_slice(&controlee.short_address); let subsession_id = controlee.subsession_id; buffer.extend_from_slice(&subsession_id.to_le_bytes()[0..4]); buffer @@ -683,8 +797,7 @@ pub fn write_controlee(controlee: &Controlee) -> BytesMut { pub fn write_controlee_2_0_16byte(controlee: &Controlee_V2_0_16_Byte_Version) -> BytesMut { let mut buffer = BytesMut::new(); - let short_address = controlee.short_address; - buffer.extend_from_slice(&short_address.to_le_bytes()[0..2]); + buffer.extend_from_slice(&controlee.short_address); let subsession_id = controlee.subsession_id; buffer.extend_from_slice(&subsession_id.to_le_bytes()[0..4]); buffer.extend_from_slice(&controlee.subsession_key); @@ -693,8 +806,7 @@ pub fn write_controlee_2_0_16byte(controlee: &Controlee_V2_0_16_Byte_Version) -> pub fn write_controlee_2_0_32byte(controlee: &Controlee_V2_0_32_Byte_Version) -> BytesMut { let mut buffer = BytesMut::new(); - let short_address = controlee.short_address; - buffer.extend_from_slice(&short_address.to_le_bytes()[0..2]); + buffer.extend_from_slice(&controlee.short_address); let subsession_id = controlee.subsession_id; buffer.extend_from_slice(&subsession_id.to_le_bytes()[0..4]); buffer.extend_from_slice(&controlee.subsession_key); @@ -706,7 +818,7 @@ pub fn write_controlee_2_0_32byte(controlee: &Controlee_V2_0_32_Byte_Version) -> /// This function can build the packet with/without message control, which /// is indicated by action parameter. pub fn build_session_update_controller_multicast_list_cmd( - session_id: u32, + session_token: u32, action: UpdateMulticastListAction, controlees: Controlees, ) -> Result<SessionUpdateControllerMulticastListCmd> { @@ -740,7 +852,7 @@ pub fn build_session_update_controller_multicast_list_cmd( _ => return Err(Error::InvalidPacketError), } Ok(SessionUpdateControllerMulticastListCmdBuilder { - session_id, + session_token, action, payload: Some(controlees_buf.freeze()), } @@ -788,9 +900,12 @@ mod tests { let frame_report = FrameReport { uwb_msg_id: 1, action: 1, antenna_set: 1, frame_report_tlvs: tlvs }; frame_reports.push(frame_report); - let packet = - AndroidRangeDiagnosticsNtfBuilder { session_id: 1, sequence_number: 1, frame_reports } - .build(); + let packet = AndroidRangeDiagnosticsNtfBuilder { + session_token: 1, + sequence_number: 1, + frame_reports, + } + .build(); let mut parsed_packet = parse_diagnostics_ntf(packet).unwrap(); let parsed_frame_report = parsed_packet.frame_reports.pop().unwrap(); assert_eq!(rssi_vec, parsed_frame_report.rssi); @@ -801,7 +916,8 @@ mod tests { #[test] fn test_write_controlee() { - let controlee: Controlee = Controlee { short_address: 2, subsession_id: 3 }; + let short_address: [u8; 2] = [2, 3]; + let controlee: Controlee = Controlee { short_address, subsession_id: 3 }; let bytes = write_controlee(&controlee); let parsed_controlee = Controlee::parse(&bytes).unwrap(); assert_eq!(controlee, parsed_controlee); @@ -809,7 +925,8 @@ mod tests { #[test] fn test_build_multicast_update_packet() { - let controlee = Controlee { short_address: 0x1234, subsession_id: 0x1324_3546 }; + let short_address: [u8; 2] = [0x12, 0x34]; + let controlee = Controlee { short_address, subsession_id: 0x1324_3546 }; let packet: UciControlPacket = build_session_update_controller_multicast_list_cmd( 0x1425_3647, UpdateMulticastListAction::AddControlee, @@ -824,7 +941,7 @@ mod tests { vec![ 0x21, 0x07, 0x00, 0x0c, // 2(packet info), RFU, payload length(12) 0x47, 0x36, 0x25, 0x14, // 4(session id (LE)) - 0x00, 0x01, 0x34, 0x12, // action, # controlee, 2(short address (LE)) + 0x00, 0x01, 0x12, 0x34, // action, # controlee, 2(short address (LE)) 0x46, 0x35, 0x24, 0x13, // 4(subsession id (LE)) ] ); diff --git a/src/rust/uwb_uci_packets/uci_packets.pdl b/src/rust/uwb_uci_packets/uci_packets.pdl index dcf7daa..12bdb6c 100644 --- a/src/rust/uwb_uci_packets/uci_packets.pdl +++ b/src/rust/uwb_uci_packets/uci_packets.pdl @@ -49,6 +49,7 @@ enum CoreOpCode : 6 { CORE_GET_CONFIG = 0x05, CORE_DEVICE_SUSPEND = 0x06, CORE_GENERIC_ERROR_NTF = 0x07, + CORE_QUERY_UWBS_TIMESTAMP = 0x08, } enum SessionConfigOpCode : 6 { @@ -101,6 +102,9 @@ enum StatusCode : 8 { UCI_STATUS_UNKNOWN_OID = 0x08, UCI_STATUS_READ_ONLY = 0x09, UCI_STATUS_COMMAND_RETRY = 0x0A, + UCI_STATUS_UNKNOWN = 0x0B, + UCI_STATUS_NOT_APPLICABLE = 0x0C, + RFU_STATUS_CODE_RANGE_1 = 0x0D..0x10, // UWB Session Specific Status Codes UCI_STATUS_SESSION_NOT_EXIST = 0x11, @@ -112,7 +116,9 @@ enum StatusCode : 8 { UCI_STATUS_MULTICAST_LIST_FULL = 0x17, UCI_STATUS_ADDRESS_NOT_FOUND = 0x18, UCI_STATUS_ADDRESS_ALREADY_PRESENT = 0x19, + UCI_STATUS_ERROR_UWB_INITIATION_TIME_TOO_OLD = 0x1A, UCI_STATUS_OK_NEGATIVE_DISTANCE_REPORT = 0x1B, + RFU_STATUS_CODE_RANGE_2 = 0x1C..0x1F, // UWB Ranging Session Specific Status Codes UCI_STATUS_RANGING_TX_FAILED = 0x20, @@ -125,24 +131,23 @@ enum StatusCode : 8 { UCI_STATUS_RANGING_RX_MAC_IE_MISSING = 0x27, UCI_STATUS_ERROR_ROUND_INDEX_NOT_ACTIVATED = 0x28, UCI_STATUS_ERROR_NUMBER_OF_ACTIVE_RANGING_ROUNDS_EXCEEDED = 0x29, - UCI_STATUS_ERROR_ROUND_INDEX_NOT_SET_AS_INITIATOR = 0x2A, - UCI_STATUS_ERROR_DL_TDOA_DEVICE_ADDRESS_NOT_MATCHING_IN_REPLY_TIME_LIST = 0x2B, + UCI_STATUS_ERROR_DL_TDOA_DEVICE_ADDRESS_NOT_MATCHING_IN_REPLY_TIME_LIST = 0x2A, + RFU_STATUS_CODE_RANGE_3 = 0x2B..0x2F, // UWB Data Session Specific Status Codes UCI_STATUS_DATA_MAX_TX_PSDU_SIZE_EXCEEDED = 0x30, UCI_STATUS_DATA_RX_CRC_ERROR = 0x31, + RFU_STATUS_CODE_RANGE_4 = 0x32..0x4F, // Vendor Specific Status Codes - UCI_STATUS_ERROR_CCC_SE_BUSY = 0x50, - UCI_STATUS_ERROR_CCC_LIFECYCLE = 0x51, - UCI_STATUS_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 0x52, -} + VENDOR_SPECIFIC_STATUS_CODE_RANGE_1 = 0x50..0xFE { + UCI_STATUS_ERROR_CCC_SE_BUSY = 0x50, + UCI_STATUS_ERROR_CCC_LIFECYCLE = 0x51, + UCI_STATUS_ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 0x52, + }, -// This needs a separate type as the Status code values in an OWR for AOA -// Measurement has different values. -enum OwrAoaStatusCode : 8 { - UCI_STATUS_SUCCESS = 0x00, - UCI_STATUS_INTER_FRAME_INTERVAL_TIMEOUT = 0x01, + // For internal usage, we will use 0xFF as default. + VENDOR_SPECIFIC_STATUS_CODE_2 = 0xFF, } // This needs a separate StatusCode as the Status code values in the DATA_RCV packet have @@ -169,12 +174,6 @@ enum DataTransferNtfStatusCode : 8 { UCI_DATA_TRANSFER_STATUS_ERROR_DATA_TRANSFER_IS_ONGOING = 0x06, } -enum FiraComponent : 8 { - UWBS = 0x00, - HOST = 0x01, - SECURE_COMPONENT = 0x02, -} - enum ResetConfig : 8 { UWBS_RESET = 0x00, } @@ -194,7 +193,7 @@ enum AppConfigTlvType : 8 { DEVICE_MAC_ADDRESS = 0x06, DST_MAC_ADDRESS = 0x07, SLOT_DURATION = 0x08, - RANGING_INTERVAL = 0x09, + RANGING_DURATION = 0x09, STS_INDEX = 0x0A, MAC_FCS_TYPE = 0x0B, RANGING_ROUND_CONTROL = 0x0C, @@ -210,6 +209,7 @@ enum AppConfigTlvType : 8 { PSDU_DATA_RATE = 0x16, PREAMBLE_DURATION = 0x17, LINK_LAYER_MODE = 0x18, + DATA_REPETITION_COUNT = 0x19, RANGING_TIME_STRUCT = 0x1A, SLOTS_PER_RR = 0x1B, TX_ADAPTIVE_PAYLOAD_POWER = 0x1C, @@ -238,29 +238,41 @@ enum AppConfigTlvType : 8 { UL_TDOA_TX_INTERVAL = 0x33, UL_TDOA_RANDOM_WINDOW = 0x34, STS_LENGTH = 0x35, + SUSPEND_RANGING_ROUNDS = 0x36, + UL_TDOA_NTF_REPORT_CONFIG = 0x37, UL_TDOA_DEVICE_ID = 0x38, UL_TDOA_TX_TIMESTAMP = 0x39, MIN_FRAMES_PER_RR = 0x3A, MTU_SIZE = 0x3B, INTER_FRAME_INTERVAL = 0x3C, + RFU_APP_CFG_TLV_TYPE_RANGE_1 = 0x3D..0x44, SESSION_KEY = 0x45, SUBSESSION_KEY = 0x46, - - // CCC specific - CCC_HOP_MODE_KEY = 0xA0, - CCC_UWB_TIME0 = 0xA1, - CCC_RANGING_PROTOCOL_VER = 0xA3, - CCC_UWB_CONFIG_ID = 0xA4, - CCC_PULSESHAPE_COMBO = 0xA5, - CCC_URSK_TTL = 0xA6, - - // Interleaving ratio if AOA_RESULT_REQ is set to 0xF0. - NB_OF_RANGE_MEASUREMENTS = 0xE3, - NB_OF_AZIMUTH_MEASUREMENTS = 0xE4, - NB_OF_ELEVATION_MEASUREMENTS = 0xE5, - - ENABLE_DIAGNOSTICS = 0xE8, - DIAGRAMS_FRAME_REPORTS_FIELDS = 0xE9, + SESSION_DATA_TRANSFER_STATUS_NTF_CONFIG = 0x47, + RFU_APP_CFG_TLV_TYPE_RANGE_2 = 0x48..0x9F, + + VENDOR_SPECIFIC_APP_CFG_TLV_TYPE_RANGE_1 = 0xA0..0xDF { + // CCC specific + CCC_HOP_MODE_KEY = 0xA0, + CCC_UWB_TIME0 = 0xA1, + CCC_RANGING_PROTOCOL_VER = 0xA3, + CCC_UWB_CONFIG_ID = 0xA4, + CCC_PULSESHAPE_COMBO = 0xA5, + CCC_URSK_TTL = 0xA6, + CCC_LAST_INDEX_USED = 0xA8, + }, + + // Reserved for extension IDs. + RFU_APP_CFG_TLV_TYPE_RANGE_3 = 0xE0..0xE2, + + VENDOR_SPECIFIC_APP_CFG_TLV_TYPE_RANGE_2 = 0xE3..0xFF { + // Interleaving ratio if AOA_RESULT_REQ is set to 0xF0. + NB_OF_RANGE_MEASUREMENTS = 0xE3, + NB_OF_AZIMUTH_MEASUREMENTS = 0xE4, + NB_OF_ELEVATION_MEASUREMENTS = 0xE5, + ENABLE_DIAGNOSTICS = 0xE8, + DIAGRAMS_FRAME_REPORTS_FIELDS = 0xE9, + }, } enum FrameReportTlvType : 8 { @@ -290,26 +302,34 @@ enum CapTlvType : 8 { SUPPORTED_EXTENDED_MAC_ADDRESS = 0x11, SUPPORTED_MAX_MESSAGE_SIZE = 0x12, SUPPORTED_MAX_DATA_PACKET_PAYLOAD_SIZE = 0x13, - SUPPORTED_AOA_RESULT_REQ_ANTENNA_INTERLEAVING = 0xE3, - SUPPORTED_MIN_RANGING_INTERVAL_MS = 0xE4, - SUPPORTED_RANGE_DATA_NTF_CONFIG = 0xE5, - SUPPORTED_RSSI_REPORTING = 0xE6, - SUPPORTED_DIAGNOSTICS = 0xE7, - SUPPORTED_MIN_SLOT_DURATION_RSTU = 0xE8, - SUPPORTED_MAX_RANGING_SESSION_NUMBER = 0xE9, - - // CCC specific - CCC_SUPPORTED_CHAPS_PER_SLOT = 0xA0, - CCC_SUPPORTED_SYNC_CODES = 0xA1, - CCC_SUPPORTED_HOPPING_CONFIG_MODES_AND_SEQUENCES = 0xA2, - CCC_SUPPORTED_CHANNELS = 0xA3, - CCC_SUPPORTED_VERSIONS = 0xA4, - CCC_SUPPORTED_UWB_CONFIGS = 0xA5, - CCC_SUPPORTED_PULSE_SHAPE_COMBOS = 0xA6, - CCC_SUPPORTED_RAN_MULTIPLIER = 0xA7, - CCC_SUPPORTED_MAX_RANGING_SESSION_NUMBER = 0xA8, + RFU_CAP_TLV_TYPE_RANGE_1 = 0x14..0x9F, + + VENDOR_SPECIFIC_CAP_TLV_TYPE_RANGE_1 = 0xA0..0xBF { + // CCC specific + CCC_SUPPORTED_CHAPS_PER_SLOT = 0xA0, + CCC_SUPPORTED_SYNC_CODES = 0xA1, + CCC_SUPPORTED_HOPPING_CONFIG_MODES_AND_SEQUENCES = 0xA2, + CCC_SUPPORTED_CHANNELS = 0xA3, + CCC_SUPPORTED_VERSIONS = 0xA4, + CCC_SUPPORTED_UWB_CONFIGS = 0xA5, + CCC_SUPPORTED_PULSE_SHAPE_COMBOS = 0xA6, + CCC_SUPPORTED_RAN_MULTIPLIER = 0xA7, + CCC_SUPPORTED_MAX_RANGING_SESSION_NUMBER = 0xA8, + }, SUPPORTED_POWER_STATS = 0xC0, + VENDOR_SPECIFIC_CAP_TLV_TYPE_RANGE_2 = 0xC1..0xDF, + RFU_CAP_TLV_TYPE_RANGE_2 = 0xE0..0xE2, + + VENDOR_SPECIFIC_CAP_TLV_TYPE_RANGE_3 = 0xE3..0xFF { + SUPPORTED_AOA_RESULT_REQ_ANTENNA_INTERLEAVING = 0xE3, + SUPPORTED_MIN_RANGING_INTERVAL_MS = 0xE4, + SUPPORTED_RANGE_DATA_NTF_CONFIG = 0xE5, + SUPPORTED_RSSI_REPORTING = 0xE6, + SUPPORTED_DIAGNOSTICS = 0xE7, + SUPPORTED_MIN_SLOT_DURATION_RSTU = 0xE8, + SUPPORTED_MAX_RANGING_SESSION_NUMBER = 0xE9, + }, } @@ -343,6 +363,7 @@ enum ReasonCode : 8 { SESSION_SUSPENDED_DUE_TO_INBAND_SIGNAL = 0x03, SESSION_RESUMED_DUE_TO_INBAND_SIGNAL = 0x04, SESSION_STOPPED_DUE_TO_INBAND_SIGNAL = 0x05, + RFU_REASON_CODE_RANGE_1 = 0x06..0x1C, ERROR_INVALID_UL_TDOA_RANDOM_WINDOW = 0x1D, ERROR_MIN_RFRAMES_PER_RR_NOT_SUPPORTED = 0x1E, ERROR_TX_DELAY_NOT_SUPPORTED = 0x1F, @@ -378,10 +399,16 @@ enum ReasonCode : 8 { ERROR_REF_UWB_SESSION_RANGING_DURATION_MISMATCH = 0x3D, ERROR_REF_UWB_SESSION_INVALID_OFFSET_TIME = 0x3E, ERROR_REF_UWB_SESSION_LOST = 0x3F, - // TODO(b/272775225): Add a range for the vendor specific space, after PDL supports - // this feature (requested in b/267339120). - ERROR_INVALID_CHANNEL_WITH_AOA = 0x80, - ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 0x81, + RFU_REASON_CODE_RANGE_2 = 0x40..0x7F { + ERROR_DT_ANCHOR_RANGING_ROUNDS_NOT_CONFIGURED = 0x40, + ERROR_DT_TAG_RANGING_ROUNDS_NOT_CONFIGURED = 0x41, + }, + VENDOR_SPECIFIC_REASON_CODE_RANGE_1 = 0x80..0xFE { + ERROR_INVALID_CHANNEL_WITH_AOA = 0x80, + ERROR_STOPPED_DUE_TO_OTHER_SESSION_CONFLICT = 0x81, + }, + // For internal usage, we will use 0xFF as default. + VENDOR_SPECIFIC_REASON_CODE_2 = 0xFF, } enum MulticastUpdateStatusCode : 8 { @@ -403,6 +430,7 @@ enum SessionType: 8 { FIRA_RANGING_SESSION = 0x00, FIRA_DATA_TRANSFER = 0x01, CCC = 0xA0, + DEVICE_TEST_MODE = 0xD0, } enum MessageType: 3 { @@ -482,21 +510,18 @@ packet UciDataPacket { } packet UciDataSnd : UciDataPacket (data_packet_format = DATA_SND, message_type = DATA) { - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) dest_mac_address: 64, - dest_fira_component: FiraComponent, - uci_sequence_number: 8, + uci_sequence_number: 16, _size_(data): 16, data: 8[] } packet UciDataRcv : UciDataPacket (data_packet_format = DATA_RCV, message_type = DATA) { - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) status: DataRcvStatusCode, - uci_sequence_number: 32, source_mac_address: 64, - source_fira_component: FiraComponent, - dest_fira_component: FiraComponent, + uci_sequence_number: 16, _size_(data): 16, data: 8[] } @@ -659,6 +684,7 @@ packet SetConfigRsp : CoreResponse (opcode = 0x4) { //CORE_SET_CONFIG test SetConfigRsp { "\x40\x04\x00\x04\x00\x00\x00\x01\x01\x01\x01", + "\x40\x04\x00\x04\x00\x00\x00\x01\x01\x01\x0B", } packet GetConfigCmd : CoreCommand (opcode = 0x5) { //CORE_GET_CONFIG @@ -688,6 +714,23 @@ test GenericError { "\x60\x07\x00\x01\x00\x00\x00\x01", } + +packet CoreQueryTimeStampCmd : CoreCommand (opcode = 0x8) { //CORE_QUERY_UWBS_TIMESTAMP +} + +test CoreQueryTimeStampCmd { + "\x20\x08\x00\\x00", +} + +packet CoreQueryTimeStampRsp : CoreResponse (opcode = 0x8) { //CORE_QUERY_UWBS_TIMESTAMP + status: StatusCode, + timeStamp: 64, +} + +test CoreQueryTimeStampRsp { + "\x40\x08\x00\x09\x00\x00\x00\x01\x01\x00\x01\x01\x01", +} + packet SessionInitCmd : SessionConfigCommand (opcode = 0x0) { //SESSION_INIT session_id: 32, session_type: SessionType, @@ -697,6 +740,17 @@ test SessionInitCmd { "\x21\x00\x00\x05\x00\x00\x00\x01\x02\x03\x04\x01", } +// FIRA version 2 introduces a new version of SESSION_INIT_RSP which +// includes UWBS generated session handle. +packet SessionInitRsp_V2 : SessionConfigResponse (opcode = 0x0) { //SESSION_INIT + status: StatusCode, + session_handle: 32, +} + +test SessionInitRsp_V2 { + "\x41\x00\x00\x01\x00\x00\x00\x11\x00\x00\x00\x01", +} + packet SessionInitRsp : SessionConfigResponse (opcode = 0x0) { //SESSION_INIT status: StatusCode, } @@ -706,7 +760,7 @@ test SessionInitRsp { } packet SessionDeinitCmd : SessionConfigCommand (opcode = 0x1) { //SESSION_DEINIT - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) } test SessionDeinitCmd { @@ -722,7 +776,7 @@ test SessionDeinitRsp { } packet SessionStatusNtf : SessionConfigNotification (opcode = 0x2) { //SESSION_STATUS_NTF - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) session_state: SessionState, // TODO(b/272775225): Switch back to the enum type ReasonCode, once PDL supports defining a // range inside an enum (for the vendor-specific space), in b/267339120. @@ -741,7 +795,7 @@ struct AppConfigTlv { } packet SessionSetAppConfigCmd : SessionConfigCommand (opcode = 0x3) { //SESSION_SET_APP_CONFIG - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) _count_(tlvs): 8, tlvs: AppConfigTlv[] } @@ -766,7 +820,7 @@ test SessionSetAppConfigRsp { } packet SessionGetAppConfigCmd : SessionConfigCommand (opcode = 0x4) { //SESSION_GET_APP_CONFIG - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) _count_(app_cfg): 8, app_cfg: 8[], // AppConfigTlvType (Infra does not allow array of enums) } @@ -802,7 +856,7 @@ test SessionGetCountRsp { } packet SessionGetStateCmd : SessionConfigCommand (opcode = 0x6) { //SESSION_GET_STATE - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) } test SessionGetStateCmd { @@ -818,39 +872,39 @@ test SessionGetStateRsp { "\x41\x06\x00\x02\x00\x00\x00\x00\x01", } -packet SessionUpdateActiveRoundsDtTagCmd : SessionConfigCommand (opcode = 0x9) { //SESSION_UPDATE_ACTIVE_ROUNDS_DT_TAG - session_id: 32, +packet SessionUpdateDtTagRangingRoundsCmd : SessionConfigCommand (opcode = 0x9) { //SESSION_UPDATE_ACTIVE_ROUNDS_DT_TAG + session_token: 32, // Session ID or Session Handle (based on UWBS version) _count_(ranging_round_indexes): 8, ranging_round_indexes: 8[], } -test SessionUpdateActiveRoundsDtTagCmd { +test SessionUpdateDtTagRangingRoundsCmd { "\x21\x09\x00\x0a\x00\x00\x00\x03\x03\x0f\x0c\x05\x08\x00\x00\x00\x00", } -packet SessionUpdateActiveRoundsDtTagRsp : SessionConfigResponse (opcode = 0x9) { //SESSION_UPDATE_ACTIVE_ROUNDS_DT_TAG +packet SessionUpdateDtTagRangingRoundsRsp : SessionConfigResponse (opcode = 0x9) { //SESSION_UPDATE_ACTIVE_ROUNDS_DT_TAG status: StatusCode, _count_(ranging_round_indexes): 8, ranging_round_indexes: 8[], } -test SessionUpdateActiveRoundsDtTagRsp { +test SessionUpdateDtTagRangingRoundsRsp { "\x41\x09\x00\x03\x00\x00\x00\x01\x01\x01", } struct Controlee { - short_address: 16, + short_address: 8[2], subsession_id: 32, } struct Controlee_V2_0_16_Byte_Version { - short_address: 16, + short_address: 8[2], subsession_id: 32, subsession_key: 8[16], } struct Controlee_V2_0_32_Byte_Version { - short_address: 16, + short_address: 8[2], subsession_id: 32, subsession_key: 8[32], } @@ -863,7 +917,7 @@ enum UpdateMulticastListAction: 8 { } packet SessionUpdateControllerMulticastListCmd : SessionConfigCommand (opcode = 0x7) { //SESSION_UPDATE_CONTROLLER_MULTICAST_LIST - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) action: UpdateMulticastListAction, _payload_, } @@ -892,13 +946,13 @@ test SessionUpdateControllerMulticastListRsp { } struct ControleeStatus { - mac_address: 16, + mac_address: 8[2], subsession_id: 32, status: MulticastUpdateStatusCode, } packet SessionUpdateControllerMulticastListNtf : SessionConfigNotification (opcode = 0x7) { //SESSION_UPDATE_CONTROLLER_MULTICAST_LIST - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) remaining_multicast_list_size: 8, _count_(controlee_status): 8, controlee_status: ControleeStatus[], @@ -909,7 +963,7 @@ test SessionUpdateControllerMulticastListNtf { } packet DataCreditNtf : SessionControlNotification (opcode = 0x04) { // SESSION_DATA_CREDIT_NTF - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) credit_availability: CreditAvailability, } @@ -918,18 +972,35 @@ test DataCreditNtf { } packet DataTransferStatusNtf : SessionControlNotification (opcode = 0x05) { // SESSION_DATA_TRANSFER_STATUS_NTF - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) uci_sequence_number: 8, status: DataTransferNtfStatusCode, - // TODO(b/261886903): Add the tx_count field for implementing the DATA_REPETITION added in CR490. + tx_count: 8, } test DataTransferStatusNtf { - "\x62\x05\x00\x06\x00\x00\x00\x00\x00\x00\x01\x01\x00", + "\x62\x05\x00\x06\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00", +} + +packet SessionQueryMaxDataSizeCmd : SessionConfigCommand (opcode = 0xB) { //QUERY_MAX_DATA_SIZE + session_token: 32, // Session ID or Session Handle (based on UWBS version) +} + +test SessionQueryMaxDataSizeCmd { + "\x21\x0B\x00\x04\x00\x00\x00\x00", +} + +packet SessionQueryMaxDataSizeRsp : SessionConfigResponse (opcode = 0xB) { //QUER_MAX_DATA_SIZE + session_token: 32, // Session ID or Session Handle (based on UWBS version) + max_data_size: 16, +} + +test SessionQueryMaxDataSizeRsp { + "\x41\x0B\x00\x06\x00\x00\x00\x00\x0E7\0x07", } packet SessionStartCmd : SessionControlCommand (opcode = 0x0) { //RANGE_START - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) } test SessionStartCmd { @@ -986,7 +1057,7 @@ struct ExtendedAddressTwoWayRangingMeasurement { struct ShortAddressOwrAoaRangingMeasurement { mac_address: 16, - status: OwrAoaStatusCode, + status: StatusCode, nlos: 8, frame_sequence_number: 8, block_index: 16, @@ -998,7 +1069,7 @@ struct ShortAddressOwrAoaRangingMeasurement { struct ExtendedAddressOwrAoaRangingMeasurement { mac_address: 64, - status: OwrAoaStatusCode, + status: StatusCode, nlos: 8, frame_sequence_number: 8, block_index: 16, @@ -1017,7 +1088,7 @@ enum RangingMeasurementType : 8 { packet SessionInfoNtf : SessionControlNotification (opcode = 0x0) { // SESSION_INFO sequence_number: 32, - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) rcr_indicator: 8, current_ranging_interval: 32, ranging_measurement_type: RangingMeasurementType, @@ -1088,7 +1159,7 @@ test ExtendedMacOwrAoaSessionInfoNtf { } packet SessionStopCmd : SessionControlCommand (opcode = 0x1) { // SESSION_STOP - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) } test SessionStopCmd { @@ -1104,7 +1175,7 @@ test SessionStopRsp { } packet SessionGetRangingCountCmd : SessionControlCommand (opcode = 0x3) { // SESSION_GET_RANGING_COUNT - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) } test SessionGetRangingCountCmd { @@ -1223,7 +1294,7 @@ struct FrameReport { } packet AndroidRangeDiagnosticsNtf : AndroidNotification (opcode = 0x2) { //FIRA_RANGE_DIAGNOSTICS - session_id: 32, + session_token: 32, // Session ID or Session Handle (based on UWBS version) sequence_number: 32, _count_(frame_reports): 8, frame_reports: FrameReport[], @@ -1273,3 +1344,7 @@ packet UciVendor_E_Notification : UciNotification (group_id = VENDOR_RESERVED_E) packet UciVendor_F_Notification : UciNotification (group_id = VENDOR_RESERVED_F) { _payload_, } + +packet TestNotification : UciNotification (group_id = TEST) { + _payload_, +} |