Ejemplo n.º 1
0
        private static byte[] GetOptions(IEnumerable <Option> options)
        {
            var writer           = new DatagramWriter();
            var lastOptionNumber = 0;

            foreach (var option in options)
            {
                var delta  = (int)option.Number - lastOptionNumber;
                var length = option.Value.Length;

                if (length <= Message.MaxOptionLengthBase)
                {
                    writer.Write(delta, Message.OptionDeltaBits);
                    writer.Write(length, Message.OptionLengthBits);
                }
                else
                {
                    const int baseLength = Message.MaxOptionLengthBase + 1;
                    writer.Write(delta, Message.OptionDeltaBits);
                    writer.Write(baseLength, Message.OptionLengthBits);
                    writer.Write(length - baseLength, Message.OptionLengthExtendedBits);
                }

                writer.WriteBytes(option.Value);
                lastOptionNumber = (int)option.Number;
            }

            return(writer.GetBytes());
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
0
        public void Should_throw_exception_when_version_is_incorrect()
        {
            var writer = new DatagramWriter();

            writer.Write(0, Message.VersionBits);
            writer.Write((int)MessageType.Confirmable, Message.TypeBits);
            writer.Write(0, Message.OptionCountBits);
            writer.Write((int)CodeRegistry.Get, Message.CodeBits);
            writer.Write(1, Message.IdBits);
            var bytes = writer.GetBytes();

            _serializer.Deserialize(bytes);
        }
Ejemplo n.º 6
0
        public virtual byte[] Serialize(Message message)
        {
            var writer = new DatagramWriter();

            writer.Write(Message.Version, Message.VersionBits);
            writer.Write((int)message.Type, Message.TypeBits);
            writer.Write(message.OptionCount, Message.OptionCountBits);
            writer.Write((int)message.Code, Message.CodeBits);
            writer.Write(message.Id, Message.IdBits);
            writer.WriteBytes(GetOptions(message.Options));
            writer.WriteBytes(message.Payload);
            return(writer.GetBytes());
        }
Ejemplo n.º 7
0
        public void TestAlignedBytes()
        {
            Byte[] bytesIn = System.Text.Encoding.UTF8.GetBytes("Some aligned bytes");

            DatagramWriter writer = new DatagramWriter();

            writer.WriteBytes(bytesIn);

            DatagramReader reader = new DatagramReader(writer.ToByteArray());

            Byte[] bytesOut = reader.ReadBytesLeft();

            Assert.IsSequenceEqualTo(bytesIn, bytesOut);
        }
Ejemplo n.º 8
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);
            }
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
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);
        }
Ejemplo n.º 12
0
            protected override void Serialize(DatagramWriter writer, Message msg, Int32 code)
            {
                // write fixed-size CoAP headers
                writer.Write(Version, VersionBits);
                writer.Write((Int32)msg.Type, TypeBits);
                writer.Write(msg.Token == null ? 0 : msg.Token.Length, TokenLengthBits);
                writer.Write(code, CodeBits);
                writer.Write(msg.ID, IDBits);

                // write token, which may be 0 to 8 bytes, given by token length field
                writer.WriteBytes(msg.Token);

                Int32 lastOptionNumber       = 0;
                IEnumerable <Option> options = msg.GetOptions();

                foreach (Option opt in options)
                {
                    // write 4-bit option delta
                    Int32 optNum            = (Int32)opt.Type;
                    Int32 optionDelta       = optNum - lastOptionNumber;
                    Int32 optionDeltaNibble = GetOptionNibble(optionDelta);
                    writer.Write(optionDeltaNibble, OptionDeltaBits);

                    // write 4-bit option length
                    Int32 optionLength       = opt.Length;
                    Int32 optionLengthNibble = GetOptionNibble(optionLength);
                    writer.Write(optionLengthNibble, OptionLengthBits);

                    // write extended option delta field (0 - 2 bytes)
                    if (optionDeltaNibble == 13)
                    {
                        writer.Write(optionDelta - 13, 8);
                    }
                    else if (optionDeltaNibble == 14)
                    {
                        writer.Write(optionDelta - 269, 16);
                    }

                    // write extended option length field (0 - 2 bytes)
                    if (optionLengthNibble == 13)
                    {
                        writer.Write(optionLength - 13, 8);
                    }
                    else if (optionLengthNibble == 14)
                    {
                        writer.Write(optionLength - 269, 16);
                    }

                    // write option value
                    writer.WriteBytes(opt.RawValue);

                    // update last option number
                    lastOptionNumber = optNum;
                }

                Byte[] payload = msg.Payload;
                if (payload != null && payload.Length > 0)
                {
                    // if payload is present and of non-zero length, it is prefixed by
                    // an one-byte Payload Marker (0xFF) which indicates the end of
                    // options and the start of the payload
                    writer.WriteByte(PayloadMarker);
                    writer.WriteBytes(payload);
                }
            }
