cbor.rs (7987B)
1 use crate::{ 2 RADROOTS_MESH_FRAME_VERSION, RadrootsMeshError, RadrootsMeshFrame, RadrootsMeshFrameType, 3 RadrootsMeshPayload, RadrootsMeshScope, 4 }; 5 use alloc::string::String; 6 use alloc::vec::Vec; 7 8 pub fn encode_mesh_frame_cbor(frame: &RadrootsMeshFrame) -> Result<Vec<u8>, RadrootsMeshError> { 9 frame.validate()?; 10 let mut output = Vec::new(); 11 encode_map_len(&mut output, 7); 12 encode_uint(&mut output, 0); 13 encode_uint(&mut output, u64::from(frame.version)); 14 encode_uint(&mut output, 1); 15 encode_uint(&mut output, frame.frame_type.code()); 16 encode_uint(&mut output, 2); 17 encode_text(&mut output, &frame.scope_id.cbor_label())?; 18 encode_uint(&mut output, 3); 19 encode_text(&mut output, &frame.message_id)?; 20 encode_uint(&mut output, 4); 21 encode_uint(&mut output, frame.created_at_ms); 22 encode_uint(&mut output, 5); 23 encode_uint(&mut output, frame.ttl); 24 encode_uint(&mut output, 6); 25 encode_payload(&mut output, &frame.payload)?; 26 Ok(output) 27 } 28 29 pub fn decode_mesh_frame_cbor(bytes: &[u8]) -> Result<RadrootsMeshFrame, RadrootsMeshError> { 30 let mut cursor = Cursor::new(bytes); 31 cursor.expect_map_len(7)?; 32 cursor.expect_uint(0)?; 33 let version = cursor.read_uint_u16()?; 34 if version != RADROOTS_MESH_FRAME_VERSION { 35 return Err(RadrootsMeshError::UnsupportedVersion); 36 } 37 cursor.expect_uint(1)?; 38 let frame_type = RadrootsMeshFrameType::parse_code(cursor.read_uint()?)?; 39 cursor.expect_uint(2)?; 40 let scope_id = RadrootsMeshScope::parse(&cursor.read_text()?)?; 41 cursor.expect_uint(3)?; 42 let message_id = cursor.read_text()?; 43 cursor.expect_uint(4)?; 44 let created_at_ms = cursor.read_uint()?; 45 cursor.expect_uint(5)?; 46 let ttl = cursor.read_uint()?; 47 cursor.expect_uint(6)?; 48 let payload = cursor.read_payload()?; 49 cursor.finish()?; 50 let frame = RadrootsMeshFrame { 51 version, 52 frame_type, 53 scope_id, 54 message_id, 55 created_at_ms, 56 ttl, 57 payload, 58 }; 59 frame.validate()?; 60 Ok(frame) 61 } 62 63 fn encode_payload( 64 output: &mut Vec<u8>, 65 payload: &RadrootsMeshPayload, 66 ) -> Result<(), RadrootsMeshError> { 67 payload.validate()?; 68 encode_map_len(output, 0); 69 Ok(()) 70 } 71 72 fn encode_uint(output: &mut Vec<u8>, value: u64) { 73 encode_major(output, 0, value); 74 } 75 76 fn encode_text(output: &mut Vec<u8>, value: &str) -> Result<(), RadrootsMeshError> { 77 let len = u64::try_from(value.len()).map_err(|_| RadrootsMeshError::InvalidCbor)?; 78 encode_major(output, 3, len); 79 output.extend_from_slice(value.as_bytes()); 80 Ok(()) 81 } 82 83 fn encode_map_len(output: &mut Vec<u8>, len: u64) { 84 encode_major(output, 5, len); 85 } 86 87 fn encode_major(output: &mut Vec<u8>, major: u8, value: u64) { 88 let prefix = major << 5; 89 match value { 90 0..=23 => output.push(prefix | value as u8), 91 24..=0xff => output.extend_from_slice(&[prefix | 24, value as u8]), 92 0x100..=0xffff => { 93 output.push(prefix | 25); 94 output.extend_from_slice(&(value as u16).to_be_bytes()); 95 } 96 0x1_0000..=0xffff_ffff => { 97 output.push(prefix | 26); 98 output.extend_from_slice(&(value as u32).to_be_bytes()); 99 } 100 _ => { 101 output.push(prefix | 27); 102 output.extend_from_slice(&value.to_be_bytes()); 103 } 104 } 105 } 106 107 struct Cursor<'a> { 108 bytes: &'a [u8], 109 offset: usize, 110 } 111 112 impl<'a> Cursor<'a> { 113 fn new(bytes: &'a [u8]) -> Self { 114 Self { bytes, offset: 0 } 115 } 116 117 fn read_byte(&mut self) -> Result<u8, RadrootsMeshError> { 118 let byte = self 119 .bytes 120 .get(self.offset) 121 .copied() 122 .ok_or(RadrootsMeshError::InvalidCbor)?; 123 self.offset += 1; 124 Ok(byte) 125 } 126 127 fn read_exact(&mut self, len: usize) -> Result<&'a [u8], RadrootsMeshError> { 128 let end = self 129 .offset 130 .checked_add(len) 131 .ok_or(RadrootsMeshError::InvalidCbor)?; 132 let slice = self 133 .bytes 134 .get(self.offset..end) 135 .ok_or(RadrootsMeshError::InvalidCbor)?; 136 self.offset = end; 137 Ok(slice) 138 } 139 140 fn read_major(&mut self, expected_major: u8) -> Result<u64, RadrootsMeshError> { 141 let initial = self.read_byte()?; 142 if initial >> 5 != expected_major { 143 return Err(RadrootsMeshError::InvalidCbor); 144 } 145 match initial & 0x1f { 146 value @ 0..=23 => Ok(u64::from(value)), 147 24 => { 148 let value = u64::from(self.read_byte()?); 149 if value < 24 { 150 return Err(RadrootsMeshError::InvalidCbor); 151 } 152 Ok(value) 153 } 154 25 => { 155 let bytes = self.read_exact(2)?; 156 let value = u64::from(u16::from_be_bytes([bytes[0], bytes[1]])); 157 if value < 0x100 { 158 return Err(RadrootsMeshError::InvalidCbor); 159 } 160 Ok(value) 161 } 162 26 => { 163 let bytes = self.read_exact(4)?; 164 let value = u64::from(u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])); 165 if value < 0x1_0000 { 166 return Err(RadrootsMeshError::InvalidCbor); 167 } 168 Ok(value) 169 } 170 27 => { 171 let bytes = self.read_exact(8)?; 172 let value = u64::from_be_bytes([ 173 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], 174 ]); 175 if value < 0x1_0000_0000 { 176 return Err(RadrootsMeshError::InvalidCbor); 177 } 178 Ok(value) 179 } 180 _ => Err(RadrootsMeshError::InvalidCbor), 181 } 182 } 183 184 fn read_uint(&mut self) -> Result<u64, RadrootsMeshError> { 185 self.read_major(0) 186 } 187 188 fn read_uint_u16(&mut self) -> Result<u16, RadrootsMeshError> { 189 u16::try_from(self.read_uint()?).map_err(|_| RadrootsMeshError::InvalidCbor) 190 } 191 192 fn expect_uint(&mut self, expected: u64) -> Result<(), RadrootsMeshError> { 193 if self.read_uint()? == expected { 194 Ok(()) 195 } else { 196 Err(RadrootsMeshError::InvalidCbor) 197 } 198 } 199 200 fn read_text(&mut self) -> Result<String, RadrootsMeshError> { 201 let len = 202 usize::try_from(self.read_major(3)?).map_err(|_| RadrootsMeshError::InvalidCbor)?; 203 let bytes = self.read_exact(len)?; 204 String::from_utf8(bytes.to_vec()).map_err(|_| RadrootsMeshError::InvalidUtf8) 205 } 206 207 fn skip_bytes(&mut self) -> Result<(), RadrootsMeshError> { 208 let len = 209 usize::try_from(self.read_major(2)?).map_err(|_| RadrootsMeshError::InvalidCbor)?; 210 self.read_exact(len)?; 211 Ok(()) 212 } 213 214 fn read_payload(&mut self) -> Result<RadrootsMeshPayload, RadrootsMeshError> { 215 let initial = self.read_byte()?; 216 match initial >> 5 { 217 2 => { 218 self.offset -= 1; 219 self.skip_bytes()?; 220 Err(RadrootsMeshError::PayloadTransmissionForbidden) 221 } 222 5 => { 223 self.offset -= 1; 224 if self.read_major(5)? == 0 { 225 Ok(RadrootsMeshPayload::EmptyMap) 226 } else { 227 Err(RadrootsMeshError::PayloadTransmissionForbidden) 228 } 229 } 230 _ => Err(RadrootsMeshError::InvalidCbor), 231 } 232 } 233 234 fn expect_map_len(&mut self, expected: u64) -> Result<(), RadrootsMeshError> { 235 if self.read_major(5)? == expected { 236 Ok(()) 237 } else { 238 Err(RadrootsMeshError::InvalidCbor) 239 } 240 } 241 242 fn finish(&self) -> Result<(), RadrootsMeshError> { 243 if self.offset == self.bytes.len() { 244 Ok(()) 245 } else { 246 Err(RadrootsMeshError::InvalidCbor) 247 } 248 } 249 }