/// <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)
                 */

            }
        }