private IMessage ReceiveMessage(PComB pComB, List <List <byte> > readDataTablesDataRequestBytes, string parentID)
        {
            if (this.BreakFlag)
            {
                throw new ComDriveExceptions("Request aborted by user",
                                             ComDriveExceptions.ComDriveException.AbortedByUser);
            }

            GuidClass guid = new GuidClass();

            lock (guid)
            {
                Channel.Send(pComB.MessageToPLC as byte[], ReceiveBytes, guid, parentID,
                             "Binary Protocol - Read/Write Data Tables", PlcGuid);
                Monitor.Wait(guid);
            }

            if (this.BreakFlag)
            {
                throw new ComDriveExceptions("Request aborted by user",
                                             ComDriveExceptions.ComDriveException.AbortedByUser);
            }

            PlcResponseMessage plcResponseMessage;

            lock (_lockObj)
            {
                plcResponseMessage = m_responseMessageQueue[guid];
                m_responseMessageQueue.Remove(guid);
            }

            if (plcResponseMessage.comException == CommunicationException.Timeout)
            {
                throw new ComDriveExceptions("Cannot communicate with the PLC with the specified UnitID!",
                                             ComDriveExceptions.ComDriveException.CommunicationTimeout);
            }

            pComB.DisAssembleBinaryResult(plcResponseMessage.responseBytesMessage, null);

            return(pComB.MessageFromPLC);
        }
