wgtk/net/
packet.rs

1//! Packet structure definition with synchronization methods.
2
3use std::io::{Cursor, Read, Write, Seek};
4use std::collections::VecDeque;
5use std::fmt;
6
7use byteorder::{ReadBytesExt, WriteBytesExt, LE};
8
9use crate::util::BytesFmt;
10
11
12/// According to disassembly of WoT, outside of a channel, the max size if always
13/// `1500 - 28 = 1472`, this includes the 4-bytes prefix.
14pub const PACKET_MAX_LEN: usize = 1300;
15// pub const PACKET_MAX_LEN: usize = 1472;
16/// The length of the unknown 4-byte prefix.
17pub const PACKET_PREFIX_LEN: usize = 4;
18/// Flags are u16.
19pub const PACKET_FLAGS_LEN: usize = 2;
20/// Minimum length of a raw packet, containing prefix and flags.
21pub const PACKET_MIN_LEN: usize = PACKET_PREFIX_LEN + PACKET_FLAGS_LEN;
22
23/// Maximum size that can possibly taken by the footer.
24/// - 8 for sequence range
25/// - 4 for first request offset
26/// - 4 for sequence number
27/// - 1 for single acks count
28/// - 4 * 1 for at least one single acks
29/// - 4 for cumulative ack
30/// - 8 for indexed channel (not yet supported in sync data/state)
31/// - 4 for checksum
32pub const PACKET_MAX_FOOTER_LEN: usize = 8 + 4 + 4 + 1 + 4 + 4 + 8 + 4;
33
34/// The theoretical maximum length for the body, if maximum length is used by header + footer.
35pub const PACKET_MAX_BODY_LEN: usize = PACKET_MAX_LEN - PACKET_MIN_LEN - PACKET_MAX_FOOTER_LEN;
36
37
38/// Raw packet layout with only data and length. This structure provides functions for
39/// growing and shrinking data, retrieving and modifying its length. Other states such
40/// are footer offset or first request offset are not saved in this structure, because
41/// this structure is intended to be used as backend of the [`Packet`] structure which
42/// contains such state.
43/// 
44/// The internal data is split in multiple slices that are accessible through the API:
45/// 
46/// - *Raw data*, it contains the full internal data with max data length, this should
47///   be used for receiving datagram from the network;
48/// 
49/// - *Data*, it contains all the data up to the packet's length;
50/// 
51/// - *Body*, it contains all the data starting with the packet's flags up to the
52///   packet's length.
53/// 
54#[derive(Clone)]
55pub struct RawPacket {
56    /// Full raw data of the packet.
57    data: [u8; PACKET_MAX_LEN],
58    /// Length of the packet, must not be lower than minimum length which
59    /// contains the prefix and the flags.
60    len: usize,
61}
62
63impl RawPacket {
64
65    #[inline]
66    pub fn new() -> Self {
67        Self { 
68            data: [0; PACKET_MAX_LEN], 
69            len: PACKET_MIN_LEN,
70        }
71    }
72
73    /// Get a slice to the full raw data, this means that this isn't 
74    /// constrained by the length of the packet.
75    #[inline]
76    pub fn raw_data(&self) -> &[u8] {
77        &self.data[..]
78    }
79
80    /// Get a mutable slice to the full raw data, this means that this isn't 
81    /// constrained by the length of the packet.
82    /// 
83    /// This mutable slice can be used to receive data from an UDP datagram.
84    #[inline]
85    pub fn raw_data_mut(&mut self) -> &mut [u8] {
86        &mut self.data[..]
87    }
88
89    /// Return the maximum size of a packet.
90    #[inline]
91    pub fn data_max_len(&self) -> usize {
92        self.data.len()
93    }
94
95    /// Return the length of this packet.
96    #[inline]
97    pub fn data_len(&self) -> usize {
98        self.len
99    }
100
101    /// Return the available length in this packet.
102    #[inline]
103    pub fn data_available_len(&self) -> usize {
104        self.data_max_len() - self.data_len()
105    }
106
107    /// Set the length of this packet. The function panics if the length
108    /// is not at least `PACKET_MIN_LEN` or at most `PACKET_MAX_LEN`.
109    #[inline]
110    pub fn set_data_len(&mut self, len: usize) {
111        assert!(len >= PACKET_MIN_LEN, "given length too small");
112        assert!(len <= PACKET_MAX_LEN, "given length too high");
113        self.len = len;
114    }
115
116    /// Get a slice to the data, with the packet's length.
117    /// 
118    /// This slice can be used to send data as an UDP datagram for exemple.
119    #[inline]
120    pub fn data(&self) -> &[u8] {
121        &self.data[..self.len]
122    }
123
124    /// Get a mutable slice to the data, with the packet's length.
125    #[inline]
126    pub fn data_mut(&mut self) -> &mut [u8] {
127        &mut self.data[..self.len]
128    }
129
130    /// Return the maximum size of the body of a packet.
131    #[inline]
132    pub fn max_body_len(&self) -> usize {
133        self.data_max_len() - PACKET_PREFIX_LEN
134    }
135
136    /// Return the length of this packet.
137    #[inline]
138    pub fn body_len(&self) -> usize {
139        self.data_len() - PACKET_PREFIX_LEN
140    }
141
142    /// Get a slice to the data from after the prefix to the end.
143    #[inline]
144    pub fn body(&self) -> &[u8] {
145        &self.data[PACKET_PREFIX_LEN..self.len]
146    }
147
148    /// Get a mutable slice to the data from after the prefix to the end.
149    #[inline]
150    pub fn body_mut(&mut self) -> &mut [u8] {
151        &mut self.data[PACKET_PREFIX_LEN..self.len]
152    }
153
154    /// Reset this packet's length, flags and prefix.
155    #[inline]
156    pub fn reset(&mut self) {
157        self.len = PACKET_MIN_LEN;
158        self.data[..PACKET_MIN_LEN].fill(0);
159    }
160
161    /// Grow the packet's data by a given amount of bytes, and return a
162    /// mutable slice to the newly allocated data.
163    /// 
164    /// This function panics if the available length is smaller than
165    /// requested length.
166    #[inline]
167    pub fn grow(&mut self, len: usize) -> &mut [u8] {
168        assert!(self.data_available_len() >= len, "not enough available data");
169        let ptr = &mut self.data[self.len..][..len];
170        self.len += len;
171        ptr
172    }
173
174    /// Grow the packet's data by a given amount of bytes, and return
175    /// a writer to the given data. This writer can be used to write
176    /// new data to the newly allocated data.
177    /// 
178    /// This function panics if the available length is smaller than
179    /// requested length.
180    #[inline]
181    pub fn grow_write(&mut self, len: usize) -> impl Write + Seek + '_ {
182        Cursor::new(self.grow(len))
183    }
184
185    /// Shrink the packet's data by a given amount of bytes, and return
186    /// a slice to the deallocated data. The slice is not mutable because
187    /// returned data is no longer contained in packet's data.
188    /// 
189    /// The discarded data is left untouched, which mean that you can 
190    /// rollback to the previous length to recover the data.
191    /// 
192    /// This function panics if the length after shrink is lower than
193    /// prefix (4 bytes) + flags (2) bytes.
194    #[inline]
195    pub fn shrink(&mut self, len: usize) -> &[u8] {
196        assert!(self.len - len >= PACKET_MIN_LEN, "not enough data to shrink");
197        self.len -= len;
198        &self.data[self.len..][..len]
199    }
200
201    /// Shrink the packet's data by a given amount of bytes, and return
202    /// a reader to the freed data.
203    /// 
204    /// This function panics if the length after shrink is lower than
205    /// prefix (4 bytes) + flags (2) bytes.
206    #[inline]
207    pub fn shrink_read(&mut self, len: usize) -> impl Read + '_ {
208        Cursor::new(self.shrink(len))
209    }
210
211    /// Read the prefix of this packet. 
212    #[inline]
213    pub fn read_prefix(&self) -> u32 {
214        u32::from_le_bytes(self.data[..PACKET_PREFIX_LEN].try_into().unwrap())
215    }
216
217    /// Write the prefix of this packet.
218    #[inline]
219    pub fn write_prefix(&mut self, prefix: u32) {
220        self.data[..PACKET_PREFIX_LEN].copy_from_slice(&prefix.to_le_bytes())
221    }
222
223    /// Read the flags of this packet.
224    #[inline]
225    pub fn read_flags(&self) -> u16 {
226        u16::from_le_bytes(self.data[PACKET_PREFIX_LEN..][..PACKET_FLAGS_LEN].try_into().unwrap())
227    }
228
229    /// Write the flags of this packet.
230    #[inline]
231    pub fn write_flags(&mut self, flags: u16) {
232        self.data[PACKET_PREFIX_LEN..][..PACKET_FLAGS_LEN].copy_from_slice(&flags.to_le_bytes())
233    }
234
235}
236
237impl fmt::Debug for RawPacket {
238    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
239        f.debug_struct("RawPacket")
240            .field("raw_data", &format_args!("{:X}", BytesFmt(self.raw_data())))
241            .field("data", &format_args!("{:X}", BytesFmt(self.data())))
242            .field("len", &self.len)
243            .finish()
244    }
245}
246
247
248/// Represent a [`RawPacket`] with additional state. The additional state keeps
249/// track of different offsets in the packet's raw data. Like footer and first
250/// request element offsets. This structure also provides functions for
251/// synchronizing data from the state and vice-versa.
252/// 
253/// This structure only expose a single slice of data which contain the content
254/// data, starting after the flags and ending before the footer. To access more
255/// low-level slices you can should use the raw packet.
256#[derive(Clone)]
257pub struct Packet {
258    /// The internal raw packet used for data manipulation.
259    raw: RawPacket,
260    /// Offset of the footer when the packet is finalized or loaded. The footer
261    /// size if the difference between the raw packet's length and this footer
262    /// offset.
263    footer_offset: usize,
264    /// The offset of the first element (see bundle) that is also a request in 
265    /// the packet. If there are more requests in the packet, their offset is
266    /// written in a link manner in the N-1 element.
267    first_request_offset: usize,
268}
269
270impl Packet {
271
272    /// Create a new packet instance.
273    #[inline]
274    pub fn new() -> Self {
275        Self {
276            raw: RawPacket::new(),
277            footer_offset: PACKET_MIN_LEN,
278            first_request_offset: 0,
279        }
280    }
281
282    /// Create a new packet instance on the heap and returns the box containing it.
283    pub fn new_boxed() -> Box<Self> {
284        Box::new(Self::new())
285    }
286
287    /// Return a shared reference to the internal raw packet.
288    #[inline]
289    pub fn raw(&self) -> &RawPacket {
290        &self.raw
291    }
292
293    /// Return a mutable reference to the internal raw packet.
294    /// 
295    /// **You should** be really careful when manipulating the internal data and
296    /// always prefer using methods of this structure over manipulating the raw
297    /// data from external modules.
298    #[inline]
299    pub fn raw_mut(&mut self) -> &mut RawPacket {
300        &mut self.raw
301    }
302
303    /// Return the maximum content length.
304    #[inline]
305    pub fn content_max_len(&self) -> usize {
306        // Subtract length of prefix + flags + max footer.
307        self.raw.data_max_len() - PACKET_MIN_LEN - PACKET_MAX_FOOTER_LEN
308    }
309
310    /// Return the length of the content.
311    #[inline]
312    pub fn content_len(&self) -> usize {
313        self.footer_offset - PACKET_MIN_LEN
314    }
315
316    /// Return the available body length for writing elements. The rest of the
317    /// length might be used for the footer.
318    #[inline]
319    pub fn content_available_len(&self) -> usize {
320        self.content_max_len() - self.content_len()
321    }
322
323    /// Return a slice to the content of this packet. The content starts after
324    /// the flags and finish before the footer.
325    #[inline]
326    pub fn content(&self) -> &[u8] {
327        &self.raw.raw_data()[PACKET_MIN_LEN..self.footer_offset]
328    }
329
330    /// Return a mutable slice to the content of this packet. The content starts
331    /// after the flags and finish before the footer.
332    #[inline]
333    pub fn content_mut(&mut self) -> &mut [u8] {
334        &mut self.raw.raw_data_mut()[PACKET_MIN_LEN..self.footer_offset]
335    }
336
337    /// Grow this packet's content by the given size. You must ensure that there
338    /// is enough space for such size, you can obtain remaining length using the 
339    /// `content_available_len` function.
340    /// 
341    /// Note that because growing the body might overwrite the footer, this
342    /// function reset the footer to zero length. Calling `footer_len()` after
343    /// this function returns 0.
344    #[inline]
345    pub fn grow(&mut self, len: usize) -> &mut [u8] {
346        assert!(self.content_available_len() >= len, "not enough available data");
347        // Reset length to footer offset, so we overwrite the footer.
348        self.raw.set_data_len(self.footer_offset);
349        // Advance the footer by the same amount raw.grow will do.
350        self.footer_offset += len;
351        // Grow should not panic because we checked available length.
352        self.raw.grow(len)
353    }
354
355    /// Grow this packet's content by the given size and return a writer to the
356    /// location to write. See `grow` function for more information.
357    #[inline]
358    pub fn grow_write(&mut self, len: usize) -> impl Write + '_ {
359        Cursor::new(self.grow(len))
360    }
361    
362    /// Return the length of the footer. It should not exceed `PACKET_MAX_FOOTER_LEN`.
363    #[inline]
364    pub fn footer_len(&self) -> usize {
365        self.raw.data_len() - self.footer_offset
366    }
367
368    /// Return the available length remaining in the footer.
369    #[inline]
370    pub fn footer_available_len(&self) -> usize {
371        PACKET_MAX_FOOTER_LEN - self.footer_len()
372    }
373
374    /// Return the offset of the next request element in this packet. Because
375    /// this offset cannot be equal to 0 or 1 (which points to packet's flags),
376    /// such values are sentinels that fill returns `None`.
377    #[inline]
378    pub fn first_request_offset(&self) -> Option<usize> {
379        (self.first_request_offset >= PACKET_FLAGS_LEN).then_some(self.first_request_offset)
380    }
381
382    /// Set the first offset of the next request element in this packet. Refer
383    /// to `first_request_offset` function for limitations.
384    #[inline]
385    pub fn set_first_request_offset(&mut self, offset: usize) {
386        assert!(offset >= PACKET_FLAGS_LEN, "invalid request offset");
387        self.first_request_offset = offset;
388    }
389
390    /// Clear the first request offset.
391    #[inline]
392    pub fn clear_first_request_offset(&mut self) {
393        self.first_request_offset = 0;
394    }
395
396    /// Write the given configuration to this packet's flags and footer. This function 
397    /// takes a configuration that will be applied to the packet, the configuration must
398    /// be mutable because the function will try to put the maximum number of
399    /// acks in the footer, the remaining acks will be left over in the config.
400    pub fn write_config(&mut self, config: &mut PacketConfig) {
401
402        // If the footer is already filled
403        if self.footer_offset < self.raw.data_len() {
404            self.raw.set_data_len(self.footer_offset);
405        }
406
407        // Note that in this function we are intentionally using the function 
408        // 'self.raw.grow[_write]'. This will cause the raw length to grow 
409        // without the footer offset, which will increase the footer length.
410
411        let mut flags = 0u16;
412
413        if config.reliable() { flags |= flags::IS_RELIABLE; }
414        if config.on_channel() { flags |= flags::ON_CHANNEL; }
415        
416        if let Some((first_num, last_num)) = config.sequence_range() {
417            flags |= flags::IS_FRAGMENT;
418            let mut cursor = self.raw.grow_write(8);
419            cursor.write_u32::<LE>(first_num).unwrap();
420            cursor.write_u32::<LE>(last_num).unwrap();
421        }
422
423        if let Some(request_offset) = self.first_request_offset() {
424            flags |= flags::HAS_REQUESTS;
425            self.raw.grow_write(2).write_u16::<LE>(request_offset as u16).unwrap();
426        }
427
428        if let Some(val) = config.unk_1000() {
429            flags |= flags::UNK_1000;
430            self.raw.grow_write(4).write_u32::<LE>(val).unwrap();
431        }
432
433        if config.reliable() || config.sequence_range().is_some() {
434            flags |= flags::HAS_SEQUENCE_NUMBER;
435            self.raw.grow_write(4).write_u32::<LE>(config.sequence_num()).unwrap();
436        }
437
438        if !config.single_acks().is_empty() {
439
440            flags |= flags::HAS_ACKS;
441
442            // Compute the remaining footer length for acks.
443            let available_len = self.footer_available_len()
444                - if config.cumulative_ack().is_some() { 4 } else { 0 }
445                - if config.indexed_channel().is_some() { 8 } else { 0 }
446                - if config.has_checksum() { 4 } else { 0 }
447                - 1; // Acks count
448
449            let mut count = 0;
450            while let Some(ack) = config.single_acks_mut().pop_front() {
451                if available_len < 4 {
452                    break
453                } else {
454                    self.raw.grow_write(4).write_u32::<LE>(ack).unwrap();
455                    count += 1;
456                }
457            }
458
459            debug_assert!(count != 0);
460            self.raw.grow(1)[0] = count as _;
461
462        }
463
464        if let Some(num) = config.cumulative_ack() {
465            flags |= flags::HAS_CUMULATIVE_ACK;
466            self.raw.grow_write(4).write_u32::<LE>(num).unwrap();
467        }
468
469        if let Some((id, version)) = config.indexed_channel() {
470            flags |= flags::INDEXED_CHANNEL;
471            let mut cursor = self.raw.grow_write(8);
472            cursor.write_u32::<LE>(version).unwrap();
473            cursor.write_u32::<LE>(id).unwrap();
474        }
475
476        if config.has_checksum() {
477            flags |= flags::HAS_CHECKSUM;
478        }
479
480        // Finally, write flags just before computing checksum (if needed).
481        self.raw.write_flags(flags);
482
483        // If checksum enabled, compute the checksum of the whole body of the packet,
484        // which range from flags to the end of the footer. The checksum will be
485        // appended to the footer after computing the checksum.
486        if config.has_checksum() {
487            let checksum = calc_checksum(Cursor::new(self.raw.body()));
488            self.raw.grow_write(4).write_u32::<LE>(checksum).unwrap();
489        }
490
491    }
492
493    /// Read the configuration from this packet's flags and footer.
494    /// 
495    /// *Note that* the given length must account for the prefix.
496    ///
497    /// *If this function returns an error, the integrity of the configuration is not 
498    /// guaranteed.*
499    pub fn read_config(&mut self, len: usize, config: &mut PacketConfig) -> Result<(), PacketConfigError> {
500
501        // We set the length of the raw packet, it allow us to use 
502        // 'shrink_read' on it to read each footer element.
503        self.raw.set_data_len(len);
504
505        // Start by reading flags.
506        let flags = self.raw.read_flags();
507
508        // This list of flags contains all flags supported by this function.
509        const KNOWN_FLAGS: u16 =
510            flags::HAS_CHECKSUM |
511            flags::INDEXED_CHANNEL |
512            flags::HAS_CUMULATIVE_ACK |
513            flags::HAS_ACKS |
514            flags::HAS_SEQUENCE_NUMBER |
515            flags::UNK_1000 |
516            flags::HAS_REQUESTS |
517            flags::IS_FRAGMENT |
518            flags::ON_CHANNEL |
519            flags::IS_RELIABLE;
520
521        if flags & !KNOWN_FLAGS != 0 {
522            return Err(PacketConfigError::UnknownFlags(flags & !KNOWN_FLAGS));
523        }
524
525        if flags & flags::HAS_CHECKSUM != 0 {
526
527            // We shrink the packet to read the checksum and then compute the checksum 
528            // from the body data, which no longer contains the checksum itself!
529            let expected_checksum = self.raw.shrink_read(4).read_u32::<LE>().unwrap();
530            let computed_checksum = calc_checksum(Cursor::new(self.raw.body()));
531
532            if expected_checksum != computed_checksum {
533                return Err(PacketConfigError::InvalidChecksum)
534            }
535
536        }
537
538        if flags & flags::INDEXED_CHANNEL != 0 {
539            let mut cursor = self.raw.shrink_read(8);
540            let version = cursor.read_u32::<LE>().unwrap();
541            let id = cursor.read_u32::<LE>().unwrap();
542            config.set_indexed_channel(id, version);
543        } else {
544            config.clear_indexed_channel();
545        }
546
547        if flags & flags::HAS_CUMULATIVE_ACK != 0 {
548            config.set_cumulative_ack(self.raw.shrink_read(4).read_u32::<LE>().unwrap());
549        } else {
550            config.clear_cumulative_ack();
551        }
552
553        if flags & flags::HAS_ACKS != 0 {
554
555            let count = self.raw.shrink(1)[0];
556            if count == 0 {
557                return Err(PacketConfigError::Corrupted)
558            }
559
560            for _ in 0..count {
561                config.single_acks_mut().push_back(self.raw.shrink_read(4).read_u32::<LE>().unwrap());
562            }
563
564        }
565
566        // let mut has_sequence_num = false;
567        if flags & flags::HAS_SEQUENCE_NUMBER != 0 {
568            config.set_sequence_num(self.raw.shrink_read(4).read_u32::<LE>().unwrap());
569        } else {
570            config.set_sequence_num(0);
571        }
572
573        if flags & flags::UNK_1000 != 0 {
574            config.set_unk_1000(self.raw.shrink_read(4).read_u32::<LE>().unwrap());
575        } else {
576            config.clear_unk_1000();
577        }
578
579        if flags & flags::HAS_REQUESTS != 0 {
580            let offset = self.raw.shrink_read(2).read_u16::<LE>().unwrap() as usize;
581            if offset < PACKET_FLAGS_LEN {
582                return Err(PacketConfigError::Corrupted)
583            } else {
584                self.set_first_request_offset(offset);
585            }
586        } else {
587            self.clear_first_request_offset();
588        }
589
590        if flags & flags::IS_FRAGMENT != 0 {
591            let mut cursor = self.raw.shrink_read(8);
592            let first_num = cursor.read_u32::<LE>().unwrap();
593            let last_num = cursor.read_u32::<LE>().unwrap();
594            if first_num >= last_num {
595                return Err(PacketConfigError::Corrupted)
596            } else {
597                config.set_sequence_range(first_num, last_num);
598            }
599        } else {
600            config.clear_sequence_range();
601        }
602
603        config.set_reliable(flags & flags::IS_RELIABLE != 0);
604        config.set_on_channel(flags & flags::ON_CHANNEL != 0);
605
606        // Now that we shrunk all the footer, set the footer offset.
607        self.footer_offset = self.raw.data_len();
608        // Rollback the length.
609        self.raw.set_data_len(len);
610
611        // Check that the footer length is coherent.
612        debug_assert!(self.footer_len() <= PACKET_MAX_FOOTER_LEN);
613
614        Ok(())
615
616    }
617
618}
619
620impl fmt::Debug for Packet {
621    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
622        f.debug_struct("Packet")
623            .field("content", &format_args!("{:X}", BytesFmt(self.content())))
624            .field("content_len", &self.content_len())
625            .field("footer_len", &self.footer_len())
626            .field("first_request_offset", &self.first_request_offset())
627            .finish()
628    }
629}
630
631
632/// Describe a packet configuration that can be used when synchronizing data or 
633/// state of a packet.
634#[derive(Debug, Clone)]
635pub struct PacketConfig {
636    /// The sequence number of this packet, it is used if reliable mode is enabled
637    /// **and/or** if the packet is a fragment of a chain of packet.
638    sequence_num: u32,
639    /// If this packet is a fragment (defined just after), this contains the
640    /// sequence number of the first packet in the chain.
641    /// 
642    /// A packet is considered to be a fragment of a chain only if `seq_first < 
643    /// seq_last`.
644    sequence_first_num: u32,
645    /// If this packet is a fragment (defined in `seq_first` doc), this contains 
646    /// the sequence number of the last packet in the chain.
647    sequence_last_num: u32,
648    /// Set to true if the sender of this packet requires an acknowledgment from
649    /// the receiver upon successful receipt of this packet.
650    reliable: bool,
651    /// The cumulative ack number. This number is sent for acknowledging that
652    /// all sequence numbers up to (but excluding) this ack have been received.
653    /// 
654    /// The cumulative ack 0 is apparently used when opening a channel.
655    cumulative_ack: Option<u32>,
656    /// Individual acks to send.
657    single_acks: VecDeque<u32>,
658    /// Set to true when this packet is being transferred on a channel.
659    on_channel: bool,
660    /// Indexed channel is a combination of the channel id and version.
661    indexed_channel: Option<(u32, u32)>,
662    /// Enable or disable checksum.
663    has_checksum: bool,
664    /// The usage of this value and flag 0x1000 is unknown. It will be
665    /// renamed in the future if its purpose is discovered.
666    unk_1000: Option<u32>,
667}
668
669impl PacketConfig {
670
671    /// Create a new packet configuration with default values.
672    #[inline]
673    pub fn new() -> Self {
674        Self {
675            sequence_num: 0,
676            sequence_first_num: 0,
677            sequence_last_num: 0,
678            reliable: false,
679            cumulative_ack: None,
680            single_acks: VecDeque::new(),
681            on_channel: false,
682            indexed_channel: None,
683            has_checksum: false,
684            unk_1000: None,
685        }
686    }
687
688    /// Returns the sequence number of this packet. It is actually used only if
689    /// this packet is marked as reliable **and/or** if the packet is a fragment.
690    /// 
691    /// It is set to 0 by default.
692    #[inline]
693    pub fn sequence_num(&self) -> u32 {
694        self.sequence_num
695    }
696
697    /// Set the sequence number of this packet. Read `sequence_num` doc for 
698    /// explanation of the usage of the sequence number.
699    #[inline]
700    pub fn set_sequence_num(&mut self, num: u32) {
701        self.sequence_num = num;
702    }
703
704    /// Returns the range of sequence number in case this packet is a fragment
705    /// of a packet chain. Both bounds are included.
706    #[inline]
707    pub fn sequence_range(&self) -> Option<(u32, u32)> {
708        if self.sequence_first_num < self.sequence_last_num {
709            Some((self.sequence_first_num, self.sequence_last_num))
710        } else {
711            None
712        }
713    }
714
715    /// Set the range of sequence number if this packet is a fragment of a
716    /// packet chain. Both bounds are included and `last` should be greater
717    /// than `first`, this function panics if this condition is not met.
718    /// 
719    /// See also `clear_sequence_range` if you want to clear the range.
720    /// 
721    /// *Note that* the sequence number is not checked to be in bounds.
722    #[inline]
723    pub fn set_sequence_range(&mut self, first: u32, last: u32) {
724        assert!(first < last, "invalid range");
725        self.sequence_first_num = first;
726        self.sequence_last_num = last;
727    }
728
729    /// Clear the range of sequence number. After calling this, the packet 
730    /// is no longer a fragment in a packet chain.
731    #[inline]
732    pub fn clear_sequence_range(&mut self) {
733        self.sequence_first_num = 0;
734        self.sequence_last_num = 0;
735    }
736
737    /// Returns true if the sender of this packet requires an acknowledgment from 
738    /// the receiver upon successful receipt of this packet.
739    #[inline]
740    pub fn reliable(&self) -> bool {
741        self.reliable
742    }
743
744    /// Read `reliable` doc for explanation of this value.
745    #[inline]
746    pub fn set_reliable(&mut self, reliable: bool) {
747        self.reliable = reliable
748    }
749
750    /// This number is sent for acknowledging that all sequence numbers up to (but 
751    /// excluding) this ack have been received.
752    #[inline]
753    pub fn cumulative_ack(&self) -> Option<u32> {
754        self.cumulative_ack
755    }
756
757    /// Set the cumulative ack if this packet. Because this value is an excluded
758    /// bound, you should not set this to 0. If you want to reset the cumulative
759    /// ack, use `clear_cumulative_ack` instead.
760    #[inline]
761    pub fn set_cumulative_ack(&mut self, num: u32) {
762        assert_ne!(num, 0, "cumulative ack is exclusive so it cannot be zero");
763        self.cumulative_ack = Some(num);
764    }
765
766    /// Clear the cumulative ack from this packet.
767    #[inline]
768    pub fn clear_cumulative_ack(&mut self) {
769        self.cumulative_ack = None;
770    }
771
772    #[inline]
773    pub fn single_acks(&self) -> &VecDeque<u32> {
774        &self.single_acks
775    }
776
777    #[inline]
778    pub fn single_acks_mut(&mut self) -> &mut VecDeque<u32> {
779        &mut self.single_acks
780    }
781
782    #[inline]
783    pub fn on_channel(&self) -> bool {
784        self.on_channel
785    }
786
787    /// Return the indexed channel, if existing, using tuple `(id, version)`.
788    #[inline]
789    pub fn indexed_channel(&self) -> Option<(u32, u32)> {
790        self.indexed_channel
791    }
792
793    #[inline]
794    pub fn set_indexed_channel(&mut self, id: u32, version: u32) {
795        self.indexed_channel = Some((id, version))
796    }
797
798    #[inline]
799    pub fn clear_indexed_channel(&mut self) {
800        self.indexed_channel = None;
801    }
802
803    #[inline]
804    pub fn set_on_channel(&mut self, on_channel: bool) {
805        self.on_channel = on_channel;
806    }
807
808    #[inline]
809    pub fn has_checksum(&self) -> bool {
810        self.has_checksum
811    }
812
813    #[inline]
814    pub fn set_checksum(&mut self, enabled: bool) {
815        self.has_checksum = enabled;
816    }
817
818    /// The usage of this value and flag 0x1000 is unknown. It will be
819    /// renamed in the future if its purpose is discovered.
820    #[inline]
821    pub fn unk_1000(&self) -> Option<u32> {
822        self.unk_1000
823    }
824
825    /// The usage of this value and flag 0x1000 is unknown. It will be
826    /// renamed in the future if its purpose is discovered.
827    #[inline]
828    pub fn set_unk_1000(&mut self, val: u32) {
829        self.unk_1000 = Some(val);
830    }
831
832    /// The usage of this value and flag 0x1000 is unknown. It will be
833    /// renamed in the future if its purpose is discovered.
834    #[inline]
835    pub fn clear_unk_1000(&mut self) {
836        self.unk_1000 = None;
837    }
838
839}
840
841
842/// Generic function to calculate the checksum from a reader and
843/// a given number of bytes available.
844fn calc_checksum(mut reader: impl Read) -> u32 {
845    let mut checksum = 0;
846    while let Ok(num) = reader.read_u32::<LE>() {
847        checksum ^= num;
848    }
849    checksum
850}
851
852
853/// Internal module defining flags for packets.
854#[allow(unused)]
855mod flags {
856    pub const HAS_REQUESTS: u16         = 0x0001;
857    pub const HAS_PIGGYBACKS: u16       = 0x0002;
858    pub const HAS_ACKS: u16             = 0x0004;
859    pub const ON_CHANNEL: u16           = 0x0008;
860    pub const IS_RELIABLE: u16          = 0x0010;
861    pub const IS_FRAGMENT: u16          = 0x0020;
862    pub const HAS_SEQUENCE_NUMBER: u16  = 0x0040;
863    pub const INDEXED_CHANNEL: u16      = 0x0080;
864    pub const HAS_CHECKSUM: u16         = 0x0100;
865    pub const CREATE_CHANNEL: u16       = 0x0200;
866    pub const HAS_CUMULATIVE_ACK: u16   = 0x0400;
867    pub const UNK_0800: u16             = 0x0800;
868    pub const UNK_1000: u16             = 0x1000;
869}
870
871
872/// Packet error when reading invalid config from a packet.
873#[derive(Debug, Clone, thiserror::Error)]
874pub enum PacketConfigError {
875    /// Unknown flags are used, the packet can't be decoded because this usually
876    /// increase length of the footer.
877    #[error("unknown flags: {0:04X}")]
878    UnknownFlags(u16),
879    /// The packet is corrupted, the footer might be too short or an invalid bit
880    /// pattern has been read.
881    #[error("corrupted")]
882    Corrupted,
883    /// The packet checksum and calculated checksum aren't equal.
884    #[error("invalid checksum")]
885    InvalidChecksum
886}