From a543c9faee47c33d1f081f9c9b41b9281f7540df Mon Sep 17 00:00:00 2001 From: NZSmartie Date: Fri, 23 Mar 2018 09:59:40 +1300 Subject: [PATCH] Coorect the byte order in Block1/Block2 as it was backwards Relevant tweet: https://twitter.com/NZSmartie/status/976926060938805249 --- src/CoAPNet/Options/BlockWise.cs | 37 ++++++------------------- tests/CoAPNet.Tests/CoapOptionsTests.cs | 19 +++++++------ 2 files changed, 18 insertions(+), 38 deletions(-) diff --git a/src/CoAPNet/Options/BlockWise.cs b/src/CoAPNet/Options/BlockWise.cs index 8589912..9ec6396 100644 --- a/src/CoAPNet/Options/BlockWise.cs +++ b/src/CoAPNet/Options/BlockWise.cs @@ -113,28 +113,18 @@ public override void FromBytes(byte[] data) BlockNumber = 0; last = 0; } - else if (data.Length == 1) + else if (data.Length <= 3) { - BlockNumber = (int)ValueUInt & 0x0F; - last = (ValueUInt & 0xF0) >> 4; - } - else if (data.Length == 2) - { - BlockNumber = (int)ValueUInt & 0x0FFF; - last = (ValueUInt & 0xF000) >> 12; - } - else if (data.Length == 3) - { - BlockNumber = (int)ValueUInt & 0x0FFFFF; - last = (ValueUInt & 0xF00000) >> 20; + BlockNumber = (int)(ValueUInt & 0xFFFFF0) >> 4; + last = ValueUInt & 0x0F; } else { throw new CoapOptionException($"Invalid length ({data.Length}) of Block1/Block2 option"); } - IsMoreFollowing = (last & 0x01) > 0; - var szx = (int)((last >> 1)); + IsMoreFollowing = (last & 0x08) > 0; + var szx = (int)((last & 0x07)); BlockSize = InternalSupportedBlockSizes.First(b => b.Item1 == szx).Item2; } @@ -142,21 +132,10 @@ public override void FromBytes(byte[] data) public override byte[] GetBytes() { var szx = InternalSupportedBlockSizes.First(b => b.Item2 == BlockSize).Item1; - var last = (byte)((szx & 0x07) << 5) | (IsMoreFollowing ? 0x10 : 0x00); - - if (BlockNumber <= 0x0F) - { - ValueUInt = (uint)(last | (BlockNumber & 0x0F)); - } - else if (BlockNumber <= 0x0FFF) - { - ValueUInt = (uint)((last << 8) | (BlockNumber & 0x0FFF)); - } - else if (BlockNumber <= 0x0FFFFF) - { - ValueUInt = (uint)((last << 16) | (BlockNumber & 0x0FFFFF)); - } + var last = (byte)((szx & 0x07) | (IsMoreFollowing ? 0x08 : 0x00)); + ValueUInt = (uint)(last | ((BlockNumber << 4) & 0xFFFFF0)); + return base.GetBytes(); } diff --git a/tests/CoAPNet.Tests/CoapOptionsTests.cs b/tests/CoAPNet.Tests/CoapOptionsTests.cs index 325e764..fdcd501 100644 --- a/tests/CoAPNet.Tests/CoapOptionsTests.cs +++ b/tests/CoAPNet.Tests/CoapOptionsTests.cs @@ -469,15 +469,16 @@ public void TestOptionInvalidCastException() [Category("[RFC7959] Section 2.2"), Category("Blocks")] [TestCase(0, 16, false, new byte[] { })] - [TestCase(1, 16, false, new byte[] { 0x01 })] - [TestCase(2, 32, false, new byte[] { 0x22 })] - [TestCase(3, 64, true, new byte[] { 0x53 })] - [TestCase(4095, 128, true, new byte[] { 0x7F, 0xFF })] - [TestCase(1048575, 256, true, new byte[] { 0x9F, 0xFF, 0xFF})] - [TestCase(15, 16, true, new byte[] { 0x1F })] - [TestCase(16, 16, true, new byte[] { 0x10, 0x10 })] - [TestCase(39, 16, false, new byte[] { 0, 39 })] - [TestCase(79, 16, false, new byte[] { 0, 79 })] + [TestCase(1, 16, false, new byte[] { 0x10 })] + [TestCase(2, 32, false, new byte[] { 0x21 })] + [TestCase(3, 64, true, new byte[] { 0x3A })] + [TestCase(4095, 128, true, new byte[] { 0xFF, 0xFB })] + [TestCase(1048575, 256, true, new byte[] { 0xFF, 0xFF, 0xFC})] + [TestCase(15, 16, true, new byte[] { 0xF8 })] + [TestCase(16, 16, true, new byte[] { 0x01, 0x08 })] + [TestCase(39, 16, false, new byte[] { 0x02, 0x70 })] + [TestCase(79, 16, false, new byte[] { 0x04, 0xF0 })] + [TestCase(0, 128, true, new byte[] { 0x0b })] public void TestBlockOption(int blockNumber, int blockSize, bool more, byte[] expected) { var optionToBytes = new Options.Block1(blockNumber, blockSize, more);