private void readStateMachine()
        {
            string telegram;
            if (m_readQ.TryDequeue(out telegram))
            {
                int loglinedisplay = Params.getParam("loglinedisplay", "viastdproto", 0);
                if (!m_readBuf.getData().Contains("line_display") || loglinedisplay == 1)
                {
                    m_socketLog.log(LogTools.getCardString("ViaStdProto", "readStateMachine", "Received: <" + telegram + ">"));
                }
                m_readBuf.Assign(telegram);

                if (m_readBuf.getLength() == 0) // bad telegram, disconnect
                {
                    m_socketLog.log(LogTools.getErrorString("ViaStdProto", "internalRead","Received telegram has invalid header or trailer (or no data) restarting the socket"));
                    disconnect();
                }

                // Data Telegram
                if (m_readBuf.isData())
                {
                    SeqNumStatus sNS = checkSeqErr(m_readBuf.getSeqNumber());
                    switch (sNS)
                    {
                        default:
                        case SeqNumStatus.INVALID_ORDER:
                            m_socketLog.log(LogTools.getErrorString("ViaStdProto", "internalRead",
                                "Sequence number received "
                                + m_readBuf.getSeqNumber() + ", but should have been " + incSeq(m_recSeqNum)));
                                //+ ". Sending ACKN and ingoring message."));
                            m_recQ.Enqueue(m_readBuf.getData());  // put it in the receive queue to be passed to the software.
                            m_recSeqNum = m_readBuf.getSeqNumber(); // accept whatever sequence number we just got...
                            break;
                        case SeqNumStatus.DUPLICATE:
                            m_socketLog.log(LogTools.getErrorString("ViaStdProto", "internalRead",
                                "Duplicate message received (sequence number: " + m_readBuf.getSeqNumber()
                                + "), send ACKN and ignored message."));
                            break;
                        case SeqNumStatus.OK:
                            m_recSeqNum = m_readBuf.getSeqNumber(); // accept whatever sequence number we just got...
                            m_recQ.Enqueue(m_readBuf.getData());  // put it in the receive queue to be passed to the software.
                            break;
                    }

                    m_lastRecieve = DateTime.Now;
                    m_ackWriteQueue.Enqueue(m_readBuf.getSeqNumber());
                }
                // ACKN telegram
                else if (m_readBuf.isAck())
                {
                    //check if we sent a telegram which waits for an ACKN (or we were in that but got interrupted)
                    if ((m_writeState == WriteState.WAIT_ACK)||(m_writeState == WriteState.WAIT_ASYNCH_INTERRUPT))
                    {
                        // yes there is a telegram waiting for an ACKN
                        // compare the sequence numbers
                        ViaTelegram writeTele = new ViaTelegram();
                        writeTele.Assign(Encoding.ASCII.GetString(m_sendBuffer));
                        if (m_readBuf.getSeqNumber() == writeTele.getSeqNumber())
                        {
                            m_sendSeqNum = incSeq(writeTele.getSeqNumber());
                            m_writeState = WriteState.READY;
                        }
                        else
                        {
                            m_writeState = WriteState.READY;
                            m_socketLog.log(LogTools.getErrorString("viaStdProto", "internalRead",
                                "Received ack telegram has wrong sequence number, accept anyway. Expected sequence number: " + writeTele.getSeqNumber() + ", got: " + m_readBuf.getSeqNumber()));
                        }
                    }
                    else
                    {
                        m_socketLog.log(LogTools.getErrorString("ViaStdProto", "internalRead",
                            "Received an ACKN telegram without having sent a telegram that's waiting for an ACK"));
                    }
                    m_lastRecieve = DateTime.Now;
                }
                else if (m_readBuf.isKeepAlive())
                {
                    m_lastRecieve = DateTime.Now;
                }
                else if (m_readBuf.isNak())
                {
                    disconnect();
                    m_socketLog.log(LogTools.getErrorString("viaStdProto", "readStateMachine", "NAK recieved, reset socket"));
                }
                else
                {
                    m_socketLog.log(LogTools.getErrorString("viaStdProto", "readStateMachine", "unknown message recieved, ignore"));
                }

            }
        }
        // Public Methods
        // ========================================================================================
        // ----------------------------------------------------------------------------------------
        // Constructor with all fields
        //      addr: IP address
        //      port: port number
        //      server: true if we are the server, false if we are the client
        //      srcid: our id Ex: "VLS1"
        //      destid: id of target Ex: "MFC1", "IOC1" ...
        //      toacknak: time to wait for ack before re-sending (in seconds)
        //      datalen: length of telegram, pad telegram if shorter than datalen.
        //      fillchar: character to pad with
        //      binary: true: telegrams are binary (IO) false: telegrams are ASCII (data)
        //      tokeepalive: time to wait before sending keep alive mesage (seconds)  0 = disabled
        // ----------------------------------------------------------------------------------------
        public ViaStdProto(IPAddress addr, int port, bool server, string srcid, string destid, int toacknak, int datalen, char fillchar, bool binary, int tokeepalive)
        {
            m_addr = addr;
            m_port = port;
            m_server = server;
            m_srcid = srcid;
            m_destid = destid;
            m_datalen = datalen;
            m_fillchar = fillchar;
            m_binary = binary;
            m_recSeqNum = 0;
            m_sendSeqNum = 1;
            m_readBuf = new ViaTelegram();
            m_writeBuf = new ViaTelegram();
            m_numResends = 0;

            m_recQ = new ConcurrentQueue<string>();
            m_readQ = new ConcurrentQueue<string>();
            m_dataWriteQueue = new ConcurrentQueue<string>();
            m_ackWriteQueue = new ConcurrentQueue<int>();

            m_keepaliveStr = "00 keep alive telegram ";
            m_socketLog = null;// MainWindow.logBook.requestLog("Kiosk_Socket" + m_port + ".log");

            m_socketLog.log(LogTools.getStatusString("ViaStdProto", "ViaStdProto",
                "Creating socket: \n" + "Addr = " + m_addr +
                "\tPort = " + m_port + "\tServer = " + m_server +
                "\tSrc ID = " + m_srcid + "\tDest ID = " + m_destid +
                "\tData Length = " + m_datalen + "\tBinary = " + m_binary));

            m_recvAccumulator = "";

            if (toacknak <= 0)
            {
                toacknak = 5000; //default the value to 5 seconds if no value was passed
            }
            m_toacknak = new TimeSpan(0, 0, 0, 0, toacknak);
            m_sendTimeout = m_toacknak;

            m_toKeepaliveSend = new TimeSpan(0, 0, tokeepalive);
            m_toKeepaliveRecv = new TimeSpan(0, 0, 2*tokeepalive);

            m_lastConnected = DateTime.Now;
        }