Ejemplo n.º 13
0
 public void SetUp()
 {
     _writer = new DatagramWriter();
 }
Ejemplo n.º 14
0
        public Byte[] Encode(Message msg)
#endif
        {
            // create datagram writer to encode options
            DatagramWriter optWriter        = new DatagramWriter();
            Int32          optionCount      = 0;
            Int32          lastOptionNumber = 0;

            List <Option> options = (List <Option>)msg.GetOptions();

            Sort.InsertionSort(options, delegate(Option o1, Option o2)
            {
                return(GetOptionNumber(o1.Type).CompareTo(GetOptionNumber(o2.Type)));
            });

            foreach (Option opt in options)
            {
                if (opt.IsDefault)
                {
                    continue;
                }

                Option opt2 = opt;

                Int32 optNum      = GetOptionNumber(opt2.Type);
                Int32 optionDelta = optNum - lastOptionNumber;

                // ensure that option delta value can be encoded correctly
                while (optionDelta > MaxOptionDelta)
                {
                    // option delta is too large to be encoded:
                    // add fencepost options in order to reduce the option delta
                    // get fencepost option that is next to the last option
                    Int32 fencepostNumber = NextFencepost(lastOptionNumber);

                    // calculate fencepost delta
                    Int32 fencepostDelta = fencepostNumber - lastOptionNumber;
                    if (fencepostDelta <= 0)
                    {
                        if (log.IsWarnEnabled)
                        {
                            log.Warn("Fencepost liveness violated: delta = " + fencepostDelta);
                        }
                    }
                    if (fencepostDelta > MaxOptionDelta)
                    {
                        if (log.IsWarnEnabled)
                        {
                            log.Warn("Fencepost safety violated: delta = " + fencepostDelta);
                        }
                    }

                    // write fencepost option delta
                    optWriter.Write(fencepostDelta, OptionDeltaBits);
                    // fencepost have an empty value
                    optWriter.Write(0, OptionLengthBaseBits);

                    ++optionCount;
                    lastOptionNumber = fencepostNumber;
                    optionDelta     -= fencepostDelta;
                }

                // write option delta
                optWriter.Write(optionDelta, OptionDeltaBits);

                if (opt2.Type == OptionType.ContentType)
                {
                    Int32 ct  = opt2.IntValue;
                    Int32 ct2 = MapOutMediaType(ct);
                    if (ct != ct2)
                    {
                        opt2 = Option.Create(opt2.Type, ct2);
                    }
                }

                // write option length
                Int32 length = opt2.Length;
                if (length <= MaxOptionLengthBase)
                {
                    // use option length base field only to encode
                    // option lengths less or equal than MAX_OPTIONLENGTH_BASE
                    optWriter.Write(length, OptionLengthBaseBits);
                }
                else
                {
                    // use both option length base and extended field
                    // to encode option lengths greater than MAX_OPTIONLENGTH_BASE
                    Int32 baseLength = MaxOptionLengthBase + 1;
                    optWriter.Write(baseLength, OptionLengthBaseBits);

                    Int32 extLength = length - baseLength;
                    optWriter.Write(extLength, OptionLengthExtendedBits);
                }

                // write option value
                optWriter.WriteBytes(opt2.RawValue);

                ++optionCount;
                lastOptionNumber = optNum;
            }

            // create datagram writer to encode message data
            DatagramWriter writer = new DatagramWriter();

            // write fixed-size CoAP headers
            writer.Write(msg.Version, VersionBits);
            writer.Write((Int32)msg.Type, TypeBits);
            writer.Write(optionCount, OptionCountBits);
            writer.Write(MapOutCode(msg.Code), CodeBits);
            writer.Write(msg.ID, IDBits);

            // write options
            writer.WriteBytes(optWriter.ToByteArray());

            //write payload
            writer.WriteBytes(msg.Payload);

            return(writer.ToByteArray());
        }