Esempio n. 2
0
        private void SplitAndSendBinaryData(ReadWriteRequest binaryRequest, string parentID)
        {
            BinaryRequest binRequest = binaryRequest as BinaryRequest;

            PComB pComB = new PComB();

            int       offsetInBuffer                = 0;
            int       chunkSize                     = 0;
            int       outgoingBufferSize            = 0;
            int       currentAddress                = binRequest.Address;
            int       messageKey                    = binRequest.MessageKey;
            const int MIN_TIME_BETWEEN_CHUNKS_WRITE = 20;

            GuidClass          guid;
            PlcResponseMessage plcResponseMessage;

            byte[] outgoingChunk;

            if (binRequest.OutgoingBuffer != null)
            {
                outgoingBufferSize = binRequest.OutgoingBuffer.Length;
            }

            switch (binRequest.CommandCode)
            {
            case 0x1:
            case 0x41:
            case 75:
            case 5:

                if ((binRequest.OutgoingBuffer == null) || (outgoingBufferSize == 0))
                {
                    binRequest.RaiseProgressEvent(0, binRequest.ElementsCount,
                                                  RequestProgress.en_NotificationType.SetMinMax, 0, "");
                    binRequest.RaiseProgressEvent(0, binRequest.ElementsCount,
                                                  RequestProgress.en_NotificationType.ProgressChanged, 0, "");

                    if (this.BreakFlag)
                    {
                        throw new ComDriveExceptions("Request aborted by user",
                                                     ComDriveExceptions.ComDriveException.AbortedByUser);
                    }

                    if (binRequest.WaitForIdle)
                    {
                        WaitForFlashIdle((byte)UnitId, parentID);
                    }


                    byte[] arrivedData = new byte[binRequest.ElementsCount];
                    while (offsetInBuffer < binRequest.ElementsCount)
                    {
                        int sizeOfDataToCopy;

                        if (this.BreakFlag)
                        {
                            throw new ComDriveExceptions("Request aborted by user",
                                                         ComDriveExceptions.ComDriveException.AbortedByUser);
                        }
                        chunkSize        = binRequest.ElementsCount - offsetInBuffer;
                        sizeOfDataToCopy = chunkSize;

                        if (chunkSize > PLCVersion.PlcBuffer - Utils.Lengths.LENGTH_HEADER_AND_FOOTER)
                        {
                            chunkSize = PLCVersion.PlcBuffer - Utils.Lengths.LENGTH_HEADER_AND_FOOTER;
                        }

                        if (binRequest.ChunkSizeAlignment != 0)
                        {
                            // Chop the end of the chunk to fit into aligment
                            chunkSize -= (chunkSize % binRequest.ChunkSizeAlignment);
                        }

                        if (binRequest.FlashBankSize != 0)
                        {
                            // Chop the end of the chunk so the burned data will not be written on 2 different flash banks
                            if (((currentAddress + chunkSize) / binRequest.FlashBankSize) !=
                                (currentAddress / binRequest.FlashBankSize))
                            {
                                chunkSize -= ((currentAddress + chunkSize) % binRequest.FlashBankSize);
                            }
                        }

                        if (chunkSize == 0)
                        {
                            chunkSize = binRequest.ChunkSizeAlignment;
                        }
                        else
                        {
                            sizeOfDataToCopy = chunkSize;
                        }


                        pComB.BuildBinaryCommand((byte)UnitId, messageKey, binRequest.CommandCode,
                                                 binRequest.SubCommand, currentAddress, chunkSize, 0, new byte[0]);

                        guid = new GuidClass();

                        lock (guid)
                        {
                            Channel.Send(pComB.MessageToPLC as byte[], ReceiveBytes, guid, parentID,
                                         "Binary Protocol - Binary Request (" + binRequest.CommandCode.ToString() + ")",
                                         PlcGuid);
                            Monitor.Wait(guid);
                        }

                        if (this.BreakFlag)
                        {
                            throw new ComDriveExceptions("Request aborted by user",
                                                         ComDriveExceptions.ComDriveException.AbortedByUser);
                        }

                        lock (_lockObj)
                        {
                            plcResponseMessage = m_responseMessageQueue[guid];
                            m_responseMessageQueue.Remove(guid);
                        }

                        if (plcResponseMessage.comException == CommunicationException.Timeout)
                        {
                            throw new ComDriveExceptions(
                                      "Cannot communicate with the PLC with the specified UnitID!",
                                      ComDriveExceptions.ComDriveException.CommunicationTimeout);
                        }

                        binRequest.IncomingBuffer =
                            new byte[plcResponseMessage.responseBytesMessage.Length -
                                     Utils.Lengths.LENGTH_HEADER_AND_FOOTER];

                        if (binRequest.IncomingBuffer.Length > 0)
                        {
                            Array.Copy(plcResponseMessage.responseBytesMessage, Utils.Lengths.LENGTH_HEADER,
                                       binRequest.IncomingBuffer, 0, binRequest.IncomingBuffer.Length);
                        }

                        Array.Copy(binRequest.IncomingBuffer, 0, arrivedData, offsetInBuffer, sizeOfDataToCopy);
                        if (plcResponseMessage.responseBytesMessage[12] == 0xFF)
                        {
                            binRequest.PlcReceiveResult =
                                (BinaryRequest.ePlcReceiveResult)plcResponseMessage.responseBytesMessage[13];
                        }
                        else if (plcResponseMessage.responseBytesMessage[12] == binRequest.CommandCode + 0x80)
                        {
                            binRequest.PlcReceiveResult = BinaryRequest.ePlcReceiveResult.Sucsess;
                        }
                        else
                        {
                            binRequest.PlcReceiveResult = BinaryRequest.ePlcReceiveResult.Unknown;
                        }

                        offsetInBuffer += sizeOfDataToCopy;
                        currentAddress += sizeOfDataToCopy;
                        messageKey++;     // Message Key is % 256. The BuildBinaryCommand takes care of that
                        binRequest.MessageKey = messageKey;
                        binRequest.MessageKey = binRequest.MessageKey % 256;

                        if (binRequest.MessageKey == 0)
                        {
                            messageKey            = binRequest.CycledMessageKey;
                            binRequest.MessageKey = messageKey;
                        }

                        if (binRequest.WaitForIdle)
                        {
                            WaitForFlashIdle((byte)UnitId, parentID);
                        }

                        binRequest.RaiseProgressEvent(0, binRequest.ElementsCount,
                                                      RequestProgress.en_NotificationType.ProgressChanged, offsetInBuffer, "");
                    }

                    binRequest.IncomingBuffer = arrivedData;
                    binRequest.RaiseProgressEvent(0, binRequest.ElementsCount,
                                                  RequestProgress.en_NotificationType.Completed, binRequest.ElementsCount, "");
                }
                else
                {
                    if (this.BreakFlag)
                    {
                        throw new ComDriveExceptions("Request aborted by user",
                                                     ComDriveExceptions.ComDriveException.AbortedByUser);
                    }

                    if (binRequest.WaitForIdle)
                    {
                        WaitForFlashIdle((byte)UnitId, parentID);
                    }

                    binRequest.RaiseProgressEvent(0, outgoingBufferSize,
                                                  RequestProgress.en_NotificationType.SetMinMax, 0, "");
                    binRequest.RaiseProgressEvent(0, outgoingBufferSize,
                                                  RequestProgress.en_NotificationType.ProgressChanged, 0, "");

                    //if (binRequest.SubCommand == (int)MemoryType.InternalFlash && binRequest.CommandCode == 0x41)
                    //{
                    //    if ((binRequest.OutgoingBuffer.Length % 8) != 0)
                    //    {
                    //        byte[] binDataToBurn = new byte[binRequest.OutgoingBuffer.Length + 8 - binRequest.OutgoingBuffer.Length % 8];
                    //        for (int i = binRequest.OutgoingBuffer.Length; i < binDataToBurn.Length; i++)
                    //        {
                    //            binDataToBurn[i] = 0xFF;
                    //        }

                    //        Array.Copy(binRequest.OutgoingBuffer, 0, binDataToBurn, 0, binRequest.OutgoingBuffer.Length);
                    //        binRequest.OutgoingBuffer = binDataToBurn;
                    //        outgoingBufferSize = binRequest.OutgoingBuffer.Length;
                    //    }
                    //}

                    Stopwatch sw = new Stopwatch();
                    sw.Start();
                    long lastTime = 0;
                    while (offsetInBuffer < outgoingBufferSize)
                    {
                        if (this.BreakFlag)
                        {
                            throw new ComDriveExceptions("Request aborted by user",
                                                         ComDriveExceptions.ComDriveException.AbortedByUser);
                        }

                        chunkSize = outgoingBufferSize - offsetInBuffer;
                        if (chunkSize > PLCVersion.PlcBuffer - Utils.Lengths.LENGTH_HEADER_AND_FOOTER)
                        {
                            chunkSize = PLCVersion.PlcBuffer - Utils.Lengths.LENGTH_HEADER_AND_FOOTER;
                        }

                        if (binRequest.ChunkSizeAlignment != 0)
                        {
                            // Chop the end of the chunk to fit into aligment
                            chunkSize -= (chunkSize % binRequest.ChunkSizeAlignment);
                        }

                        if (binRequest.FlashBankSize != 0)
                        {
                            // Chop the end of the chunk so the burned data will not be written on 2 different flash banks
                            if (((currentAddress + chunkSize) / binRequest.FlashBankSize) !=
                                (currentAddress / binRequest.FlashBankSize))
                            {
                                chunkSize -= ((currentAddress + chunkSize) % binRequest.FlashBankSize);
                            }
                        }

                        //if (binRequest.SubCommand == (int)MemoryType.InternalFlash && binRequest.CommandCode == 0x41)
                        //{
                        //    if ((chunkSize % 8) != 0)
                        //        chunkSize -= chunkSize % 8;
                        //}

                        outgoingChunk = new byte[chunkSize];
                        Array.Copy(binRequest.OutgoingBuffer, offsetInBuffer, outgoingChunk, 0, chunkSize);

                        // Programming command (0x41)
                        // We want to put it on PLC even if the chunk is full with 0xff (Because it is not a flash memory)
                        if ((binRequest.CommandCode == 0x41 && binRequest.SubCommand == (int)MemoryType.SRAM) ||
                            IsValidChunkBufferData(outgoingChunk, binRequest.DecodeValue))
                        {
                            if (sw.ElapsedMilliseconds - lastTime < MIN_TIME_BETWEEN_CHUNKS_WRITE)
                            {
                                Thread.Sleep((int)(MIN_TIME_BETWEEN_CHUNKS_WRITE -
                                                   (sw.ElapsedMilliseconds - lastTime)));
                            }

                            pComB.BuildBinaryCommand((byte)UnitId, messageKey, binRequest.CommandCode,
                                                     binRequest.SubCommand, currentAddress, chunkSize, (ushort)chunkSize,
                                                     outgoingChunk);

                            lastTime = sw.ElapsedMilliseconds;
                            messageKey++;     // Message Key is % 256. The BuildBinaryCommand takes care of that
                            binRequest.MessageKey = messageKey;
                            binRequest.MessageKey = binRequest.MessageKey % 256;

                            if (binRequest.MessageKey == 0)
                            {
                                messageKey            = binRequest.CycledMessageKey;
                                binRequest.MessageKey = messageKey;
                            }

                            guid = new GuidClass();

                            lock (guid)
                            {
                                Channel.Send(pComB.MessageToPLC as byte[], ReceiveBytes, guid, parentID,
                                             "Binary Protocol - Binary Request (" + binRequest.CommandCode.ToString() + ")",
                                             PlcGuid);
                                Monitor.Wait(guid);
                            }

                            if (this.BreakFlag)
                            {
                                throw new ComDriveExceptions("Request aborted by user",
                                                             ComDriveExceptions.ComDriveException.AbortedByUser);
                            }

                            lock (_lockObj)
                            {
                                plcResponseMessage = m_responseMessageQueue[guid];
                                m_responseMessageQueue.Remove(guid);
                            }

                            if (plcResponseMessage.comException == CommunicationException.Timeout)
                            {
                                throw new ComDriveExceptions(
                                          "Cannot communicate with the PLC with the specified UnitID!",
                                          ComDriveExceptions.ComDriveException.CommunicationTimeout);
                            }

                            binRequest.IncomingBuffer =
                                new byte[plcResponseMessage.responseBytesMessage.Length -
                                         Utils.Lengths.LENGTH_HEADER_AND_FOOTER];
                            if (binRequest.IncomingBuffer.Length > 0)
                            {
                                Array.Copy(plcResponseMessage.responseBytesMessage, Utils.Lengths.LENGTH_HEADER,
                                           binRequest.IncomingBuffer, 0, binRequest.IncomingBuffer.Length);
                            }

                            if (plcResponseMessage.responseBytesMessage[12] == 0xFF)
                            {
                                binRequest.PlcReceiveResult =
                                    (BinaryRequest.ePlcReceiveResult)plcResponseMessage.responseBytesMessage[13];
                            }
                            else if (plcResponseMessage.responseBytesMessage[12] == binRequest.CommandCode + 0x80)
                            {
                                binRequest.PlcReceiveResult = BinaryRequest.ePlcReceiveResult.Sucsess;
                            }
                            else
                            {
                                binRequest.PlcReceiveResult = BinaryRequest.ePlcReceiveResult.Unknown;
                            }

                            if (binRequest.PlcReceiveResult != BinaryRequest.ePlcReceiveResult.Sucsess)
                            {
                                return;
                            }

                            if (binRequest.WaitForIdle)
                            {
                                WaitForFlashIdle((byte)UnitId, parentID);
                            }
                            else
                            {
                                if (binRequest.CommandCode == 0x41)
                                {
                                    Thread.Sleep(25);
                                }
                            }
                        }
                        else
                        {
                            Debug.Print("Not Valid");
                        }

                        offsetInBuffer += chunkSize;
                        currentAddress += chunkSize;

                        binRequest.RaiseProgressEvent(0, outgoingBufferSize,
                                                      RequestProgress.en_NotificationType.ProgressChanged, offsetInBuffer, "");
                    }

                    binRequest.RaiseProgressEvent(0, outgoingBufferSize,
                                                  RequestProgress.en_NotificationType.Completed, outgoingBufferSize, "");
                }

                break;

            default:

                binRequest.RaiseProgressEvent(0, 100, RequestProgress.en_NotificationType.SetMinMax, 0, "");
                binRequest.RaiseProgressEvent(0, 100, RequestProgress.en_NotificationType.ProgressChanged, 0, "");

                pComB.BuildBinaryCommand((byte)UnitId, messageKey, binRequest.CommandCode,
                                         binRequest.SubCommand, currentAddress, binRequest.ElementsCount, (ushort)outgoingBufferSize,
                                         binRequest.OutgoingBuffer);

                if (this.BreakFlag)
                {
                    throw new ComDriveExceptions("Request aborted by user",
                                                 ComDriveExceptions.ComDriveException.AbortedByUser);
                }

                if (binRequest.WaitForIdle)
                {
                    WaitForFlashIdle((byte)UnitId, parentID);
                }

                guid = new GuidClass();

                lock (guid)
                {
                    Channel.Send(pComB.MessageToPLC as byte[], ReceiveBytes, guid, parentID,
                                 "Binary Protocol - Binary Request (" + binRequest.CommandCode.ToString() + ")", PlcGuid);
                    Monitor.Wait(guid);
                }

                if (this.BreakFlag)
                {
                    throw new ComDriveExceptions("Request aborted by user",
                                                 ComDriveExceptions.ComDriveException.AbortedByUser);
                }

                lock (_lockObj)
                {
                    plcResponseMessage = m_responseMessageQueue[guid];
                    m_responseMessageQueue.Remove(guid);
                }

                if (plcResponseMessage.comException == CommunicationException.Timeout)
                {
                    throw new ComDriveExceptions("Cannot communicate with the PLC with the specified UnitID!",
                                                 ComDriveExceptions.ComDriveException.CommunicationTimeout);
                }

                binRequest.IncomingBuffer = new byte[plcResponseMessage.responseBytesMessage.Length -
                                                     Utils.Lengths.LENGTH_HEADER_AND_FOOTER];
                if (binRequest.IncomingBuffer.Length > 0)
                {
                    Array.Copy(plcResponseMessage.responseBytesMessage, Utils.Lengths.LENGTH_HEADER,
                               binRequest.IncomingBuffer, 0, binRequest.IncomingBuffer.Length);
                }

                if (plcResponseMessage.responseBytesMessage[12] == 0xFF)
                {
                    binRequest.PlcReceiveResult =
                        (BinaryRequest.ePlcReceiveResult)plcResponseMessage.responseBytesMessage[13];
                }
                else if (plcResponseMessage.responseBytesMessage[12] == binRequest.CommandCode + 0x80)
                {
                    binRequest.PlcReceiveResult = BinaryRequest.ePlcReceiveResult.Sucsess;
                }
                else
                {
                    binRequest.PlcReceiveResult = BinaryRequest.ePlcReceiveResult.Unknown;
                }

                if (binRequest.WaitForIdle)
                {
                    WaitForFlashIdle((byte)UnitId, parentID);
                }

                binRequest.RaiseProgressEvent(0, 100, RequestProgress.en_NotificationType.Completed, 100, "");

                break;
            }
        }
