public byte[] ReceiveResponsePacket()
        {
            int start = Environment.TickCount;

            int myTimeout = RECEIVE_RESPONSE_TIMEOUT;

            if (!_masterMode)
            {
                myTimeout = Timeout.Infinite;
            }

            while (NetworkTpdu.CreateFromBuffer(_receiveBuffer, false) == null && (!_masterMode || Environment.TickCount - start < myTimeout))
            {
                _receiveBuffer.WaitForByte(myTimeout, false);
            }

            NetworkTpdu responseTpdu = NetworkTpdu.CreateFromBuffer(_receiveBuffer, true);

            if (responseTpdu != null)
            {
                _log.Debug("Received TPDU: {0}", ByteHelpers.ByteToString(responseTpdu.GetTPDUData()));
            }

            if (responseTpdu == null)
            {
                return(null);
            }
            else
            {
                return(responseTpdu.GetAPDUData());
            }
        }
        public void WriteXml(XmlElement rootNode)
        {
            XmlHelper.WriteString(rootNode, "RawData", ByteHelpers.ByteToString(_rawApduData));
            BCDNumberParameter receiptNr = this.FindParameter <BCDNumberParameter>(StatusInformationApdu.StatusParameterEnum.ReceiptNr);

            if (receiptNr != null)
            {
                XmlHelper.WriteInt64(rootNode, "ReceiptNr", receiptNr.DecodeNumber());
            }
            PrefixedParameter <AsciiLVarParameter> additional = this.FindParameter <PrefixedParameter <AsciiLVarParameter> >(StatusInformationApdu.StatusParameterEnum.AdditionalCardDataForECCash);

            if (additional != null)
            {
                XmlHelper.WriteString(rootNode, "Additional", additional.SubParameter.Text);
            }
            PrefixedParameter <StatusPanEfId> panefid = this.FindParameter <PrefixedParameter <StatusPanEfId> >(StatusInformationApdu.StatusParameterEnum.PanEfId);

            if (panefid != null)
            {
                XmlHelper.WriteString(rootNode, "PanEfid", panefid.SubParameter.DecodeNumberAsString());
            }

            PrefixedParameter <BCDNumberParameter> amount = this.FindParameter <PrefixedParameter <BCDNumberParameter> >(StatusInformationApdu.StatusParameterEnum.Amount);

            if (amount != null)
            {
                XmlHelper.WriteInt64(rootNode, "Amount", amount.SubParameter.DecodeNumber());
            }
            PrefixedParameter <AsciiLVarParameter> additionalInfo = this.FindParameter <PrefixedParameter <AsciiLVarParameter> >(StatusInformationApdu.StatusParameterEnum.AdditionalTextForCC);

            if (additionalInfo != null)
            {
                XmlHelper.WriteString(rootNode, "AdditionalInfo", additionalInfo.SubParameter.Text);
            }
        }
        public byte[] ReceiveResponsePacket()
        {
            int start = Environment.TickCount;

            int myTimeout = RECEIVE_RESPONSE_TIMEOUT;

            if (!_masterMode)
            {
                myTimeout = MASTER_RESPONES_TIMEOUT;
            }
            int waitTimeLeft = -1;

            while (NetworkTpdu.CreateFromBuffer(_receiveBuffer, false) == null && (Environment.TickCount - start < myTimeout))
            {
                if (waitTimeLeft < 1)
                {
                    _receiveBuffer.WaitForByte(myTimeout, false);
                }
                else
                {
                    _receiveBuffer.WaitForByte(waitTimeLeft, false);
                }

                /*
                 * the waitTimeLeft variable is used if one waitForByte call does not wait for the full timeout duration
                 * Without the waitTimeLeft variable the system would try to wait another full timeout duration instead of
                 * the time left.
                 */
                waitTimeLeft = myTimeout - (Environment.TickCount - start);
            }

            NetworkTpdu responseTpdu = NetworkTpdu.CreateFromBuffer(_receiveBuffer, true);

            if (responseTpdu != null)
            {
                _log.Debug("Received TPDU: {0}", ByteHelpers.ByteToString(responseTpdu.GetTPDUData()));
            }

            if (responseTpdu == null)
            {
                throw new ConnectionTimeOutException();
            }
            else
            {
                return(responseTpdu.GetAPDUData());
            }
        }
        /// <summary>
        /// Transmits one tpdu and sends the NAK or ACK
        /// </summary>
        /// <param name="tpduData"></param>
        /// <returns></returns>
        private void SafeTransmit(byte[] tpduData)
        {
            int  transmitCounter  = 0;
            bool transmitSucceded = false;

            while (transmitCounter <= MAX_BLOCKREPEATS && !transmitSucceded)
            {
                _log.Debug("Sending transmitCounter={1}: {0}", ByteHelpers.ByteToString(tpduData), transmitCounter);
                //Write Data to the serial port
                _serialPort.SendData(tpduData, 0, tpduData.Length);

                //Read NAK or ACK or something else ;)
                byte?statusByte = null;

                statusByte = _buffer.WaitForByte(BLOCK_TIMEOUT, true);

                if (statusByte != null && statusByte == ACK)
                {
                    transmitSucceded = true;
                    return;
                }
                else
                {
                    _log.Debug("TPDU transmission failed, increasing transmitCounter to '{0}'", transmitCounter + 1);
                    transmitCounter++;
                }
            }

            if (transmitSucceded == false)
            {
                _log.Debug("TPDU transmission failed {0}-times, reporting error to application layer", transmitCounter);
                throw new RS232TransportException(string.Format("TPDU transmission failed {0}-times, reporting error to application layer", transmitCounter));
            }
            else
            {
                //Should never get here
                Debug.Assert(false);
                throw new InvalidOperationException("Transmission succeeded but no data");
            }
        }
 public void Transmit(IZvtTpdu tpdu)
 {
     byte[] data = tpdu.GetTPDUData();
     _log.Debug("Transmitting TPDU: {0}", ByteHelpers.ByteToString(data));
     _client.GetStream().Write(data, 0, data.Length);
 }
        /// <summary>
        /// Waits for a complete TPDU frame, checks the checksum and sends the ACK, NAK
        /// </summary>
        /// <returns></returns>
        private byte[] ReceiveTpduFrame()
        {
            bool        frameComplete = false;
            List <byte> frameData     = new List <byte>();

            //Time measurement, the receive of a whole Frame should not exceed BLOCK_TIMEOUT
            int startTick = Environment.TickCount;

            ReceiveStates currentState = ReceiveStates.WaitForStartingDLE;

            int myTimeout = RECEIVE_RESPONSE_TIMEOUT;

            if (!_masterMode)
            {
                myTimeout = MASTER_RESPONES_TIMEOUT;
            }

            while (!frameComplete && (!_masterMode || Environment.TickCount - startTick < RECEIVE_RESPONSE_TIMEOUT))
            {
                //For the first [DLE] the timeout is BLOCK_TIMEOUT, after the DLE was received
                //only BYTE_TIMEOUT is allowed during the bytes
                byte?myByte = _buffer.WaitForByte(myTimeout, true);

                //A Timeout occured, set state to error state and send nak
                if (myByte == null)
                {
                    _log.Debug("ReceiveTpduFrame: timeout occured, going into error state");
                    frameComplete = true;
                    currentState  = ReceiveStates.Error;
                    continue;
                }


                if (currentState != ReceiveStates.WaitForStartingDLE)
                {
                    frameData.Add(myByte.Value);
                }


                //Simple Statemachine implementation see ReceiveStates for possible state transitions

                if (currentState == ReceiveStates.WaitForStartingDLE && myByte.Value == RS232Tpdu.DLE)
                {
                    frameData.Add(myByte.Value);
                    currentState = ReceiveStates.WaitForSTX;
                }
                else if (currentState == ReceiveStates.WaitForSTX && myByte.Value == RS232Tpdu.STX)
                {
                    currentState = ReceiveStates.APDUData;
                }
                else if (currentState == ReceiveStates.WaitForSTX)
                {
                    _log.Debug("ReceiveTpduFrame: No STX after DLE, resetting and waiting for DLE");
                    currentState = ReceiveStates.WaitForStartingDLE;
                    frameData.Clear();
                }
                else if (currentState == ReceiveStates.APDUData && myByte.Value == RS232Tpdu.DLE)
                {
                    currentState = ReceiveStates.WaitForDoubleDLE;
                }
                else if (currentState == ReceiveStates.WaitForDoubleDLE && myByte.Value == RS232Tpdu.DLE)
                {
                    currentState = ReceiveStates.APDUData;
                }
                else if (currentState == ReceiveStates.WaitForDoubleDLE && myByte.Value == RS232Tpdu.ETX)
                {
                    currentState = ReceiveStates.WaitForCRCLow;
                }
                else if (currentState == ReceiveStates.WaitForDoubleDLE)
                {
                    _log.Debug("ReceiveTpduFrame: Invalid byte after DLE, received {0:X2}", myByte.Value);
                    frameComplete = true;
                    currentState  = ReceiveStates.Error;
                }
                else if (currentState == ReceiveStates.WaitForCRCLow)
                {
                    currentState = ReceiveStates.WaitForCRCHigh;
                }
                else if (currentState == ReceiveStates.WaitForCRCHigh)
                {
                    _log.Debug("ReceiveTpduFrame: {0}", ByteHelpers.ByteToString(frameData.ToArray()));
                    frameComplete = true;
                    currentState  = ReceiveStates.Completed;
                }
            }

            if (currentState == ReceiveStates.Completed)
            {
                return(frameData.ToArray());
            }
            else
            {
                return(null);
            }
        }
 public void WriteXml(XmlElement rootNode)
 {
     XmlHelper.WriteString(rootNode, "RawData", ByteHelpers.ByteToString(_rawApduData));
 }