public static TelloDatagram DeserializeNew(byte[] buffer, int offset, int count, out TelloErrorCode errorCode)
    {
        if (buffer == null)
        {
            throw new ArgumentNullException(nameof(buffer));
        }
        if (count <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(count), count, $"Argument {nameof(count)} must be positive.");
        }
        if (buffer.Length < offset + count)
        {
            throw new ArgumentException(
                      $"The length of '{nameof(buffer)}' can't be " +
                      $"less than the sum of '{nameof(offset)}' and '{nameof(count)}'.");
        }
        var magic = buffer[offset];

        switch (magic)
        {
        case TelloCommand.Magic:
            return(TelloCommand.DeserializeNew(buffer, offset, count, out errorCode));

        default:
            var datagram = TelloAsciiDatagram.DeserializeNew(buffer, offset, count, out errorCode);
            if (errorCode == TelloErrorCode.NoError)
            {
                return(datagram);
            }
            if (errorCode == TelloErrorCode.InvalidAsciiCharacter)
            {
                errorCode = TelloErrorCode.UnsupportedMagic;
            }
            return(null);
        }
    }
Example #2
0
    public static new TelloAsciiDatagram DeserializeNew(byte[] buffer, int offset, int count, out TelloErrorCode errorCode)
    {
        if (buffer == null)
        {
            throw new ArgumentNullException(nameof(buffer));
        }
        if (count <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(count), count, $"Argument {nameof(count)} must be positive.");
        }
        if (buffer.Length < offset + count)
        {
            throw new ArgumentException(
                      $"The length of '{nameof(buffer)}' can't be " +
                      $"less than the sum of '{nameof(offset)}' and '{nameof(count)}'.");
        }
        // find the colon character in the buffer:
        int  asciiLength;
        bool found = false;

        for (asciiLength = 0; asciiLength < count; ++asciiLength)
        {
            var b = buffer[offset + asciiLength];
            found = b == (byte)':';
            if (found)
            {
                break;
            }
            else if (!IsPrintableAscii(b))
            {
                errorCode = TelloErrorCode.InvalidAsciiCharacter;
                return(null);
            }
        }
        if (!found)
        {
            errorCode = TelloErrorCode.UnexpectedAsciiSequence;
            return(null);
        }
        var text     = Encoding.ASCII.GetString(buffer, offset, asciiLength);
        var datagram = Create(text);

        errorCode = datagram.DeserializeBody(buffer, asciiLength + 1, count - asciiLength - 1);
        return(datagram);
    }
 public static TelloDatagram DeserializeNew(byte[] buffer, out TelloErrorCode errorCode)
 {
     return(DeserializeNew(buffer, 0, buffer.Length, out errorCode));
 }
    public static new TelloCommand DeserializeNew(byte[] buffer, int offset, int count, out TelloErrorCode errorCode)
    {
        if (buffer == null)
        {
            throw new ArgumentNullException(nameof(buffer));
        }
        if (buffer.Length < offset + count)
        {
            throw new ArgumentException(
                      $"The length of '{nameof(buffer)}' can't be " +
                      $"less than the sum of '{nameof(offset)}' and '{nameof(count)}'.");
        }
        if (count < HeaderSize)
        {
            errorCode = TelloErrorCode.PacketTooShort;
            return(null);
        }

        using (var reader = new BinaryReader(new MemoryStream(buffer, offset, count)))
        {
            var magic = reader.ReadByte();
            if (magic != Magic)
            {
                errorCode = TelloErrorCode.UnsupportedMagic;
                return(null);
            }
            var size         = reader.ReadUInt16() >> 3;
            var givenCrc8    = reader.ReadByte();
            var computedCrc8 = ComputeCrc8(buffer, offset, 3);
            if (givenCrc8 != computedCrc8)
            {
                errorCode = TelloErrorCode.BadCrc8;
                return(null);
            }
            var packetType = (TelloPacketType)reader.ReadByte();
            var commandId  = (TelloCommandId)reader.ReadUInt16();
            var command    = Create(packetType, commandId);
            command.SequenceNumber = reader.ReadUInt16();
            var data          = reader.ReadBytes(count - HeaderSize);
            var givenCrc16    = reader.ReadUInt16();
            var computedCrc16 = ComputeCrc16(buffer, offset, count - sizeof(UInt16));
            if (givenCrc16 != computedCrc16)
            {
                errorCode = TelloErrorCode.BadCrc16;
                return(null);
            }
            errorCode = command.DeserializeBody(data, 0, data.Length);
            return(command);
        }
    }