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); }
public CoLaBTelegram SendTelegram(CoLaCommandType commandType, string commandName, int acknowledgeTimeout) { return(SendTelegram(commandType, commandName, writeTelegram: null, acknowledgeTimeout: acknowledgeTimeout)); }