ieee802154.rs 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  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, value: Address) {
  550. match value {
  551. Address::Absent => self.set_dst_addressing_mode(AddressingMode::Absent),
  552. Address::Short(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(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, 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(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(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. #[test]
  731. fn test_broadcast() {
  732. assert!(Address::BROADCAST.is_broadcast());
  733. assert!(!Address::BROADCAST.is_unicast());
  734. }
  735. #[test]
  736. fn prepare_frame() {
  737. let mut buffer = [0u8; 128];
  738. let repr = Repr {
  739. frame_type: FrameType::Data,
  740. security_enabled: false,
  741. frame_pending: false,
  742. ack_request: true,
  743. pan_id_compression: true,
  744. frame_version: FrameVersion::Ieee802154,
  745. sequence_number: Some(1),
  746. dst_pan_id: Some(Pan(0xabcd)),
  747. dst_addr: Some(Address::BROADCAST),
  748. src_pan_id: None,
  749. src_addr: Some(Address::Extended([
  750. 0xc7, 0xd9, 0xb5, 0x14, 0x00, 0x4b, 0x12, 0x00,
  751. ])),
  752. };
  753. let buffer_len = repr.buffer_len();
  754. let mut frame = Frame::new_unchecked(&mut buffer[..buffer_len]);
  755. repr.emit(&mut frame);
  756. println!("{frame:2x?}");
  757. assert_eq!(frame.frame_type(), FrameType::Data);
  758. assert!(!frame.security_enabled());
  759. assert!(!frame.frame_pending());
  760. assert!(frame.ack_request());
  761. assert!(frame.pan_id_compression());
  762. assert_eq!(frame.frame_version(), FrameVersion::Ieee802154);
  763. assert_eq!(frame.sequence_number(), Some(1));
  764. assert_eq!(frame.dst_pan_id(), Some(Pan(0xabcd)));
  765. assert_eq!(frame.dst_addr(), Some(Address::BROADCAST));
  766. assert_eq!(frame.src_pan_id(), None);
  767. assert_eq!(
  768. frame.src_addr(),
  769. Some(Address::Extended([
  770. 0xc7, 0xd9, 0xb5, 0x14, 0x00, 0x4b, 0x12, 0x00
  771. ]))
  772. );
  773. }
  774. macro_rules! vector_test {
  775. ($name:ident $bytes:expr ; $($test_method:ident -> $expected:expr,)*) => {
  776. #[test]
  777. #[allow(clippy::bool_assert_comparison)]
  778. fn $name() -> Result<()> {
  779. let frame = &$bytes;
  780. let frame = Frame::new_checked(frame)?;
  781. $(
  782. assert_eq!(frame.$test_method(), $expected, stringify!($test_method));
  783. )*
  784. Ok(())
  785. }
  786. }
  787. }
  788. vector_test! {
  789. extended_addr
  790. [
  791. 0b0000_0001, 0b1100_1100, // frame control
  792. 0b0, // seq
  793. 0xcd, 0xab, // pan id
  794. 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, // dst addr
  795. 0x03, 0x04, // pan id
  796. 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, // src addr
  797. ];
  798. frame_type -> FrameType::Data,
  799. dst_addr -> Some(Address::Extended([0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00])),
  800. src_addr -> Some(Address::Extended([0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00])),
  801. dst_pan_id -> Some(Pan(0xabcd)),
  802. }
  803. vector_test! {
  804. short_addr
  805. [
  806. 0x01, 0x98, // frame control
  807. 0x00, // sequence number
  808. 0x34, 0x12, 0x78, 0x56, // PAN identifier and address of destination
  809. 0x34, 0x12, 0xbc, 0x9a, // PAN identifier and address of source
  810. ];
  811. frame_type -> FrameType::Data,
  812. security_enabled -> false,
  813. frame_pending -> false,
  814. ack_request -> false,
  815. pan_id_compression -> false,
  816. dst_addressing_mode -> AddressingMode::Short,
  817. frame_version -> FrameVersion::Ieee802154_2006,
  818. src_addressing_mode -> AddressingMode::Short,
  819. dst_pan_id -> Some(Pan(0x1234)),
  820. dst_addr -> Some(Address::Short([0x56, 0x78])),
  821. src_pan_id -> Some(Pan(0x1234)),
  822. src_addr -> Some(Address::Short([0x9a, 0xbc])),
  823. }
  824. vector_test! {
  825. zolertia_remote
  826. [
  827. 0x41, 0xd8, // frame control
  828. 0x01, // sequence number
  829. 0xcd, 0xab, // Destination PAN id
  830. 0xff, 0xff, // Short destination address
  831. 0xc7, 0xd9, 0xb5, 0x14, 0x00, 0x4b, 0x12, 0x00, // Extended source address
  832. 0x2b, 0x00, 0x00, 0x00, // payload
  833. ];
  834. frame_type -> FrameType::Data,
  835. security_enabled -> false,
  836. frame_pending -> false,
  837. ack_request -> false,
  838. pan_id_compression -> true,
  839. dst_addressing_mode -> AddressingMode::Short,
  840. frame_version -> FrameVersion::Ieee802154_2006,
  841. src_addressing_mode -> AddressingMode::Extended,
  842. payload -> Some(&[0x2b, 0x00, 0x00, 0x00][..]),
  843. }
  844. vector_test! {
  845. security
  846. [
  847. 0x69,0xdc, // frame control
  848. 0x32, // sequence number
  849. 0xcd,0xab, // destination PAN id
  850. 0xbf,0x9b,0x15,0x06,0x00,0x4b,0x12,0x00, // extended destination address
  851. 0xc7,0xd9,0xb5,0x14,0x00,0x4b,0x12,0x00, // extended source address
  852. 0x05, // security control field
  853. 0x31,0x01,0x00,0x00, // frame counter
  854. 0x3e,0xe8,0xfb,0x85,0xe4,0xcc,0xf4,0x48,0x90,0xfe,0x56,0x66,0xf7,0x1c,0x65,0x9e,0xf9, // data
  855. 0x93,0xc8,0x34,0x2e,// MIC
  856. ];
  857. frame_type -> FrameType::Data,
  858. security_enabled -> true,
  859. frame_pending -> false,
  860. ack_request -> true,
  861. pan_id_compression -> true,
  862. dst_addressing_mode -> AddressingMode::Extended,
  863. frame_version -> FrameVersion::Ieee802154_2006,
  864. src_addressing_mode -> AddressingMode::Extended,
  865. dst_pan_id -> Some(Pan(0xabcd)),
  866. dst_addr -> Some(Address::Extended([0x00,0x12,0x4b,0x00,0x06,0x15,0x9b,0xbf])),
  867. src_pan_id -> None,
  868. src_addr -> Some(Address::Extended([0x00,0x12,0x4b,0x00,0x14,0xb5,0xd9,0xc7])),
  869. security_level -> 5,
  870. key_identifier_mode -> 0,
  871. frame_counter -> 305,
  872. key_source -> None,
  873. key_index -> None,
  874. payload -> Some(&[0x3e,0xe8,0xfb,0x85,0xe4,0xcc,0xf4,0x48,0x90,0xfe,0x56,0x66,0xf7,0x1c,0x65,0x9e,0xf9,0x93,0xc8,0x34,0x2e][..]),
  875. message_integrity_code -> Some(&[0x93, 0xC8, 0x34, 0x2E][..]),
  876. mac_header -> &[
  877. 0x69,0xdc, // frame control
  878. 0x32, // sequence number
  879. 0xcd,0xab, // destination PAN id
  880. 0xbf,0x9b,0x15,0x06,0x00,0x4b,0x12,0x00, // extended destination address
  881. 0xc7,0xd9,0xb5,0x14,0x00,0x4b,0x12,0x00, // extended source address
  882. 0x05, // security control field
  883. 0x31,0x01,0x00,0x00, // frame counter
  884. ][..],
  885. }
  886. }