Ejemplo n.º 15
0
        public Byte[] Encode(Message msg)
#endif
        {
            // create datagram writer to encode options
            DatagramWriter optWriter        = new DatagramWriter();
            Int32          optionCount      = 0;
            Int32          lastOptionNumber = 0;

            List <Option> options = (List <Option>)msg.GetOptions();

            Sort.InsertionSort(options, delegate(Option o1, Option o2)
            {
                return(GetOptionNumber(o1.Type).CompareTo(GetOptionNumber(o2.Type)));
            });

            foreach (Option opt in options)
            {
                if (opt.IsDefault)
                {
                    continue;
                }

                Int32 optNum      = GetOptionNumber(opt.Type);
                Int32 optionDelta = optNum - lastOptionNumber;

                /*
                 * The Option Jump mechanism is used when the delta to the next option
                 * number is larger than 14.
                 */
                if (optionDelta > MaxOptionDelta)
                {
                    /*
                     * For the formats that include an Option Jump Value, the actual
                     * addition to the current Option number is computed as follows:
                     * Delta = ((Option Jump Value) + N) * 8 where N is 2 for the
                     * one-byte version and N is 258 for the two-byte version.
                     */
                    if (optionDelta < 30)
                    {
                        optWriter.Write(0xF1, SingleOptionJumpBits);
                        optionDelta -= 15;
                    }
                    else if (optionDelta < 2064)
                    {
                        Int32 optionJumpValue = (optionDelta / 8) - 2;
                        optionDelta -= (optionJumpValue + 2) * 8;
                        optWriter.Write(0xF2, SingleOptionJumpBits);
                        optWriter.Write(optionJumpValue, SingleOptionJumpBits);
                    }
                    else if (optionDelta < 526359)
                    {
                        optionDelta = Math.Min(optionDelta, 526344); // Limit to avoid overflow
                        Int32 optionJumpValue = (optionDelta / 8) - 258;
                        optionDelta -= (optionJumpValue + 258) * 8;
                        optWriter.Write(0xF3, SingleOptionJumpBits);
                        optWriter.Write(optionJumpValue, 2 * SingleOptionJumpBits);
                    }
                    else
                    {
                        throw new Exception("Option delta too large. Actual delta: " + optionDelta);
                    }
                }

                // write option delta
                optWriter.Write(optionDelta, OptionDeltaBits);

                // write option length
                Int32 length = opt.Length;
                if (length <= MaxOptionLengthBase)
                {
                    // use option length base field only to encode
                    // option lengths less or equal than MAX_OPTIONLENGTH_BASE
                    optWriter.Write(length, OptionLengthBaseBits);
                }
                else if (length <= 1034)
                {
                    /*
                     * 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". Options that are
                     * longer than 1034 bytes MUST NOT be sent
                     */
                    optWriter.Write(15, OptionLengthBaseBits);

                    Int32 rounds = (length - 15) / 255;
                    for (Int32 i = 0; i < rounds; i++)
                    {
                        optWriter.Write(255, OptionLengthExtendedBits);
                    }
                    Int32 remainingLength = length - ((rounds * 255) + 15);
                    optWriter.Write(remainingLength, OptionLengthExtendedBits);
                }
                else
                {
                    throw new Exception("Option length larger than allowed 1034. Actual length: " + length);
                }

                // write option value
                if (length > 0)
                {
                    optWriter.WriteBytes(opt.RawValue);
                }

                ++optionCount;
                lastOptionNumber = optNum;
            }

            // create datagram writer to encode message data
            DatagramWriter writer = new DatagramWriter();

            // write fixed-size CoAP headers
            writer.Write(msg.Version, VersionBits);
            writer.Write((Int32)msg.Type, TypeBits);
            if (optionCount < 15)
            {
                writer.Write(optionCount, OptionCountBits);
            }
            else
            {
                writer.Write(15, OptionCountBits);
            }
            writer.Write(msg.Code, CodeBits);
            writer.Write(msg.ID, IDBits);

            // write options
            writer.WriteBytes(optWriter.ToByteArray());

            if (optionCount > 14)
            {
                // end-of-options marker when there are more than 14 options
                writer.Write(0xf0, 8);
            }

            //write payload
            writer.WriteBytes(msg.Payload);

            return(writer.ToByteArray());
        }
