Esempio n. 1
0
        public override async Task WriteBuffer(ByteArrayWriter Writer, int CurrentOffset)
        {
            Writer.WriteInt32(TypeReference);
            Writer.WriteInt32(ParentReference);
            Writer.WriteInt32(OwnerReference);

            await NameTableIndex.WriteBuffer(Writer, 0);

            Writer.WriteInt32(ArchetypeReference);

            Writer.WriteUInt32(FlagsHigh);
            Writer.WriteUInt32(FlagsLow);

            Writer.WriteInt32(BuilderSerialDataSize);
            Writer.WriteInt32(BuilderSerialDataOffset);

            Writer.WriteUInt32(ExportFlags);

            Writer.WriteInt32(NetObjectCount);

            await Writer.WriteBytes(Guid);

            Writer.WriteUInt32(Unknown1);

            await Writer.WriteBytes(Unknown2);
        }
Esempio n. 2
0
        public override async Task WriteBuffer(ByteArrayWriter Writer, int CurrentOffset)
        {
            Writer.WriteInt32(Size);

            if (Size < 0)
            {
                await Writer.WriteBytes(Encoding.Unicode.GetBytes(String));
            }
            else
            {
                await Writer.WriteBytes(Encoding.ASCII.GetBytes(String));

                Writer.WriteByte(0);
            }
        }
Esempio n. 3
0
        void IProtocolCodec.ServerEncode(CommDataBase data)
        {
            ModbusServer    ownerProtocol    = (ModbusServer)data.OwnerProtocol;
            ModbusCommand   userData         = (ModbusCommand)data.UserData;
            byte            functionCode     = userData.FunctionCode;
            ByteArrayWriter byteArrayWriter1 = new ByteArrayWriter();

            ModbusCodecBase.CommandCodecs[(int)functionCode]?.ServerEncode(userData, byteArrayWriter1);
            int             num = userData.ExceptionCode == (byte)0 ? 2 + byteArrayWriter1.Length : 3;
            ByteArrayWriter byteArrayWriter2 = new ByteArrayWriter();

            byteArrayWriter2.WriteUInt16BE((ushort)userData.TransId);
            byteArrayWriter2.WriteInt16BE((short)0);
            byteArrayWriter2.WriteInt16BE((short)num);
            byteArrayWriter2.WriteByte(ownerProtocol.Address);
            if (userData.ExceptionCode == (byte)0)
            {
                byteArrayWriter2.WriteByte(userData.FunctionCode);
                byteArrayWriter2.WriteBytes(byteArrayWriter1);
            }
            else
            {
                byteArrayWriter2.WriteByte((byte)((uint)userData.FunctionCode | 128U));
                byteArrayWriter2.WriteByte(userData.ExceptionCode);
            }
            data.OutgoingData = byteArrayWriter2.ToReader();
        }
Esempio n. 4
0
        public void GetPosition_AfterWriteBytes(bool alwaysCopyInputData)
        {
            IByteArrayWriter writer = new ByteArrayWriter(alwaysCopyInputData);

            writer.WriteBytes(100, 100);
            Assert.AreEqual(2, writer.Position);
        }
Esempio n. 5
0
        void IProtocolCodec.ServerEncode(CommDataBase data)
        {
            ModbusServer    ownerProtocol    = (ModbusServer)data.OwnerProtocol;
            ModbusCommand   userData         = (ModbusCommand)data.UserData;
            byte            functionCode     = userData.FunctionCode;
            ByteArrayWriter byteArrayWriter1 = new ByteArrayWriter();

            ModbusCodecBase.CommandCodecs[(int)functionCode]?.ServerEncode(userData, byteArrayWriter1);
            if (userData.ExceptionCode == (byte)0)
            {
                int length = byteArrayWriter1.Length;
            }
            ByteArrayWriter byteArrayWriter2 = new ByteArrayWriter();

            byteArrayWriter2.WriteByte(ownerProtocol.Address);
            if (userData.ExceptionCode == (byte)0)
            {
                byteArrayWriter2.WriteByte(userData.FunctionCode);
                byteArrayWriter2.WriteBytes(byteArrayWriter1);
            }
            else
            {
                byteArrayWriter2.WriteByte((byte)((uint)userData.FunctionCode | 128U));
                byteArrayWriter2.WriteByte(userData.ExceptionCode);
            }
            ushort num = ByteArrayHelpers.CalcCRC16(byteArrayWriter2.ToArray(), 0, byteArrayWriter2.Length);

            byteArrayWriter2.WriteInt16LE((short)num);
            data.OutgoingData = byteArrayWriter2.ToReader();
        }
