private static string getROWORequestsPropertiesString(ReadWriteRequest readWriteRequest)
        {
            string result = String.Empty;

            // The string results format is:
            // RequestType:OperandType-StartAddress-NumberOfOperands.  where
            // ':' - is the delimitator for the requestType
            // '-' - is the delimitator between request properties.
            // '.' - used to mark the end of the request properties.
            // Example: RO:MI-1-10. means Read 10 MI from address 1.

            if (readWriteRequest is ReadOperands)
            {
                ReadOperands ro = readWriteRequest as ReadOperands;

                result += "RO:" + ro.OperandType.ToString() +
                          "-" + ro.StartAddress.ToString() +
                          "-" + ro.NumberOfOperands.ToString() +
                          ".";
            }
            else
            {
                WriteOperands wo = readWriteRequest as WriteOperands;
                result += "WO" + wo.OperandType.ToString() +
                          "-" + wo.StartAddress.ToString() +
                          "-" + wo.NumberOfOperands.ToString() +
                          ".";
            }

            return(result);
        }
        private void ReadWriteWriteOperand(ReadWriteRequest operand, string parentID, bool suppressEthernetHeader)
        {
            WriteOperands writeOperands = operand as WriteOperands;
            GuidClass     guid          = new GuidClass();

            pcomA.BuildAsciiCommand(UnitId,
                                    Utils.ASCIIOperandTypes[Enum.GetName(typeof(OperandTypes), writeOperands.OperandType)]
                                    .CommandCodeForWrite,
                                    (operand as WriteOperands).StartAddress, writeOperands.NumberOfOperands, writeOperands.Values,
                                    (operand as WriteOperands).TimerValueFormat);

            string readMessage = pcomA.MessageToPLC as string;

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

            lock (guid)
            {
                Channel.Send(readMessage, ReceiveString, guid, parentID, "ASCII Protocol - Write Operands", PlcGuid,
                             suppressEthernetHeader);
                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);
            }

            pcomA.DisAssembleAsciiResult(plcResponseMessage.response, UnitId,
                                         Utils.ASCIIOperandTypes[Enum.GetName(typeof(OperandTypes), writeOperands.OperandType)]
                                         .CommandCodeForWrite,
                                         (operand as WriteOperands).StartAddress, writeOperands.NumberOfOperands, null,
                                         writeOperands.TimerValueFormat);
            if (pcomA.MessageFromPLC != null)
            {
                operand.ResponseValues = (pcomA.MessageFromPLC as AbstractASCIIMessage).Values;
            }
        }
        private bool sentMessageSizeFitsThePLCBuffer(ReadWriteRequest operand)
        {
            WriteOperands writeOperands   = operand as WriteOperands;
            int           operandSize     = Utils.GetOperandSizeByCommandCode(writeOperands.OperandType.ToString());
            int           sentDataSize    = writeOperands.NumberOfOperands * operandSize;
            int           sentMessageSize = 0;

            sentMessageSize = Utils.Lengths.LENGTH_ASCII_SEND_MESSAGE + sentDataSize + Utils.Lengths.LENGTH_LENGTH +
                              Utils.Lengths.LENGTH_ADDRESS;
            return(sentMessageSize <= PLCVersion.PlcBuffer && writeOperands.NumberOfOperands <= 255);
        }
        private void _addRequestsWhenNoOfOperandsExceed255(ReadWriteRequest readWriteRequest)
        {
            ushort startAddress;
            ushort noOfOperands;
            ushort remainingNoOfOperands;

            if (readWriteRequest is ReadOperands)
            {
                ReadOperands ro = readWriteRequest as ReadOperands;
                remainingNoOfOperands = ro.NumberOfOperands;
                startAddress          = ro.StartAddress;
                noOfOperands          = 255;

                while (remainingNoOfOperands > 0)
                {
                    requestsList.Add(new ReadOperands(noOfOperands, ro.OperandType, startAddress, ro.TimerValueFormat));
                    startAddress          += noOfOperands;
                    remainingNoOfOperands -= noOfOperands;

                    if (remainingNoOfOperands <= 255)
                    {
                        noOfOperands = remainingNoOfOperands;
                    }

                    _updateSplitDetailsList();
                }
            }
            else
            {
                WriteOperands wo = readWriteRequest as WriteOperands;
                remainingNoOfOperands = wo.NumberOfOperands;
                startAddress          = wo.StartAddress;
                noOfOperands          = 255;

                while (remainingNoOfOperands > 0)
                {
                    object[] values = new object[noOfOperands];
                    Array.Copy(wo.Values, startAddress - wo.StartAddress, values, 0, noOfOperands);

                    requestsList.Add(new WriteOperands(noOfOperands, wo.OperandType, startAddress, values,
                                                       wo.TimerValueFormat));
                    startAddress          += noOfOperands;
                    remainingNoOfOperands -= noOfOperands;

                    if (remainingNoOfOperands <= 255)
                    {
                        noOfOperands = remainingNoOfOperands;
                    }

                    _updateSplitDetailsList();
                }
            }
        }
