Пример #1
0
        public void Should_read_16_bits()
        {
            var reader = new DatagramReader(new byte[] { 66, 69 });

            Assert.AreEqual(66, reader.Read(8));
            Assert.AreEqual(69, reader.Read(8));
        }
Пример #2
0
        public void Should_read_8_bits()
        {
            var reader = new DatagramReader(new byte[] { 80 });

            Assert.AreEqual(1, reader.Read(2));
            Assert.AreEqual(1, reader.Read(2));
            Assert.AreEqual(0, reader.Read(4));
        }
Пример #3
0
        public void Should_read_bytes()
        {
            var reader = new DatagramReader(new byte[] { 0, 255 });

            Assert.AreEqual(0, reader.Read(4));
            Assert.AreEqual(0, reader.Read(4));
            Assert.AreEqual(new byte[] { 255 }, reader.ReadAllBytes());
        }
Пример #4
0
        public virtual Message Deserialize(byte[] bytes)
        {
            var reader  = new DatagramReader(bytes);
            var factory = new MessageFactory();
            var version = reader.Read(Message.VersionBits);

            if (version != Message.Version)
            {
                throw new SerializationException("incorrect version");
            }

            var type          = (MessageType)reader.Read(Message.TypeBits);
            var optionCount   = reader.Read(Message.OptionCountBits);
            var code          = (CodeRegistry)reader.Read(Message.CodeBits);
            var id            = reader.Read(Message.IdBits);
            var message       = factory.Create(type, code, id);
            var currentOption = 0;

            for (var i = 0; i < optionCount; i++)
            {
                var delta  = reader.Read(Message.OptionDeltaBits);
                var length = reader.Read(Message.OptionLengthBits);
                currentOption += delta;
                var option = new Option((OptionNumber)currentOption)
                {
                    Value = reader.ReadBytes(length)
                };
                message.AddOption(option);
            }

            message.Payload = reader.ReadAllBytes();
            return(message);
        }
Пример #5
0
 /// <summary>
 /// Calculates the value used in the extended option fields as specified
 /// in draft-ietf-core-coap-14, section 3.1.
 /// </summary>
 /// <param name="nibble">the 4-bit option header value</param>
 /// <param name="datagram">the datagram</param>
 /// <returns>the value calculated from the nibble and the extended option value</returns>
 private static Int32 GetValueFromOptionNibble(Int32 nibble, DatagramReader datagram)
 {
     if (nibble < 13)
     {
         return(nibble);
     }
     else if (nibble == 13)
     {
         return(datagram.Read(8) + 13);
     }
     else if (nibble == 14)
     {
         return(datagram.Read(16) + 269);
     }
     else
     {
         throw ThrowHelper.Argument("nibble", "Unsupported option delta " + nibble);
     }
 }
Пример #6
0
        public void Test2BitInt()
        {
            Int32 intIn = 0x00000002;

            DatagramWriter writer = new DatagramWriter();

            writer.Write(intIn, 2);

            DatagramReader reader = new DatagramReader(writer.ToByteArray());
            Int32          intOut = reader.Read(2);

            Assert.IsEqualTo(intIn, intOut);
        }
Пример #7
0
        public void Test16BitInt()
        {
            Int32 intIn = (Int32)0x00004321;

            DatagramWriter writer = new DatagramWriter();

            writer.Write(intIn, 16);

            DatagramReader reader = new DatagramReader(writer.ToByteArray());
            Int32          intOut = reader.Read(16);

            Assert.IsEqualTo(intIn, intOut);
        }
Пример #8
0
        public void TestGETRequestHeader()
        {
            Int32 versionIn   = 1;
            Int32 versionSz   = 2;
            Int32 typeIn      = 0; // Confirmable
            Int32 typeSz      = 2;
            Int32 optionCntIn = 1;
            Int32 optionCntSz = 4;
            Int32 codeIn      = 1; // GET Request
            Int32 codeSz      = 8;
            Int32 msgIdIn     = 0x1234;
            Int32 msgIdSz     = 16;

            DatagramWriter writer = new DatagramWriter();

            writer.Write(versionIn, versionSz);
            writer.Write(typeIn, typeSz);
            writer.Write(optionCntIn, optionCntSz);
            writer.Write(codeIn, codeSz);
            writer.Write(msgIdIn, msgIdSz);

            Byte[] data    = writer.ToByteArray();
            Byte[] dataRef = { 0x41, 0x01, 0x12, 0x34 };

            Assert.IsSequenceEqualTo(dataRef, data);

            DatagramReader reader       = new DatagramReader(data);
            Int32          versionOut   = reader.Read(versionSz);
            Int32          typeOut      = reader.Read(typeSz);
            Int32          optionCntOut = reader.Read(optionCntSz);
            Int32          codeOut      = reader.Read(codeSz);
            Int32          msgIdOut     = reader.Read(msgIdSz);

            Assert.IsEqualTo(versionIn, versionOut);
            Assert.IsEqualTo(typeIn, typeOut);
            Assert.IsEqualTo(optionCntIn, optionCntOut);
            Assert.IsEqualTo(codeIn, codeOut);
            Assert.IsEqualTo(msgIdIn, msgIdOut);
        }