Esempio n. 6
0
        void IProtocolCodec.ClientEncode(CommDataBase data)
        {
            var client = (ModbusClient)data.OwnerProtocol;
            var command = (ModbusCommand)data.UserData;
            var fncode = command.FunctionCode;

            //encode the command body, if applies
            var body = new ByteArrayWriter();
            var codec = CommandCodecs[fncode];
            if (codec != null)
                codec.ClientEncode(command, body);

            //create a writer for the outgoing data
            var writer = new ByteArrayWriter();

            //unit identifier (address)
            writer.WriteByte(client.Address);

            //function code
            writer.WriteByte(fncode);

            //body data
            writer.WriteBytes(body);

            //CRC-16
            ushort crc = ByteArrayHelpers.CalcCRC16(
                writer.ToArray(),
                0,
                writer.Length);

            writer.WriteInt16LE((short)crc);

            data.OutgoingData = writer.ToReader();
        }
Esempio n. 7
0
        void IProtocolCodec.ServerEncode(CommDataBase data)
        {
            var server  = (ModbusServer)data.OwnerProtocol;
            var command = (ModbusCommand)data.UserData;
            var fncode  = command.FunctionCode;

            //encode the command body, if applies
            var body  = new ByteArrayWriter();
            var codec = CommandCodecs[fncode];

            if (codec != null)
            {
                codec.ServerEncode(command, body);
            }

            //calculate length field
            var length = (command.ExceptionCode == 0)
                ? 2 + body.Length
                : 3;

            //create a writer for the outgoing data
            var writer = new ByteArrayWriter();

            //unit identifier (address)
            writer.WriteByte(server.Address);

            if (command.ExceptionCode == 0)
            {
                //function code
                writer.WriteByte(fncode);

                //body data
                writer.WriteBytes(body);
            }
            else
            {
                //function code
                writer.WriteByte((byte)(command.FunctionCode | 0x80));

                //exception code
                writer.WriteByte(command.ExceptionCode);
            }

            //CRC-16
            ushort crc;

            unchecked
            {
                crc = (ushort)ModbusRtuCodec.Crc16.Compute(
                    ((IByteArray)writer).Data,
                    0,
                    writer.Length);
            }

            writer.WriteUInt16LE(crc);

            data.OutgoingData = writer.ToReader();
        }
Esempio n. 8
0
        public void GetBytes_AfterWrite1ByteWithoutOffsetCount()
        {
            IByteArrayWriter writer = new ByteArrayWriter(true);

            writer.WriteBytes(30);

            byte[] output = writer.GetBytes();
            Assert.AreEqual(1, output.Length);
            Assert.AreEqual(30, output[0]);
        }
Esempio n. 9
0
        /// <summary>
        /// Entry-point for submitting a query to the remote device
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public CommResponse Query(ClientCommData data)
        {
            //convert the request data as an ordinary byte array
            byte[] outgoing = data
                              .OutgoingData
                              .ToArray();

            int totalTimeout = this.Latency + data.Timeout;

            //retries loop
            for (int attempt = 0, retries = data.Retries; attempt < retries; attempt++)
            {
                //phyiscal writing
                this.Send(outgoing);

                //create a writer for accumulate the incoming data
                var incoming = new ByteArrayWriter();

                //read the incoming data from the physical port
                incoming.WriteBytes(
                    this.Receive(totalTimeout)
                    );

                //try to decode the stream
                data.IncomingData = incoming.ToReader();

                CommResponse result = data
                                      .OwnerProtocol
                                      .Codec
                                      .ClientDecode(data);

                //exit whether any concrete result: either good or bad
                if (result.Status == CommResponse.Ack)
                {
                    return(result);
                }
                else if (result.Status == CommResponse.Critical)
                {
                    return(result);
                }
                else if (result.Status != CommResponse.Unknown)
                {
                    break;
                }

                //stop immediately if the host asked to abort

                //TODO
            }       //for

            //no attempt was successful
            return(new CommResponse(
                       data,
                       CommResponse.Critical));
        }
