/// <summary> /// Sends Cctalk message to device and waits for answer. /// </summary> public CctalkMessage Send(CctalkMessage com, ICctalkChecksum chHandler) { // TODO: handle BUSY message lock (_callSyncRoot) { Trace.TraceInformation("Sending message from {0} to {1}. Header={2}", com.SourceAddr, com.DestAddr, com.Header); var msgBytes = com.GetTransferDataNoChecksumm(); chHandler.CalcAndApply(msgBytes); //_respondChecksumChecker = chHandler; _port.DiscardInBuffer(); _port.Write(msgBytes, 0, msgBytes.Length); Trace.TraceInformation("Message sent, waiting for respond"); _port.ReadTimeout = RespondStartTimeout; Int32 respondBufPos = 0; CctalkMessage respond; var echoRemover = 0; while (true) { try { var b = (Byte)_port.ReadByte(); // after first respond package we wait fo rest respond packages with another timout _port.ReadTimeout = RespondDataTimeout; if (_removeEcho && (echoRemover < msgBytes.Length)) { echoRemover++; continue; } _respondBuf[respondBufPos] = b; respondBufPos++; var isRespondComplete = GenericCctalkDevice.IsRespondComplete(_respondBuf, respondBufPos); if (isRespondComplete) { if (!chHandler.Check(_respondBuf, 0, respondBufPos)) { var copy = new byte[respondBufPos]; Array.Copy(_respondBuf, copy, respondBufPos); throw new InvalidRespondFormatException(copy, "Checksumm check fail"); } respond = GenericCctalkDevice.ParseRespond(_respondBuf, 0, respondBufPos); Array.Clear(_respondBuf, 0, _respondBuf.Length); break; } } catch (TimeoutException ex) { if (_port.ReadTimeout == RespondStartTimeout) throw new TimeoutException("Device not respondng", ex); var respondBufContents = new StringBuilder(); for (int i = 0; i > respondBufPos; i++) { respondBufContents.Append(_respondBuf[i].ToString("X")) .Append(" "); } Trace.TraceInformation("Pause in reply error. Recive buffer contents {0} bytes: {1}", respondBufPos, respondBufContents); Array.Clear(_respondBuf, 0, _respondBuf.Length); throw new TimeoutException("Pause in reply (should reset all communication vatiables and be ready to recive the next message)", ex); } } return respond; /* * When receiving bytes within a message packet, the communication software should * wait up to 50ms for another byte if it is expected. If a timeout condition occurs, the * software should reset all communication variables and be ready to receive the next * message. No other action should be taken. (cctalk spec part1, 11.1) */ } }
public CctalkMessage Send(CctalkMessage com, ICctalkChecksum checksumHandler) { throw new NotImplementedException(); }
public static CctalkMessage ParseMessage(Byte[] source, Int32 offset, Int32 length) { if (source == null) throw new ArgumentNullException("source"); if (source.Length < offset + length) throw new ArgumentException("offset or length are invalid"); if (length < CctalkMessage.MinMessageLength) throw new ArgumentException("too small for message", "length"); //if (header != this.Header) // throw new ArgumentException("invalid message type for this class", "source"); var dataLen = source[CctalkMessage.PosDataLen + offset]; if (dataLen + 5 != length) throw new ArgumentException("invalid message data lengh", "source"); var ret = new CctalkMessage { Header = source[CctalkMessage.PosHeader + offset], DestAddr = source[CctalkMessage.PosDestAddr + offset], SourceAddr = source[CctalkMessage.PosSourceAddr + offset] }; if (dataLen > 0) { ret.Data = new byte[dataLen]; Array.Copy(source, CctalkMessage.PosDataStart + offset, ret.Data, 0, dataLen); } return ret; }
public InvalidRespondException(CctalkMessage respond, string message) : base(message) { InvalidRespond = respond; }
public InvalidRespondException(CctalkMessage respond) : this(respond, "Invalid respond") { }
/// <summary> /// Sends Cctalk message to device and waits for answer. /// </summary> public CctalkMessage Send(CctalkMessage com, ICctalkChecksum chHandler) { // TODO: handle BUSY message lock (_callSyncRoot) { var msgBytes = com.GetTransferDataNoChecksumm(); chHandler.CalcAndApply(msgBytes); //_respondChecksumChecker = chHandler; _port.DiscardInBuffer(); _port.Write(msgBytes, 0, msgBytes.Length); _port.ReadTimeout = RespondStartTimeout; Int32 respondBufPos = 0; CctalkMessage respond; var echoRemover = 0; while (true) { try { var b = (Byte)_port.ReadByte(); _port.ReadTimeout = RespondDataTimeout; if (_removeEcho && (echoRemover < msgBytes.Length)) { echoRemover++; continue; } _respondBuf[respondBufPos] = b; respondBufPos++; var isRespondComplete = GenericCctalkDevice.IsRespondComplete(_respondBuf, respondBufPos); if (isRespondComplete) { if (!chHandler.Check(_respondBuf, 0, respondBufPos)) { var copy = new byte[respondBufPos]; Array.Copy(_respondBuf, copy, respondBufPos); throw new InvalidRespondFormatException(copy, "Checksumm check fail"); } respond = GenericCctalkDevice.ParseRespond(_respondBuf, 0, respondBufPos); Array.Clear(_respondBuf, 0, _respondBuf.Length); break; } } catch (TimeoutException ex) { if (_port.ReadTimeout == RespondStartTimeout) throw new TimeoutException("Device not respondng", ex); throw new TimeoutException("Pause in reply (should reset all communication vatiables and be ready to recive the next message)", ex); } } return respond; /* * When receiving bytes within a message packet, the communication software should * wait up to 50ms for another byte if it is expected. If a timeout condition occurs, the * software should reset all communication variables and be ready to receive the next * message. No other action should be taken. (cctalk spec part1, 11.1) */ } }