Пример #9
0
        public void Test32BitIntZero()
        {
            Int32 intIn = (Int32)0x00000000;

            DatagramWriter writer = new DatagramWriter();

            writer.Write(intIn, 32);

            DatagramReader reader = new DatagramReader(writer.ToByteArray());
            Int32          intOut = reader.Read(32);

            Assert.IsEqualTo(intIn, intOut);
        }
Пример #10
0
        public void Test32BitInt()
        {
            unchecked
            {
                Int32 intIn = (Int32)0x87654321;

                DatagramWriter writer = new DatagramWriter();
                writer.Write(intIn, 32);

                DatagramReader reader = new DatagramReader(writer.ToByteArray());
                Int32          intOut = reader.Read(32);

                Assert.IsEqualTo(intIn, intOut);
            }
        }
Пример #11
0
 /// <summary>
 /// Calculates the value used in the extended option fields as specified
 /// in draft-ietf-core-coap-13, section 3.1.
 /// </summary>
 /// <param name="nibble">the 4-bit option header value</param>
 /// <param name="datagram">the datagram</param>
 /// <returns>the value calculated from the nibble and the extended option value</returns>
 private static Int32 GetValueFromOptionNibble(Int32 nibble, DatagramReader datagram)
 {
     if (nibble < 13)
     {
         return(nibble);
     }
     else if (nibble == 13)
     {
         return(datagram.Read(8) + 13);
     }
     else if (nibble == 14)
     {
         return(datagram.Read(16) + 269);
     }
     else
     {
         // TODO error
         if (log.IsWarnEnabled)
         {
             log.Warn("15 is reserved for payload marker, message format error");
         }
         return(0);
     }
 }
Пример #12
0
        public void TestByteOrder()
        {
            Int32 intIn = 1234567890;

            DatagramWriter writer = new DatagramWriter();

            writer.Write(intIn, 32);

            Byte[] data     = writer.ToByteArray();
            Int32  intTrans = System.Net.IPAddress.HostToNetworkOrder(BitConverter.ToInt32(data, 0));

            Assert.IsEqualTo(intIn, intTrans);

            DatagramReader reader = new DatagramReader(data);
            Int32          intOut = reader.Read(32);

            Assert.IsEqualTo(intIn, intOut);
        }
Пример #13
0
        public void TestBytesLeftUnaligned()
        {
            Int32 bitCount = 7;
            Int32 bitsIn   = 0x55;

            Byte[] bytesIn = System.Text.Encoding.UTF8.GetBytes("Some aligned bytes");

            DatagramWriter writer = new DatagramWriter();

            writer.Write(bitsIn, bitCount);
            writer.WriteBytes(bytesIn);

            DatagramReader reader  = new DatagramReader(writer.ToByteArray());
            Int32          bitsOut = reader.Read(bitCount);

            Byte[] bytesOut = reader.ReadBytesLeft();

            Assert.IsEqualTo(bitsIn, bitsOut);
            Assert.IsSequenceEqualTo(bytesIn, bytesOut);
        }
Пример #14
0
        public Message Decode(Byte[] bytes)
#endif
        {
            DatagramReader datagram = new DatagramReader(bytes);

            // read headers
            Int32 version = datagram.Read(VersionBits);

            if (version != SupportedVersion)
            {
                return(null);
            }

            MessageType type        = (MessageType)datagram.Read(TypeBits);
            Int32       optionCount = datagram.Read(OptionCountBits);
            Int32       code        = datagram.Read(CodeBits);

            // create new message with subtype according to code number
            Message msg = Message.Create(code);

            msg.Type = type;
            msg.ID   = datagram.Read(IDBits);

            // read options
            Int32 currentOption = 0;

            for (Int32 i = 0; i < optionCount; i++)
            {
                // read option delta bits
                Int32 optionDelta = datagram.Read(OptionDeltaBits);

                currentOption += optionDelta;
                OptionType currentOptionType = GetOptionType(currentOption);

                if (IsFencepost(currentOptionType))
                {
                    // read number of options
                    datagram.Read(OptionLengthBaseBits);
                }
                else
                {
                    // read option length
                    Int32 length = datagram.Read(OptionLengthBaseBits);
                    if (length > MaxOptionLengthBase)
                    {
                        // read extended option length
                        length += datagram.Read(OptionLengthExtendedBits);
                    }
                    // read option
                    Option opt = Option.Create(currentOptionType);
                    opt.RawValue = datagram.ReadBytes(length);

                    msg.AddOption(opt);
                }
            }

            msg.Payload = datagram.ReadBytesLeft();

            // incoming message already have a token,
            // including implicit empty token
            msg.RequiresToken = false;

            return(msg);
        }
