ieee802154.rs 32 KB

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