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()); }
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); }
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); }
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); }
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); }
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()); }
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); }
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); } }
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); }
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); }
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); }
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); } }
public void SetUp() { _writer = new DatagramWriter(); }
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()); }
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()); }
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()); }