Пример #15
0
        public Message Decode(Byte[] bytes)
#endif
        {
            DatagramReader datagram = new DatagramReader(bytes);

            // read headers
            Int32 version = datagram.Read(VersionBits);

            if (version != SupportedVersion)
            {
                return(null);
            }

            MessageType type        = (MessageType)datagram.Read(TypeBits);
            Int32       tokenLength = datagram.Read(TokenLengthBits);
            Int32       code        = datagram.Read(CodeBits);

            // create new message with subtype according to code number
            Message msg = Message.Create(code);

            msg.Type = type;
            msg.ID   = datagram.Read(IDBits);

            // read token
            if (tokenLength > 0)
            {
                msg.Token = datagram.ReadBytes(tokenLength);
            }
            else
            {
                msg.RequiresToken = false;
            }

            // read options
            Int32 currentOption = 0;

            while (datagram.BytesAvailable)
            {
                Byte nextByte = datagram.ReadNextByte();
                if (nextByte == PayloadMarker)
                {
                    if (!datagram.BytesAvailable)
                    {
                        // the presence of a marker followed by a zero-length payload
                        // must be processed as a message format error
                        return(null);
                    }

                    msg.Payload = datagram.ReadBytesLeft();
                }
                else
                {
                    // the first 4 bits of the byte represent the option delta
                    Int32 optionDeltaNibble = (0xF0 & nextByte) >> 4;
                    currentOption += GetValueFromOptionNibble(optionDeltaNibble, datagram);

                    // the second 4 bits represent the option length
                    Int32 optionLengthNibble = (0x0F & nextByte);
                    Int32 optionLength       = GetValueFromOptionNibble(optionLengthNibble, datagram);

                    // read option
                    OptionType currentOptionType = GetOptionType(currentOption);
                    Option     opt = Option.Create(currentOptionType);
                    opt.RawValue = datagram.ReadBytes(optionLength);

                    msg.AddOption(opt);
                }
            }

            return(msg);
        }
Пример #16
0
        public Message Decode(Byte[] bytes)
#endif
        {
            DatagramReader datagram = new DatagramReader(bytes);

            // read headers
            Int32 version = datagram.Read(VersionBits);

            if (version != SupportedVersion)
            {
                return(null);
            }

            MessageType type        = (MessageType)datagram.Read(TypeBits);
            Int32       optionCount = datagram.Read(OptionCountBits);
            Int32       code        = datagram.Read(CodeBits);

            // create new message with subtype according to code number
            Message msg = Message.Create(code);

            msg.Type = type;
            msg.ID   = datagram.Read(IDBits);

            // read options
            Int32   currentOption  = 0;
            Boolean hasMoreOptions = optionCount == 15;

            for (Int32 i = 0; (i < optionCount || hasMoreOptions) && datagram.BytesAvailable; i++)
            {
                // first 4 option bits: either option jump or option delta
                Int32 optionDelta = datagram.Read(OptionDeltaBits);

                if (optionDelta == 15)
                {
                    // option jump or end-of-options marker
                    Int32 bits = datagram.Read(4);
                    switch (bits)
                    {
                    case 0:
                        // end-of-options marker read (0xF0), payload follows
                        hasMoreOptions = false;
                        continue;

                    case 1:
                        // 0xF1 (Delta = 15)
                        optionDelta = 15 + datagram.Read(OptionDeltaBits);
                        break;

                    case 2:
                        // Delta = ((Option Jump Value) + 2) * 8
                        optionDelta = (datagram.Read(8) + 2) * 8 + datagram.Read(OptionDeltaBits);
                        break;

                    case 3:
                        // Delta = ((Option Jump Value) + 258) * 8
                        optionDelta = (datagram.Read(16) + 258) * 8 + datagram.Read(OptionDeltaBits);
                        break;

                    default:
                        break;
                    }
                }

                currentOption += optionDelta;
                OptionType currentOptionType = GetOptionType(currentOption);

                Int32 length = datagram.Read(OptionLengthBaseBits);
                if (length == 15)
                {
                    /*
                     * When the Length field is set to 15, another byte is added as
                     * an 8-bit unsigned integer whose value is added to the 15,
                     * allowing option value lengths of 15-270 bytes. For option
                     * lengths beyond 270 bytes, we reserve the value 255 of an
                     * extension byte to mean
                     * "add 255, read another extension byte".
                     */
                    Int32 additionalLength = 0;
                    do
                    {
                        additionalLength = datagram.Read(8);
                        length          += additionalLength;
                    } while (additionalLength >= 255);
                }

                // read option
                Option opt = Option.Create(currentOptionType);
                opt.RawValue = datagram.ReadBytes(length);

                msg.AddOption(opt);
            }

            msg.Payload = datagram.ReadBytesLeft();

            // incoming message already have a token, including implicit empty token
            msg.RequiresToken = false;

            return(msg);
        }