ieee802154.rs 32 KB

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