xref: /webrtc/stun/src/message.rs (revision 5d8fe953)
1 #[cfg(test)]
2 mod message_test;
3 
4 use crate::agent::*;
5 use crate::attributes::*;
6 use crate::error::*;
7 
8 use rand::Rng;
9 use std::fmt;
10 use std::io::{Read, Write};
11 
12 // MAGIC_COOKIE is fixed value that aids in distinguishing STUN packets
13 // from packets of other protocols when STUN is multiplexed with those
14 // other protocols on the same Port.
15 //
16 // The magic cookie field MUST contain the fixed value 0x2112A442 in
17 // network byte order.
18 //
19 // Defined in "STUN Message Structure", section 6.
20 pub const MAGIC_COOKIE: u32 = 0x2112A442;
21 pub const ATTRIBUTE_HEADER_SIZE: usize = 4;
22 pub const MESSAGE_HEADER_SIZE: usize = 20;
23 
24 // TRANSACTION_ID_SIZE is length of transaction id array (in bytes).
25 pub const TRANSACTION_ID_SIZE: usize = 12; // 96 bit
26 
27 // Interfaces that are implemented by message attributes, shorthands for them,
28 // or helpers for message fields as type or transaction id.
29 pub trait Setter {
30     // Setter sets *Message attribute.
add_to(&self, m: &mut Message) -> Result<()>31     fn add_to(&self, m: &mut Message) -> Result<()>;
32 }
33 
34 // Getter parses attribute from *Message.
35 pub trait Getter {
get_from(&mut self, m: &Message) -> Result<()>36     fn get_from(&mut self, m: &Message) -> Result<()>;
37 }
38 
39 // Checker checks *Message attribute.
40 pub trait Checker {
check(&self, m: &Message) -> Result<()>41     fn check(&self, m: &Message) -> Result<()>;
42 }
43 
44 // is_message returns true if b looks like STUN message.
45 // Useful for multiplexing. is_message does not guarantee
46 // that decoding will be successful.
is_message(b: &[u8]) -> bool47 pub fn is_message(b: &[u8]) -> bool {
48     b.len() >= MESSAGE_HEADER_SIZE && u32::from_be_bytes([b[4], b[5], b[6], b[7]]) == MAGIC_COOKIE
49 }
50 // Message represents a single STUN packet. It uses aggressive internal
51 // buffering to enable zero-allocation encoding and decoding,
52 // so there are some usage constraints:
53 //
54 // 	Message, its fields, results of m.Get or any attribute a.GetFrom
55 //	are valid only until Message.Raw is not modified.
56 #[derive(Default, Debug, Clone)]
57 pub struct Message {
58     pub typ: MessageType,
59     pub length: u32, // len(Raw) not including header
60     pub transaction_id: TransactionId,
61     pub attributes: Attributes,
62     pub raw: Vec<u8>,
63 }
64 
65 impl fmt::Display for Message {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result66     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67         let t_id = base64::encode(self.transaction_id.0);
68         write!(
69             f,
70             "{} l={} attrs={} id={}",
71             self.typ,
72             self.length,
73             self.attributes.0.len(),
74             t_id
75         )
76     }
77 }
78 
79 // Equal returns true if Message b equals to m.
80 // Ignores m.Raw.
81 impl PartialEq for Message {
eq(&self, other: &Self) -> bool82     fn eq(&self, other: &Self) -> bool {
83         if self.typ != other.typ {
84             return false;
85         }
86         if self.transaction_id != other.transaction_id {
87             return false;
88         }
89         if self.length != other.length {
90             return false;
91         }
92         if self.attributes != other.attributes {
93             return false;
94         }
95         true
96     }
97 }
98 
99 const DEFAULT_RAW_CAPACITY: usize = 120;
100 
101 impl Setter for Message {
102     // add_to sets b.TransactionID to m.TransactionID.
103     //
104     // Implements Setter to aid in crafting responses.
add_to(&self, b: &mut Message) -> Result<()>105     fn add_to(&self, b: &mut Message) -> Result<()> {
106         b.transaction_id = self.transaction_id;
107         b.write_transaction_id();
108         Ok(())
109     }
110 }
111 
112 impl Message {
113     // New returns *Message with pre-allocated Raw.
new() -> Self114     pub fn new() -> Self {
115         Message {
116             raw: {
117                 let mut raw = Vec::with_capacity(DEFAULT_RAW_CAPACITY);
118                 raw.extend_from_slice(&[0; MESSAGE_HEADER_SIZE]);
119                 raw
120             },
121             ..Default::default()
122         }
123     }
124 
125     // marshal_binary implements the encoding.BinaryMarshaler interface.
marshal_binary(&self) -> Result<Vec<u8>>126     pub fn marshal_binary(&self) -> Result<Vec<u8>> {
127         // We can't return m.Raw, allocation is expected by implicit interface
128         // contract induced by other implementations.
129         Ok(self.raw.clone())
130     }
131 
132     // unmarshal_binary implements the encoding.BinaryUnmarshaler interface.
unmarshal_binary(&mut self, data: &[u8]) -> Result<()>133     pub fn unmarshal_binary(&mut self, data: &[u8]) -> Result<()> {
134         // We can't retain data, copy is expected by interface contract.
135         self.raw.clear();
136         self.raw.extend_from_slice(data);
137         self.decode()
138     }
139 
140     // NewTransactionID sets m.TransactionID to random value from crypto/rand
141     // and returns error if any.
new_transaction_id(&mut self) -> Result<()>142     pub fn new_transaction_id(&mut self) -> Result<()> {
143         rand::thread_rng().fill(&mut self.transaction_id.0);
144         self.write_transaction_id();
145         Ok(())
146     }
147 
148     // Reset resets Message, attributes and underlying buffer length.
reset(&mut self)149     pub fn reset(&mut self) {
150         self.raw.clear();
151         self.length = 0;
152         self.attributes.0.clear();
153     }
154 
155     // grow ensures that internal buffer has n length.
grow(&mut self, n: usize, resize: bool)156     fn grow(&mut self, n: usize, resize: bool) {
157         if self.raw.len() >= n {
158             if resize {
159                 self.raw.resize(n, 0);
160             }
161             return;
162         }
163         self.raw.extend_from_slice(&vec![0; n - self.raw.len()]);
164     }
165 
166     // Add appends new attribute to message. Not goroutine-safe.
167     //
168     // Value of attribute is copied to internal buffer so
169     // it is safe to reuse v.
add(&mut self, t: AttrType, v: &[u8])170     pub fn add(&mut self, t: AttrType, v: &[u8]) {
171         // Allocating buffer for TLV (type-length-value).
172         // T = t, L = len(v), V = v.
173         // m.Raw will look like:
174         // [0:20]                               <- message header
175         // [20:20+m.Length]                     <- existing message attributes
176         // [20+m.Length:20+m.Length+len(v) + 4] <- allocated buffer for new TLV
177         // [first:last]                         <- same as previous
178         // [0 1|2 3|4    4 + len(v)]            <- mapping for allocated buffer
179         //   T   L        V
180         let alloc_size = ATTRIBUTE_HEADER_SIZE + v.len(); // ~ len(TLV) = len(TL) + len(V)
181         let first = MESSAGE_HEADER_SIZE + self.length as usize; // first byte number
182         let mut last = first + alloc_size; // last byte number
183         self.grow(last, true); // growing cap(Raw) to fit TLV
184         self.length += alloc_size as u32; // rendering length change
185 
186         // Encoding attribute TLV to allocated buffer.
187         let buf = &mut self.raw[first..last];
188         buf[0..2].copy_from_slice(&t.value().to_be_bytes()); // T
189         buf[2..4].copy_from_slice(&(v.len() as u16).to_be_bytes()); // L
190 
191         let value = &mut buf[ATTRIBUTE_HEADER_SIZE..];
192         value.copy_from_slice(v); // V
193 
194         let attr = RawAttribute {
195             typ: t,                 // T
196             length: v.len() as u16, // L
197             value: value.to_vec(),  // V
198         };
199 
200         // Checking that attribute value needs padding.
201         if attr.length as usize % PADDING != 0 {
202             // Performing padding.
203             let bytes_to_add = nearest_padded_value_length(v.len()) - v.len();
204             last += bytes_to_add;
205             self.grow(last, true);
206             // setting all padding bytes to zero
207             // to prevent data leak from previous
208             // data in next bytes_to_add bytes
209             let buf = &mut self.raw[last - bytes_to_add..last];
210             for b in buf {
211                 *b = 0;
212             }
213             self.length += bytes_to_add as u32; // rendering length change
214         }
215         self.attributes.0.push(attr);
216         self.write_length();
217     }
218 
219     // WriteLength writes m.Length to m.Raw.
write_length(&mut self)220     pub fn write_length(&mut self) {
221         self.grow(4, false);
222         self.raw[2..4].copy_from_slice(&(self.length as u16).to_be_bytes());
223     }
224 
225     // WriteHeader writes header to underlying buffer. Not goroutine-safe.
write_header(&mut self)226     pub fn write_header(&mut self) {
227         self.grow(MESSAGE_HEADER_SIZE, false);
228 
229         self.write_type();
230         self.write_length();
231         self.raw[4..8].copy_from_slice(&MAGIC_COOKIE.to_be_bytes()); // magic cookie
232         self.raw[8..MESSAGE_HEADER_SIZE].copy_from_slice(&self.transaction_id.0);
233         // transaction ID
234     }
235 
236     // WriteTransactionID writes m.TransactionID to m.Raw.
write_transaction_id(&mut self)237     pub fn write_transaction_id(&mut self) {
238         self.raw[8..MESSAGE_HEADER_SIZE].copy_from_slice(&self.transaction_id.0);
239         // transaction ID
240     }
241 
242     // WriteAttributes encodes all m.Attributes to m.
write_attributes(&mut self)243     pub fn write_attributes(&mut self) {
244         let attributes: Vec<RawAttribute> = self.attributes.0.drain(..).collect();
245         for a in &attributes {
246             self.add(a.typ, &a.value);
247         }
248         self.attributes = Attributes(attributes);
249     }
250 
251     // WriteType writes m.Type to m.Raw.
write_type(&mut self)252     pub fn write_type(&mut self) {
253         self.grow(2, false);
254         self.raw[..2].copy_from_slice(&self.typ.value().to_be_bytes()); // message type
255     }
256 
257     // SetType sets m.Type and writes it to m.Raw.
set_type(&mut self, t: MessageType)258     pub fn set_type(&mut self, t: MessageType) {
259         self.typ = t;
260         self.write_type();
261     }
262 
263     // Encode re-encodes message into m.Raw.
encode(&mut self)264     pub fn encode(&mut self) {
265         self.raw.clear();
266         self.write_header();
267         self.length = 0;
268         self.write_attributes();
269     }
270 
271     // Decode decodes m.Raw into m.
decode(&mut self) -> Result<()>272     pub fn decode(&mut self) -> Result<()> {
273         // decoding message header
274         let buf = &self.raw;
275         if buf.len() < MESSAGE_HEADER_SIZE {
276             return Err(Error::ErrUnexpectedHeaderEof);
277         }
278 
279         let t = u16::from_be_bytes([buf[0], buf[1]]); // first 2 bytes
280         let size = u16::from_be_bytes([buf[2], buf[3]]) as usize; // second 2 bytes
281         let cookie = u32::from_be_bytes([buf[4], buf[5], buf[6], buf[7]]); // last 4 bytes
282         let full_size = MESSAGE_HEADER_SIZE + size; // len(m.Raw)
283 
284         if cookie != MAGIC_COOKIE {
285             return Err(Error::Other(format!(
286                 "{cookie:x} is invalid magic cookie (should be {MAGIC_COOKIE:x})"
287             )));
288         }
289         if buf.len() < full_size {
290             return Err(Error::Other(format!(
291                 "buffer length {} is less than {} (expected message size)",
292                 buf.len(),
293                 full_size
294             )));
295         }
296 
297         // saving header data
298         self.typ.read_value(t);
299         self.length = size as u32;
300         self.transaction_id
301             .0
302             .copy_from_slice(&buf[8..MESSAGE_HEADER_SIZE]);
303 
304         self.attributes.0.clear();
305         let mut offset = 0;
306         let mut b = &buf[MESSAGE_HEADER_SIZE..full_size];
307 
308         while offset < size {
309             // checking that we have enough bytes to read header
310             if b.len() < ATTRIBUTE_HEADER_SIZE {
311                 return Err(Error::Other(format!(
312                     "buffer length {} is less than {} (expected header size)",
313                     b.len(),
314                     ATTRIBUTE_HEADER_SIZE
315                 )));
316             }
317 
318             let mut a = RawAttribute {
319                 typ: compat_attr_type(u16::from_be_bytes([b[0], b[1]])), // first 2 bytes
320                 length: u16::from_be_bytes([b[2], b[3]]),                // second 2 bytes
321                 ..Default::default()
322             };
323             let a_l = a.length as usize; // attribute length
324             let a_buff_l = nearest_padded_value_length(a_l); // expected buffer length (with padding)
325 
326             b = &b[ATTRIBUTE_HEADER_SIZE..]; // slicing again to simplify value read
327             offset += ATTRIBUTE_HEADER_SIZE;
328             if b.len() < a_buff_l {
329                 // checking size
330                 return Err(Error::Other(format!(
331                     "buffer length {} is less than {} (expected value size for {})",
332                     b.len(),
333                     a_buff_l,
334                     a.typ
335                 )));
336             }
337             a.value = b[..a_l].to_vec();
338             offset += a_buff_l;
339             b = &b[a_buff_l..];
340 
341             self.attributes.0.push(a);
342         }
343 
344         Ok(())
345     }
346 
347     // WriteTo implements WriterTo via calling Write(m.Raw) on w and returning
348     // call result.
write_to<W: Write>(&self, writer: &mut W) -> Result<usize>349     pub fn write_to<W: Write>(&self, writer: &mut W) -> Result<usize> {
350         let n = writer.write(&self.raw)?;
351         Ok(n)
352     }
353 
354     // ReadFrom implements ReaderFrom. Reads message from r into m.Raw,
355     // Decodes it and return error if any. If m.Raw is too small, will return
356     // ErrUnexpectedEOF, ErrUnexpectedHeaderEOF or *DecodeErr.
357     //
358     // Can return *DecodeErr while decoding too.
read_from<R: Read>(&mut self, reader: &mut R) -> Result<usize>359     pub fn read_from<R: Read>(&mut self, reader: &mut R) -> Result<usize> {
360         let mut t_buf = vec![0; DEFAULT_RAW_CAPACITY];
361         let n = reader.read(&mut t_buf)?;
362         self.raw = t_buf[..n].to_vec();
363         self.decode()?;
364         Ok(n)
365     }
366 
367     // Write decodes message and return error if any.
368     //
369     // Any error is unrecoverable, but message could be partially decoded.
write(&mut self, t_buf: &[u8]) -> Result<usize>370     pub fn write(&mut self, t_buf: &[u8]) -> Result<usize> {
371         self.raw.clear();
372         self.raw.extend_from_slice(t_buf);
373         self.decode()?;
374         Ok(t_buf.len())
375     }
376 
377     // CloneTo clones m to b securing any further m mutations.
clone_to(&self, b: &mut Message) -> Result<()>378     pub fn clone_to(&self, b: &mut Message) -> Result<()> {
379         b.raw.clear();
380         b.raw.extend_from_slice(&self.raw);
381         b.decode()
382     }
383 
384     // Contains return true if message contain t attribute.
contains(&self, t: AttrType) -> bool385     pub fn contains(&self, t: AttrType) -> bool {
386         for a in &self.attributes.0 {
387             if a.typ == t {
388                 return true;
389             }
390         }
391         false
392     }
393 
394     // get returns byte slice that represents attribute value,
395     // if there is no attribute with such type,
396     // ErrAttributeNotFound is returned.
get(&self, t: AttrType) -> Result<Vec<u8>>397     pub fn get(&self, t: AttrType) -> Result<Vec<u8>> {
398         let (v, ok) = self.attributes.get(t);
399         if ok {
400             Ok(v.value)
401         } else {
402             Err(Error::ErrAttributeNotFound)
403         }
404     }
405 
406     // Build resets message and applies setters to it in batch, returning on
407     // first error. To prevent allocations, pass pointers to values.
408     //
409     // Example:
410     //  var (
411     //  	t        = BindingRequest
412     //  	username = NewUsername("username")
413     //  	nonce    = NewNonce("nonce")
414     //  	realm    = NewRealm("example.org")
415     //  )
416     //  m := new(Message)
417     //  m.Build(t, username, nonce, realm)     // 4 allocations
418     //  m.Build(&t, &username, &nonce, &realm) // 0 allocations
419     //
420     // See BenchmarkBuildOverhead.
build(&mut self, setters: &[Box<dyn Setter>]) -> Result<()>421     pub fn build(&mut self, setters: &[Box<dyn Setter>]) -> Result<()> {
422         self.reset();
423         self.write_header();
424         for s in setters {
425             s.add_to(self)?;
426         }
427         Ok(())
428     }
429 
430     // Check applies checkers to message in batch, returning on first error.
check<C: Checker>(&self, checkers: &[C]) -> Result<()>431     pub fn check<C: Checker>(&self, checkers: &[C]) -> Result<()> {
432         for c in checkers {
433             c.check(self)?;
434         }
435         Ok(())
436     }
437 
438     // Parse applies getters to message in batch, returning on first error.
parse<G: Getter>(&self, getters: &mut [G]) -> Result<()>439     pub fn parse<G: Getter>(&self, getters: &mut [G]) -> Result<()> {
440         for c in getters {
441             c.get_from(self)?;
442         }
443         Ok(())
444     }
445 }
446 
447 // MessageClass is 8-bit representation of 2-bit class of STUN Message Class.
448 #[derive(Default, PartialEq, Eq, Debug, Copy, Clone)]
449 pub struct MessageClass(u8);
450 
451 // Possible values for message class in STUN Message Type.
452 pub const CLASS_REQUEST: MessageClass = MessageClass(0x00); // 0b00
453 pub const CLASS_INDICATION: MessageClass = MessageClass(0x01); // 0b01
454 pub const CLASS_SUCCESS_RESPONSE: MessageClass = MessageClass(0x02); // 0b10
455 pub const CLASS_ERROR_RESPONSE: MessageClass = MessageClass(0x03); // 0b11
456 
457 impl fmt::Display for MessageClass {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result458     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
459         let s = match *self {
460             CLASS_REQUEST => "request",
461             CLASS_INDICATION => "indication",
462             CLASS_SUCCESS_RESPONSE => "success response",
463             CLASS_ERROR_RESPONSE => "error response",
464             _ => "unknown message class",
465         };
466 
467         write!(f, "{s}")
468     }
469 }
470 
471 // Method is uint16 representation of 12-bit STUN method.
472 #[derive(Default, PartialEq, Eq, Debug, Copy, Clone)]
473 pub struct Method(u16);
474 
475 // Possible methods for STUN Message.
476 pub const METHOD_BINDING: Method = Method(0x001);
477 pub const METHOD_ALLOCATE: Method = Method(0x003);
478 pub const METHOD_REFRESH: Method = Method(0x004);
479 pub const METHOD_SEND: Method = Method(0x006);
480 pub const METHOD_DATA: Method = Method(0x007);
481 pub const METHOD_CREATE_PERMISSION: Method = Method(0x008);
482 pub const METHOD_CHANNEL_BIND: Method = Method(0x009);
483 
484 // Methods from RFC 6062.
485 pub const METHOD_CONNECT: Method = Method(0x000a);
486 pub const METHOD_CONNECTION_BIND: Method = Method(0x000b);
487 pub const METHOD_CONNECTION_ATTEMPT: Method = Method(0x000c);
488 
489 impl fmt::Display for Method {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result490     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
491         let unknown = format!("0x{:x}", self.0);
492 
493         let s = match *self {
494             METHOD_BINDING => "Binding",
495             METHOD_ALLOCATE => "Allocate",
496             METHOD_REFRESH => "Refresh",
497             METHOD_SEND => "Send",
498             METHOD_DATA => "Data",
499             METHOD_CREATE_PERMISSION => "CreatePermission",
500             METHOD_CHANNEL_BIND => "ChannelBind",
501 
502             // RFC 6062.
503             METHOD_CONNECT => "Connect",
504             METHOD_CONNECTION_BIND => "ConnectionBind",
505             METHOD_CONNECTION_ATTEMPT => "ConnectionAttempt",
506             _ => unknown.as_str(),
507         };
508 
509         write!(f, "{s}")
510     }
511 }
512 
513 // MessageType is STUN Message Type Field.
514 #[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
515 pub struct MessageType {
516     pub method: Method,      // e.g. binding
517     pub class: MessageClass, // e.g. request
518 }
519 
520 // Common STUN message types.
521 // Binding request message type.
522 pub const BINDING_REQUEST: MessageType = MessageType {
523     method: METHOD_BINDING,
524     class: CLASS_REQUEST,
525 };
526 // Binding success response message type
527 pub const BINDING_SUCCESS: MessageType = MessageType {
528     method: METHOD_BINDING,
529     class: CLASS_SUCCESS_RESPONSE,
530 };
531 // Binding error response message type.
532 pub const BINDING_ERROR: MessageType = MessageType {
533     method: METHOD_BINDING,
534     class: CLASS_ERROR_RESPONSE,
535 };
536 
537 impl fmt::Display for MessageType {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result538     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
539         write!(f, "{} {}", self.method, self.class)
540     }
541 }
542 
543 const METHOD_ABITS: u16 = 0xf; // 0b0000000000001111
544 const METHOD_BBITS: u16 = 0x70; // 0b0000000001110000
545 const METHOD_DBITS: u16 = 0xf80; // 0b0000111110000000
546 
547 const METHOD_BSHIFT: u16 = 1;
548 const METHOD_DSHIFT: u16 = 2;
549 
550 const FIRST_BIT: u16 = 0x1;
551 const SECOND_BIT: u16 = 0x2;
552 
553 const C0BIT: u16 = FIRST_BIT;
554 const C1BIT: u16 = SECOND_BIT;
555 
556 const CLASS_C0SHIFT: u16 = 4;
557 const CLASS_C1SHIFT: u16 = 7;
558 
559 impl Setter for MessageType {
560     // add_to sets m type to t.
add_to(&self, m: &mut Message) -> Result<()>561     fn add_to(&self, m: &mut Message) -> Result<()> {
562         m.set_type(*self);
563         Ok(())
564     }
565 }
566 
567 impl MessageType {
568     // NewType returns new message type with provided method and class.
new(method: Method, class: MessageClass) -> Self569     pub fn new(method: Method, class: MessageClass) -> Self {
570         MessageType { method, class }
571     }
572 
573     // Value returns bit representation of messageType.
value(&self) -> u16574     pub fn value(&self) -> u16 {
575         //	 0                 1
576         //	 2  3  4 5 6 7 8 9 0 1 2 3 4 5
577         //	+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
578         //	|M |M |M|M|M|C|M|M|M|C|M|M|M|M|
579         //	|11|10|9|8|7|1|6|5|4|0|3|2|1|0|
580         //	+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
581         // Figure 3: Format of STUN Message Type Field
582 
583         // Warning: Abandon all hope ye who enter here.
584         // Splitting M into A(M0-M3), B(M4-M6), D(M7-M11).
585         let method = self.method.0;
586         let a = method & METHOD_ABITS; // A = M * 0b0000000000001111 (right 4 bits)
587         let b = method & METHOD_BBITS; // B = M * 0b0000000001110000 (3 bits after A)
588         let d = method & METHOD_DBITS; // D = M * 0b0000111110000000 (5 bits after B)
589 
590         // Shifting to add "holes" for C0 (at 4 bit) and C1 (8 bit).
591         let method = a + (b << METHOD_BSHIFT) + (d << METHOD_DSHIFT);
592 
593         // C0 is zero bit of C, C1 is first bit.
594         // C0 = C * 0b01, C1 = (C * 0b10) >> 1
595         // Ct = C0 << 4 + C1 << 8.
596         // Optimizations: "((C * 0b10) >> 1) << 8" as "(C * 0b10) << 7"
597         // We need C0 shifted by 4, and C1 by 8 to fit "11" and "7" positions
598         // (see figure 3).
599         let c = self.class.0 as u16;
600         let c0 = (c & C0BIT) << CLASS_C0SHIFT;
601         let c1 = (c & C1BIT) << CLASS_C1SHIFT;
602         let class = c0 + c1;
603 
604         method + class
605     }
606 
607     // ReadValue decodes uint16 into MessageType.
read_value(&mut self, value: u16)608     pub fn read_value(&mut self, value: u16) {
609         // Decoding class.
610         // We are taking first bit from v >> 4 and second from v >> 7.
611         let c0 = (value >> CLASS_C0SHIFT) & C0BIT;
612         let c1 = (value >> CLASS_C1SHIFT) & C1BIT;
613         let class = c0 + c1;
614         self.class = MessageClass(class as u8);
615 
616         // Decoding method.
617         let a = value & METHOD_ABITS; // A(M0-M3)
618         let b = (value >> METHOD_BSHIFT) & METHOD_BBITS; // B(M4-M6)
619         let d = (value >> METHOD_DSHIFT) & METHOD_DBITS; // D(M7-M11)
620         let m = a + b + d;
621         self.method = Method(m);
622     }
623 }
624