// Used internally
        /// <summary>
        /// Sends reading command using ABECS when card have a chip.
        /// </summary>
        /// <param name="pinpadCommunication">Pinpad communication, through which the communication with the pinpad is made.</param>
        /// <param name="amount">Transaction amount.</param>
        /// <returns>ABECS GOC command response.</returns>
        private GocResponse SendGoc(IPinpadCommunication pinpadCommunication, decimal amount)
        {
            GocRequest request = new GocRequest();

            request.GOC_AMOUNT.Value   = Convert.ToInt64(amount * 100);
            request.GOC_CASHBACK.Value = 0;
            request.GOC_EXCLIST.Value  = false;
            request.GOC_CONNECT.Value  = true;
            request.GOC_METHOD.Value   = new CryptographyMethod(KeyManagementMode.DerivedUniqueKeyPerTransaction,
                                                                CryptographyMode.TripleDataEncryptionStandard);
            request.GOC_KEYIDX.Value   = (int)StoneIndexCode.EncryptionKey;
            request.GOC_WKENC.Value    = new HexadecimalData("00000000000000000000000000000000");
            request.GOC_RISKMAN.Value  = false;
            request.GOC_FLRLIMIT.Value = new HexadecimalData("00000000");
            request.GOC_TPBRS.Value    = 0;
            request.GOC_TVBRS.Value    = new HexadecimalData("00000000");
            request.GOC_MTPBRS.Value   = 0;
            request.GOC_TAGS1.Value    = new HexadecimalData(EmvTag.GetEmvTagsRequired());
            request.GOC_TAGS2.Value    = new HexadecimalData(string.Empty);

            GocResponse response = pinpadCommunication.SendRequestAndReceiveResponse <GocResponse>(request);

            return(response);
        }
        // Methods
        /// <summary>
        /// Reads the card.
        /// </summary>
        /// <param name="communication">Pinpad facade, responsible for pinpad communication and plus.</param>
        /// <param name="amount">Transaction amount.</param>
        /// <param name="pin">Pin information read.</param>
        /// <returns>Operation status.</returns>
        internal ResponseStatus Read(IPinpadCommunication communication, decimal amount, out Pin pin)
        {
            pin = null;

            // Validating data
            this.Validate(communication, amount);

            // Using ABECS GOC command to communicate with pinpad.
            GocResponse commandResponse = this.SendGoc(communication, amount);

            if (commandResponse == null)
            {
                if (communication.Ping() == true)
                {
                    // Pinpad is connected. Time out.
                    return(ResponseStatus.TimeOut);
                }
                else
                {
                    // Pinpad loss conection.
                    throw new PinpadDisconnectedException("Não foi possível ler a senha.\nVerifique a conexão com o pinpad.");
                }
            }

            // Saving command response status:
            AbecsResponseStatus legacyStatus = commandResponse.RSP_STAT.Value;
            ResponseStatus      status       = ResponseStatusMapper.MapLegacyResponseStatus(legacyStatus);

            if (status != ResponseStatus.Ok)
            {
                return(status);
            }
            //if (status == ResponseStatus.OperationCancelled) { return status; }

            pin = new Pin();
            pin.ApplicationCryptogram = this.GetValueFromEmvData(
                commandResponse.GOC_EMVDAT.Value.DataString, EmvTagCode.ApplicationCryptogram);
            pin.CardholderNameExtended = this.GetValueFromEmvData(
                commandResponse.GOC_EMVDAT.Value.DataString, EmvTagCode.CardholderNameExtended);

            // Whether is a pin online authentication or not.
            if (commandResponse.GOC_PINONL.Value.HasValue == true)
            {
                pin.IsOnline = commandResponse.GOC_PINONL.Value.Value;
            }

            // If EMV data war not returned from the command:
            if (commandResponse.GOC_EMVDAT.HasValue == false)
            {
                return(ResponseStatus.PinBusy);
            }

            // Savind EMV data:
            if (commandResponse.GOC_EMVDAT.Value != null)
            {
                pin.EmvData = commandResponse.GOC_EMVDAT.Value.DataString;
            }

            if (pin.IsOnline == true && commandResponse.GOC_DECISION.Value == OfflineTransactionStatus.RequiresAuthorization)
            {
                // If it's an online transaction, that is, needs pin and ksn emv validation:
                pin.PinBlock        = commandResponse.GOC_PINBLK.Value.DataString;
                pin.KeySerialNumber = commandResponse.GOC_KSN.Value.DataString;
            }

            // Returns read pin block.
            return(status);
        }