Esempio n. 10
0
        private async Task writeUpkHeader()
        {
            writer.Seek(0);

            writer.WriteUInt32(Signature);

            writer.WriteUInt16(Version);
            writer.WriteUInt16(Licensee);

            writer.WriteInt32(BuilderSize);

            await Group.WriteBuffer(writer, 0);

            writer.WriteUInt32(Flags);

            writer.WriteInt32(NameTable.Count);
            writer.WriteInt32(BuilderNameTableOffset);

            writer.WriteInt32(ExportTable.Count);
            writer.WriteInt32(BuilderExportTableOffset);

            writer.WriteInt32(ImportTable.Count);
            writer.WriteInt32(BuilderImportTableOffset);

            writer.WriteInt32(BuilderDependsTableOffset);

            writer.WriteBytes(Guid);

            writer.WriteInt32(GenerationTable.Count);

            await writeGenerationTable();

            writer.WriteUInt32(EngineVersion);
            writer.WriteUInt32(CookerVersion);

            writer.WriteUInt32(CompressionFlags);

            writer.WriteInt32(CompressedChunks.Count);

            writer.WriteUInt32(Unknown1);
            writer.WriteUInt32(Unknown2);
        }
Esempio n. 11
0
        void IProtocolCodec.ServerEncode(CommDataBase data)
        {
            var server  = (ModbusServer)data.OwnerProtocol;
            var command = (ModbusCommand)data.UserData;
            var fncode  = command.FunctionCode;

            //encode the command body, if applies
            var body  = new ByteArrayWriter();
            var codec = CommandCodecs[fncode];

            if (codec != null)
            {
                codec.ServerEncode(command, body);
            }

            //calculate length field
            var length = (command.ExceptionCode == 0)
                ? 2 + body.Length
                : 3;

            //create a writer for the outgoing data
            var writer = new ByteArrayWriter();

            //transaction-id
            writer.WriteUInt16BE((ushort)command.TransId);

            //protocol-identifier
            writer.WriteInt16BE(0);

            //message length
            writer.WriteInt16BE((short)length);

            //unit identifier (address)
            writer.WriteByte(data.Address);

            if (command.ExceptionCode == 0)
            {
                //function code
                writer.WriteByte(command.FunctionCode);

                //body data
                writer.WriteBytes(body);
            }
            else
            {
                //function code
                writer.WriteByte((byte)(command.FunctionCode | 0x80));

                //exception code
                writer.WriteByte(command.ExceptionCode);
            }

            data.OutgoingData = writer.ToReader();
        }
Esempio n. 12
0
        public void GetBytes_AfterWrite2Bytes3Offset(bool alwaysCopyInputData)
        {
            byte[]           data   = new byte[] { 1, 2, 3, 4, 5 };
            IByteArrayWriter writer = new ByteArrayWriter(alwaysCopyInputData);

            writer.WriteBytes(data, 3, 2);

            byte[] output = writer.GetBytes();
            Assert.AreEqual(2, output.Length);
            Assert.AreEqual(4, output[0]);
            Assert.AreEqual(5, output[1]);
        }
Esempio n. 13
0
        public void WriteGetBytes_4BytesWithoutOffsetCount()
        {
            IByteArrayWriter writer = new ByteArrayWriter(true);

            writer.WriteBytes(10, 20, 30, 40);

            byte[] output = writer.GetBytes();
            Assert.AreEqual(4, output.Length);
            Assert.AreEqual(10, output[0]);
            Assert.AreEqual(20, output[1]);
            Assert.AreEqual(30, output[2]);
            Assert.AreEqual(40, output[3]);
        }