Ejemplo n.º 16
0
        public Byte[] Encode(Message msg)
#endif
        {
            // create datagram writer to encode message data
            DatagramWriter writer = new DatagramWriter();

            // write fixed-size CoAP headers
            writer.Write(msg.Version, VersionBits);
            writer.Write((Int32)msg.Type, TypeBits);
            writer.Write(msg.Token.Length, TokenLengthBits);
            writer.Write(msg.Code, CodeBits);
            writer.Write(msg.ID, IDBits);

            // write token, which may be 0 to 8 bytes, given by token length field
            writer.WriteBytes(msg.Token);

            Int32         lastOptionNumber = 0;
            List <Option> options          = (List <Option>)msg.GetOptions();

            Sort.InsertionSort(options, delegate(Option o1, Option o2)
            {
                return(GetOptionNumber(o1.Type).CompareTo(GetOptionNumber(o2.Type)));
            });

            foreach (Option opt in options)
            {
                if (opt.Type == OptionType.Token)
                {
                    continue;
                }
                if (opt.IsDefault)
                {
                    continue;
                }

                // write 4-bit option delta
                Int32 optNum            = GetOptionNumber(opt.Type);
                Int32 optionDelta       = optNum - lastOptionNumber;
                Int32 optionDeltaNibble = GetOptionNibble(optionDelta);
                writer.Write(optionDeltaNibble, OptionDeltaBits);

                // write 4-bit option length
                Int32 optionLength       = opt.Length;
                Int32 optionLengthNibble = GetOptionNibble(optionLength);
                writer.Write(optionLengthNibble, OptionLengthBits);

                // write extended option delta field (0 - 2 bytes)
                if (optionDeltaNibble == 13)
                {
                    writer.Write(optionDelta - 13, 8);
                }
                else if (optionDeltaNibble == 14)
                {
                    writer.Write(optionDelta - 269, 16);
                }

                // write extended option length field (0 - 2 bytes)
                if (optionLengthNibble == 13)
                {
                    writer.Write(optionLength - 13, 8);
                }
                else if (optionLengthNibble == 14)
                {
                    writer.Write(optionLength - 269, 16);
                }

                // write option value
                writer.WriteBytes(opt.RawValue);

                lastOptionNumber = optNum;
            }

            if (msg.Payload != null && msg.Payload.Length > 0)
            {
                // if payload is present and of non-zero length, it is prefixed by
                // an one-byte Payload Marker (0xFF) which indicates the end of
                // options and the start of the payload
                writer.WriteByte(PayloadMarker);
            }
            //write payload
            writer.WriteBytes(msg.Payload);

            return(writer.ToByteArray());
        }