• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022, 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 #![allow(clippy::all)]
16 #![allow(non_upper_case_globals)]
17 #![allow(non_camel_case_types)]
18 #![allow(non_snake_case)]
19 #![allow(unused)]
20 #![allow(missing_docs)]
21 
22 use std::cmp;
23 
24 use log::error;
25 use num_derive::FromPrimitive;
26 use num_traits::FromPrimitive;
27 use zeroize::Zeroize;
28 
29 mod debug_display;
30 
31 include!(concat!(env!("OUT_DIR"), "/uci_packets.rs"));
32 
33 const MAX_PAYLOAD_LEN: usize = 255;
34 // TODO: Use a PDL struct to represent the headers and avoid hardcoding
35 // lengths below.
36 // Real UCI packet header len.
37 pub const UCI_PACKET_HAL_HEADER_LEN: usize = 4;
38 // Unfragmented UCI packet header len.
39 pub const UCI_PACKET_HEADER_LEN: usize = 7;
40 // Unfragmented UCI DATA_MESSAGE_SND packet header len.
41 const UCI_DATA_SND_PACKET_HEADER_LEN: usize = 6;
42 
43 // Opcode field byte position (within UCI packet header) and mask (of bits to be used).
44 const UCI_HEADER_MT_BYTE_POSITION: usize = 0;
45 const UCI_HEADER_MT_BIT_SHIFT: u8 = 5;
46 const UCI_HEADER_MT_MASK: u8 = 0x7;
47 
48 const UCI_HEADER_PBF_BYTE_POSITION: usize = 0;
49 const UCI_HEADER_PBF_BIT_SHIFT: u8 = 4;
50 const UCI_HEADER_PBF_MASK: u8 = 0x1;
51 
52 const UCI_CONTROL_HEADER_GID_BYTE_POSITION: usize = 0;
53 const UCI_CONTROL_HEADER_GID_MASK: u8 = 0xF;
54 
55 const UCI_CONTROL_HEADER_OID_BYTE_POSITION: usize = 1;
56 const UCI_CONTROL_HEADER_OID_MASK: u8 = 0x3F;
57 
58 // Radar field lengths
59 pub const UCI_RADAR_SEQUENCE_NUMBER_LEN: usize = 4;
60 pub const UCI_RADAR_TIMESTAMP_LEN: usize = 4;
61 pub const UCI_RADAR_VENDOR_DATA_LEN_LEN: usize = 1;
62 
63 #[derive(Debug, Clone, PartialEq, FromPrimitive)]
64 pub enum TimeStampLength {
65     Timestamp40Bit = 0x0,
66     Timestamp64Bit = 0x1,
67 }
68 
69 #[derive(Debug, Clone, PartialEq, FromPrimitive)]
70 pub enum DTAnchorLocationType {
71     NotIncluded = 0x0,
72     Wgs84 = 0x1,
73     Relative = 0x2,
74 }
75 
76 #[allow(dead_code)]
77 #[derive(Debug, Clone, PartialEq)]
78 pub struct DlTdoaRangingMeasurement {
79     pub status: u8,
80     pub message_type: u8,
81     pub message_control: u16,
82     pub block_index: u16,
83     pub round_index: u8,
84     pub nlos: u8,
85     pub aoa_azimuth: u16,
86     pub aoa_azimuth_fom: u8,
87     pub aoa_elevation: u16,
88     pub aoa_elevation_fom: u8,
89     pub rssi: u8,
90     pub tx_timestamp: u64,
91     pub rx_timestamp: u64,
92     pub anchor_cfo: u16,
93     pub cfo: u16,
94     pub initiator_reply_time: u32,
95     pub responder_reply_time: u32,
96     pub initiator_responder_tof: u16,
97     pub dt_anchor_location: Vec<u8>,
98     pub ranging_rounds: Vec<u8>,
99     total_size: usize,
100 }
101 
102 impl DlTdoaRangingMeasurement {
parse_one(bytes: &[u8]) -> Option<Self>103     pub fn parse_one(bytes: &[u8]) -> Option<Self> {
104         let mut ptr = 0;
105         let status = extract_u8(bytes, &mut ptr, 1)?;
106         let message_type = extract_u8(bytes, &mut ptr, 1)?;
107         let message_control = extract_u16(bytes, &mut ptr, 2)?;
108         let block_index = extract_u16(bytes, &mut ptr, 2)?;
109         let round_index = extract_u8(bytes, &mut ptr, 1)?;
110         let nlos = extract_u8(bytes, &mut ptr, 1)?;
111         let aoa_azimuth = extract_u16(bytes, &mut ptr, 2)?;
112         let aoa_azimuth_fom = extract_u8(bytes, &mut ptr, 1)?;
113         let aoa_elevation = extract_u16(bytes, &mut ptr, 2)?;
114         let aoa_elevation_fom = extract_u8(bytes, &mut ptr, 1)?;
115         let rssi = extract_u8(bytes, &mut ptr, 1)?;
116         let tx_timestamp_length = (message_control >> 1) & 0x1;
117         let tx_timestamp = match TimeStampLength::from_u16(tx_timestamp_length)? {
118             TimeStampLength::Timestamp40Bit => extract_u64(bytes, &mut ptr, 5)?,
119             TimeStampLength::Timestamp64Bit => extract_u64(bytes, &mut ptr, 8)?,
120         };
121         let rx_timestamp_length = (message_control >> 3) & 0x1;
122         let rx_timestamp = match TimeStampLength::from_u16(rx_timestamp_length)? {
123             TimeStampLength::Timestamp40Bit => extract_u64(bytes, &mut ptr, 5)?,
124             TimeStampLength::Timestamp64Bit => extract_u64(bytes, &mut ptr, 8)?,
125         };
126         let anchor_cfo = extract_u16(bytes, &mut ptr, 2)?;
127         let cfo = extract_u16(bytes, &mut ptr, 2)?;
128         let initiator_reply_time = extract_u32(bytes, &mut ptr, 4)?;
129         let responder_reply_time = extract_u32(bytes, &mut ptr, 4)?;
130         let initiator_responder_tof = extract_u16(bytes, &mut ptr, 2)?;
131         let dt_location_type = (message_control >> 5) & 0x3;
132         let dt_anchor_location = match DTAnchorLocationType::from_u16(dt_location_type)? {
133             DTAnchorLocationType::Wgs84 => extract_vec(bytes, &mut ptr, 12)?,
134             DTAnchorLocationType::Relative => extract_vec(bytes, &mut ptr, 10)?,
135             _ => vec![],
136         };
137         let active_ranging_rounds = ((message_control >> 7) & 0xf) as u8;
138         let ranging_round = extract_vec(bytes, &mut ptr, active_ranging_rounds as usize)?;
139 
140         Some(DlTdoaRangingMeasurement {
141             status,
142             message_type,
143             message_control,
144             block_index,
145             round_index,
146             nlos,
147             aoa_azimuth,
148             aoa_azimuth_fom,
149             aoa_elevation,
150             aoa_elevation_fom,
151             rssi,
152             tx_timestamp,
153             rx_timestamp,
154             anchor_cfo,
155             cfo,
156             initiator_reply_time,
157             responder_reply_time,
158             initiator_responder_tof,
159             dt_anchor_location: dt_anchor_location.to_vec(),
160             ranging_rounds: ranging_round.to_vec(),
161             total_size: ptr,
162         })
163     }
get_total_size(&self) -> usize164     pub fn get_total_size(&self) -> usize {
165         self.total_size
166     }
167 }
168 
169 #[derive(Debug, Clone, PartialEq)]
170 pub struct ShortAddressDlTdoaRangingMeasurement {
171     pub mac_address: u16,
172     pub measurement: DlTdoaRangingMeasurement,
173 }
174 
175 impl ShortAddressDlTdoaRangingMeasurement {
176     /// Parse the `payload` byte buffer from PDL to the vector of measurement.
parse(bytes: &[u8], no_of_ranging_measurement: u8) -> Option<Vec<Self>>177     pub fn parse(bytes: &[u8], no_of_ranging_measurement: u8) -> Option<Vec<Self>> {
178         let mut ptr = 0;
179         let mut measurements = vec![];
180         let mut count = 0;
181         while (count < no_of_ranging_measurement) {
182             let mac_address = extract_u16(bytes, &mut ptr, 2)?;
183             let rem = &bytes[ptr..];
184             let measurement = DlTdoaRangingMeasurement::parse_one(rem);
185             match measurement {
186                 Some(measurement) => {
187                     ptr += measurement.get_total_size();
188                     measurements
189                         .push(ShortAddressDlTdoaRangingMeasurement { mac_address, measurement });
190                     count = count + 1;
191                 }
192                 None => return None,
193             }
194         }
195         Some(measurements)
196     }
197 }
198 
199 #[derive(Debug, Clone, PartialEq)]
200 pub struct ExtendedAddressDlTdoaRangingMeasurement {
201     pub mac_address: u64,
202     pub measurement: DlTdoaRangingMeasurement,
203 }
204 
205 impl ExtendedAddressDlTdoaRangingMeasurement {
206     /// Parse the `payload` byte buffer from PDL to the vector of measurement.
parse(bytes: &[u8], no_of_ranging_measurement: u8) -> Option<Vec<Self>>207     pub fn parse(bytes: &[u8], no_of_ranging_measurement: u8) -> Option<Vec<Self>> {
208         let mut ptr = 0;
209         let mut measurements = vec![];
210         let mut count = 0;
211         while (count < no_of_ranging_measurement) {
212             let mac_address = extract_u64(bytes, &mut ptr, 8)?;
213             let rem = &bytes[ptr..];
214             let measurement = DlTdoaRangingMeasurement::parse_one(rem);
215             match measurement {
216                 Some(measurement) => {
217                     ptr += measurement.get_total_size();
218                     measurements
219                         .push(ExtendedAddressDlTdoaRangingMeasurement { mac_address, measurement });
220                     count = count + 1;
221                 }
222                 None => return None,
223             }
224         }
225         Some(measurements)
226     }
227 }
228 
extract_vec(bytes: &[u8], ptr: &mut usize, consumed_size: usize) -> Option<Vec<u8>>229 pub fn extract_vec(bytes: &[u8], ptr: &mut usize, consumed_size: usize) -> Option<Vec<u8>> {
230     if bytes.len() < *ptr + consumed_size {
231         return None;
232     }
233 
234     let res = bytes[*ptr..*ptr + consumed_size].to_vec();
235     *ptr += consumed_size;
236     Some(res)
237 }
238 
239 /// Generate the function that extracts the value from byte buffers.
240 macro_rules! generate_extract_func {
241     ($func_name:ident, $type:ty) => {
242         /// Extract the value from |byte[ptr..ptr + consumed_size]| in little endian.
243         fn $func_name(bytes: &[u8], ptr: &mut usize, consumed_size: usize) -> Option<$type> {
244             const type_size: usize = std::mem::size_of::<$type>();
245             if consumed_size > type_size {
246                 return None;
247             }
248 
249             let extracted_bytes = extract_vec(bytes, ptr, consumed_size)?;
250             let mut le_bytes = [0; type_size];
251             le_bytes[0..consumed_size].copy_from_slice(&extracted_bytes);
252             Some(<$type>::from_le_bytes(le_bytes))
253         }
254     };
255 }
256 
257 generate_extract_func!(extract_u8, u8);
258 generate_extract_func!(extract_u16, u16);
259 generate_extract_func!(extract_u32, u32);
260 generate_extract_func!(extract_u64, u64);
261 
262 // The GroupIdOrDataPacketFormat enum has all the values defined in both the GroupId and
263 // DataPacketFormat enums. It represents the same bits in UCI packet header - the GID field in
264 // a UCI control packet, and the DataPacketFormat field in a UCI data packet. Hence the unwrap()
265 // calls in the conversions below should always succeed (as long as care is taken in future, to
266 // keep the two enums in sync, for any additional values defined in the UCI spec).
267 impl From<GroupId> for GroupIdOrDataPacketFormat {
from(gid: GroupId) -> Self268     fn from(gid: GroupId) -> Self {
269         GroupIdOrDataPacketFormat::try_from(u8::from(gid)).unwrap()
270     }
271 }
272 
273 impl From<GroupIdOrDataPacketFormat> for GroupId {
from(gid_or_dpf: GroupIdOrDataPacketFormat) -> Self274     fn from(gid_or_dpf: GroupIdOrDataPacketFormat) -> Self {
275         GroupId::try_from(u8::from(gid_or_dpf)).unwrap()
276     }
277 }
278 
279 impl From<DataPacketFormat> for GroupIdOrDataPacketFormat {
from(dpf: DataPacketFormat) -> Self280     fn from(dpf: DataPacketFormat) -> Self {
281         GroupIdOrDataPacketFormat::try_from(u8::from(dpf)).unwrap()
282     }
283 }
284 
285 // The GroupIdOrDataPacketFormat enum has more values defined (for the GroupId bits) than the
286 // DataPacketFormat enum. Hence this is implemented as TryFrom() instead of From().
287 impl TryFrom<GroupIdOrDataPacketFormat> for DataPacketFormat {
288     type Error = DecodeError;
289 
try_from(gid_or_dpf: GroupIdOrDataPacketFormat) -> Result<Self, DecodeError>290     fn try_from(gid_or_dpf: GroupIdOrDataPacketFormat) -> Result<Self, DecodeError> {
291         DataPacketFormat::try_from(u8::from(gid_or_dpf)).or(Err(DecodeError::InvalidPacketError))
292     }
293 }
294 
295 // Container for UCI packet header fields.
296 struct UciControlPacketHeader {
297     message_type: MessageType,
298     group_id: GroupId,
299     opcode: u8,
300 }
301 
302 impl UciControlPacketHeader {
new(message_type: MessageType, group_id: GroupId, opcode: u8) -> Result<Self, DecodeError>303     fn new(message_type: MessageType, group_id: GroupId, opcode: u8) -> Result<Self, DecodeError> {
304         if !is_uci_control_packet(message_type) {
305             return Err(DecodeError::InvalidPacketError);
306         }
307 
308         Ok(UciControlPacketHeader {
309             message_type: message_type,
310             group_id: group_id,
311             opcode: opcode,
312         })
313     }
314 }
315 
316 // Helper methods to extract the UCI Packet header fields.
get_mt_from_uci_packet(packet: &[u8]) -> u8317 fn get_mt_from_uci_packet(packet: &[u8]) -> u8 {
318     (packet[UCI_HEADER_MT_BYTE_POSITION] >> UCI_HEADER_MT_BIT_SHIFT) & UCI_HEADER_MT_MASK
319 }
320 
get_pbf_from_uci_packet(packet: &[u8]) -> u8321 fn get_pbf_from_uci_packet(packet: &[u8]) -> u8 {
322     (packet[UCI_HEADER_PBF_BYTE_POSITION] >> UCI_HEADER_PBF_BIT_SHIFT) & UCI_HEADER_PBF_MASK
323 }
324 
get_gid_from_uci_control_packet(packet: &[u8]) -> u8325 fn get_gid_from_uci_control_packet(packet: &[u8]) -> u8 {
326     packet[UCI_CONTROL_HEADER_GID_BYTE_POSITION] & UCI_CONTROL_HEADER_GID_MASK
327 }
328 
get_oid_from_uci_control_packet(packet: &[u8]) -> u8329 fn get_oid_from_uci_control_packet(packet: &[u8]) -> u8 {
330     packet[UCI_CONTROL_HEADER_OID_BYTE_POSITION] & UCI_CONTROL_HEADER_OID_MASK
331 }
332 
333 // This function parses the packet bytes to return the Control Packet Opcode (OID) field. The
334 // caller should check that the packet bytes represent a UCI control packet. The code will not
335 // panic because UciPacketHal::encode_to_bytes() should always be larger then the place we access.
get_opcode_from_uci_control_packet(packet: &UciPacketHal) -> u8336 fn get_opcode_from_uci_control_packet(packet: &UciPacketHal) -> u8 {
337     get_oid_from_uci_control_packet(&packet.encode_to_bytes().unwrap())
338 }
339 
is_uci_control_packet(message_type: MessageType) -> bool340 fn is_uci_control_packet(message_type: MessageType) -> bool {
341     match message_type {
342         MessageType::Command
343         | MessageType::Response
344         | MessageType::Notification
345         | MessageType::ReservedForTesting1
346         | MessageType::ReservedForTesting2 => true,
347         _ => false,
348     }
349 }
350 
build_uci_control_packet( message_type: MessageType, group_id: GroupId, opcode: u8, payload: Option<Bytes>, ) -> Option<UciControlPacket>351 pub fn build_uci_control_packet(
352     message_type: MessageType,
353     group_id: GroupId,
354     opcode: u8,
355     payload: Option<Bytes>,
356 ) -> Option<UciControlPacket> {
357     if !is_uci_control_packet(message_type) {
358         error!("Only control packets are allowed, MessageType: {message_type:?}");
359         return None;
360     }
361     Some(UciControlPacketBuilder { group_id, message_type, opcode, payload }.build())
362 }
363 
364 // Ensure that the new packet fragment belong to the same packet.
is_same_control_packet(header: &UciControlPacketHeader, packet: &UciPacketHal) -> bool365 fn is_same_control_packet(header: &UciControlPacketHeader, packet: &UciPacketHal) -> bool {
366     is_uci_control_packet(header.message_type)
367         && header.message_type == packet.get_message_type()
368         && header.group_id == packet.get_group_id_or_data_packet_format().into()
369         && header.opcode == get_opcode_from_uci_control_packet(packet)
370 }
371 
is_device_state_err_control_packet(packet: &UciPacketHal) -> bool372 fn is_device_state_err_control_packet(packet: &UciPacketHal) -> bool {
373     packet.get_message_type() == MessageType::Notification.into()
374         && packet.get_group_id_or_data_packet_format() == GroupIdOrDataPacketFormat::Core.into()
375         && get_opcode_from_uci_control_packet(packet) == CoreOpCode::CoreDeviceStatusNtf.into()
376         && packet.encode_to_vec().unwrap()[UCI_PACKET_HAL_HEADER_LEN]
377             == DeviceState::DeviceStateError.into()
378 }
379 
380 impl UciControlPacket {
381     // For some usage, we need to get the raw payload.
to_raw_payload(self) -> Vec<u8>382     pub fn to_raw_payload(self) -> Vec<u8> {
383         self.encode_to_bytes().unwrap().slice(UCI_PACKET_HEADER_LEN..).to_vec()
384     }
385 }
386 
387 // Helper to convert from vector of |UciPacketHal| to |UciControlPacket|. An example
388 // usage is to convert a list UciPacketHAL fragments to one UciPacket, during de-fragmentation.
389 impl TryFrom<Vec<UciPacketHal>> for UciControlPacket {
390     type Error = DecodeError;
391 
try_from(packets: Vec<UciPacketHal>) -> Result<Self, DecodeError>392     fn try_from(packets: Vec<UciPacketHal>) -> Result<Self, DecodeError> {
393         if packets.is_empty() {
394             return Err(DecodeError::InvalidPacketError);
395         }
396 
397         // Store header info from the first packet.
398         let header = UciControlPacketHeader::new(
399             packets[0].get_message_type(),
400             packets[0].get_group_id_or_data_packet_format().into(),
401             get_opcode_from_uci_control_packet(&packets[0]),
402         )?;
403 
404         // Create the reassembled payload.
405         let mut payload_buf = BytesMut::new();
406         for packet in packets {
407             // Ensure that the new fragment is part of the same packet.
408             if !is_same_control_packet(&header, &packet) {
409                 // if DEVICE_STATE_ERROR notification is received while waiting for remaining fragments,
410                 // process it and send to upper layer for device recovery
411                 if is_device_state_err_control_packet(&packet) {
412                     error!("Received device reset error: {:?}", packet);
413                     return UciControlPacket::parse(
414                         &UciControlPacketBuilder {
415                             message_type: packet.get_message_type(),
416                             group_id: packet.get_group_id_or_data_packet_format().into(),
417                             opcode: get_opcode_from_uci_control_packet(&packet),
418                             payload: Some(
419                                 packet
420                                     .encode_to_bytes()
421                                     .unwrap()
422                                     .slice(UCI_PACKET_HAL_HEADER_LEN..),
423                             ),
424                         }
425                         .build()
426                         .encode_to_bytes()
427                         .unwrap(),
428                     );
429                 }
430                 error!("Received unexpected fragment: {:?}", packet);
431                 return Err(DecodeError::InvalidPacketError);
432             }
433             // get payload by stripping the header.
434             payload_buf.extend_from_slice(
435                 &packet.encode_to_bytes().unwrap().slice(UCI_PACKET_HAL_HEADER_LEN..),
436             )
437         }
438 
439         // Create assembled |UciControlPacket| and convert to bytes again since we need to
440         // reparse the packet after defragmentation to get the appropriate message.
441         UciControlPacket::parse(
442             &UciControlPacketBuilder {
443                 message_type: header.message_type,
444                 group_id: header.group_id,
445                 opcode: header.opcode,
446                 payload: Some(payload_buf.into()),
447             }
448             .build()
449             .encode_to_bytes()
450             .unwrap(),
451         )
452     }
453 }
454 
455 #[derive(Debug, Clone)]
456 pub struct RawUciControlPacket {
457     pub mt: u8,
458     pub gid: u8,
459     pub oid: u8,
460     pub payload: Vec<u8>,
461 }
462 
463 impl RawUciControlPacket {
464     // Match the GID and OID to confirm the UCI packet (represented by header) is
465     // the same as the stored signature. We don't match the MT because they can be
466     // different (eg: CMD/RSP pair).
is_same_signature_bytes(&self, header: &[u8]) -> bool467     pub fn is_same_signature_bytes(&self, header: &[u8]) -> bool {
468         let gid = get_gid_from_uci_control_packet(header);
469         let oid = get_oid_from_uci_control_packet(header);
470         gid == self.gid && oid == self.oid
471     }
472 }
473 
is_uci_data_packet(message_type: MessageType) -> bool474 fn is_uci_data_packet(message_type: MessageType) -> bool {
475     message_type == MessageType::Data
476 }
477 
is_data_rcv_or_radar_format(data_packet_format: DataPacketFormat) -> bool478 fn is_data_rcv_or_radar_format(data_packet_format: DataPacketFormat) -> bool {
479     data_packet_format == DataPacketFormat::DataRcv
480         || data_packet_format == DataPacketFormat::RadarDataMessage
481 }
482 
try_into_data_payload( packet: UciPacketHal, expected_data_packet_format: DataPacketFormat, ) -> Result<Bytes, DecodeError>483 fn try_into_data_payload(
484     packet: UciPacketHal,
485     expected_data_packet_format: DataPacketFormat,
486 ) -> Result<Bytes, DecodeError> {
487     let dpf: DataPacketFormat = packet.get_group_id_or_data_packet_format().try_into()?;
488     if is_uci_data_packet(packet.get_message_type()) && dpf == expected_data_packet_format {
489         Ok(packet.encode_to_bytes().unwrap().slice(UCI_PACKET_HAL_HEADER_LEN..))
490     } else {
491         error!("Received unexpected data packet fragment: {:?}", packet);
492         Err(DecodeError::InvalidPacketError)
493     }
494 }
495 
496 // Helper to convert from vector of |UciPacketHal| to |UciDataPacket|. An example
497 // usage is to convert a list UciPacketHAL fragments to one UciPacket, during de-fragmentation.
498 impl TryFrom<Vec<UciPacketHal>> for UciDataPacket {
499     type Error = DecodeError;
500 
try_from(packets: Vec<UciPacketHal>) -> Result<Self, DecodeError>501     fn try_from(packets: Vec<UciPacketHal>) -> Result<Self, DecodeError> {
502         if packets.is_empty() {
503             return Err(DecodeError::InvalidPacketError);
504         }
505 
506         let dpf: DataPacketFormat = packets[0].get_group_id_or_data_packet_format().try_into()?;
507         if !is_data_rcv_or_radar_format(dpf) {
508             error!("Unexpected data packet format {:?}", dpf);
509         }
510 
511         // Create the reassembled payload.
512         let mut payload_buf = Bytes::new();
513         for packet in packets {
514             // Ensure that the fragment is a Data Rcv packet.
515             // Get payload by stripping the header.
516             payload_buf = [payload_buf, try_into_data_payload(packet, dpf)?].concat().into();
517         }
518 
519         // Create assembled |UciDataPacket| and convert to bytes again since we need to
520         // reparse the packet after defragmentation to get the appropriate message.
521         UciDataPacket::parse(
522             &UciDataPacketBuilder {
523                 message_type: MessageType::Data,
524                 data_packet_format: dpf,
525                 payload: Some(payload_buf.into()),
526             }
527             .build()
528             .encode_to_bytes()
529             .unwrap(),
530         )
531     }
532 }
533 
534 // Helper to convert from |UciControlPacket| to vector of |UciControlPacketHal|s. An
535 // example usage is to do this conversion for fragmentation (from Host to UWBS).
536 impl From<UciControlPacket> for Vec<UciControlPacketHal> {
from(packet: UciControlPacket) -> Self537     fn from(packet: UciControlPacket) -> Self {
538         // Store header info.
539         let header = match UciControlPacketHeader::new(
540             packet.get_message_type(),
541             packet.get_group_id(),
542             packet.get_opcode(),
543         ) {
544             Ok(hdr) => hdr,
545             _ => {
546                 error!(
547                     "Unable to parse UciControlPacketHeader from UciControlPacket: {:?}",
548                     packet
549                 );
550                 return Vec::new();
551             }
552         };
553 
554         let mut fragments = Vec::new();
555         // get payload by stripping the header.
556         let payload = packet.encode_to_bytes().unwrap().slice(UCI_PACKET_HEADER_LEN..);
557         if payload.is_empty() {
558             fragments.push(
559                 UciControlPacketHalBuilder {
560                     message_type: header.message_type,
561                     group_id_or_data_packet_format: header.group_id.into(),
562                     opcode: header.opcode,
563                     packet_boundary_flag: PacketBoundaryFlag::Complete,
564                     payload: None,
565                 }
566                 .build(),
567             );
568         } else {
569             let mut fragments_iter = payload.chunks(MAX_PAYLOAD_LEN).peekable();
570             while let Some(fragment) = fragments_iter.next() {
571                 // Set the last fragment complete if this is last fragment.
572                 let pbf = if let Some(nxt_fragment) = fragments_iter.peek() {
573                     PacketBoundaryFlag::NotComplete
574                 } else {
575                     PacketBoundaryFlag::Complete
576                 };
577                 fragments.push(
578                     UciControlPacketHalBuilder {
579                         message_type: header.message_type,
580                         group_id_or_data_packet_format: header.group_id.into(),
581                         opcode: header.opcode,
582                         packet_boundary_flag: pbf,
583                         payload: Some(Bytes::from(fragment.to_owned())),
584                     }
585                     .build(),
586                 );
587             }
588         }
589         fragments
590     }
591 }
592 
593 // Helper to convert From<UciDataSnd> into Vec<UciDataPacketHal>. An
594 // example usage is for fragmentation in the Data Packet Tx flow.
fragment_data_msg_send(packet: UciDataSnd, max_payload_len: usize) -> Vec<UciDataPacketHal>595 pub fn fragment_data_msg_send(packet: UciDataSnd, max_payload_len: usize) -> Vec<UciDataPacketHal> {
596     let mut fragments = Vec::new();
597     let dpf = packet.get_data_packet_format().into();
598 
599     // get payload by stripping the header.
600     let payload = packet.encode_to_bytes().unwrap().slice(UCI_DATA_SND_PACKET_HEADER_LEN..);
601     if payload.is_empty() {
602         fragments.push(
603             UciDataPacketHalBuilder {
604                 group_id_or_data_packet_format: dpf,
605                 packet_boundary_flag: PacketBoundaryFlag::Complete,
606                 payload: None,
607             }
608             .build(),
609         );
610     } else {
611         let mut fragments_iter = payload.chunks(max_payload_len).peekable();
612         while let Some(fragment) = fragments_iter.next() {
613             // Set the last fragment complete if this is last fragment.
614             let pbf = if let Some(nxt_fragment) = fragments_iter.peek() {
615                 PacketBoundaryFlag::NotComplete
616             } else {
617                 PacketBoundaryFlag::Complete
618             };
619             fragments.push(
620                 UciDataPacketHalBuilder {
621                     group_id_or_data_packet_format: dpf,
622                     packet_boundary_flag: pbf,
623                     payload: Some(Bytes::from(fragment.to_owned())),
624                 }
625                 .build(),
626             );
627         }
628     }
629     fragments
630 }
631 
632 #[derive(Default, Debug)]
633 pub struct PacketDefrager {
634     // Cache to store incoming fragmented packets in the middle of reassembly.
635     // Will be empty if there is no reassembly in progress.
636     // TODO(b/261762781): Prefer this to be UciControlPacketHal
637     control_fragment_cache: Vec<UciPacketHal>,
638     // TODO(b/261762781): Prefer this to be UciDataPacketHal
639     data_fragment_cache: Vec<UciPacketHal>,
640     // Raw packet payload bytes cache
641     raw_fragment_cache: Vec<u8>,
642 }
643 
644 pub enum UciDefragPacket {
645     Control(UciControlPacket),
646     Data(UciDataPacket),
647     Raw(Result<(), DecodeError>, RawUciControlPacket),
648 }
649 
650 impl PacketDefrager {
defragment_packet( &mut self, msg: &[u8], last_raw_cmd: Option<RawUciControlPacket>, ) -> Option<UciDefragPacket>651     pub fn defragment_packet(
652         &mut self,
653         msg: &[u8],
654         last_raw_cmd: Option<RawUciControlPacket>,
655     ) -> Option<UciDefragPacket> {
656         if let Some(raw_cmd) = last_raw_cmd {
657             let mt_u8 = get_mt_from_uci_packet(msg);
658             match MessageType::try_from(u8::from(mt_u8)) {
659                 Ok(mt) => match mt {
660                     // Parse only a UCI response packet as a Raw packet.
661                     MessageType::Response => {
662                         return self.defragment_raw_uci_response_packet(msg, raw_cmd);
663                     }
664                     _ => { /* Fallthrough to de-frag as a normal UCI packet below */ }
665                 },
666                 Err(_) => {
667                     error!("Rx packet from HAL has unrecognized MT={}", mt_u8);
668                     return Some(UciDefragPacket::Raw(
669                         Err(DecodeError::InvalidPacketError),
670                         RawUciControlPacket { mt: mt_u8, gid: 0, oid: 0, payload: Vec::new() },
671                     ));
672                 }
673             };
674         }
675 
676         let packet = UciPacketHal::parse(msg)
677             .or_else(|e| {
678                 error!("Failed to parse packet: {:?}", e);
679                 Err(e)
680             })
681             .ok()?;
682 
683         let pbf = packet.get_packet_boundary_flag();
684 
685         // TODO(b/261762781): The current implementation allows for the possibility that we receive
686         // interleaved Control/Data HAL packets, and so uses separate caches for them. In the
687         // future, if we determine that interleaving is not possible, this can be simplified.
688         if is_uci_control_packet(packet.get_message_type()) {
689             // Add the incoming fragment to the control packet cache.
690             self.control_fragment_cache.push(packet);
691             if pbf == PacketBoundaryFlag::NotComplete {
692                 // Wait for remaining fragments.
693                 return None;
694             }
695 
696             // All fragments received, defragment the control packet.
697             match self.control_fragment_cache.drain(..).collect::<Vec<_>>().try_into() {
698                 Ok(packet) => Some(UciDefragPacket::Control(packet)),
699                 Err(e) => {
700                     error!("Failed to defragment control packet: {:?}", e);
701                     None
702                 }
703             }
704         } else {
705             // Add the incoming fragment to the data packet cache.
706             self.data_fragment_cache.push(packet);
707             if pbf == PacketBoundaryFlag::NotComplete {
708                 // Wait for remaining fragments.
709                 return None;
710             }
711 
712             // All fragments received, defragment the data packet.
713             match self.data_fragment_cache.drain(..).collect::<Vec<_>>().try_into() {
714                 Ok(packet) => Some(UciDefragPacket::Data(packet)),
715                 Err(e) => {
716                     error!("Failed to defragment data packet: {:?}", e);
717                     None
718                 }
719             }
720         }
721     }
722 
defragment_raw_uci_response_packet( &mut self, msg: &[u8], raw_cmd: RawUciControlPacket, ) -> Option<UciDefragPacket>723     fn defragment_raw_uci_response_packet(
724         &mut self,
725         msg: &[u8],
726         raw_cmd: RawUciControlPacket,
727     ) -> Option<UciDefragPacket> {
728         let mt_u8 = get_mt_from_uci_packet(msg);
729         let pbf = get_pbf_from_uci_packet(msg);
730         let gid = get_gid_from_uci_control_packet(msg);
731         let oid = get_oid_from_uci_control_packet(msg);
732         if raw_cmd.is_same_signature_bytes(msg) {
733             // Store only the packet payload bytes (UCI header should not be stored).
734             self.raw_fragment_cache.extend_from_slice(&msg[UCI_PACKET_HAL_HEADER_LEN..]);
735 
736             if pbf == u8::from(PacketBoundaryFlag::NotComplete) {
737                 return None;
738             }
739 
740             // All fragments received, defragment and return the Raw packet's payload bytes.
741             return Some(UciDefragPacket::Raw(
742                 Ok(()),
743                 RawUciControlPacket {
744                     mt: mt_u8,
745                     gid,
746                     oid,
747                     payload: self.raw_fragment_cache.drain(..).collect(),
748                 },
749             ));
750         } else {
751             error!(
752                 "Rx packet from HAL (MT={}, PBF={}, GID={}, OID={}) has non-matching\
753                    RawCmd signature",
754                 mt_u8, pbf, gid, oid
755             );
756             return Some(UciDefragPacket::Raw(
757                 Err(DecodeError::InvalidPacketError),
758                 RawUciControlPacket { mt: mt_u8, gid, oid, payload: Vec::new() },
759             ));
760         }
761     }
762 }
763 
764 #[allow(dead_code)]
765 #[derive(Debug, Clone)]
766 pub struct ParsedDiagnosticNtfPacket {
767     session_token: u32,
768     sequence_number: u32,
769     frame_reports: Vec<ParsedFrameReport>,
770 }
771 
772 #[allow(dead_code)]
773 #[derive(Clone)]
774 pub struct ParsedFrameReport {
775     uwb_msg_id: u8,
776     action: u8,
777     antenna_set: u8,
778     rssi: Vec<u8>,
779     aoa: Vec<AoaMeasurement>,
780     cir: Vec<CirValue>,
781     segment_metrics: Vec<SegmentMetricsValue>,
782 }
783 
parse_diagnostics_ntf( evt: AndroidRangeDiagnosticsNtf, ) -> Result<ParsedDiagnosticNtfPacket, DecodeError>784 pub fn parse_diagnostics_ntf(
785     evt: AndroidRangeDiagnosticsNtf,
786 ) -> Result<ParsedDiagnosticNtfPacket, DecodeError> {
787     let session_token = evt.get_session_token();
788     let sequence_number = evt.get_sequence_number();
789     let mut parsed_frame_reports = Vec::new();
790     for report in evt.get_frame_reports() {
791         let mut rssi_vec = Vec::new();
792         let mut aoa_vec = Vec::new();
793         let mut cir_vec = Vec::new();
794         let mut segment_metrics_vec = Vec::new();
795         for tlv in &report.frame_report_tlvs {
796             match FrameReportTlvPacket::parse(
797                 &[vec![tlv.t as u8, tlv.v.len() as u8, (tlv.v.len() >> 8) as u8], tlv.v.clone()]
798                     .concat(),
799             ) {
800                 Ok(pkt) => match pkt.specialize() {
801                     FrameReportTlvPacketChild::Rssi(rssi) => {
802                         rssi_vec.append(&mut rssi.get_rssi().clone())
803                     }
804                     FrameReportTlvPacketChild::Aoa(aoa) => {
805                         aoa_vec.append(&mut aoa.get_aoa().clone())
806                     }
807                     FrameReportTlvPacketChild::Cir(cir) => {
808                         cir_vec.append(&mut cir.get_cir_value().clone())
809                     }
810                     FrameReportTlvPacketChild::SegmentMetrics(sm) => {
811                         segment_metrics_vec.append(&mut sm.get_segment_metrics().clone())
812                     }
813                     _ => return Err(DecodeError::InvalidPacketError),
814                 },
815                 Err(e) => {
816                     error!("Failed to parse the packet {:?}", e);
817                     return Err(DecodeError::InvalidPacketError);
818                 }
819             }
820         }
821         parsed_frame_reports.push(ParsedFrameReport {
822             uwb_msg_id: report.uwb_msg_id,
823             action: report.action,
824             antenna_set: report.antenna_set,
825             rssi: rssi_vec,
826             aoa: aoa_vec,
827             cir: cir_vec,
828             segment_metrics: segment_metrics_vec,
829         });
830     }
831     Ok(ParsedDiagnosticNtfPacket {
832         session_token,
833         sequence_number,
834         frame_reports: parsed_frame_reports,
835     })
836 }
837 
838 #[derive(Debug, Clone, PartialEq)]
839 pub enum Controlees {
840     NoSessionKey(Vec<Controlee>),
841     ShortSessionKey(Vec<Controlee_V2_0_16_Byte_Version>),
842     LongSessionKey(Vec<Controlee_V2_0_32_Byte_Version>),
843 }
844 
845 // TODO(ziyiw): Replace these functions after making uwb_uci_packets::Controlee::write_to() public.
write_controlee(controlee: &Controlee) -> BytesMut846 pub fn write_controlee(controlee: &Controlee) -> BytesMut {
847     let mut buffer = BytesMut::new();
848     buffer.extend_from_slice(&controlee.short_address);
849     let subsession_id = controlee.subsession_id;
850     buffer.extend_from_slice(&subsession_id.to_le_bytes()[0..4]);
851     buffer
852 }
853 
write_controlee_2_0_16byte(controlee: &Controlee_V2_0_16_Byte_Version) -> BytesMut854 pub fn write_controlee_2_0_16byte(controlee: &Controlee_V2_0_16_Byte_Version) -> BytesMut {
855     let mut buffer = BytesMut::new();
856     buffer.extend_from_slice(&controlee.short_address);
857     let subsession_id = controlee.subsession_id;
858     buffer.extend_from_slice(&subsession_id.to_le_bytes()[0..4]);
859     buffer.extend_from_slice(&controlee.subsession_key);
860     buffer
861 }
862 
write_controlee_2_0_32byte(controlee: &Controlee_V2_0_32_Byte_Version) -> BytesMut863 pub fn write_controlee_2_0_32byte(controlee: &Controlee_V2_0_32_Byte_Version) -> BytesMut {
864     let mut buffer = BytesMut::new();
865     buffer.extend_from_slice(&controlee.short_address);
866     let subsession_id = controlee.subsession_id;
867     buffer.extend_from_slice(&subsession_id.to_le_bytes()[0..4]);
868     buffer.extend_from_slice(&controlee.subsession_key);
869     buffer
870 }
871 
872 /// Generate the SessionUpdateControllerMulticastListCmd packet.
873 ///
874 /// This function can build the packet with/without message control, which
875 /// is indicated by action parameter.
build_session_update_controller_multicast_list_cmd( session_token: u32, action: UpdateMulticastListAction, controlees: Controlees, ) -> Result<SessionUpdateControllerMulticastListCmd, DecodeError>876 pub fn build_session_update_controller_multicast_list_cmd(
877     session_token: u32,
878     action: UpdateMulticastListAction,
879     controlees: Controlees,
880 ) -> Result<SessionUpdateControllerMulticastListCmd, DecodeError> {
881     let mut controlees_buf = BytesMut::new();
882     match controlees {
883         Controlees::NoSessionKey(controlee_v1) => {
884             controlees_buf.extend_from_slice(&(controlee_v1.len() as u8).to_le_bytes());
885             for controlee in controlee_v1 {
886                 controlees_buf.extend_from_slice(&write_controlee(&controlee));
887             }
888         }
889         Controlees::ShortSessionKey(controlee_v2)
890             if action == UpdateMulticastListAction::AddControleeWithShortSubSessionKey =>
891         {
892             controlees_buf.extend_from_slice(&(controlee_v2.len() as u8).to_le_bytes());
893             for controlee in controlee_v2 {
894                 controlees_buf.extend_from_slice(&write_controlee_2_0_16byte(&controlee));
895             }
896         }
897         Controlees::LongSessionKey(controlee_v2)
898             if action == UpdateMulticastListAction::AddControleeWithLongSubSessionKey =>
899         {
900             controlees_buf.extend_from_slice(&(controlee_v2.len() as u8).to_le_bytes());
901             for controlee in controlee_v2 {
902                 controlees_buf.extend_from_slice(&write_controlee_2_0_32byte(&controlee));
903             }
904         }
905         _ => return Err(DecodeError::InvalidPacketError),
906     }
907     Ok(SessionUpdateControllerMulticastListCmdBuilder {
908         session_token,
909         action,
910         payload: Some(controlees_buf.freeze()),
911     }
912     .build())
913 }
914 
915 /// building Data transfer phase config command
build_data_transfer_phase_config_cmd( session_token: u32, dtpcm_repetition: u8, data_transfer_control: u8, dtpml_size: u8, mac_address: Vec<u8>, slot_bitmap: Vec<u8>, stop_data_transfer: Vec<u8>, ) -> Result<SessionDataTransferPhaseConfigCmd, DecodeError>916 pub fn build_data_transfer_phase_config_cmd(
917     session_token: u32,
918     dtpcm_repetition: u8,
919     data_transfer_control: u8,
920     dtpml_size: u8,
921     mac_address: Vec<u8>,
922     slot_bitmap: Vec<u8>,
923     stop_data_transfer: Vec<u8>,
924 ) -> Result<SessionDataTransferPhaseConfigCmd, DecodeError> {
925     let mut dtpml_buffer = BytesMut::new();
926 
927     //calculate mac address mode from data transfer control
928     let mac_address_mode = data_transfer_control & 0x01;
929 
930     // Calculate mac address size based on address mode
931     let mac_address_size = match mac_address_mode {
932         SHORT_ADDRESS => 2,
933         EXTENDED_ADDRESS => 8,
934         _ => return Err(DecodeError::InvalidPacketError),
935     };
936 
937     // Calculate slot bitmap size from data transfer control
938     let slot_bitmap_size = 1 << ((data_transfer_control & 0x0F) >> 1);
939 
940     // Prepare segmented vectors for mac_address
941     let mac_address_vec: Vec<_> =
942         mac_address.chunks(mac_address_size).map(|chunk| chunk.to_owned()).collect();
943 
944     // Prepare segmented vectors for slot_bitmap
945     let slot_bitmap_vec: Vec<_> =
946         slot_bitmap.chunks(slot_bitmap_size).map(|chunk| chunk.to_owned()).collect();
947 
948     // Validate sizes of mac_address and slot_bitmap
949     if slot_bitmap_vec.len() != dtpml_size.into() || mac_address_vec.len() != dtpml_size.into() {
950         return Err(DecodeError::InvalidPacketError);
951     }
952 
953     // Prepare segmented vectors for stop_data_transfer
954     let stop_data_transfer_vector: Vec<_> =
955         stop_data_transfer.chunks(1).map(|chunk| chunk.to_owned()).collect();
956 
957     // Combine segmented vectors into dtpml_buffer
958     for ((elem1, elem2), elem3) in mac_address_vec
959         .into_iter()
960         .zip(slot_bitmap_vec.into_iter())
961         .zip(stop_data_transfer.into_iter())
962     {
963         dtpml_buffer.extend_from_slice(&elem1);
964         dtpml_buffer.extend_from_slice(&elem2);
965         dtpml_buffer.extend_from_slice(&[elem3]);
966     }
967 
968     Ok(SessionDataTransferPhaseConfigCmdBuilder {
969         session_token,
970         dtpcm_repetition,
971         data_transfer_control,
972         dtpml_size,
973         payload: Some(dtpml_buffer.freeze()),
974     }
975     .build())
976 }
977 
978 impl Drop for AppConfigTlv {
drop(&mut self)979     fn drop(&mut self) {
980         if self.cfg_id == AppConfigTlvType::VendorId || self.cfg_id == AppConfigTlvType::StaticStsIv
981         {
982             self.v.zeroize();
983         }
984     }
985 }
986 
987 // Radar data 'bits per sample' field isn't a raw value, instead it's an enum
988 // that maps to the raw value. We need this mapping to get the max sample size
989 // length.
radar_bytes_per_sample_value(bps: BitsPerSample) -> u8990 pub fn radar_bytes_per_sample_value(bps: BitsPerSample) -> u8 {
991     match bps {
992         BitsPerSample::Value32 => 4,
993         BitsPerSample::Value48 => 6,
994         BitsPerSample::Value64 => 8,
995     }
996 }
997 
998 #[cfg(test)]
999 mod tests {
1000     use super::*;
1001 
1002     #[test]
test_parse_diagnostics_ntf()1003     fn test_parse_diagnostics_ntf() {
1004         let rssi_vec = vec![0x01, 0x02, 0x03];
1005         let rssi = RssiBuilder { rssi: rssi_vec.clone() }.build();
1006         let aoa_1 = AoaMeasurement { tdoa: 1, pdoa: 2, aoa: 3, fom: 4, t: 1 };
1007         let aoa_2 = AoaMeasurement { tdoa: 5, pdoa: 6, aoa: 7, fom: 8, t: 2 };
1008         let aoa = AoaBuilder { aoa: vec![aoa_1.clone(), aoa_2.clone()] }.build();
1009         let cir_vec = vec![CirValue {
1010             first_path_index: 1,
1011             first_path_snr: 2,
1012             first_path_ns: 3,
1013             peak_path_index: 4,
1014             peak_path_snr: 5,
1015             peak_path_ns: 6,
1016             first_path_sample_offset: 7,
1017             samples_number: 2,
1018             sample_window: vec![0, 1, 2, 3],
1019         }];
1020         let cir = CirBuilder { cir_value: cir_vec.clone() }.build();
1021         let segment_metrics_vec = vec![SegmentMetricsValue {
1022             receiver_and_segment: ReceiverAndSegmentValue::parse(&[1]).unwrap(),
1023             rf_noise_floor: 2,
1024             segment_rsl: 3,
1025             first_path: PathSample { index: 4, rsl: 5, time_ns: 6 },
1026             peak_path: PathSample { index: 7, rsl: 8, time_ns: 9 },
1027         }];
1028         let segment_metrics =
1029             SegmentMetricsBuilder { segment_metrics: segment_metrics_vec.clone() }.build();
1030         let mut frame_reports = Vec::new();
1031         let tlvs = vec![
1032             FrameReportTlv { t: rssi.get_t(), v: rssi.get_rssi().to_vec() },
1033             FrameReportTlv { t: aoa.get_t(), v: aoa.encode_to_vec().unwrap()[3..].to_vec() },
1034             FrameReportTlv { t: cir.get_t(), v: cir.encode_to_vec().unwrap()[3..].to_vec() },
1035             FrameReportTlv {
1036                 t: segment_metrics.get_t(),
1037                 v: segment_metrics.encode_to_vec().unwrap()[3..].to_vec(),
1038             },
1039         ];
1040         let frame_report =
1041             FrameReport { uwb_msg_id: 1, action: 1, antenna_set: 1, frame_report_tlvs: tlvs };
1042         frame_reports.push(frame_report);
1043         let packet = AndroidRangeDiagnosticsNtfBuilder {
1044             session_token: 1,
1045             sequence_number: 1,
1046             frame_reports,
1047         }
1048         .build();
1049         let mut parsed_packet = parse_diagnostics_ntf(packet).unwrap();
1050         let parsed_frame_report = parsed_packet.frame_reports.pop().unwrap();
1051         assert_eq!(rssi_vec, parsed_frame_report.rssi);
1052         assert_eq!(aoa_1, parsed_frame_report.aoa[0]);
1053         assert_eq!(aoa_2, parsed_frame_report.aoa[1]);
1054         assert_eq!(cir_vec, parsed_frame_report.cir);
1055         assert_eq!(segment_metrics_vec, parsed_frame_report.segment_metrics);
1056     }
1057 
1058     #[test]
test_write_controlee()1059     fn test_write_controlee() {
1060         let short_address: [u8; 2] = [2, 3];
1061         let controlee: Controlee = Controlee { short_address, subsession_id: 3 };
1062         let bytes = write_controlee(&controlee);
1063         let parsed_controlee = Controlee::parse(&bytes).unwrap();
1064         assert_eq!(controlee, parsed_controlee);
1065     }
1066 
1067     #[test]
test_build_multicast_update_packet()1068     fn test_build_multicast_update_packet() {
1069         let short_address: [u8; 2] = [0x12, 0x34];
1070         let controlee = Controlee { short_address, subsession_id: 0x1324_3546 };
1071         let packet: UciControlPacket = build_session_update_controller_multicast_list_cmd(
1072             0x1425_3647,
1073             UpdateMulticastListAction::AddControlee,
1074             Controlees::NoSessionKey(vec![controlee; 1]),
1075         )
1076         .unwrap()
1077         .into();
1078         let packet_fragments: Vec<UciControlPacketHal> = packet.into();
1079         let uci_packet = packet_fragments[0].encode_to_vec();
1080         assert_eq!(
1081             uci_packet,
1082             Ok(vec![
1083                 0x21, 0x07, 0x00, 0x0c, // 2(packet info), RFU, payload length(12)
1084                 0x47, 0x36, 0x25, 0x14, // 4(session id (LE))
1085                 0x00, 0x01, 0x12, 0x34, // action, # controlee, 2(short address (LE))
1086                 0x46, 0x35, 0x24, 0x13, // 4(subsession id (LE))
1087             ])
1088         );
1089     }
1090 
1091     #[test]
test_build_multicast_update_packet_v2_short_session_key()1092     fn test_build_multicast_update_packet_v2_short_session_key() {
1093         let short_address: [u8; 2] = [0x12, 0x34];
1094         let controlee = Controlee_V2_0_16_Byte_Version {
1095             short_address,
1096             subsession_id: 0x1324_3546,
1097             subsession_key: [
1098                 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab,
1099                 0xcd, 0xef,
1100             ],
1101         };
1102         let packet: UciControlPacket = build_session_update_controller_multicast_list_cmd(
1103             0x1425_3647,
1104             UpdateMulticastListAction::AddControleeWithShortSubSessionKey,
1105             Controlees::ShortSessionKey(vec![controlee; 1]),
1106         )
1107         .unwrap()
1108         .into();
1109         let packet_fragments: Vec<UciControlPacketHal> = packet.into();
1110         let uci_packet = packet_fragments[0].encode_to_vec();
1111         assert_eq!(
1112             uci_packet,
1113             Ok(vec![
1114                 0x21, 0x07, 0x00, 0x1c, // 2(packet info), RFU, payload length(28)
1115                 0x47, 0x36, 0x25, 0x14, // 4(session id (LE))
1116                 0x02, 0x01, 0x12, 0x34, // action, # controlee, 2(short address (LE))
1117                 0x46, 0x35, 0x24, 0x13, // 4(subsession id (LE))
1118                 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab,
1119                 0xcd, 0xef, // 16(subsession key(LE))
1120             ])
1121         );
1122     }
1123 
1124     #[test]
test_build_multicast_update_packet_v2_long_session_key()1125     fn test_build_multicast_update_packet_v2_long_session_key() {
1126         let short_address: [u8; 2] = [0x12, 0x34];
1127         let controlee = Controlee_V2_0_32_Byte_Version {
1128             short_address,
1129             subsession_id: 0x1324_3546,
1130             subsession_key: [
1131                 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab,
1132                 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78,
1133                 0x90, 0xab, 0xcd, 0xef,
1134             ],
1135         };
1136         let packet: UciControlPacket = build_session_update_controller_multicast_list_cmd(
1137             0x1425_3647,
1138             UpdateMulticastListAction::AddControleeWithLongSubSessionKey,
1139             Controlees::LongSessionKey(vec![controlee; 1]),
1140         )
1141         .unwrap()
1142         .into();
1143         let packet_fragments: Vec<UciControlPacketHal> = packet.into();
1144         let uci_packet = packet_fragments[0].encode_to_vec();
1145         assert_eq!(
1146             uci_packet,
1147             Ok(vec![
1148                 0x21, 0x07, 0x00, 0x2c, // 2(packet info), RFU, payload length(44)
1149                 0x47, 0x36, 0x25, 0x14, // 4(session id (LE))
1150                 0x03, 0x01, 0x12, 0x34, // action, # controlee, 2(short address (LE))
1151                 0x46, 0x35, 0x24, 0x13, // 4(subsession id (LE))
1152                 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab,
1153                 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78,
1154                 0x90, 0xab, 0xcd, 0xef, // 32(subsession key(LE))
1155             ])
1156         );
1157     }
1158 
1159     #[test]
test_to_raw_payload()1160     fn test_to_raw_payload() {
1161         let payload = vec![0x11, 0x22, 0x33];
1162         let payload_clone = payload.clone();
1163         let packet = UciControlPacketBuilder {
1164             group_id: GroupId::Test,
1165             message_type: MessageType::Response,
1166             opcode: 0x5,
1167             payload: Some(payload_clone.into()),
1168         }
1169         .build();
1170 
1171         assert_eq!(payload, packet.to_raw_payload());
1172     }
1173 
1174     #[test]
test_to_raw_payload_empty()1175     fn test_to_raw_payload_empty() {
1176         let payload: Vec<u8> = vec![];
1177         let packet = UciControlPacketBuilder {
1178             group_id: GroupId::Test,
1179             message_type: MessageType::Response,
1180             opcode: 0x5,
1181             payload: None,
1182         }
1183         .build();
1184 
1185         assert_eq!(payload, packet.to_raw_payload());
1186     }
1187 
1188     #[cfg(test)]
1189     mod tests {
1190         use crate::{extract_u16, extract_u32, extract_u64, extract_u8, extract_vec};
1191         #[test]
test_extract_func()1192         fn test_extract_func() {
1193             let bytes = [0x1, 0x3, 0x5, 0x7, 0x9, 0x2, 0x4, 0x05, 0x07, 0x09, 0x0a];
1194             let mut ptr = 0;
1195 
1196             let u8_val = extract_u8(&bytes, &mut ptr, 1);
1197             assert_eq!(u8_val, Some(0x1));
1198             assert_eq!(ptr, 1);
1199 
1200             let u16_val = extract_u16(&bytes, &mut ptr, 2);
1201             assert_eq!(u16_val, Some(0x0503));
1202             assert_eq!(ptr, 3);
1203 
1204             let u32_val = extract_u32(&bytes, &mut ptr, 3);
1205             assert_eq!(u32_val, Some(0x020907));
1206             assert_eq!(ptr, 6);
1207 
1208             let u64_val = extract_u64(&bytes, &mut ptr, 5);
1209             assert_eq!(u64_val, Some(0x0a09070504));
1210             assert_eq!(ptr, 11);
1211 
1212             let vec = extract_vec(&bytes, &mut ptr, 3);
1213             assert_eq!(vec, None);
1214             assert_eq!(ptr, 11);
1215         }
1216     }
1217 
1218     #[test]
test_short_dltdoa_ranging_measurement()1219     fn test_short_dltdoa_ranging_measurement() {
1220         let bytes = [
1221             // All Fields in Little Endian (LE)
1222             // First measurement
1223             0x0a, 0x01, 0x33, 0x05, // 2(Mac address), Status, Message Type
1224             0x53, 0x05, 0x02, 0x05, // 2(Message control), 2(Block Index)
1225             0x07, 0x09, 0x0a, 0x01, // Round Index, NLoS, 2(AoA Azimuth)
1226             0x02, 0x05, 0x07, 0x09, // AoA Azimuth FOM, 2(AoA Elevation), AoA Elevation FOM
1227             0x0a, 0x01, 0x02, 0x05, // RSSI, 3(Tx Timestamp..)
1228             0x07, 0x09, 0x0a, 0x01, // 4(Tx Timestamp..)
1229             0x02, 0x05, 0x07, 0x09, // Tx Timestamp, 3(Rx Timestamp..)
1230             0x05, 0x07, 0x09, 0x0a, // 2(Rx Timestamp), 2(Anchor Cfo)
1231             0x01, 0x02, 0x05, 0x07, // 2(Cfo), 2(Initiator Reply Time..)
1232             0x09, 0x05, 0x07, 0x09, // 2(Initiator Reply Time), 2(Responder Reply Time..)
1233             0x0a, 0x01, 0x02, 0x05, // 2(Responder Reply Time), 2(Initiator-Responder ToF)
1234             0x07, 0x09, 0x07, 0x09, // 4(Anchor Location..)
1235             0x05, 0x07, 0x09, 0x0a, // 4(Anchor Location..)
1236             0x01, 0x02, 0x05, 0x07, // 2(Anchor Location..), 2(Active Ranging Rounds..)
1237             0x09, 0x0a, 0x01, 0x02, // 4(Active Ranging Rounds..)
1238             0x05, 0x07, 0x09, 0x05, // 4(Active Ranging Rounds)
1239             // Second measurement
1240             0x0a, 0x01, 0x33, 0x05, // 2(Mac address), Status, Message Type
1241             0x33, 0x05, 0x02, 0x05, // 2(Message control), 2(Block Index)
1242             0x07, 0x09, 0x0a, 0x01, // Round Index, NLoS, 2(AoA Azimuth)
1243             0x02, 0x05, 0x07, 0x09, // AoA Azimuth FOM, 2(AoA Elevation), AoA Elevation FOM
1244             0x0a, 0x01, 0x02, 0x05, // RSSI, 3(Tx Timestamp..)
1245             0x07, 0x09, 0x0a, 0x01, // 4(Tx Timestamp..)
1246             0x02, 0x05, 0x07, 0x09, // Tx Timestamp, 3(Rx Timestamp..)
1247             0x05, 0x07, 0x09, 0x0a, // 2(Rx Timestamp), 2(Anchor Cfo)
1248             0x01, 0x02, 0x05, 0x07, // 2(Cfo), 2(Initiator Reply Time..)
1249             0x09, 0x05, 0x07, 0x09, // 2(Initiator Reply Time), 2(Responder Reply Time..)
1250             0x0a, 0x01, 0x02, 0x05, // 2(Responder Reply Time), 2(Initiator-Responder ToF)
1251             0x07, 0x09, 0x07, 0x09, // 4(Anchor Location..)
1252             0x05, 0x07, 0x09, 0x0a, // 4(Anchor Location..)
1253             0x01, 0x02, 0x01, 0x02, // 4(Anchor Location)
1254             0x05, 0x07, 0x09, 0x0a, // 4(Active Ranging Rounds..)
1255             0x01, 0x02, 0x05, 0x07, // 4(Active Ranging Rounds..)
1256             0x09, 0x05, // 2(Active Ranging Rounds)
1257         ];
1258 
1259         let measurements = ShortAddressDlTdoaRangingMeasurement::parse(&bytes, 2).unwrap();
1260         assert_eq!(measurements.len(), 2);
1261         let measurement_1 = &measurements[0].measurement;
1262         let mac_address_1 = &measurements[0].mac_address;
1263         assert_eq!(*mac_address_1, 0x010a);
1264         assert_eq!(measurement_1.status, 0x33);
1265         assert_eq!(measurement_1.message_type, 0x05);
1266         assert_eq!(measurement_1.message_control, 0x0553);
1267         assert_eq!(measurement_1.block_index, 0x0502);
1268         assert_eq!(measurement_1.round_index, 0x07);
1269         assert_eq!(measurement_1.nlos, 0x09);
1270         assert_eq!(measurement_1.aoa_azimuth, 0x010a);
1271         assert_eq!(measurement_1.aoa_azimuth_fom, 0x02);
1272         assert_eq!(measurement_1.aoa_elevation, 0x0705);
1273         assert_eq!(measurement_1.aoa_elevation_fom, 0x09);
1274         assert_eq!(measurement_1.rssi, 0x0a);
1275         assert_eq!(measurement_1.tx_timestamp, 0x02010a0907050201);
1276         assert_eq!(measurement_1.rx_timestamp, 0x0705090705);
1277         assert_eq!(measurement_1.anchor_cfo, 0x0a09);
1278         assert_eq!(measurement_1.cfo, 0x0201);
1279         assert_eq!(measurement_1.initiator_reply_time, 0x05090705);
1280         assert_eq!(measurement_1.responder_reply_time, 0x010a0907);
1281         assert_eq!(measurement_1.initiator_responder_tof, 0x0502);
1282         assert_eq!(
1283             measurement_1.dt_anchor_location,
1284             vec![0x07, 0x09, 0x07, 0x09, 0x05, 0x07, 0x09, 0x0a, 0x01, 0x02]
1285         );
1286         assert_eq!(
1287             measurement_1.ranging_rounds,
1288             vec![0x05, 0x07, 0x09, 0x0a, 0x01, 0x02, 0x05, 0x07, 0x09, 0x05,]
1289         );
1290 
1291         let measurement_2 = &measurements[1].measurement;
1292         let mac_address_2 = &measurements[1].mac_address;
1293         assert_eq!(*mac_address_2, 0x010a);
1294         assert_eq!(measurement_2.status, 0x33);
1295         assert_eq!(measurement_2.message_type, 0x05);
1296         assert_eq!(measurement_2.message_control, 0x0533);
1297         assert_eq!(measurement_2.block_index, 0x0502);
1298         assert_eq!(measurement_2.round_index, 0x07);
1299         assert_eq!(measurement_2.nlos, 0x09);
1300         assert_eq!(measurement_2.aoa_azimuth, 0x010a);
1301         assert_eq!(measurement_2.aoa_azimuth_fom, 0x02);
1302         assert_eq!(measurement_2.aoa_elevation, 0x0705);
1303         assert_eq!(measurement_2.aoa_elevation_fom, 0x09);
1304         assert_eq!(measurement_2.rssi, 0x0a);
1305         assert_eq!(measurement_2.tx_timestamp, 0x02010a0907050201);
1306         assert_eq!(measurement_2.rx_timestamp, 0x0705090705);
1307         assert_eq!(measurement_2.anchor_cfo, 0x0a09);
1308         assert_eq!(measurement_2.cfo, 0x0201);
1309         assert_eq!(measurement_2.initiator_reply_time, 0x05090705);
1310         assert_eq!(measurement_2.responder_reply_time, 0x010a0907);
1311         assert_eq!(measurement_2.initiator_responder_tof, 0x0502);
1312         assert_eq!(
1313             measurement_2.dt_anchor_location,
1314             vec![0x07, 0x09, 0x07, 0x09, 0x05, 0x07, 0x09, 0x0a, 0x01, 0x02, 0x01, 0x02]
1315         );
1316         assert_eq!(
1317             measurement_2.ranging_rounds,
1318             vec![0x05, 0x07, 0x09, 0x0a, 0x01, 0x02, 0x05, 0x07, 0x09, 0x05,]
1319         );
1320     }
1321 
1322     #[test]
test_extended_dltdoa_ranging_measurement()1323     fn test_extended_dltdoa_ranging_measurement() {
1324         let bytes = [
1325             // All Fields in Little Endian (LE)
1326             /* First measurement  */
1327             0x0a, 0x01, 0x33, 0x05, // 4(Mac address..)
1328             0x33, 0x05, 0x02, 0x05, // 4(Mac address)
1329             0x07, 0x09, 0x0a, 0x01, // Status, Message Type, 2(Message control),
1330             0x02, 0x05, 0x07, 0x09, // 2(Block Index), Round Index, NLoS,
1331             0x0a, 0x01, 0x02, 0x05, // 2(AoA Azimuth), AoA Azimuth FOM, 1(AoA Elevation..)
1332             0x07, 0x09, 0x0a, // 1(AoA Elevation), AoA Elevation FOM, RSSI,
1333             0x01, 0x02, 0x05, 0x07, // 4(Tx Timestamp..)
1334             0x09, 0x05, 0x07, 0x09, // 4(Tx Timestamp),
1335             0x0a, 0x01, 0x02, 0x05, // 4(Rx Timestamp..)
1336             0x07, 0x09, 0x05, 0x07, // 4(Rx Timestamp)
1337             0x09, 0x0a, 0x01, 0x02, // 2(Anchor Cfo), 2(Cfo),
1338             0x05, 0x07, 0x09, 0x05, // 4(Initiator Reply Time)
1339             0x07, 0x09, 0x0a, 0x01, // 4(Responder Reply Time),
1340             0x02, 0x05, 0x02, 0x05, // 2(Initiator-Responder ToF), 2(Active Ranging Rounds)
1341         ];
1342 
1343         let measurements = ExtendedAddressDlTdoaRangingMeasurement::parse(&bytes, 1).unwrap();
1344         assert_eq!(measurements.len(), 1);
1345         let measurement = &measurements[0].measurement;
1346         let mac_address = &measurements[0].mac_address;
1347         assert_eq!(*mac_address, 0x050205330533010a);
1348         assert_eq!(measurement.message_control, 0x010a);
1349         assert_eq!(measurement.block_index, 0x0502);
1350         assert_eq!(measurement.round_index, 0x07);
1351         assert_eq!(measurement.nlos, 0x09);
1352         assert_eq!(measurement.aoa_azimuth, 0x010a);
1353         assert_eq!(measurement.aoa_azimuth_fom, 0x02);
1354         assert_eq!(measurement.aoa_elevation, 0x0705);
1355         assert_eq!(measurement.aoa_elevation_fom, 0x09);
1356         assert_eq!(measurement.rssi, 0x0a);
1357         assert_eq!(measurement.tx_timestamp, 0x0907050907050201);
1358         assert_eq!(measurement.rx_timestamp, 0x070509070502010a);
1359         assert_eq!(measurement.anchor_cfo, 0x0a09);
1360         assert_eq!(measurement.cfo, 0x0201);
1361         assert_eq!(measurement.initiator_reply_time, 0x05090705);
1362         assert_eq!(measurement.responder_reply_time, 0x010a0907);
1363         assert_eq!(measurement.initiator_responder_tof, 0x0502);
1364         assert_eq!(measurement.dt_anchor_location, vec![]);
1365         assert_eq!(measurement.ranging_rounds, vec![0x02, 0x05]);
1366     }
1367 
1368     #[test]
test_build_data_transfer_phase_config_cmd()1369     fn test_build_data_transfer_phase_config_cmd() {
1370         let packet: UciControlPacket = build_data_transfer_phase_config_cmd(
1371             0x1234_5678,
1372             0x0,
1373             0x2,
1374             1,
1375             vec![0, 1],
1376             vec![2, 3],
1377             vec![0x00],
1378         )
1379         .unwrap()
1380         .into();
1381         let packet_fragments: Vec<UciControlPacketHal> = packet.into();
1382         let uci_packet = packet_fragments[0].encode_to_vec();
1383         assert_eq!(
1384             uci_packet,
1385             Ok(vec![
1386                 0x21, 0x0e, 0x00, 0x0c, // 2(packet info), RFU, payload length(12)
1387                 0x78, 0x56, 0x34, 0x12, // 4(session id (LE))
1388                 0x00, 0x02, 0x01, // dtpcm_repetition, data_transfer_control, dtpml_size
1389                 0x00, 0x01, 0x02, 0x03, // payload
1390                 0x00, //stop_data_transfer
1391             ])
1392         );
1393     }
1394 }
1395