diff --git a/Cargo.toml b/Cargo.toml index 32cacc6a2814dee6ae0de4a1d67de3c09c615ef6..0cb16f91de5eefc89cb9bfd319360454c7d99ed0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ num = "0.1" rand = "0.3" log = "0.3" threadpool = "1.3" +enum_primitive = "0.1.1" [dev-dependencies] quickcheck = "0.2.27" diff --git a/src/lib.rs b/src/lib.rs index 3e04e3e9c0efc59adea1d9eedbf1096271b188c6..0768f03ffca2f309bc175508593ebfa82c5bc75c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,6 +74,8 @@ extern crate url; extern crate num; extern crate rand; extern crate threadpool; +#[macro_use] extern crate enum_primitive; + #[cfg(test)] extern crate quickcheck; diff --git a/src/message/packet.rs b/src/message/packet.rs index a2e401012d53b8d38a8b5256ba250050bb439a2d..83d621766eb6e6e0bd987364f6e451f9a2562018 100644 --- a/src/message/packet.rs +++ b/src/message/packet.rs @@ -2,6 +2,8 @@ use bincode; use std::collections::BTreeMap; use std::collections::LinkedList; +use num::FromPrimitive; + use message::header; macro_rules! u8_to_unsigned_be { @@ -32,6 +34,18 @@ pub enum CoAPOption { Size1, } +enum_from_primitive! { +#[derive(PartialEq, Eq, Debug)] +pub enum ContentFormat { + TextPlain = 0, + ApplicationLinkFormat = 40, + ApplicationXML = 41, + ApplicationOctetStream = 42, + ApplicationEXI = 47, + ApplicationJSON = 50, +} +} + #[derive(Debug)] pub enum PackageError { InvalidHeader, @@ -78,6 +92,15 @@ impl Packet { self.options.insert(num, value); } + pub fn set_content_format(&mut self, cf: ContentFormat) { + let content_format = cf as u16; + let msb = (content_format >> 8) as u8; + let lsb = (content_format & 0xFF) as u8; + + let content_format: Vec<u8> = vec![msb, lsb]; + self.add_option(CoAPOption::ContentFormat, content_format); + } + pub fn set_payload(&mut self, payload: Vec<u8>) { self.payload = payload; } @@ -105,6 +128,20 @@ impl Packet { } } + pub fn get_content_format(&self) -> Option<ContentFormat> { + if let Some(list) = self.get_option(CoAPOption::ContentFormat) { + if let Some(vector) = list.front() { + let msb = vector[0] as u16; + let lsb = vector[1] as u16; + let number = (msb << 8) + lsb; + + return ContentFormat::from_u16(number); + } + } + + None + } + /// Decodes a byte slice and construct the equivalent Packet. pub fn from_bytes(buf: &[u8]) -> Result<Packet, ParseError> { let header_result: bincode::DecodingResult<header::HeaderRaw> = bincode::decode(buf); @@ -442,6 +479,19 @@ mod test { 0x6C, 0x6F]); } + #[test] + fn test_encode_decode_content_format() { + let mut packet = Packet::new(); + packet.set_content_format(ContentFormat::ApplicationJSON); + assert_eq!(ContentFormat::ApplicationJSON, packet.get_content_format().unwrap()) + } + + #[test] + fn test_decode_empty_content_format() { + let packet = Packet::new(); + assert!(packet.get_content_format().is_none()); + } + #[test] fn test_malicious_packet() { use rand;