diff --git a/include/dot11.h b/include/dot11.h index 6ca1ada..d72bdf1 100644 --- a/include/dot11.h +++ b/include/dot11.h @@ -3372,7 +3372,7 @@ namespace Tins { * \brief Getter for the bar control field. * \return The stored bar control field. */ - uint16_t bar_control() const { + small_uint<4> bar_control() const { #if TINS_IS_LITTLE_ENDIAN return _bar_control & 0xf; #else @@ -3384,7 +3384,7 @@ namespace Tins { * \brief Getter for the start sequence field. * \return The stored start sequence. */ - uint16_t start_sequence() const { + small_uint<12> start_sequence() const { #if TINS_IS_LITTLE_ENDIAN return (_start_sequence >> 4) & 0xfff; #else @@ -3396,7 +3396,7 @@ namespace Tins { * \brief Getter for the fragment number field. * \return The stored fragment number field. */ - uint8_t fragment_number() const { + small_uint<4> fragment_number() const { #if TINS_IS_LITTLE_ENDIAN return _start_sequence & 0xf; #else @@ -3418,19 +3418,19 @@ namespace Tins { * \brief Setter for the bar control field. * \param bar The bar control field to be set. */ - void bar_control(uint16_t bar); + void bar_control(small_uint<4> bar); /** * \brief Setter for the start sequence field. * \param bar The start sequence field to be set. */ - void start_sequence(uint16_t seq); + void start_sequence(small_uint<12> seq); /** * \brief Setter for the fragment number field. * \param frag The fragment number field to be set. */ - void fragment_number(uint8_t frag); + void fragment_number(small_uint<4> frag); /** * \brief Clones this PDU. @@ -3515,13 +3515,38 @@ namespace Tins { * \brief Getter for the bar control field. * \return The stored bar control field. */ - uint16_t bar_control() const { return _bar_control.tid; } + small_uint<4> bar_control() const { + #if TINS_IS_LITTLE_ENDIAN + return _bar_control & 0xf; + #else + return (_bar_control >> 8) & 0xf; + #endif + } /** * \brief Getter for the start sequence field. - * \return The stored bar start sequence. + * \return The stored start sequence. */ - uint16_t start_sequence() const { return (_start_sequence.frag << 12) | (_start_sequence.seq); } + small_uint<12> start_sequence() const { + #if TINS_IS_LITTLE_ENDIAN + return (_start_sequence >> 4) & 0xfff; + #else + return (Endian::le_to_host(_start_sequence) >> 4) & 0xfff; + #endif + } + + /** + * \brief Getter for the fragment number field. + * \return The stored fragment number field. + */ + small_uint<4> fragment_number() const { + #if TINS_IS_LITTLE_ENDIAN + return _start_sequence & 0xf; + #else + return (_start_sequence >> 8) & 0xf; + #endif + } + /** * \brief Returns the 802.11 frame's header length. * @@ -3534,15 +3559,21 @@ namespace Tins { /** * \brief Setter for the bar control field. - * \param bar The bar control to be set. + * \param bar The bar control field to be set. */ - void bar_control(uint16_t bar); + void bar_control(small_uint<4> bar); /** * \brief Setter for the start sequence field. - * \param bar The start sequence to be set. + * \param bar The start sequence field to be set. */ - void start_sequence(uint16_t seq); + void start_sequence(small_uint<12> seq); + + /** + * \brief Setter for the fragment number field. + * \param frag The fragment number field to be set. + */ + void fragment_number(small_uint<4> frag); /** * \brief Getter for the bitmap field. @@ -3583,24 +3614,10 @@ namespace Tins { return new Dot11BlockAck(*this); } private: - TINS_BEGIN_PACK - struct BarControl { - uint16_t reserved:12, - tid:4; - } TINS_END_PACK; - - TINS_BEGIN_PACK - struct StartSequence { - uint16_t frag:4, - seq:12; - } TINS_END_PACK; - void init_block_ack(); uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz); - - BarControl _bar_control; - StartSequence _start_sequence; + uint16_t _bar_control, _start_sequence; uint8_t _bitmap[bitmap_size]; }; } diff --git a/src/dot11.cpp b/src/dot11.cpp index 632c8af..978a687 100644 --- a/src/dot11.cpp +++ b/src/dot11.cpp @@ -1530,7 +1530,7 @@ uint32_t Dot11BlockAckRequest::write_ext_header(uint8_t *buffer, uint32_t total_ return parent_size + sizeof(_start_sequence) + sizeof(_bar_control); } -void Dot11BlockAckRequest::bar_control(uint16_t bar) { +void Dot11BlockAckRequest::bar_control(small_uint<4> bar) { #if TINS_IS_LITTLE_ENDIAN _bar_control = bar | (_bar_control & 0xfff0); #else @@ -1538,7 +1538,7 @@ void Dot11BlockAckRequest::bar_control(uint16_t bar) { #endif } -void Dot11BlockAckRequest::start_sequence(uint16_t seq) { +void Dot11BlockAckRequest::start_sequence(small_uint<12> seq) { #if TINS_IS_LITTLE_ENDIAN _start_sequence = (seq << 4) | (_start_sequence & 0xf); #else @@ -1546,7 +1546,7 @@ void Dot11BlockAckRequest::start_sequence(uint16_t seq) { #endif } -void Dot11BlockAckRequest::fragment_number(uint8_t frag) { +void Dot11BlockAckRequest::fragment_number(small_uint<4> frag) { #if TINS_IS_LITTLE_ENDIAN _start_sequence = frag | (_start_sequence & 0xfff0); #else @@ -1581,12 +1581,28 @@ Dot11BlockAck::Dot11BlockAck(const uint8_t *buffer, uint32_t total_sz) : Dot11Co std::memcpy(&_bitmap, buffer, sizeof(_bitmap)); } -void Dot11BlockAck::bar_control(uint16_t bar) { - std::memcpy(&_bar_control, &bar, sizeof(bar)); +void Dot11BlockAck::bar_control(small_uint<4> bar) { + #if TINS_IS_LITTLE_ENDIAN + _bar_control = bar | (_bar_control & 0xfff0); + #else + _bar_control = (bar << 8) | (_bar_control & 0xf0ff); + #endif } -void Dot11BlockAck::start_sequence(uint16_t seq) { - std::memcpy(&_start_sequence, &seq, sizeof(seq)); +void Dot11BlockAck::start_sequence(small_uint<12> seq) { + #if TINS_IS_LITTLE_ENDIAN + _start_sequence = (seq << 4) | (_start_sequence & 0xf); + #else + _start_sequence = Endian::host_to_le(seq << 4) | (_start_sequence & 0xf00); + #endif +} + +void Dot11BlockAck::fragment_number(small_uint<4> frag) { + #if TINS_IS_LITTLE_ENDIAN + _start_sequence = frag | (_start_sequence & 0xfff0); + #else + _start_sequence = (frag << 8) | (_start_sequence & 0xf0ff); + #endif } void Dot11BlockAck::bitmap(const uint8_t *bit) { diff --git a/tests/src/dot11/block_ack_request.cpp b/tests/src/dot11/block_ack_request.cpp index 2ecdee8..5ebd2e7 100644 --- a/tests/src/dot11/block_ack_request.cpp +++ b/tests/src/dot11/block_ack_request.cpp @@ -55,7 +55,7 @@ TEST_F(Dot11BlockAckRequestTest, CopyConstructor) { Dot11BlockAckRequest dot1; dot1.fragment_number(6); dot1.start_sequence(0x294); - dot1.bar_control(0x92f); + dot1.bar_control(0x9); Dot11BlockAckRequest dot2(dot1); test_equals(dot1, dot2); } @@ -64,7 +64,7 @@ TEST_F(Dot11BlockAckRequestTest, CopyAssignmentOperator) { Dot11BlockAckRequest dot1; dot1.fragment_number(6); dot1.start_sequence(0x294); - dot1.bar_control(0x92f); + dot1.bar_control(0x9); Dot11BlockAckRequest dot2; dot2 = dot1; test_equals(dot1, dot2); @@ -74,7 +74,7 @@ TEST_F(Dot11BlockAckRequestTest, ClonePDU) { Dot11BlockAckRequest dot1; dot1.fragment_number(6); dot1.start_sequence(0x294); - dot1.bar_control(0x92f); + dot1.bar_control(0x9); std::auto_ptr dot2(dot1.clone()); test_equals(dot1, *dot2); }