示例#1
0
        /// <summary>
        ///  Sends Cctalk message to device and waits for answer.
        /// </summary>
        public CctalkMessage Send(CctalkMessage com, ICctalkChecksum chHandler)
        {
            bool testing = false;

            if (chHandler.CRCType == CRCType.None)
            {
                testing           = true;
                chHandler.CRCType = CRCType.CRC8;
                //chHandler.CRCType = CRCType.CRC16CCITT;
            }

            do
            {
                try
                {
                    return(_doSend(com, chHandler));
                }
                catch (Exception ex)
                {
                    if (testing)
                    {
                        switch (chHandler.CRCType)
                        {
                        case CRCType.CRC8:
                            chHandler.CRCType = CRCType.CRC16CCITT;
                            break;

                        //case CRCType.CRC16CCITT:
                        //    chHandler.CRCType = CRCType.CRC8;
                        //    break;
                        default:
                            testing = false;
                            throw ex;
                        }
                    }
                    else
                    {
                        throw ex;
                    }
                }
            } while (testing);

            throw new Exception("Can't find CRC checksum mode");
        }
示例#2
0
        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);
        }
示例#3
0
        /// <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);
                            //var temp = new byte[respondBufPos];
                            //Array.Copy(_respondBuf, 0, temp, 0, temp.Length);
                            //DllLog.In(temp.ToStr());
                            Array.Clear(_respondBuf, 0, _respondBuf.Length);
                            break;
                        }
                    }
                    catch (TimeoutException ex)
                    {
                        if (_port.ReadTimeout == RespondStartTimeout)
                        {
                            Log.In("Device not respondng");
                            //throw new TimeoutException("Device not respondng", ex);
                            return(null);
                        }

                        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 InvalidRespondException(CctalkMessage respond)
     : this(respond, "Invalid respond")
 {
 }
 public InvalidRespondException(CctalkMessage respond, string message)
     : base(message)
 {
     InvalidRespond = respond;
 }
示例#6
0
        CctalkMessage _doSend(CctalkMessage com, ICctalkChecksum chHandler)
        {
            // TODO: handle BUSY message
            lock (_callSyncRoot)
            {
                var msgBytes = com.GetTransferDataNoChecksumm();
                chHandler.CalcAndApply(msgBytes);

                //_respondChecksumChecker = chHandler;

                //_port.DiscardInBuffer();
                _port.WriteTimeout = WriteTimeout;
                _port.Write(msgBytes, 0, msgBytes.Length);

                Thread.Sleep(100);

                _port.ReadTimeout = RespondStartTimeout;
                Int32         respondBufPos = 0;
                CctalkMessage respond;


                var echoRemover = 0;
                while (true)
                {
                    try
                    {
                        var b = (Byte)_port.ReadByte();
                        if (com.Header == CctalkCommands.TestOutputLines || com.Header == CctalkCommands.TestSolenoids)
                        {
                            _port.ReadTimeout = RespondHeavyCommandsTimeout;
                        }
                        else
                        {
                            _port.ReadTimeout = RespondDataTimeout;
                        }

                        if (_removeEcho && (echoRemover < msgBytes.Length))
                        {
                            echoRemover++;
                            continue;
                        }
                        _respondBuf[respondBufPos] = b;
                        respondBufPos++;

                        var isResponseComplete = GenericCctalkDevice.IsResponseComplete(_respondBuf, respondBufPos);
                        if (isResponseComplete)
                        {
                            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.ParseResponse(_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 variables and be ready to recive the next message)", ex);
                    }
                }

                Thread.Sleep(100);

                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();
 }