Esempio n. 14
0
        void IProtocolCodec.ClientEncode(CommDataBase data)
        {
            ModbusClient    ownerProtocol    = (ModbusClient)data.OwnerProtocol;
            ModbusCommand   userData         = (ModbusCommand)data.UserData;
            byte            functionCode     = userData.FunctionCode;
            ByteArrayWriter byteArrayWriter1 = new ByteArrayWriter();

            ModbusCodecBase.CommandCodecs[(int)functionCode]?.ClientEncode(userData, byteArrayWriter1);
            ByteArrayWriter byteArrayWriter2 = new ByteArrayWriter();

            byteArrayWriter2.WriteByte(ownerProtocol.Address);
            byteArrayWriter2.WriteByte(functionCode);
            byteArrayWriter2.WriteBytes(byteArrayWriter1);
            ushort num = ByteArrayHelpers.CalcCRC16(byteArrayWriter2.ToArray(), 0, byteArrayWriter2.Length);

            byteArrayWriter2.WriteInt16LE((short)num);
            data.OutgoingData = byteArrayWriter2.ToReader();
        }
Esempio n. 15
0
        public override async Task WriteBuffer(ByteArrayWriter Writer, int CurrentOffset)
        {
            await PropertyHeader.WriteBuffer(Writer, CurrentOffset);

            await base.WriteBuffer(Writer, CurrentOffset);

            Writer.WriteInt32(MipMaps.Count);

            for (int i = 0; i < MipMaps.Count; ++i)
            {
                await CompressedChunks[i].WriteCompressedChunk(Writer, CurrentOffset);

                Writer.WriteInt32(MipMaps[i].Width);
                Writer.WriteInt32(MipMaps[i].Height);
            }

            await Writer.WriteBytes(Guid);
        }
Esempio n. 16
0
        void IProtocolCodec.ClientEncode(CommDataBase data)
        {
            ModbusClient    ownerProtocol    = (ModbusClient)data.OwnerProtocol;
            ModbusCommand   userData         = (ModbusCommand)data.UserData;
            byte            functionCode     = userData.FunctionCode;
            ByteArrayWriter byteArrayWriter1 = new ByteArrayWriter();

            ModbusCodecBase.CommandCodecs[(int)functionCode]?.ClientEncode(userData, byteArrayWriter1);
            int             num = 2 + byteArrayWriter1.Length;
            ByteArrayWriter byteArrayWriter2 = new ByteArrayWriter();

            byteArrayWriter2.WriteUInt16BE((ushort)userData.TransId);
            byteArrayWriter2.WriteInt16BE((short)0);
            byteArrayWriter2.WriteInt16BE((short)num);
            byteArrayWriter2.WriteByte(ownerProtocol.Address);
            byteArrayWriter2.WriteByte(functionCode);
            byteArrayWriter2.WriteBytes(byteArrayWriter1);
            data.OutgoingData = byteArrayWriter2.ToReader();
        }
Esempio n. 17
0
        void IProtocolCodec.ClientEncode(CommDataBase data)
        {
            var client  = (ModbusClient)data.OwnerProtocol;
            var command = (ModbusCommand)data.UserData;
            var fncode  = command.FunctionCode;

            //encode the command body, if applies
            var body  = new ByteArrayWriter();
            var codec = CommandCodecs[fncode];

            if (codec != null)
            {
                codec.ClientEncode(command, body);
            }

            //create a writer for the outgoing data
            var writer = new ByteArrayWriter();

            //unit identifier (address)
            writer.WriteByte(client.Address);

            //function code
            writer.WriteByte(fncode);

            //body data
            writer.WriteBytes(body);

            //CRC-16
            ushort crc;

            unchecked
            {
                crc = (ushort)ModbusRtuCodec.Crc16.Compute(
                    ((IByteArray)writer).Data,
                    0,
                    writer.Length
                    );
            }

            writer.WriteUInt16LE(crc);

            data.OutgoingData = writer.ToReader();
        }