Example #5
0
        private List <WriteOperands> GetSplitedWriteOperands(ReadWriteRequest operand)
        {
            WriteOperands writeOperands = operand as WriteOperands;

            List <WriteOperands> results = new List <WriteOperands>();
            int    operandSize           = Utils.GetOperandSizeByCommandCode(writeOperands.OperandType.ToString());
            ushort startAddress          = writeOperands.StartAddress;
            ushort remainingNoOfOperands = writeOperands.NumberOfOperands;
            int    splitMaxDataSize      = PLCVersion.PlcBuffer - Utils.Lengths.LENGTH_ASCII_SEND_MESSAGE -
                                           Utils.Lengths.LENGTH_ADDRESS;
            ushort splitMaxNoOfOperands = (ushort)(splitMaxDataSize / operandSize);

            object[] valuesToWrite    = (operand as WriteOperands).Values;
            int      sourceIndex      = 0;
            int      destinationIndex = 0;

            if (splitMaxNoOfOperands > 255)
            {
                splitMaxNoOfOperands = 255;
            }

            bool bDone = false;

            while (!bDone)
            {
                if (remainingNoOfOperands <= splitMaxNoOfOperands)
                {
                    object[] splitValues = new object[remainingNoOfOperands];
                    Array.Copy(valuesToWrite, sourceIndex, splitValues, destinationIndex, remainingNoOfOperands);
                    results.Add(new WriteOperands(remainingNoOfOperands, writeOperands.OperandType, startAddress,
                                                  splitValues, writeOperands.TimerValueFormat));
                    bDone = true;
                }
                else
                {
                    object[] splitValues = new object[splitMaxNoOfOperands];
                    Array.Copy(valuesToWrite, sourceIndex, splitValues, destinationIndex, splitMaxNoOfOperands);
                    results.Add(new WriteOperands(splitMaxNoOfOperands, writeOperands.OperandType, startAddress,
                                                  splitValues.ToArray(), writeOperands.TimerValueFormat));
                    startAddress          += splitMaxNoOfOperands;
                    remainingNoOfOperands -= splitMaxNoOfOperands;
                    sourceIndex           += splitMaxNoOfOperands;
                }
            }

            return(results);
        }
        private List <byte> GetDataRequestsBytesForWriteOperands(WriteOperands writeOperandsExecuter)
        {
            List <byte> results = new List <byte>();

            results.AddRange(BitConverter.GetBytes((UInt16)0));
            results.AddRange(
                BitConverter.GetBytes((writeOperandsExecuter.NumberOfOperands > 0) ? (UInt16)1 : (UInt16)0));

            if (writeOperandsExecuter.NumberOfOperands > 0)
            {
                results.AddRange(UpdateWriteDataRequest(
                                     writeOperandsExecuter.OperandType.ToString().GetOperandIdByNameForFullBinary(),
                                     writeOperandsExecuter.NumberOfOperands, writeOperandsExecuter.StartAddress,
                                     writeOperandsExecuter.Values));
            }

            return(results);
        }
        private void _getRequestBytesSize(ReadWriteRequest readWriteRequest)
        {
            ushort noOfOperands;
            int    noOf255Splits, noOfSplits;

            if (readWriteRequest is WriteOperands)
            {
                WriteOperands wo = readWriteRequest as WriteOperands;
                noOfOperands = wo.NumberOfOperands;
                operandSize  = wo.OperandType.GetOperandSizeByOperandTypeForFullBinarry();

                noOf255Splits = noOfOperands / 255;
                noOfSplits    = noOfOperands % 255;

                if (noOfOperands > 255)
                {
                    requestBytesNoToSend =
                        (ushort)(noOf255Splits * Utils.Lengths.LENGTH_WR_DETAILS + noOf255Splits * 255 * operandSize);
                    requestBytesNoToSend += (ushort)((operandSize % 2) * (noOf255Splits + noOfSplits % 2));

                    if (noOfSplits > 0)
                    {
                        requestBytesNoToSend += (ushort)(Utils.Lengths.LENGTH_WR_DETAILS + noOfSplits * operandSize);
                    }
                }
                else
                {
                    requestBytesNoToSend  = (ushort)(operandSize * noOfOperands + Utils.Lengths.LENGTH_WR_DETAILS);
                    requestBytesNoToSend += (ushort)(requestBytesNoToSend % 2);
                }

                requestBytesNoToReceive = 0;
            }
            else
            {
                ReadOperands ro = readWriteRequest as ReadOperands;
                noOfOperands = ro.NumberOfOperands;
                operandSize  = ro.OperandType.GetOperandSizeByOperandTypeForFullBinarry();

                if (noOfOperands > 255)
                {
                    noOf255Splits = (noOfOperands / 255);
                    noOfSplits    = (noOfOperands % 255);

                    requestBytesNoToSend    = (ushort)(noOf255Splits * Utils.Lengths.LENGTH_WR_DETAILS);
                    requestBytesNoToReceive =
                        (ushort)(noOf255Splits * Utils.Lengths.LENGTH_WR_DETAILS + noOf255Splits * 255 * operandSize);
                    requestBytesNoToReceive += (ushort)((operandSize % 2) * (noOf255Splits + noOfSplits % 2));

                    if (noOfSplits != 0)
                    {
                        requestBytesNoToSend    += Utils.Lengths.LENGTH_WR_DETAILS;
                        requestBytesNoToReceive +=
                            (ushort)(Utils.Lengths.LENGTH_WR_DETAILS + noOfSplits * operandSize);
                    }
                }
                else
                {
                    requestBytesNoToReceive  = (ushort)(operandSize * noOfOperands + Utils.Lengths.LENGTH_WR_DETAILS);
                    requestBytesNoToReceive += (ushort)(requestBytesNoToReceive % 2);
                    requestBytesNoToSend     = Utils.Lengths.LENGTH_WR_DETAILS;
                }
            }
        }
        private void _sendSizeExceedPLCBuffer(ReadWriteRequest readWriteRequest)
        {
            WriteOperands wo = readWriteRequest as WriteOperands;
            ushort        availableSendSize     = (ushort)(plcBuffer - bytesNoToSend - Utils.Lengths.LENGTH_WR_DETAILS);
            ushort        availableNoOfOperands = (ushort)(availableSendSize / operandSize);

            if (availableNoOfOperands > 255)
            {
                availableSendSize    -= (ushort)((availableNoOfOperands / 255) * (Utils.Lengths.LENGTH_WR_DETAILS + 1));
                availableSendSize    -= 1;
                availableSendSize    -= (ushort)((availableNoOfOperands % 255) % 2);
                availableNoOfOperands = (ushort)(availableSendSize / operandSize);
            }

            ushort noOfOperands = 0;
            ushort startAddress = wo.StartAddress;
            int    requestNo    = 0;

            WriteOperands remainingWo = new WriteOperands
            {
                NumberOfOperands = (ushort)(wo.NumberOfOperands - availableNoOfOperands),
                OperandType      = wo.OperandType,
                StartAddress     = (ushort)(wo.StartAddress + availableNoOfOperands),
                TimerValueFormat = wo.TimerValueFormat
            };

            object[] remainingValues = new object[remainingWo.NumberOfOperands];
            Array.Copy(wo.Values, availableNoOfOperands, remainingValues, 0, remainingWo.NumberOfOperands);
            remainingWo.Values = remainingValues;

            if (_canWriteAtLeast1Operand())
            {
                object[] values = null;

                while (availableNoOfOperands > 0)
                {
                    requestNo++;

                    if (availableNoOfOperands > 255)
                    {
                        noOfOperands           = 255;
                        availableNoOfOperands -= noOfOperands;
                        values = new object[noOfOperands];
                    }
                    else
                    {
                        noOfOperands          = availableNoOfOperands;
                        availableNoOfOperands = 0;
                        values = new object[noOfOperands];
                    }

                    Array.Copy(wo.Values, (requestNo - 1) * 255, values, 0, noOfOperands);
                    WriteOperands tmpWO = new WriteOperands(noOfOperands, wo.OperandType, startAddress, values,
                                                            wo.TimerValueFormat);
                    requestsList.Add(tmpWO);
                    startAddress += noOfOperands;
                    _updateSplitDetailsList();
                }

                ReadWriteRequest[] tmpReq = requestsList.ToArray();
                allRequestsList.Add(tmpReq.ToList());

                _resetRequestsList();
                AddNewRequest(remainingWo, reqPosition, true);
            }
        }
        internal void CheckReadWriteRequests(ReadWriteRequest[] values)
        {
            foreach (ReadWriteRequest rw in values)
            {
                if (rw is ReadOperands)
                {
                    ReadOperands ro = rw as ReadOperands;
                    if (ro == null)
                    {
                        throw new ComDriveExceptions("Read Operand Request cannot be Null",
                                                     ComDriveExceptions.ComDriveException.UserInputException);
                    }

                    if (ro.NumberOfOperands <= 0)
                    {
                        throw new ComDriveExceptions("The number of Operands to read cannot be less than 1",
                                                     ComDriveExceptions.ComDriveException.UserInputException);
                    }

                    if ((ro.StartAddress < 0) ||
                        (ro.StartAddress + ro.NumberOfOperands > m_plcVersion.OperandCount(ro.OperandType)))
                    {
                        throw new ComDriveExceptions(
                                  "Operand start address and end must be non-negative and less than the operand count on the PLC",
                                  ComDriveExceptions.ComDriveException.OperandAddressOutOfRange);
                    }
                }
                else if (rw is WriteOperands)
                {
                    WriteOperands wo = rw as WriteOperands;
                    if (wo == null)
                    {
                        throw new ComDriveExceptions("Write Operand Request cannot be Null",
                                                     ComDriveExceptions.ComDriveException.UserInputException);
                    }

                    if (wo.NumberOfOperands <= 0)
                    {
                        throw new ComDriveExceptions("The number of Operands to write cannot be less than 1",
                                                     ComDriveExceptions.ComDriveException.UserInputException);
                    }

                    if (wo.Values == null)
                    {
                        throw new ComDriveExceptions("Values cannot be Null in a Write Operands request",
                                                     ComDriveExceptions.ComDriveException.UserInputException);
                    }

                    if (wo.NumberOfOperands > wo.Values.Length)
                    {
                        throw new ComDriveExceptions(
                                  "The number of Operands to write is larger than the number of values that were entered",
                                  ComDriveExceptions.ComDriveException.UserInputException);
                    }

                    if ((wo.StartAddress < 0) ||
                        (wo.StartAddress + wo.NumberOfOperands > m_plcVersion.OperandCount(wo.OperandType)))
                    {
                        throw new ComDriveExceptions(
                                  "Operand start address and end must be non-negative and less than the operand count on the PLC",
                                  ComDriveExceptions.ComDriveException.OperandAddressOutOfRange);
                    }
                }
                else if (rw is ReadDataTables)
                {
                    ReadDataTables rdt = rw as ReadDataTables;
                    if (rdt == null)
                    {
                        throw new ComDriveExceptions("Read DataTables Request cannot be Null",
                                                     ComDriveExceptions.ComDriveException.UserInputException);
                    }

                    if ((rdt.NumberOfBytesToReadInRow <= 0) && (rdt.NumberOfRowsToRead <= 0) &&
                        (rdt.RowSizeInBytes <= 0) && (rdt.StartAddress < 0))
                    {
                        throw new ComDriveExceptions("Invalid request parameters in Read DataTables Request",
                                                     ComDriveExceptions.ComDriveException.UserInputException);
                    }
                }
                else if (rw is WriteDataTables)
                {
                    WriteDataTables wdt = rw as WriteDataTables;
                    if (wdt == null)
                    {
                        throw new ComDriveExceptions("Write DataTables Request cannot be Null",
                                                     ComDriveExceptions.ComDriveException.UserInputException);
                    }

                    if ((wdt.NumberOfBytesToWriteInRow <= 0) && (wdt.NumberOfRowsToWrite <= 0) &&
                        (wdt.RowSizeInBytes <= 0) && (wdt.StartAddress < 0))
                    {
                        throw new ComDriveExceptions("Invalid request parameters in Read DataTables Request",
                                                     ComDriveExceptions.ComDriveException.UserInputException);
                    }
                }
                else if (rw == null)
                {
                    throw new ComDriveExceptions("One or more ReadWriteRequest object are Null",
                                                 ComDriveExceptions.ComDriveException.UserInputException);
                }
                else if (rw is BinaryRequest)
                {
                    // Nothing specific to check
                }
                else
                {
                    throw new ComDriveExceptions("Unsupported request",
                                                 ComDriveExceptions.ComDriveException.UnsupportedCommand);
                }
            }
        }