Esempio n. 3
0
        private void WaitForFlashIdle(byte unitID, string parentID)
        {
            int       idleCount           = 0;
            const int READ_STATUS_COMMAND = 7;
            const int TOTAL_TIME_OUT      = 300;

            byte[]      incomingBuffer;
            FlashStatus flashStatus;
            DateTime    dateTime = DateTime.Now;
            PComB       pComB    = new PComB();

            pComB.BuildBinaryCommand(unitID, 0, READ_STATUS_COMMAND,
                                     0, 0, 106, 0, new byte[0]);

            if (this.BreakFlag)
            {
                throw new ComDriveExceptions("Request aborted by user",
                                             ComDriveExceptions.ComDriveException.AbortedByUser);
            }

            while ((DateTime.Now - dateTime).Seconds <= TOTAL_TIME_OUT)
            {
                GuidClass guid = new GuidClass();

                lock (guid)
                {
                    Channel.Send(pComB.MessageToPLC as byte[], ReceiveBytes, guid, parentID,
                                 "Binary Protocol - Binary Request (" + READ_STATUS_COMMAND + ")", PlcGuid);
                    Monitor.Wait(guid);
                }

                if (this.BreakFlag)
                {
                    throw new ComDriveExceptions("Request aborted by user",
                                                 ComDriveExceptions.ComDriveException.AbortedByUser);
                }

                PlcResponseMessage plcResponseMessage;

                lock (_lockObj)
                {
                    plcResponseMessage = m_responseMessageQueue[guid];
                    m_responseMessageQueue.Remove(guid);
                }

                if (plcResponseMessage.comException == CommunicationException.Timeout)
                {
                    throw new ComDriveExceptions("Cannot communicate with the PLC with the specified UnitID!",
                                                 ComDriveExceptions.ComDriveException.CommunicationTimeout);
                }

                incomingBuffer = new byte[plcResponseMessage.responseBytesMessage.Length -
                                          Utils.Lengths.LENGTH_HEADER_AND_FOOTER];
                if (incomingBuffer.Length > 0)
                {
                    Array.Copy(plcResponseMessage.responseBytesMessage, Utils.Lengths.LENGTH_HEADER, incomingBuffer, 0,
                               incomingBuffer.Length);
                }

                flashStatus = GetFlashStatus(incomingBuffer);

                if ((flashStatus.MemoryStatus != (MemoryStatus)'I') || (flashStatus.eFlashStatus != eFlashStatus.Idle))
                {
                    Thread.Sleep(20);
                }
                else
                {
                    idleCount++;
                    if (idleCount > 1)
                    {
                        return;
                    }
                }
            }
        }
        private void ReadWriteOperandsCommand(ref ReadWriteRequest[] values, string parentID, byte messageEnumerator)
        {
            PComB pComB = new PComB();
            List <List <byte> > dataRequestsBytes = new List <List <byte> >();

            #region Group Requests by type.

            List <ReadOperands>  operandReads  = new List <ReadOperands>();
            List <WriteOperands> operandWrites = new List <WriteOperands>();

            for (int i = 0; i < values.Length; i++)
            {
                if (values[i] is ReadOperands)
                {
                    operandReads.Add(values[i] as ReadOperands);
                }
                if (values[i] is WriteOperands)
                {
                    operandWrites.Add(values[i] as WriteOperands);
                }
            }

            #endregion

            #region Detail Area Header

            int totalNumberOfReads  = 0;
            int totalNumberOfWrites = 0;

            foreach (ReadWriteRequest operand in values)
            {
                if (operand is ReadOperands)
                {
                    totalNumberOfReads += (operand as ReadOperands).NumberOfOperands;
                    dataRequestsBytes.Add(GetDataRequestsBytesForReadOperands(operand as ReadOperands));
                }

                if (operand is WriteOperands)
                {
                    totalNumberOfWrites += (operand as WriteOperands).NumberOfOperands;
                    dataRequestsBytes.Add(GetDataRequestsBytesForWriteOperands(operand as WriteOperands));
                }
            }

            byte[] command_detailes = new byte[4];

            byte[] NoOfReads  = BitConverter.GetBytes(totalNumberOfReads);
            byte[] NoOfWrites = BitConverter.GetBytes(totalNumberOfWrites);

            command_detailes[0] = NoOfReads[0];
            command_detailes[1] = NoOfReads[1];

            command_detailes[2] = NoOfWrites[0];
            command_detailes[3] = NoOfWrites[1];

            #endregion

            if (operandReads.Count > 0 || operandWrites.Count > 0)
            {
                pComB.BuildBinaryCommand((byte)UnitId, BinaryCommand.ReadWrite, command_detailes,
                                         values.ToList(), dataRequestsBytes);

                if (Channel != null)
                {
                    if (this.BreakFlag)
                    {
                        throw new ComDriveExceptions("Request aborted by user",
                                                     ComDriveExceptions.ComDriveException.AbortedByUser);
                    }

                    GuidClass guid = new GuidClass();

                    lock (guid)
                    {
                        Channel.Send(pComB.MessageToPLC as byte[], ReceiveBytes, guid, parentID,
                                     "Binary Protocol - Read/Write Operands (80)", PlcGuid, messageEnumerator);
                        Monitor.Wait(guid);
                    }

                    if (this.BreakFlag)
                    {
                        throw new ComDriveExceptions("Request aborted by user",
                                                     ComDriveExceptions.ComDriveException.AbortedByUser);
                    }

                    PlcResponseMessage plcResponseMessage;

                    lock (_lockObj)
                    {
                        plcResponseMessage = m_responseMessageQueue[guid];
                        m_responseMessageQueue.Remove(guid);
                    }

                    if (plcResponseMessage.comException == CommunicationException.Timeout)
                    {
                        throw new ComDriveExceptions("Cannot communicate with the PLC with the specified UnitID!",
                                                     ComDriveExceptions.ComDriveException.CommunicationTimeout);
                    }

                    // receivedMessage[13] shows if there was occured an error.
                    if (plcResponseMessage.responseBytesMessage[13] == 0)
                    {
                        pComB.DisAssembleBinaryResult(plcResponseMessage.responseBytesMessage, dataRequestsBytes);
                    }
                }
            }
            else
            {
                //System.Diagnostics.Debug.Assert(false);
            }
        }