Esempio n. 18
0
        void IProtocolCodec.ClientEncode(CommDataBase data)
        {
            var client  = (ModbusClient)data.OwnerProtocol;
            var command = (ModbusCommand)data.UserData;
            var fncode  = command.FunctionCode;

            //encode the command body, if applies
            var body  = new ByteArrayWriter();
            var codec = CommandCodecs[fncode];

            if (codec != null)
            {
                codec.ClientEncode(command, body);
            }

            //calculate length field
            var length = 2 + body.Length;

            //create a writer for the outgoing data
            var writer = new ByteArrayWriter();

            //transaction-id
            writer.WriteUInt16BE((ushort)command.TransId);

            //protocol-identifier (always zero)
            writer.WriteInt16BE(0);

            //message length
            writer.WriteInt16BE((short)length);

            //unit identifier (address)
            writer.WriteByte(client.Address);

            //function code
            writer.WriteByte(fncode);

            //body data
            writer.WriteBytes(body);

            data.OutgoingData = writer.ToReader();
        }
Esempio n. 19
0
        void IProtocolCodec.ClientEncode(CommDataBase data)
        {
            var client = (ModbusClient)data.OwnerProtocol;
            var command = (ModbusCommand)data.UserData;
            var fncode = command.FunctionCode;

            //encode the command body, if applies
            var body = new ByteArrayWriter();
            var codec = CommandCodecs[fncode];
            if (codec != null)
                codec.ClientEncode(command, body);

            //calculate length field
            var length = 2 + body.Length;

            //create a writer for the outgoing data
            var writer = new ByteArrayWriter();

            //transaction-id 
            writer.WriteUInt16BE((ushort)command.TransId);

            //protocol-identifier (always zero)
            writer.WriteInt16BE(0);

            //message length
            writer.WriteInt16BE((short)length);

            //unit identifier (address)
            writer.WriteByte(client.Address);

            //function code
            writer.WriteByte(fncode);

            //body data
            writer.WriteBytes(body);

            data.OutgoingData = writer.ToReader();
        }
Esempio n. 20
0
        void IProtocolCodec.ClientEncode(CommDataBase data)
        {
            var client  = (ModbusClient)data.OwnerProtocol;
            var command = (ModbusCommand)data.UserData;
            var fncode  = command.FunctionCode;

            //encode the command body, if applies
            var body  = new ByteArrayWriter();
            var codec = CommandCodecs[fncode];

            if (codec != null)
            {
                codec.ClientEncode(command, body);
            }

            //create a writer for the outgoing data
            var writer = new ByteArrayWriter();

            //unit identifier (address)
            writer.WriteByte(client.Address);

            //function code
            writer.WriteByte(fncode);

            //body data
            writer.WriteBytes(body);

            //CRC-16
            ushort crc = ByteArrayHelpers.CalcCRC16(
                writer.ToArray(),
                0,
                writer.Length);

            writer.WriteInt16LE((short)crc);

            data.OutgoingData = writer.ToReader();
        }
Esempio n. 21
0
        void IProtocolCodec.ServerEncode(CommDataBase data)
        {
            var server = (ModbusServer)data.OwnerProtocol;
            var command = (ModbusCommand)data.UserData;
            var fncode = command.FunctionCode;

            //encode the command body, if applies
            var body = new ByteArrayWriter();
            var codec = CommandCodecs[fncode];
            if (codec != null)
                codec.ServerEncode(command, body);

            //calculate length field
            var length = (command.ExceptionCode == 0)
                ? 2 + body.Length
                : 3;

            //create a writer for the outgoing data
            var writer = new ByteArrayWriter();

            //unit identifier (address)
            writer.WriteByte(server.Address);

            if (command.ExceptionCode == 0)
            {
                //function code
                writer.WriteByte(command.FunctionCode);

                //body data
                writer.WriteBytes(body);
            }
            else
            {
                //function code
                writer.WriteByte((byte)(command.FunctionCode | 0x80));

                //exception code
                writer.WriteByte(command.ExceptionCode);
            }

            //CRC-16
            ushort crc = ByteArrayHelpers.CalcCRC16(
                writer.ToArray(),
                0,
                writer.Length);

            writer.WriteInt16LE((short)crc);

            data.OutgoingData = writer.ToReader();
        }
 public async Task WriteCompressedChunkBlockData(ByteArrayWriter Writer)
 {
     await Writer.WriteBytes(CompressedData.GetBytes());
 }
