예제 #1
0
        /// <summary>
        /// Try to create an <see cref="CoapOption"/> from the option number and data.
        /// </summary>
        /// <param name="number"></param>
        /// <param name="data"></param>
        /// <returns><value>null</value> if the option is unsupported.</returns>
        /// <exception cref="CoapOptionException">If the option number is unsuppported and is critical (See RFC 7252 Section 5.4.1)</exception>
        public CoapOption Create(int number, byte[] data = null)
        {
            CoapOption option;

            // Let the exception get thrown if index is out of range
            if (_options.TryGetValue(number, out var type))
            {
                option = (CoapOption)Activator.CreateInstance(type);
            }
            else
            {
                // Critial option must be registered as they're esssential for understanding the message
                if (number % 2 == 1)
                {
                    throw new CoapOptionException($"Unsupported critical option ({number})", new ArgumentOutOfRangeException(nameof(number)));
                }

                // Return a placeholder option to give the application chance at reading them
                option = new CoapOption(number, type: OptionType.Opaque);
            }

            if (data != null)
            {
                option.FromBytes(data);
            }

            return(option);
        }
예제 #2
0
        public void TestOpaqueOption(byte[] data, int length)
        {
            var option = new CoapOption(0, type: OptionType.Opaque, maxLength: 256);

            option.ValueOpaque = new byte[] { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xF0 };
            Assert.AreEqual(8, option.Length);
            Assert.AreEqual(new byte[] { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xF0 }, option.ValueOpaque);
            Assert.AreEqual(new byte[] { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xF0 }, option.GetBytes());
        }
예제 #3
0
        public static string Convert(CoapOption option)
        {
            if (option is null)
            {
                return(string.Empty);
            }

            var name = Consts.CoapOptionTypes.SingleOrDefault(p => p.Item2 == option.GetType()).Item1
                       ?? option.GetType().Name;

            return(name);
        }
예제 #4
0
        public void TestOpaqueOption()
        {
            var option = new CoapOption(0, type: OptionType.Opaque);

            option.ValueOpaque = new byte[] { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xF0 };
            Assert.AreEqual(8, option.Length);
            Assert.AreEqual(new byte[] { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xF0 }, option.ValueOpaque);
            Assert.AreEqual(new byte[] { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xF0 }, option.GetBytes());

            option.FromBytes(new byte[] { 0xAA, 0x55, 0x11 });
            Assert.AreEqual(3, option.Length);
            Assert.AreEqual(new byte[] { 0xAA, 0x55, 0x11 }, option.ValueOpaque);
        }
예제 #5
0
        public void TestValueOption(uint value, int length, byte[] expected)
        {
            var optionToBytes = new CoapOption(0, type: OptionType.UInt, maxLength: 4);

            optionToBytes.ValueUInt = value;
            Assert.AreEqual(length, optionToBytes.Length);
            Assert.AreEqual(expected, optionToBytes.GetBytes());

            var optionFromBytes = new CoapOption(0, type: OptionType.UInt, maxLength: 4);

            optionFromBytes.FromBytes(expected);
            Assert.AreEqual(length, optionFromBytes.Length);
            Assert.AreEqual(value, optionFromBytes.ValueUInt);
        }
예제 #6
0
        public IEnumerable <CoapOption> DeserializeOptions(EndianBinaryReader reader)
        {
            var options = new List <CoapOption>();

            var nextOptionNumber = 0;

            while (!reader.EndOfStream())
            {
                var smallDeltaLength = reader.ReadByte();
                if (smallDeltaLength == 0xFF)
                {
                    break;
                }

                var delta  = (smallDeltaLength >> 4) & 0xF;
                var length = smallDeltaLength & 0xF;

                // Read extended delta
                if (delta == 13)
                {
                    var int8Delta = reader.ReadByte();
                    delta = int8Delta + 13;
                }
                else if (delta == 14)
                {
                    var int16Delta = reader.ReadUInt16();
                    delta = int16Delta + 269;
                }

                // Read extended length
                if (length == 13)
                {
                    var int8Length = reader.ReadByte();
                    length = int8Length + 13;
                }
                else if (length == 14)
                {
                    var int16Length = reader.ReadUInt16();
                    length = int16Length + 269;
                }

                var number = delta + nextOptionNumber;
                var value  = reader.ReadBytes(length);
                options.Add(CoapOption.FromNumberValue(number, value));

                nextOptionNumber = number;
            }

            return(options);
        }
예제 #7
0
        public byte[] TestMessageEncodeOptions(CoapOption option)
        {
            _message.OptionFactory = new Options.OptionFactory();
            _message.OptionFactory.Register <TestOpaqueCoapOption>();

            _message.Code = CoapMessageCode.Get;
            _message.Type = CoapMessageType.Confirmable;
            _message.Id   = 0;
            _message.Options.Add(option);
            using (var writer = new MemoryStream())
            {
                _message.Encode(writer);
                return(writer.ToArray());
            }
        }
예제 #8
0
        public void TestOptionInvalidCastException()
        {
            var option = new CoapOption(0);

            Assert.Throws <InvalidCastException>(() => _ = option.ValueString);
            Assert.Throws <InvalidCastException>(() => _ = option.ValueString = "test");

            Assert.Throws <InvalidCastException>(() => _ = option.ValueOpaque);
            Assert.Throws <InvalidCastException>(() => _ = option.ValueOpaque = Encoding.UTF8.GetBytes("test"));

            Assert.Throws <InvalidCastException>(() => _ = option.ValueUInt);
            Assert.Throws <InvalidCastException>(() => _ = option.ValueUInt = 1234);

            Assert.Throws <InvalidCastException>(() => _ = option.DefaultString);
            Assert.Throws <InvalidCastException>(() => _ = option.DefaultOpaque);
            Assert.Throws <InvalidCastException>(() => _ = option.DefaultUInt);

            option.FromBytes(null);          // No-op
            option.FromBytes(new byte[] {}); // No-op
            Assert.Throws <InvalidCastException>(() => option.FromBytes(new byte[] { 0x12 }));
        }
예제 #9
0
 public void NullOptionComapreNull(CoapOption option)
 {
     Assert.True(option.Equals(option));
 }