Esempio n. 5
0
        private void ReadOperations(ref List <ReadWriteRequest> pdataRequestsForRead, string parentID)
        {
            List <ReadWriteRequest> dataRequestsForRead = null;

            dataRequestsForRead = pdataRequestsForRead.OrderBy(dr => GetOperandSize(dr)).ToList();

            List <List <byte> > dataRequestBytes = new List <List <byte> >();

            for (int i = 0; i < dataRequestsForRead.Count; i++)
            {
                if (dataRequestsForRead[i] is ReadOperands)
                {
                    dataRequestBytes.Add(GetDataRequestBytes(dataRequestsForRead[i] as ReadOperands));
                }
            }

            //set number of read requests in position 4 and 5 of command_details which in header will be 18 and 19
            byte[] command_detailes = new byte[6];
            byte[] count            = BitConverter.GetBytes(dataRequestsForRead.Count);
            command_detailes[4] = count[0];
            command_detailes[5] = count[1];

            PComB pComB = new PComB();

            pComB.BuildBinaryCommand((byte)UnitId, BinaryCommand.ReadOperands, command_detailes,
                                     dataRequestsForRead, dataRequestBytes);

            if (this.BreakFlag)
            {
                throw new ComDriveExceptions("Request aborted by user",
                                             ComDriveExceptions.ComDriveException.AbortedByUser);
            }

            GuidClass guid = new GuidClass();

            lock (guid)
            {
                Channel.Send(pComB.MessageToPLC as byte[], ReceiveBytes, guid, parentID,
                             "Binary Protocol - Read Operands (77)", PlcGuid);
                Monitor.Wait(guid);
            }

            if (this.BreakFlag)
            {
                throw new ComDriveExceptions("Request aborted by user",
                                             ComDriveExceptions.ComDriveException.AbortedByUser);
            }

            PlcResponseMessage plcResponseMessage;

            lock (_lockObj)
            {
                plcResponseMessage = m_responseMessageQueue[guid];
                m_responseMessageQueue.Remove(guid);
            }

            if (plcResponseMessage.comException == CommunicationException.Timeout)
            {
                throw new ComDriveExceptions("Cannot communicate with the PLC with the specified UnitID!",
                                             ComDriveExceptions.ComDriveException.CommunicationTimeout);
            }

            pComB.DisAssembleBinaryResult(plcResponseMessage.responseBytesMessage, dataRequestBytes);
        }
        private void ReadWriteDataTable(ref List <ReadWriteRequest> dataTableDRs, string parentID)
        {
            PComB           pComB = new PComB();
            BinaryCommand   binaryCommand;
            ReadDataTables  rdt = null;
            WriteDataTables wdt = null;

            if (this.BreakFlag)
            {
                throw new ComDriveExceptions("Request aborted by user",
                                             ComDriveExceptions.ComDriveException.AbortedByUser);
            }

            foreach (ReadWriteRequest rwr in dataTableDRs)
            {
                if (this.BreakFlag)
                {
                    throw new ComDriveExceptions("Request aborted by user",
                                                 ComDriveExceptions.ComDriveException.AbortedByUser);
                }

                if (rwr is ReadDataTables)
                {
                    binaryCommand = BinaryCommand.ReadDataTables;
                    rdt           = rwr as ReadDataTables;

                    rdt.RaiseProgressEvent(0, rdt.NumberOfBytesToReadInRow * rdt.NumberOfRowsToRead,
                                           RequestProgress.en_NotificationType.SetMinMax, 0, "");
                    rdt.RaiseProgressEvent(0, rdt.NumberOfBytesToReadInRow * rdt.NumberOfRowsToRead,
                                           RequestProgress.en_NotificationType.ProgressChanged, 0, "");

                    if (rdt.PartOfProject)
                    {
                        binaryCommand = BinaryCommand.ReadPartOfProjectDataTables;
                    }

                    List <List <byte> > readDataTablesDataRequestBytes = new List <List <byte> >();
                    readDataTablesDataRequestBytes.Add(GetDataRequestBytesForReadDataTables(rdt));

                    if (rdt != null)
                    {
                        byte[] cmdDetails = new byte[6];
                        Array.Copy(BitConverter.GetBytes(rdt.StartAddress), cmdDetails, 4);

                        pComB.BuildBinaryCommand((byte)UnitId, binaryCommand, cmdDetails, dataTableDRs,
                                                 readDataTablesDataRequestBytes, (byte)rdt.SubCommand);

                        BinaryMessage receivedMessage =
                            ReceiveMessage(pComB, readDataTablesDataRequestBytes, parentID) as BinaryMessage;
                    }

                    rdt.RaiseProgressEvent(0, rdt.NumberOfBytesToReadInRow * rdt.NumberOfRowsToRead,
                                           RequestProgress.en_NotificationType.Completed,
                                           rdt.NumberOfBytesToReadInRow * rdt.NumberOfRowsToRead, "");
                }

                if (rwr is WriteDataTables)
                {
                    binaryCommand = BinaryCommand.WriteDataTables;
                    wdt           = rwr as WriteDataTables;

                    wdt.RaiseProgressEvent(0, wdt.NumberOfBytesToWriteInRow * wdt.NumberOfRowsToWrite,
                                           RequestProgress.en_NotificationType.SetMinMax, 0, "");
                    wdt.RaiseProgressEvent(0, wdt.NumberOfBytesToWriteInRow * wdt.NumberOfRowsToWrite,
                                           RequestProgress.en_NotificationType.ProgressChanged, 0, "");

                    List <List <byte> > writeDataTablesDataRequestBytes = new List <List <byte> >();
                    writeDataTablesDataRequestBytes.Add(GetDataRequestBytesForWriteDataTables(wdt));

                    if (wdt != null)
                    {
                        byte[] cmdDetails = new byte[6];
                        Array.Copy(BitConverter.GetBytes(wdt.StartAddress), cmdDetails, 4);

                        pComB.BuildBinaryCommand((byte)UnitId, binaryCommand, cmdDetails, dataTableDRs,
                                                 writeDataTablesDataRequestBytes, (byte)wdt.SubCommand);

                        BinaryMessage receivedMessage = ReceiveMessage(pComB, null, parentID) as BinaryMessage;
                    }

                    wdt.RaiseProgressEvent(0, wdt.NumberOfBytesToWriteInRow * wdt.NumberOfRowsToWrite,
                                           RequestProgress.en_NotificationType.ProgressChanged,
                                           wdt.NumberOfBytesToWriteInRow * wdt.NumberOfRowsToWrite, "");
                }
            }
        }