Esempio n. 23
0
        void IProtocolCodec.ServerEncode(CommDataBase data)
        {
            var server = (ModbusServer)data.OwnerProtocol;
            var command = (ModbusCommand)data.UserData;
            var fncode = command.FunctionCode;

            //encode the command body, if applies
            var body = new ByteArrayWriter();
            var codec = CommandCodecs[fncode];
            if (codec != null)
                codec.ServerEncode(command, body);

            //calculate length field
            var length = (command.ExceptionCode == 0)
                ? 2 + body.Length
                : 3;

            //create a writer for the outgoing data
            var writer = new ByteArrayWriter();

            //transaction-id
            writer.WriteUInt16BE((ushort)command.TransId);

            //protocol-identifier
            writer.WriteInt16BE(0);

            //message length
            writer.WriteInt16BE((short)length);

            //unit identifier (address)
            writer.WriteByte(server.Address);

            if (command.ExceptionCode == 0)
            {
                //function code
                writer.WriteByte(command.FunctionCode);

                //body data
                writer.WriteBytes(body);
            }
            else
            {
                //function code
                writer.WriteByte((byte)(command.FunctionCode | 0x80));

                //exception code
                writer.WriteByte(command.ExceptionCode);
            }

            data.OutgoingData = writer.ToReader();
        }
Esempio n. 24
0
 public override async Task WriteBuffer(ByteArrayWriter Writer, int CurrentOffset)
 {
     Writer.WriteBytes(DataReader?.GetBytes());
 }
Esempio n. 25
0
        public override async Task WriteBuffer(ByteArrayWriter Writer, int CurrentOffset)
        {
            await PropertyHeader.WriteBuffer(Writer, CurrentOffset);

            await Writer.WriteBytes(AdditionalDataReader?.GetBytes());
        }
Esempio n. 26
0
        public override async Task WriteBuffer(ByteArrayWriter Writer, int CurrentOffset)
        {
            Writer.WriteBytes(Unknown1);

            Writer.WriteInt32(CurrentOffset + Writer.Index + sizeof(int));
        }
Esempio n. 27
0
        /// <summary>
        /// Entry-point for submitting a query to the remote device
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public CommResponse Query(ClientCommData data)
        {
            lock (this.Port)
            {
                //convert the request data as an ordinary byte array
                byte[] outgoing = ((IByteArray)data.OutgoingData).Data;

                //create a writer for accumulate the incoming data
                var incoming = new ByteArrayWriter();

                const int tempSize = 64;
                var       temp     = new byte[tempSize];

                //retries loop
                for (int attempt = 0, retries = data.Retries; attempt < retries; attempt++)
                {
                    //phyiscal writing
                    this.Port
                    .Send(outgoing);

                    incoming.Drop();

                    //start the local timer
                    bool timeoutExpired;
                    int  totalTimeout = this.Latency + data.Timeout;

                    using (Timer timer = new Timer(
                               _ => timeoutExpired = true,
                               state: null,
                               dueTime: totalTimeout,
                               period: Timeout.Infinite))
                    {
                        //reception loop, until a valid response or timeout
                        timeoutExpired = false;
                        while (timeoutExpired == false)
                        {
                            var length = this.Port.Available;

                            if (length > 0)
                            {
                                if (length > tempSize)
                                {
                                    length = tempSize;
                                }

                                //read the incoming data from the physical port
                                this.Port
                                .Receive(temp, length, SocketFlags.None);

                                //append data to the writer
                                incoming.WriteBytes(
                                    temp,
                                    0,
                                    length);

                                //try to decode the stream
                                data.IncomingData = incoming.ToReader();

                                CommResponse result = data
                                                      .OwnerProtocol
                                                      .Codec
                                                      .ClientDecode(data);

                                //exit whether any concrete result: either good or bad
                                if (result.Status == CommResponse.Ack)
                                {
                                    return(result);
                                }
                                else if (result.Status == CommResponse.Critical)
                                {
                                    return(result);
                                }
                                else if (result.Status != CommResponse.Unknown)
                                {
                                    break;
                                }
                            }

                            Thread.Sleep(0);

                            //stop immediately if the host asked to abort

                            //TODO
                        }
                    }   //using (timer)
                }       //for

                //no attempt was successful
                return(new CommResponse(
                           data,
                           CommResponse.Critical));
            }   //lock
        }
