ieee802154.rs 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  1. use core::fmt;
  2. use byteorder::{ByteOrder, LittleEndian};
  3. use super::{Error, Result};
  4. use crate::wire::ipv6::Address as Ipv6Address;
  5. enum_with_unknown! {
  6. /// IEEE 802.15.4 frame type.
  7. pub enum FrameType(u8) {
  8. Beacon = 0b000,
  9. Data = 0b001,
  10. Acknowledgement = 0b010,
  11. MacCommand = 0b011,
  12. Multipurpose = 0b101,
  13. FragmentOrFrak = 0b110,
  14. Extended = 0b111,
  15. }
  16. }
  17. impl fmt::Display for FrameType {
  18. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  19. match self {
  20. FrameType::Beacon => write!(f, "Beacon"),
  21. FrameType::Data => write!(f, "Data"),
  22. FrameType::Acknowledgement => write!(f, "Ack"),
  23. FrameType::MacCommand => write!(f, "MAC command"),
  24. FrameType::Multipurpose => write!(f, "Multipurpose"),
  25. FrameType::FragmentOrFrak => write!(f, "FragmentOrFrak"),
  26. FrameType::Extended => write!(f, "Extended"),
  27. FrameType::Unknown(id) => write!(f, "0b{id:04b}"),
  28. }
  29. }
  30. }
  31. enum_with_unknown! {
  32. /// IEEE 802.15.4 addressing mode for destination and source addresses.
  33. pub enum AddressingMode(u8) {
  34. Absent = 0b00,
  35. Short = 0b10,
  36. Extended = 0b11,
  37. }
  38. }
  39. impl AddressingMode {
  40. /// Return the size in octets of the address.
  41. const fn size(&self) -> usize {
  42. match self {
  43. AddressingMode::Absent => 0,
  44. AddressingMode::Short => 2,
  45. AddressingMode::Extended => 8,
  46. AddressingMode::Unknown(_) => 0, // TODO(thvdveld): what do we need to here?
  47. }
  48. }
  49. }
  50. impl fmt::Display for AddressingMode {
  51. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  52. match self {
  53. AddressingMode::Absent => write!(f, "Absent"),
  54. AddressingMode::Short => write!(f, "Short"),
  55. AddressingMode::Extended => write!(f, "Extended"),
  56. AddressingMode::Unknown(id) => write!(f, "0b{id:04b}"),
  57. }
  58. }
  59. }
  60. /// A IEEE 802.15.4 PAN.
  61. #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
  62. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  63. pub struct Pan(pub u16);
  64. impl Pan {
  65. pub const BROADCAST: Self = Self(0xffff);
  66. /// Return the PAN ID as bytes.
  67. pub fn as_bytes(&self) -> [u8; 2] {
  68. let mut pan = [0u8; 2];
  69. LittleEndian::write_u16(&mut pan, self.0);
  70. pan
  71. }
  72. }
  73. /// A IEEE 802.15.4 address.
  74. #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
  75. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  76. pub enum Address {
  77. Absent,
  78. Short([u8; 2]),
  79. Extended([u8; 8]),
  80. }
  81. #[cfg(test)]
  82. impl Default for Address {
  83. fn default() -> Self {
  84. Address::Extended([0u8; 8])
  85. }
  86. }
  87. impl Address {
  88. /// The broadcast address.
  89. pub const BROADCAST: Address = Address::Short([0xff; 2]);
  90. /// Query whether the address is an unicast address.
  91. pub fn is_unicast(&self) -> bool {
  92. !self.is_broadcast()
  93. }
  94. /// Query whether this address is the broadcast address.
  95. pub fn is_broadcast(&self) -> bool {
  96. *self == Self::BROADCAST
  97. }
  98. const fn short_from_bytes(a: [u8; 2]) -> Self {
  99. Self::Short(a)
  100. }
  101. const fn extended_from_bytes(a: [u8; 8]) -> Self {
  102. Self::Extended(a)
  103. }
  104. pub fn from_bytes(a: &[u8]) -> Self {
  105. if a.len() == 2 {
  106. let mut b = [0u8; 2];
  107. b.copy_from_slice(a);
  108. Address::Short(b)
  109. } else if a.len() == 8 {
  110. let mut b = [0u8; 8];
  111. b.copy_from_slice(a);
  112. Address::Extended(b)
  113. } else {
  114. panic!("Not an IEEE802.15.4 address");
  115. }
  116. }
  117. pub const fn as_bytes(&self) -> &[u8] {
  118. match self {
  119. Address::Absent => &[],
  120. Address::Short(value) => value,
  121. Address::Extended(value) => value,
  122. }
  123. }
  124. /// Convert the extended address to an Extended Unique Identifier (EUI-64)
  125. pub fn as_eui_64(&self) -> Option<[u8; 8]> {
  126. match self {
  127. Address::Absent | Address::Short(_) => None,
  128. Address::Extended(value) => {
  129. let mut bytes = [0; 8];
  130. bytes.copy_from_slice(&value[..]);
  131. bytes[0] ^= 1 << 1;
  132. Some(bytes)
  133. }
  134. }
  135. }
  136. /// Convert an extended address to a link-local IPv6 address using the EUI-64 format from
  137. /// RFC2464.
  138. pub fn as_link_local_address(&self) -> Option<Ipv6Address> {
  139. let mut bytes = [0; 16];
  140. bytes[0] = 0xfe;
  141. bytes[1] = 0x80;
  142. bytes[8..].copy_from_slice(&self.as_eui_64()?);
  143. Some(Ipv6Address::from_bytes(&bytes))
  144. }
  145. }
  146. impl fmt::Display for Address {
  147. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  148. match self {
  149. Self::Absent => write!(f, "not-present"),
  150. Self::Short(bytes) => write!(f, "{:02x}-{:02x}", bytes[0], bytes[1]),
  151. Self::Extended(bytes) => write!(
  152. f,
  153. "{:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}",
  154. bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]
  155. ),
  156. }
  157. }
  158. }
  159. enum_with_unknown! {
  160. /// IEEE 802.15.4 addressing mode for destination and source addresses.
  161. pub enum FrameVersion(u8) {
  162. Ieee802154_2003 = 0b00,
  163. Ieee802154_2006 = 0b01,
  164. Ieee802154 = 0b10,
  165. }
  166. }
  167. /// A read/write wrapper around an IEEE 802.15.4 frame buffer.
  168. #[derive(Debug, Clone)]
  169. pub struct Frame<T: AsRef<[u8]>> {
  170. buffer: T,
  171. }
  172. mod field {
  173. use crate::wire::field::*;
  174. pub const FRAMECONTROL: Field = 0..2;
  175. pub const SEQUENCE_NUMBER: usize = 2;
  176. pub const ADDRESSING: Rest = 3..;
  177. }
  178. macro_rules! fc_bit_field {
  179. ($field:ident, $bit:literal) => {
  180. #[inline]
  181. pub fn $field(&self) -> bool {
  182. let data = self.buffer.as_ref();
  183. let raw = LittleEndian::read_u16(&data[field::FRAMECONTROL]);
  184. ((raw >> $bit) & 0b1) == 0b1
  185. }
  186. };
  187. }
  188. macro_rules! set_fc_bit_field {
  189. ($field:ident, $bit:literal) => {
  190. #[inline]
  191. pub fn $field(&mut self, val: bool) {
  192. let data = &mut self.buffer.as_mut()[field::FRAMECONTROL];
  193. let mut raw = LittleEndian::read_u16(data);
  194. raw |= ((val as u16) << $bit);
  195. data.copy_from_slice(&raw.to_le_bytes());
  196. }
  197. };
  198. }
  199. impl<T: AsRef<[u8]>> Frame<T> {
  200. /// Input a raw octet buffer with Ethernet frame structure.
  201. pub const fn new_unchecked(buffer: T) -> Frame<T> {
  202. Frame { buffer }
  203. }
  204. /// Shorthand for a combination of [new_unchecked] and [check_len].
  205. ///
  206. /// [new_unchecked]: #method.new_unchecked
  207. /// [check_len]: #method.check_len
  208. pub fn new_checked(buffer: T) -> Result<Frame<T>> {
  209. let packet = Self::new_unchecked(buffer);
  210. packet.check_len()?;
  211. if matches!(packet.dst_addressing_mode(), AddressingMode::Unknown(_)) {
  212. return Err(Error);
  213. }
  214. if matches!(packet.src_addressing_mode(), AddressingMode::Unknown(_)) {
  215. return Err(Error);
  216. }
  217. Ok(packet)
  218. }
  219. /// Ensure that no accessor method will panic if called.
  220. /// Returns `Err(Error)` if the buffer is too short.
  221. pub fn check_len(&self) -> Result<()> {
  222. // We need at least 3 bytes
  223. if self.buffer.as_ref().len() < 3 {
  224. return Err(Error);
  225. }
  226. let mut offset = field::ADDRESSING.start + 2;
  227. // Calculate the size of the addressing field.
  228. offset += self.dst_addressing_mode().size();
  229. offset += self.src_addressing_mode().size();
  230. if !self.pan_id_compression() {
  231. offset += 2;
  232. }
  233. if offset > self.buffer.as_ref().len() {
  234. return Err(Error);
  235. }
  236. Ok(())
  237. }
  238. /// Consumes the frame, returning the underlying buffer.
  239. pub fn into_inner(self) -> T {
  240. self.buffer
  241. }
  242. /// Return the FrameType field.
  243. #[inline]
  244. pub fn frame_type(&self) -> FrameType {
  245. let data = self.buffer.as_ref();
  246. let raw = LittleEndian::read_u16(&data[field::FRAMECONTROL]);
  247. let ft = (raw & 0b11) as u8;
  248. FrameType::from(ft)
  249. }
  250. fc_bit_field!(security_enabled, 3);
  251. fc_bit_field!(frame_pending, 4);
  252. fc_bit_field!(ack_request, 5);
  253. fc_bit_field!(pan_id_compression, 6);
  254. fc_bit_field!(sequence_number_suppression, 8);
  255. fc_bit_field!(ie_present, 9);
  256. /// Return the destination addressing mode.
  257. #[inline]
  258. pub fn dst_addressing_mode(&self) -> AddressingMode {
  259. let data = self.buffer.as_ref();
  260. let raw = LittleEndian::read_u16(&data[field::FRAMECONTROL]);
  261. let am = ((raw >> 10) & 0b11) as u8;
  262. AddressingMode::from(am)
  263. }
  264. /// Return the frame version.
  265. #[inline]
  266. pub fn frame_version(&self) -> FrameVersion {
  267. let data = self.buffer.as_ref();
  268. let raw = LittleEndian::read_u16(&data[field::FRAMECONTROL]);
  269. let fv = ((raw >> 12) & 0b11) as u8;
  270. FrameVersion::from(fv)
  271. }
  272. /// Return the source addressing mode.
  273. #[inline]
  274. pub fn src_addressing_mode(&self) -> AddressingMode {
  275. let data = self.buffer.as_ref();
  276. let raw = LittleEndian::read_u16(&data[field::FRAMECONTROL]);
  277. let am = ((raw >> 14) & 0b11) as u8;
  278. AddressingMode::from(am)
  279. }
  280. /// Return the sequence number of the frame.
  281. #[inline]
  282. pub fn sequence_number(&self) -> Option<u8> {
  283. match self.frame_type() {
  284. FrameType::Beacon
  285. | FrameType::Data
  286. | FrameType::Acknowledgement
  287. | FrameType::MacCommand
  288. | FrameType::Multipurpose => {
  289. let data = self.buffer.as_ref();
  290. let raw = data[field::SEQUENCE_NUMBER];
  291. Some(raw)
  292. }
  293. FrameType::Extended | FrameType::FragmentOrFrak | FrameType::Unknown(_) => None,
  294. }
  295. }
  296. /// Return the addressing fields.
  297. #[inline]
  298. fn addressing_fields(&self) -> Option<&[u8]> {
  299. match self.frame_type() {
  300. FrameType::Beacon
  301. | FrameType::Data
  302. | FrameType::MacCommand
  303. | FrameType::Multipurpose => (),
  304. FrameType::Acknowledgement if self.frame_version() == FrameVersion::Ieee802154 => (),
  305. FrameType::Acknowledgement
  306. | FrameType::Extended
  307. | FrameType::FragmentOrFrak
  308. | FrameType::Unknown(_) => return None,
  309. }
  310. let mut offset = 2;
  311. // Calculate the size of the addressing field.
  312. offset += self.dst_addressing_mode().size();
  313. offset += self.src_addressing_mode().size();
  314. if !self.pan_id_compression() {
  315. offset += 2;
  316. }
  317. Some(&self.buffer.as_ref()[field::ADDRESSING][..offset])
  318. }
  319. /// Return the destination PAN field.
  320. #[inline]
  321. pub fn dst_pan_id(&self) -> Option<Pan> {
  322. let addressing_fields = self.addressing_fields()?;
  323. match self.dst_addressing_mode() {
  324. AddressingMode::Absent => None,
  325. AddressingMode::Short | AddressingMode::Extended => {
  326. Some(Pan(LittleEndian::read_u16(&addressing_fields[0..2])))
  327. }
  328. AddressingMode::Unknown(_) => None,
  329. }
  330. }
  331. /// Return the destination address field.
  332. #[inline]
  333. pub fn dst_addr(&self) -> Option<Address> {
  334. let addressing_fields = self.addressing_fields()?;
  335. match self.dst_addressing_mode() {
  336. AddressingMode::Absent => Some(Address::Absent),
  337. AddressingMode::Short => {
  338. let mut raw = [0u8; 2];
  339. raw.clone_from_slice(&addressing_fields[2..4]);
  340. raw.reverse();
  341. Some(Address::short_from_bytes(raw))
  342. }
  343. AddressingMode::Extended => {
  344. let mut raw = [0u8; 8];
  345. raw.clone_from_slice(&addressing_fields[2..10]);
  346. raw.reverse();
  347. Some(Address::extended_from_bytes(raw))
  348. }
  349. AddressingMode::Unknown(_) => None,
  350. }
  351. }
  352. /// Return the destination PAN field.
  353. #[inline]
  354. pub fn src_pan_id(&self) -> Option<Pan> {
  355. if self.pan_id_compression() {
  356. return None;
  357. }
  358. let addressing_fields = self.addressing_fields()?;
  359. let offset = self.dst_addressing_mode().size() + 2;
  360. match self.src_addressing_mode() {
  361. AddressingMode::Absent => None,
  362. AddressingMode::Short | AddressingMode::Extended => Some(Pan(LittleEndian::read_u16(
  363. &addressing_fields[offset..offset + 2],
  364. ))),
  365. AddressingMode::Unknown(_) => None,
  366. }
  367. }
  368. /// Return the source address field.
  369. #[inline]
  370. pub fn src_addr(&self) -> Option<Address> {
  371. let addressing_fields = self.addressing_fields()?;
  372. let mut offset = match self.dst_addressing_mode() {
  373. AddressingMode::Absent => 0,
  374. AddressingMode::Short => 2,
  375. AddressingMode::Extended => 8,
  376. _ => return None, // TODO(thvdveld): what do we do here?
  377. } + 2;
  378. if !self.pan_id_compression() {
  379. offset += 2;
  380. }
  381. match self.src_addressing_mode() {
  382. AddressingMode::Absent => Some(Address::Absent),
  383. AddressingMode::Short => {
  384. let mut raw = [0u8; 2];
  385. raw.clone_from_slice(&addressing_fields[offset..offset + 2]);
  386. raw.reverse();
  387. Some(Address::short_from_bytes(raw))
  388. }
  389. AddressingMode::Extended => {
  390. let mut raw = [0u8; 8];
  391. raw.clone_from_slice(&addressing_fields[offset..offset + 8]);
  392. raw.reverse();
  393. Some(Address::extended_from_bytes(raw))
  394. }
  395. AddressingMode::Unknown(_) => None,
  396. }
  397. }
  398. /// Return the index where the auxiliary security header starts.
  399. fn aux_security_header_start(&self) -> usize {
  400. // We start with 3, because 2 bytes for frame control and the sequence number.
  401. let mut index = 3;
  402. index += self.addressing_fields().unwrap().len();
  403. index
  404. }
  405. /// Return the index where the payload starts.
  406. fn payload_start(&self) -> usize {
  407. let mut index = self.aux_security_header_start();
  408. if self.security_enabled() {
  409. // We add 5 because 1 byte for control bits and 4 bytes for frame counter.
  410. index += 5;
  411. index += if let Some(len) = self.key_identifier_length() {
  412. len as usize
  413. } else {
  414. 0
  415. };
  416. }
  417. index
  418. }
  419. /// Return the length of the key identifier field.
  420. fn key_identifier_length(&self) -> Option<u8> {
  421. Some(match self.key_identifier_mode() {
  422. 0 => 0,
  423. 1 => 1,
  424. 2 => 5,
  425. 3 => 9,
  426. _ => return None,
  427. })
  428. }
  429. /// Return the security level of the auxiliary security header.
  430. pub fn security_level(&self) -> u8 {
  431. let index = self.aux_security_header_start();
  432. let b = self.buffer.as_ref()[index..][0];
  433. b & 0b111
  434. }
  435. /// Return the key identifier mode used by the auxiliary security header.
  436. pub fn key_identifier_mode(&self) -> u8 {
  437. let index = self.aux_security_header_start();
  438. let b = self.buffer.as_ref()[index..][0];
  439. (b >> 3) & 0b11
  440. }
  441. /// Return the frame counter field.
  442. pub fn frame_counter(&self) -> u32 {
  443. let index = self.aux_security_header_start();
  444. let b = &self.buffer.as_ref()[index..];
  445. LittleEndian::read_u32(&b[1..1 + 4])
  446. }
  447. /// Return the Key Identifier field.
  448. fn key_identifier(&self) -> &[u8] {
  449. let index = self.aux_security_header_start();
  450. let b = &self.buffer.as_ref()[index..];
  451. let length = if let Some(len) = self.key_identifier_length() {
  452. len as usize
  453. } else {
  454. 0
  455. };
  456. &b[5..][..length]
  457. }
  458. /// Return the Key Source field.
  459. pub fn key_source(&self) -> Option<&[u8]> {
  460. let ki = self.key_identifier();
  461. let len = ki.len();
  462. if len > 1 {
  463. Some(&ki[..len - 1])
  464. } else {
  465. None
  466. }
  467. }
  468. /// Return the Key Index field.
  469. pub fn key_index(&self) -> Option<u8> {
  470. let ki = self.key_identifier();
  471. let len = ki.len();
  472. if len > 0 {
  473. Some(ki[len - 1])
  474. } else {
  475. None
  476. }
  477. }
  478. /// Return the Message Integrity Code (MIC).
  479. pub fn message_integrity_code(&self) -> Option<&[u8]> {
  480. let mic_len = match self.security_level() {
  481. 0 | 4 => return None,
  482. 1 | 5 => 4,
  483. 2 | 6 => 8,
  484. 3 | 7 => 16,
  485. _ => panic!(),
  486. };
  487. let data = &self.buffer.as_ref();
  488. let len = data.len();
  489. Some(&data[len - mic_len..])
  490. }
  491. /// Return the MAC header.
  492. pub fn mac_header(&self) -> &[u8] {
  493. let data = &self.buffer.as_ref();
  494. &data[..self.payload_start()]
  495. }
  496. }
  497. impl<'a, T: AsRef<[u8]> + ?Sized> Frame<&'a T> {
  498. /// Return a pointer to the payload.
  499. #[inline]
  500. pub fn payload(&self) -> Option<&'a [u8]> {
  501. match self.frame_type() {
  502. FrameType::Data => {
  503. let index = self.payload_start();
  504. let data = &self.buffer.as_ref();
  505. Some(&data[index..])
  506. }
  507. _ => None,
  508. }
  509. }
  510. }
  511. impl<T: AsRef<[u8]> + AsMut<[u8]>> Frame<T> {
  512. /// Set the frame type.
  513. #[inline]
  514. pub fn set_frame_type(&mut self, frame_type: FrameType) {
  515. let data = &mut self.buffer.as_mut()[field::FRAMECONTROL];
  516. let mut raw = LittleEndian::read_u16(data);
  517. raw = (raw & !(0b111)) | (u8::from(frame_type) as u16 & 0b111);
  518. data.copy_from_slice(&raw.to_le_bytes());
  519. }
  520. set_fc_bit_field!(set_security_enabled, 3);
  521. set_fc_bit_field!(set_frame_pending, 4);
  522. set_fc_bit_field!(set_ack_request, 5);
  523. set_fc_bit_field!(set_pan_id_compression, 6);
  524. /// Set the frame version.
  525. #[inline]
  526. pub fn set_frame_version(&mut self, version: FrameVersion) {
  527. let data = &mut self.buffer.as_mut()[field::FRAMECONTROL];
  528. let mut raw = LittleEndian::read_u16(data);
  529. raw = (raw & !(0b11 << 12)) | ((u8::from(version) as u16 & 0b11) << 12);
  530. data.copy_from_slice(&raw.to_le_bytes());
  531. }
  532. /// Set the frame sequence number.
  533. #[inline]
  534. pub fn set_sequence_number(&mut self, value: u8) {
  535. let data = self.buffer.as_mut();
  536. data[field::SEQUENCE_NUMBER] = value;
  537. }
  538. /// Set the destination PAN ID.
  539. #[inline]
  540. pub fn set_dst_pan_id(&mut self, value: Pan) {
  541. // NOTE the destination addressing mode must be different than Absent.
  542. // This is the reason why we set it to Extended.
  543. self.set_dst_addressing_mode(AddressingMode::Extended);
  544. let data = self.buffer.as_mut();
  545. data[field::ADDRESSING][..2].copy_from_slice(&value.as_bytes());
  546. }
  547. /// Set the destination address.
  548. #[inline]
  549. pub fn set_dst_addr(&mut self, mut value: Address) {
  550. match value {
  551. Address::Absent => self.set_dst_addressing_mode(AddressingMode::Absent),
  552. Address::Short(ref mut value) => {
  553. value.reverse();
  554. self.set_dst_addressing_mode(AddressingMode::Short);
  555. let data = self.buffer.as_mut();
  556. data[field::ADDRESSING][2..2 + 2].copy_from_slice(value);
  557. value.reverse();
  558. }
  559. Address::Extended(ref mut value) => {
  560. value.reverse();
  561. self.set_dst_addressing_mode(AddressingMode::Extended);
  562. let data = &mut self.buffer.as_mut()[field::ADDRESSING];
  563. data[2..2 + 8].copy_from_slice(value);
  564. value.reverse();
  565. }
  566. }
  567. }
  568. /// Set the destination addressing mode.
  569. #[inline]
  570. fn set_dst_addressing_mode(&mut self, value: AddressingMode) {
  571. let data = &mut self.buffer.as_mut()[field::FRAMECONTROL];
  572. let mut raw = LittleEndian::read_u16(data);
  573. raw = (raw & !(0b11 << 10)) | ((u8::from(value) as u16 & 0b11) << 10);
  574. data.copy_from_slice(&raw.to_le_bytes());
  575. }
  576. /// Set the source PAN ID.
  577. #[inline]
  578. pub fn set_src_pan_id(&mut self, value: Pan) {
  579. let offset = match self.dst_addressing_mode() {
  580. AddressingMode::Absent => 0,
  581. AddressingMode::Short => 2,
  582. AddressingMode::Extended => 8,
  583. _ => unreachable!(),
  584. } + 2;
  585. let data = &mut self.buffer.as_mut()[field::ADDRESSING];
  586. data[offset..offset + 2].copy_from_slice(&value.as_bytes());
  587. }
  588. /// Set the source address.
  589. #[inline]
  590. pub fn set_src_addr(&mut self, mut value: Address) {
  591. let offset = match self.dst_addressing_mode() {
  592. AddressingMode::Absent => 0,
  593. AddressingMode::Short => 2,
  594. AddressingMode::Extended => 8,
  595. _ => unreachable!(),
  596. } + 2;
  597. let offset = offset + if self.pan_id_compression() { 0 } else { 2 };
  598. match value {
  599. Address::Absent => self.set_src_addressing_mode(AddressingMode::Absent),
  600. Address::Short(ref mut value) => {
  601. value.reverse();
  602. self.set_src_addressing_mode(AddressingMode::Short);
  603. let data = &mut self.buffer.as_mut()[field::ADDRESSING];
  604. data[offset..offset + 2].copy_from_slice(value);
  605. value.reverse();
  606. }
  607. Address::Extended(ref mut value) => {
  608. value.reverse();
  609. self.set_src_addressing_mode(AddressingMode::Extended);
  610. let data = &mut self.buffer.as_mut()[field::ADDRESSING];
  611. data[offset..offset + 8].copy_from_slice(value);
  612. value.reverse();
  613. }
  614. }
  615. }
  616. /// Set the source addressing mode.
  617. #[inline]
  618. fn set_src_addressing_mode(&mut self, value: AddressingMode) {
  619. let data = &mut self.buffer.as_mut()[field::FRAMECONTROL];
  620. let mut raw = LittleEndian::read_u16(data);
  621. raw = (raw & !(0b11 << 14)) | ((u8::from(value) as u16 & 0b11) << 14);
  622. data.copy_from_slice(&raw.to_le_bytes());
  623. }
  624. /// Return a mutable pointer to the payload.
  625. #[inline]
  626. pub fn payload_mut(&mut self) -> Option<&mut [u8]> {
  627. match self.frame_type() {
  628. FrameType::Data => {
  629. let index = self.payload_start();
  630. let data = self.buffer.as_mut();
  631. Some(&mut data[index..])
  632. }
  633. _ => None,
  634. }
  635. }
  636. }
  637. impl<T: AsRef<[u8]>> fmt::Display for Frame<T> {
  638. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  639. write!(
  640. f,
  641. "IEEE802.15.4 frame type={} seq={:2x?} dst_pan={:x?} dest={:x?} src_pan={:?} src={:x?}",
  642. self.frame_type(),
  643. self.sequence_number(),
  644. self.dst_pan_id(),
  645. self.dst_addr(),
  646. self.src_pan_id(),
  647. self.src_addr(),
  648. )
  649. }
  650. }
  651. /// A high-level representation of an IEEE802.15.4 frame.
  652. #[derive(Debug, PartialEq, Eq, Clone, Copy)]
  653. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  654. pub struct Repr {
  655. pub frame_type: FrameType,
  656. pub security_enabled: bool,
  657. pub frame_pending: bool,
  658. pub ack_request: bool,
  659. pub sequence_number: Option<u8>,
  660. pub pan_id_compression: bool,
  661. pub frame_version: FrameVersion,
  662. pub dst_pan_id: Option<Pan>,
  663. pub dst_addr: Option<Address>,
  664. pub src_pan_id: Option<Pan>,
  665. pub src_addr: Option<Address>,
  666. }
  667. impl Repr {
  668. /// Parse an IEEE 802.15.4 frame and return a high-level representation.
  669. pub fn parse<T: AsRef<[u8]> + ?Sized>(packet: &Frame<&T>) -> Result<Repr> {
  670. // Ensure the basic accessors will work.
  671. packet.check_len()?;
  672. Ok(Repr {
  673. frame_type: packet.frame_type(),
  674. security_enabled: packet.security_enabled(),
  675. frame_pending: packet.frame_pending(),
  676. ack_request: packet.ack_request(),
  677. sequence_number: packet.sequence_number(),
  678. pan_id_compression: packet.pan_id_compression(),
  679. frame_version: packet.frame_version(),
  680. dst_pan_id: packet.dst_pan_id(),
  681. dst_addr: packet.dst_addr(),
  682. src_pan_id: packet.src_pan_id(),
  683. src_addr: packet.src_addr(),
  684. })
  685. }
  686. /// Return the length of a buffer required to hold a packet with the payload of a given length.
  687. #[inline]
  688. pub const fn buffer_len(&self) -> usize {
  689. 3 + 2
  690. + match self.dst_addr {
  691. Some(Address::Absent) | None => 0,
  692. Some(Address::Short(_)) => 2,
  693. Some(Address::Extended(_)) => 8,
  694. }
  695. + if !self.pan_id_compression { 2 } else { 0 }
  696. + match self.src_addr {
  697. Some(Address::Absent) | None => 0,
  698. Some(Address::Short(_)) => 2,
  699. Some(Address::Extended(_)) => 8,
  700. }
  701. }
  702. /// Emit a high-level representation into an IEEE802.15.4 frame.
  703. pub fn emit<T: AsRef<[u8]> + AsMut<[u8]>>(&self, frame: &mut Frame<T>) {
  704. frame.set_frame_type(self.frame_type);
  705. frame.set_security_enabled(self.security_enabled);
  706. frame.set_frame_pending(self.frame_pending);
  707. frame.set_ack_request(self.ack_request);
  708. frame.set_pan_id_compression(self.pan_id_compression);
  709. frame.set_frame_version(self.frame_version);
  710. if let Some(sequence_number) = self.sequence_number {
  711. frame.set_sequence_number(sequence_number);
  712. }
  713. if let Some(dst_pan_id) = self.dst_pan_id {
  714. frame.set_dst_pan_id(dst_pan_id);
  715. }
  716. if let Some(dst_addr) = self.dst_addr {
  717. frame.set_dst_addr(dst_addr);
  718. }
  719. if !self.pan_id_compression && self.src_pan_id.is_some() {
  720. frame.set_src_pan_id(self.src_pan_id.unwrap());
  721. }
  722. if let Some(src_addr) = self.src_addr {
  723. frame.set_src_addr(src_addr);
  724. }
  725. }
  726. }
  727. #[cfg(test)]
  728. mod test {
  729. use super::*;
  730. use crate::Result;
  731. #[test]
  732. fn test_broadcast() {
  733. assert!(Address::BROADCAST.is_broadcast());
  734. assert!(!Address::BROADCAST.is_unicast());
  735. }
  736. #[test]
  737. fn prepare_frame() {
  738. let mut buffer = [0u8; 128];
  739. let repr = Repr {
  740. frame_type: FrameType::Data,
  741. security_enabled: false,
  742. frame_pending: false,
  743. ack_request: true,
  744. pan_id_compression: true,
  745. frame_version: FrameVersion::Ieee802154,
  746. sequence_number: Some(1),
  747. dst_pan_id: Some(Pan(0xabcd)),
  748. dst_addr: Some(Address::BROADCAST),
  749. src_pan_id: None,
  750. src_addr: Some(Address::Extended([
  751. 0xc7, 0xd9, 0xb5, 0x14, 0x00, 0x4b, 0x12, 0x00,
  752. ])),
  753. };
  754. let buffer_len = repr.buffer_len();
  755. let mut frame = Frame::new_unchecked(&mut buffer[..buffer_len]);
  756. repr.emit(&mut frame);
  757. println!("{frame:2x?}");
  758. assert_eq!(frame.frame_type(), FrameType::Data);
  759. assert!(!frame.security_enabled());
  760. assert!(!frame.frame_pending());
  761. assert!(frame.ack_request());
  762. assert!(frame.pan_id_compression());
  763. assert_eq!(frame.frame_version(), FrameVersion::Ieee802154);
  764. assert_eq!(frame.sequence_number(), Some(1));
  765. assert_eq!(frame.dst_pan_id(), Some(Pan(0xabcd)));
  766. assert_eq!(frame.dst_addr(), Some(Address::BROADCAST));
  767. assert_eq!(frame.src_pan_id(), None);
  768. assert_eq!(
  769. frame.src_addr(),
  770. Some(Address::Extended([
  771. 0xc7, 0xd9, 0xb5, 0x14, 0x00, 0x4b, 0x12, 0x00
  772. ]))
  773. );
  774. }
  775. macro_rules! vector_test {
  776. ($name:ident $bytes:expr ; $($test_method:ident -> $expected:expr,)*) => {
  777. #[test]
  778. #[allow(clippy::bool_assert_comparison)]
  779. fn $name() -> Result<()> {
  780. let frame = &$bytes;
  781. let frame = Frame::new_checked(frame)?;
  782. $(
  783. assert_eq!(frame.$test_method(), $expected, stringify!($test_method));
  784. )*
  785. Ok(())
  786. }
  787. }
  788. }
  789. vector_test! {
  790. extended_addr
  791. [
  792. 0b0000_0001, 0b1100_1100, // frame control
  793. 0b0, // seq
  794. 0xcd, 0xab, // pan id
  795. 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, // dst addr
  796. 0x03, 0x04, // pan id
  797. 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, // src addr
  798. ];
  799. frame_type -> FrameType::Data,
  800. dst_addr -> Some(Address::Extended([0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00])),
  801. src_addr -> Some(Address::Extended([0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00])),
  802. dst_pan_id -> Some(Pan(0xabcd)),
  803. }
  804. vector_test! {
  805. short_addr
  806. [
  807. 0x01, 0x98, // frame control
  808. 0x00, // sequence number
  809. 0x34, 0x12, 0x78, 0x56, // PAN identifier and address of destination
  810. 0x34, 0x12, 0xbc, 0x9a, // PAN identifier and address of source
  811. ];
  812. frame_type -> FrameType::Data,
  813. security_enabled -> false,
  814. frame_pending -> false,
  815. ack_request -> false,
  816. pan_id_compression -> false,
  817. dst_addressing_mode -> AddressingMode::Short,
  818. frame_version -> FrameVersion::Ieee802154_2006,
  819. src_addressing_mode -> AddressingMode::Short,
  820. dst_pan_id -> Some(Pan(0x1234)),
  821. dst_addr -> Some(Address::Short([0x56, 0x78])),
  822. src_pan_id -> Some(Pan(0x1234)),
  823. src_addr -> Some(Address::Short([0x9a, 0xbc])),
  824. }
  825. vector_test! {
  826. zolertia_remote
  827. [
  828. 0x41, 0xd8, // frame control
  829. 0x01, // sequence number
  830. 0xcd, 0xab, // Destination PAN id
  831. 0xff, 0xff, // Short destination address
  832. 0xc7, 0xd9, 0xb5, 0x14, 0x00, 0x4b, 0x12, 0x00, // Extended source address
  833. 0x2b, 0x00, 0x00, 0x00, // payload
  834. ];
  835. frame_type -> FrameType::Data,
  836. security_enabled -> false,
  837. frame_pending -> false,
  838. ack_request -> false,
  839. pan_id_compression -> true,
  840. dst_addressing_mode -> AddressingMode::Short,
  841. frame_version -> FrameVersion::Ieee802154_2006,
  842. src_addressing_mode -> AddressingMode::Extended,
  843. payload -> Some(&[0x2b, 0x00, 0x00, 0x00][..]),
  844. }
  845. vector_test! {
  846. security
  847. [
  848. 0x69,0xdc, // frame control
  849. 0x32, // sequence number
  850. 0xcd,0xab, // destination PAN id
  851. 0xbf,0x9b,0x15,0x06,0x00,0x4b,0x12,0x00, // extended destination address
  852. 0xc7,0xd9,0xb5,0x14,0x00,0x4b,0x12,0x00, // extended source address
  853. 0x05, // security control field
  854. 0x31,0x01,0x00,0x00, // frame counter
  855. 0x3e,0xe8,0xfb,0x85,0xe4,0xcc,0xf4,0x48,0x90,0xfe,0x56,0x66,0xf7,0x1c,0x65,0x9e,0xf9, // data
  856. 0x93,0xc8,0x34,0x2e,// MIC
  857. ];
  858. frame_type -> FrameType::Data,
  859. security_enabled -> true,
  860. frame_pending -> false,
  861. ack_request -> true,
  862. pan_id_compression -> true,
  863. dst_addressing_mode -> AddressingMode::Extended,
  864. frame_version -> FrameVersion::Ieee802154_2006,
  865. src_addressing_mode -> AddressingMode::Extended,
  866. dst_pan_id -> Some(Pan(0xabcd)),
  867. dst_addr -> Some(Address::Extended([0x00,0x12,0x4b,0x00,0x06,0x15,0x9b,0xbf])),
  868. src_pan_id -> None,
  869. src_addr -> Some(Address::Extended([0x00,0x12,0x4b,0x00,0x14,0xb5,0xd9,0xc7])),
  870. security_level -> 5,
  871. key_identifier_mode -> 0,
  872. frame_counter -> 305,
  873. key_source -> None,
  874. key_index -> None,
  875. payload -> Some(&[0x3e,0xe8,0xfb,0x85,0xe4,0xcc,0xf4,0x48,0x90,0xfe,0x56,0x66,0xf7,0x1c,0x65,0x9e,0xf9,0x93,0xc8,0x34,0x2e][..]),
  876. message_integrity_code -> Some(&[0x93, 0xC8, 0x34, 0x2E][..]),
  877. mac_header -> &[
  878. 0x69,0xdc, // frame control
  879. 0x32, // sequence number
  880. 0xcd,0xab, // destination PAN id
  881. 0xbf,0x9b,0x15,0x06,0x00,0x4b,0x12,0x00, // extended destination address
  882. 0xc7,0xd9,0xb5,0x14,0x00,0x4b,0x12,0x00, // extended source address
  883. 0x05, // security control field
  884. 0x31,0x01,0x00,0x00, // frame counter
  885. ][..],
  886. }
  887. }