Пример #1
0
        public CoLaBTelegram SendTelegram(CoLaCommandType commandType, string commandName, Action <BinaryWriter> writeTelegram, int acknowledgeTimeout)
        {
            // Convert the Command-Type to a String
            string commandString;
            string acknowledgeType;

            switch (commandType)
            {
            case CoLaCommandType.Read: commandString = $"sRN " + commandName; acknowledgeType = "sRA"; break;

            case CoLaCommandType.Write: commandString = $"sWN " + commandName; acknowledgeType = "sWA"; break;

            case CoLaCommandType.Method: commandString = $"sMN " + commandName; acknowledgeType = "sAN"; break;

            case CoLaCommandType.Event: commandString = $"sEN " + commandName; acknowledgeType = "sEA"; break;

            default: throw new ArgumentException("Unknown or unsupported CoLa command type: " + commandType.ToString(), nameof(commandType));
            }

            // Initialize the Upstream Buffer on first telegram
            if (null == _upstreamWriter)
            {
                _upstreamBuffer = new MemoryStream();
                _upstreamWriter = new BinaryWriter(_upstreamBuffer, Encoding.ASCII);

                _upstreamWriter.Write(new byte[] { _stx, _stx, _stx, _stx, 0x00, 0x00, 0x00, 0x00 });
            }
            else
            {
                _upstreamBuffer.Seek(8, SeekOrigin.Begin);
            }

            // Generate the Telegram
            _upstreamWriter.Write(Encoding.ASCII.GetBytes(commandString));

            if (null != writeTelegram)
            {
                _upstreamWriter.Write(_space);
                writeTelegram(_upstreamWriter);
            }

            int length = (int)(_upstreamBuffer.Position - 8L);

            // Encode the Telegram Size
            _upstreamBuffer.Seek(4, SeekOrigin.Begin);
            for (int i = 3; i >= 0; --i)
            {
                _upstreamWriter.Write((byte)(length >> (i * 8)));
            }

            // Calculate the Telegram Checksum
            byte checksum = 0;

            for (int i = 0; i < length; ++i)
            {
                checksum ^= (byte)_upstreamBuffer.ReadByte();
            }

            _upstreamWriter.Write(checksum);

            // Send the Telegram
            _client.Client.Send(_upstreamBuffer.GetBuffer(), 0, (int)_upstreamBuffer.Position, SocketFlags.None);

            // Look for Acknowledgement
            _client.Client.ReceiveTimeout = acknowledgeTimeout;
            CoLaBTelegram acknowledgement;

            try
            {
                acknowledgement = ReceiveTelegram();
            }
            catch (SocketException socketException)
            {
                switch (socketException.SocketErrorCode)
                {
                // Timeouts indicate that the port is not configured for the binary dialect
                case SocketError.TimedOut:
                    throw new CoLaBException($"Upstream CoLa (binary) Telegram not acknowledged: CoLa (binary) dialect ignored", socketException);

                // Other socket errors are unknown
                default:
                    throw new CoLaBException($"Upstream CoLa (binary) Telegram not acknowledged: socket error", socketException);
                }
            }

            if ((null == acknowledgement) || (acknowledgement.CommandPrefix != acknowledgeType) || (acknowledgement.CommandName != commandName))
            {
                throw new CoLaBException($"Upstream CoLa (binary) Telegram acknowledged incorrectly: expected `{acknowledgeType} {commandName}`");
            }

            return(acknowledgement);
        }
Пример #2
0
 public CoLaBTelegram SendTelegram(CoLaCommandType commandType, string commandName, int acknowledgeTimeout)
 {
     return(SendTelegram(commandType, commandName, writeTelegram: null, acknowledgeTimeout: acknowledgeTimeout));
 }