Esempio n. 28
0
        /// <summary>
        /// Entry-point for submitting a query to the remote device
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public CommResponse Query(ClientCommData data)
        {
            lock (this.Port)
            {
                try
                {
                    //set the proper parameters to the port
                    this.Port.BaudRate  = this.Setting.BaudRate;
                    this.Port.Parity    = this.Setting.Parity;
                    this.Port.DataBits  = this.Setting.DataBits;
                    this.Port.StopBits  = this.Setting.StopBits;
                    this.Port.RtsEnable = this.Setting.RtsEnable;
                }
                catch (Exception ex)
                {
                    return(new CommResponse(
                               data,
                               CommResponse.Critical,
                               ex.Message));
                }

                //convert the request data as an ordinary byte array
                byte[] outgoing = ((IByteArray)data.OutgoingData).Data;

                //create a writer for accumulate the incoming data
                var incoming = new ByteArrayWriter();

                const int tempSize = 64;
                var       temp     = new byte[tempSize];

                //retries loop
                for (int attempt = 0, retries = data.Retries; attempt < retries; attempt++)
                {
                    try
                    {
                        //flush any residual content
                        this.Port
                        .DiscardInBuffer();

                        this.Port
                        .DiscardOutBuffer();

#if NET45
                        //System.Diagnostics.Trace.WriteLine("TX: " + ByteArrayHelpers.ToHex(outgoing));
#endif

                        //phyiscal writing
                        this.Port.WriteTimeout = 500;
                        this.Port
                        .Write(outgoing, 0, outgoing.Length);
                    }
                    catch (Exception ex)
                    {
                        return(new CommResponse(
                                   data,
                                   CommResponse.Critical,
                                   ex.Message));
                    }

                    incoming.Drop();

                    //start the local timer
                    bool timeoutExpired;
                    int  totalTimeout = this.Latency + data.Timeout;

                    using (Timer timer = new Timer(
                               _ => timeoutExpired = true,
                               state: null,
                               dueTime: totalTimeout,
                               period: Timeout.Infinite))
                    {
                        //reception loop, until a valid response or timeout
                        timeoutExpired = false;
                        while (timeoutExpired == false)
                        {
                            int length = this.Port.BytesToRead;

                            if (length > 0)
                            {
                                if (length > tempSize)
                                {
                                    length = tempSize;
                                }

                                try
                                {
                                    //read the incoming data from the physical port
                                    this.Port
                                    .Read(temp, 0, length);
                                }
                                catch (Exception ex)
                                {
                                    return(new CommResponse(
                                               data,
                                               CommResponse.Critical,
                                               ex.Message));
                                }

                                //append data to the writer
                                incoming.WriteBytes(
                                    temp,
                                    0,
                                    length);

                                //try to decode the stream
                                data.IncomingData = incoming.ToReader();

#if NET45
                                //System.Diagnostics.Trace.WriteLine("RX: " + ByteArrayHelpers.ToHex(incoming.ToByteArray()));
#endif

                                CommResponse result = data
                                                      .OwnerProtocol
                                                      .Codec
                                                      .ClientDecode(data);

                                //exit whether any concrete result: either good or bad
                                if (result.Status == CommResponse.Ack)
                                {
                                    return(result);
                                }
                                else if (result.Status == CommResponse.Critical)
                                {
                                    return(result);
                                }
                                else if (result.Status != CommResponse.Unknown)
                                {
                                    break;
                                }
                            }

                            Thread.Sleep(0);

                            //stop immediately if the host asked to abort

                            //TODO
                        }
                    }   //using (timer)
                }       //for

                //no attempt was successful
                return(new CommResponse(
                           data,
                           CommResponse.Critical));
            }   //lock
        }