public override int Deserialize(byte[] rawTlv, int pos)
            {
                pos = base.Deserialize(rawTlv, pos);

                byte[] amountXBytes = new byte[4];
                byte[] amountYBytes = new byte[4];
                Array.Copy(Value, 0, amountXBytes, 0, 4);
                Array.Copy(Value, 4, amountYBytes, 0, 4);

                AmountX = Formatting.BcdToLong(amountXBytes);
                AmountY = Formatting.BcdToLong(amountYBytes);

                int noEntriesLength = Value.Length;

                for (int i = 8; i < noEntriesLength;)//dont increment
                {
                    CardHolderVerificationRule r = new CardHolderVerificationRule();
                    i = r.deserialize(Value, i);
                    CardHolderVerificationRules.Add(r);
                }

                return(pos);
            }
        internal static SignalsEnum DoCommonProcessing(string source, Kernel2Database database, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            if (database.IsEmpty(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag))
            {
                DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
                #region 78.2
                dataNeeded.Value.Tags.Add(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag);
                #endregion
                dataNeeded.UpdateDB();

                return(Do78_3(source, database, qManager, sw));
            }
            else
            {
                #region 78.7
                if (database.IsPresent(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag) &&
                    database.Get(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2).Value[0] == 0x00)
                #endregion
                {
                    #region 78.3
                    return(Do78_3(source, database, qManager, sw));

                    #endregion
                }
                else
                {
                    #region 78.8
                    if (database.IsEmpty(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN.Tag))
                    #endregion
                    {
                        #region 78.9
                        CommonRoutines.CreateEMVDiscretionaryData(database);
                        return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, L1Enum.NOT_SET, L2Enum.NOT_SET, L3Enum.AMOUNT_NOT_PRESENT));

                        #endregion
                    }
                    #region 78.10
                    long aa   = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);
                    long rctl = database.ReaderContactlessTransactionLismit;
                    if (aa > rctl)
                    #endregion
                    {
                        #region 78.11
                        CommonRoutines.CreateEMVDiscretionaryData(database);
                        return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.MAX_LIMIT_EXCEEDED, L3Enum.NOT_SET));

                        #endregion
                    }

                    #region 78.12
                    foreach (TLV tlv in database.TagsToReadYet)
                    {
                        if (database.IsPresent(tlv.Tag.TagLable))
                        {
                            database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(tlv);
                        }
                        else
                        if (database.IsKnown(tlv.Tag.TagLable))
                        {
                            database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(TLV.Create(tlv.Tag.TagLable));
                        }

                        database.TagsToReadYet.RemoveFromList(tlv);
                    }
                    #endregion

                    #region 78.13
                    if (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag))
                    #endregion
                    {
                        #region 78.14
                        CommonRoutines.PostDEK(database, qManager);
                        database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                        database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
                        #endregion
                    }

                    #region 78.15
                    //The 8-nUN most significant digits must be set to zero
                    TLV rNN = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_NUMERIC_9F6A_KRN2);
                    if (rNN == null)
                    {
                        database.AddToList(TLV.Create(EMVTagsEnum.UNPREDICTABLE_NUMBER_NUMERIC_9F6A_KRN2.Tag));
                        rNN = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_NUMERIC_9F6A_KRN2);
                    }
                    rNN.Value = Formatting.GetRandomNumberNumeric(8 - database.NUN);
                    #endregion

                    #region 78.16
                    APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
                    if (aip.Value.OnDeviceCardholderVerificationIsSupported)
                    #endregion
                    {
                        #region 78.19
                        if (aa > rctl)
                        #endregion
                        {
                            #region 78.20
                            byte msi = database.Get(EMVTagsEnum.MOBILE_SUPPORT_INDICATOR_9F7E_KRN2).Value[0];
                            msi = (byte)(msi | 0x02);
                            database.Get(EMVTagsEnum.MOBILE_SUPPORT_INDICATOR_9F7E_KRN2).Value[0] = msi;
                            #endregion
                        }

                        #region 78.21
                        EMVComputeCryptographicChecksumRequest request = new EMVComputeCryptographicChecksumRequest(CommonRoutines.PackUdolRelatedDataTag(database));
                        #endregion

                        #region 78.22
                        cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                        #endregion

                        return(SignalsEnum.WAITING_FOR_CCC_RESPONSE_2);
                    }
                    else
                    {
                        #region 78.17
                        EMVComputeCryptographicChecksumRequest request = new EMVComputeCryptographicChecksumRequest(CommonRoutines.PackUdolRelatedDataTag(database));
                        #endregion

                        #region 78.17
                        cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                        #endregion

                        return(SignalsEnum.WAITING_FOR_CCC_RESPONSE_1);
                    }
                }
            }
        }
Beispiel #3
0
        /*
         * 14.6
         */
        private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, TornTransactionLogManager tornTransactionLogManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager)
        {
            #region 14.9
            if (!cardResponse.ApduResponse.Succeeded)
            #endregion
            {
                #region 14.10
                CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.STATUS_BYTES, L3Enum.NOT_SET);
                return(DoInvalidResponse(database, qManager));

                #endregion
            }

            #region 14.11
            bool parsingResult = false;
            if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77)
            {
                EMVComputeCryptographicChecksumResponse response = cardResponse.ApduResponse as EMVComputeCryptographicChecksumResponse;
                parsingResult = database.ParseAndStoreCardResponse(response.ResponseData);
            }
            else
            {
                parsingResult = false;
            }
            #endregion

            #region 14.12
            if (!parsingResult)
            #endregion
            {
                #region 14.13
                CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET);
                return(DoInvalidResponse(database, qManager));

                #endregion
            }

            #region 14.12.1
            CommonRoutines.PostUIOnly(database, qManager, KernelMessageidentifierEnum.CLEAR_DISPLAY, KernelStatusEnum.CARD_READ_SUCCESSFULLY, true);
            #endregion

            #region 14.14
            if (database.IsEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) ||
                database.IsEmpty(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2.Tag))
            #endregion
            {
                #region 14.17
                CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET);
                return(DoInvalidResponse(database, qManager));

                #endregion
            }

            long nUN = 0;
            #region 14.15
            if (database.IsNotEmpty(EMVTagsEnum.CVC3_TRACK2_9F61_KRN2.Tag))
            #endregion
            {
                #region 14.16
                if (database.IsNotEmpty(EMVTagsEnum.TRACK_1_DATA_56_KRN2.Tag) &&
                    (database.IsNotPresent(EMVTagsEnum.CVC3_TRACK1_9F60_KRN2.Tag) ||
                     database.IsEmpty(EMVTagsEnum.CVC3_TRACK1_9F60_KRN2.Tag)))
                #endregion
                {
                    #region 14.17
                    CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET);
                    return(DoInvalidResponse(database, qManager));

                    #endregion
                }

                #region 14.20
                byte pcii = database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value[1];
                #endregion
                if ((pcii & 0x10) == 0x10)   //OD-CVM verification successful
                {
                    #region 14.24
                    nUN = (nUN + 5) % 10;
                    #endregion
                }
                else
                {
                    #region 14.21
                    long aa   = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);
                    long rctl = database.ReaderContactlessTransactionLismit;
                    if (aa > rctl)
                    #endregion
                    {
                        #region 14.21.1
                        CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET);
                        return(DoInvalidResponse(database, qManager));

                        #endregion
                    }
                    else
                    {
                        #region 14.25
                        nUN = (int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value);
                        #endregion
                    }
                }

                #region 14.25.1
                database.FailedMSCntr = 0;
                #endregion

                #region 14.26
                TRACK_2_DATA_9F6B_KRN2 t2d = new TRACK_2_DATA_9F6B_KRN2(database);
                ushort t2 = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.NATC_TRACK2_9F67_KRN2).Value);

                TLV       PCVC3_TRACK2_9F65_KRN2       = database.Get(EMVTagsEnum.PCVC3_TRACK2_9F65_KRN2);
                MagBitmap bitmapPCVC3_TRACK2_9F65_KRN2 = new MagBitmap(PCVC3_TRACK2_9F65_KRN2.Value);

                TLV    CVC3_TRACK2_9F61_KRN2 = database.Get(EMVTagsEnum.CVC3_TRACK2_9F61_KRN2);
                ushort cvc3T2AsShort         = Formatting.ConvertToInt16(CVC3_TRACK2_9F61_KRN2.Value.Reverse().ToArray());

                string q2LeastSigDigits = Convert.ToString(cvc3T2AsShort);
                q2LeastSigDigits            = q2LeastSigDigits.Substring(q2LeastSigDigits.Length - bitmapPCVC3_TRACK2_9F65_KRN2.NonZeroCount);
                t2d.Value.DiscretionaryData = Formatting.StringToBcd(bitmapPCVC3_TRACK2_9F65_KRN2.ReplaceValues(Formatting.BcdToString(t2d.Value.DiscretionaryData), q2LeastSigDigits, bitmapPCVC3_TRACK2_9F65_KRN2.NonZeroCount, true), false);

                TLV       PUNATC_TRACK2_9F66_KRN2       = database.Get(EMVTagsEnum.PUNATC_TRACK2_9F66_KRN2);
                MagBitmap bitmapPUNATC_TRACK2_9F66_KRN2 = new MagBitmap(PUNATC_TRACK2_9F66_KRN2.Value);
                uint      unpredInt    = Formatting.ConvertToInt32(database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_NUMERIC_9F6A_KRN2).Value.Reverse().ToArray());
                string    unpredString = Convert.ToString(unpredInt);
                unpredString = unpredString.Substring(unpredString.Length - database.NUN);
                t2d.Value.DiscretionaryData = Formatting.StringToBcd(bitmapPUNATC_TRACK2_9F66_KRN2.ReplaceValues(Formatting.BcdToString(t2d.Value.DiscretionaryData), unpredString, database.NUN, true), false);

                if (t2 != 0)
                {
                    TLV    APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN = database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN);
                    uint   atcAsShort = Formatting.ConvertToInt32(APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Value.Reverse().ToArray());
                    string atcAsShortLeastSigDigits = Convert.ToString(atcAsShort);
                    atcAsShortLeastSigDigits    = atcAsShortLeastSigDigits.PadLeft(t2, '0').Substring(atcAsShortLeastSigDigits.Length - t2);
                    t2d.Value.DiscretionaryData = Formatting.StringToBcd(bitmapPUNATC_TRACK2_9F66_KRN2.ReplaceValues(Formatting.BcdToString(t2d.Value.DiscretionaryData), atcAsShortLeastSigDigits, t2, false), false);
                }
                #endregion

                #region 14.27
                StringBuilder dd = new StringBuilder(Formatting.BcdToString(t2d.Value.DiscretionaryData));
                dd[dd.Length - 1]           = Convert.ToString(nUN)[0];
                t2d.Value.DiscretionaryData = Formatting.StringToBcd(dd.ToString(), false);
                #endregion

                t2d.Serialize(); //reserialize in case the length of discretionary data changed
                t2d.UpdateDB();

                #region 14.28
                if (database.IsNotEmpty(EMVTagsEnum.TRACK_1_DATA_56_KRN2.Tag))
                #endregion
                {
                    #region 14.29
                    TRACK_1_DATA_56_KRN2 t1d = new TRACK_1_DATA_56_KRN2(database);
                    ushort t1 = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.NATC_TRACK1_9F64_KRN2).Value);

                    TLV       PCVC3_TRACK1_9F62_KRN2       = database.Get(EMVTagsEnum.PCVC3_TRACK1_9F62_KRN2);
                    MagBitmap bitmapPCVC3_TRACK1_9F62_KRN2 = new MagBitmap(PCVC3_TRACK1_9F62_KRN2.Value);

                    TLV    CVC3_TRACK1_9F60_KRN2 = database.Get(EMVTagsEnum.CVC3_TRACK1_9F60_KRN2);
                    ushort cvc3T1AsShort         = Formatting.ConvertToInt16(CVC3_TRACK1_9F60_KRN2.Value.Reverse().ToArray());

                    string q1LeastSigDigits = Convert.ToString(cvc3T1AsShort);
                    q1LeastSigDigits            = q1LeastSigDigits.Substring(q1LeastSigDigits.Length - bitmapPCVC3_TRACK1_9F62_KRN2.NonZeroCount);
                    t1d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(bitmapPCVC3_TRACK1_9F62_KRN2.ReplaceValues(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData), q1LeastSigDigits, bitmapPCVC3_TRACK1_9F62_KRN2.NonZeroCount, true));

                    TLV       PUNATC_TRACK1_9F63_KRN2       = database.Get(EMVTagsEnum.PUNATC_TRACK1_9F63_KRN2);
                    MagBitmap bitmapPUNATC_TRACK1_9F63_KRN2 = new MagBitmap(PUNATC_TRACK1_9F63_KRN2.Value);
                    t1d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(bitmapPUNATC_TRACK1_9F63_KRN2.ReplaceValues(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData), unpredString, database.NUN, true));

                    if (t2 != 0)
                    {
                        TLV    APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN = database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN);
                        uint   atcAsShort = Formatting.ConvertToInt32(APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Value.Reverse().ToArray());
                        string atcAsShortLeastSigDigits = Convert.ToString(atcAsShort);
                        atcAsShortLeastSigDigits    = atcAsShortLeastSigDigits.PadLeft(t2, '0').Substring(atcAsShortLeastSigDigits.Length - t1);
                        t2d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(bitmapPUNATC_TRACK1_9F63_KRN2.ReplaceValues(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData), atcAsShortLeastSigDigits, t1, false));
                    }
                    #endregion

                    #region 14.30
                    StringBuilder dd1 = new StringBuilder(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData));
                    dd1[dd1.Length - 1]         = Convert.ToString(nUN)[0];
                    t1d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(dd1.ToString());
                    #endregion

                    t1d.Serialize(); //reserialize in case the length of discretionary data changed
                    t1d.UpdateDB();
                }

                #region 14.32
                Kernel2OutcomeStatusEnum k2OutcomeStatus = Kernel2OutcomeStatusEnum.ONLINE_REQUEST;
                KernelCVMEnum            cvmEnum         = KernelCVMEnum.N_A;
                bool receipt = false;

                pcii = database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value[1];
                if ((pcii & 0x10) == 0x10)   //OD-CVM verification successful
                #endregion
                {
                    #region 14.34
                    cvmEnum = KernelCVMEnum.CONFIRMATION_CODE_VERIFIED;
                    long aa   = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);
                    long rctl = database.ReaderContactlessTransactionLismit;
                    if (aa > rctl)
                    {
                        receipt = true;
                    }
                    #endregion
                }
                else
                {
                    #region 14.33
                    cvmEnum = KernelCVMEnum.NO_CVM;
                    #endregion
                }
                CommonRoutines.CreateMSDiscretionaryDataRecord(database);
                CommonRoutines.CreateMSDataRecord(database);
                return(CommonRoutines.PostOutcomeOnly(database, qManager, k2OutcomeStatus, cvmEnum, receipt));
            }
            else
            {
                #region 14.19.1
                if (((int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value) & 0x00030F) != 0x000000)
                #endregion
                {
                    KernelMessageidentifierEnum k2MessageIdentifier = KernelMessageidentifierEnum.DECLINED;
                    KernelStatusEnum            k2Status            = KernelStatusEnum.READY_TO_READ;
                    byte[] holdTime = new byte[] { 0x00, 0x00, 0x00 };

                    #region 14.22
                    PHONE_MESSAGE_TABLE_DF8131_KRN2 pmt = (PHONE_MESSAGE_TABLE_DF8131_KRN2)database.GetDefault(EMVTagsEnum.PHONE_MESSAGE_TABLE_DF8131_KRN2);
                    foreach (PhoneMessageTableEntry_DF8131 entry in pmt.Value.Entries)
                    {
                        int pcii     = (int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value);
                        int pciMask  = (int)Formatting.ConvertToInt32(entry.PCIIMask);
                        int pciValue = (int)Formatting.ConvertToInt32(entry.PCIIValue);
                        if ((pciMask & pcii) == pciValue)
                        {
                            k2MessageIdentifier = entry.MessageIdentifier;
                            k2Status            = entry.Status;
                            holdTime            = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value;
                            break;
                        }
                    }
                    #endregion

                    #region 14.21.1
                    int waitTime = ((2 ^ database.FailedMSCntr) * 300);
                    Task.Delay(TimeSpan.FromMilliseconds(waitTime)).Wait();
                    #endregion

                    #region 14.21.2
                    database.FailedMSCntr = Math.Min(database.FailedMSCntr + 1, 5);
                    #endregion

                    #region 14.23
                    CommonRoutines.CreateMSDiscretionaryDataRecord(database);
                    CommonRoutines.CreateMSDataRecord(database);

                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      k2MessageIdentifier,
                                                      k2Status,
                                                      holdTime,
                                                      Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                      Kernel2StartEnum.B,
                                                      false,
                                                      KernelMessageidentifierEnum.N_A,
                                                      L1Enum.NOT_SET,
                                                      null,
                                                      L2Enum.NOT_SET,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
                else
                {
                    #region 14.19.2.1
                    int waitTime = ((2 ^ database.FailedMSCntr) * 300);
                    Task.Delay(TimeSpan.FromMilliseconds(waitTime)).Wait();
                    #endregion
                    #region 14.19.2.2
                    database.FailedMSCntr = Math.Min(database.FailedMSCntr + 1, 5);
                    #endregion

                    #region 14.19.3
                    CommonRoutines.CreateMSDiscretionaryDataRecord(database);
                    CommonRoutines.CreateMSDataRecord(database);

                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      KernelMessageidentifierEnum.DECLINED,
                                                      KernelStatusEnum.NOT_READY,
                                                      database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value,
                                                      Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                      Kernel2StartEnum.N_A,
                                                      true,
                                                      KernelMessageidentifierEnum.N_A,
                                                      L1Enum.NOT_SET,
                                                      null,
                                                      L2Enum.NOT_SET,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
            }
        }
Beispiel #4
0
        public static void ProcessingRestrictions(KernelDatabaseBase database)
        {
            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

            if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_VERSION_NUMBER_CARD_9F08_KRN.Tag))
            {
                #region pre.2
                string pvnCard = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_VERSION_NUMBER_CARD_9F08_KRN).Value);
                string pvnTerm = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_VERSION_NUMBER_TERMINAL_9F09_KRN).Value);
                if (pvnCard != pvnTerm)
                #endregion
                {
                    #region pre.3
                    tvr.Value.ICCAndTerminalHaveDifferentApplicationVersions = true;
                    tvr.UpdateDB();
                    #endregion
                }
            }

            DateTime transactionDate = EMVTagsEnum.TRANSACTION_DATE_9A_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.TRANSACTION_DATE_9A_KRN).Value);
            DateTime appExpiryDate   = EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN).Value);

            #region pre.4
            if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_EFFECTIVE_DATE_5F25_KRN.Tag))
            #endregion
            {
                DateTime appEffectiveDate = EMVTagsEnum.APPLICATION_EFFECTIVE_DATE_5F25_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.APPLICATION_EFFECTIVE_DATE_5F25_KRN).Value);
                #region pre.5
                if (transactionDate < appEffectiveDate)
                #endregion
                {
                    #region pre.6
                    tvr.Value.ApplicationNotYetEffective = true;
                    tvr.UpdateDB();
                    #endregion
                }
            }

            #region pre.7
            if (transactionDate > appExpiryDate)
            #endregion
            {
                #region pre.8

                tvr.Value.ExpiredApplication = true;
                tvr.UpdateDB();
                #endregion
            }

            #region pre.9
            if (database.IsEmpty(EMVTagsEnum.APPLICATION_USAGE_CONTROL_9F07_KRN.Tag))
            {
                return;
            }
            #endregion

            #region pre.10
            TERMINAL_TYPE_9F35_KRN tt = new TERMINAL_TYPE_9F35_KRN(database);
            ADDITIONAL_TERMINAL_CAPABILITIES_9F40_KRN atc = new ADDITIONAL_TERMINAL_CAPABILITIES_9F40_KRN(database);
            APPLICATION_USAGE_CONTROL_9F07_KRN        auc = new APPLICATION_USAGE_CONTROL_9F07_KRN(database);

            if ((tt.Value.TerminalType.Code == 0x14 || tt.Value.TerminalType.Code == 0x15 || tt.Value.TerminalType.Code == 0x16) &&
                atc.Value.IsCash)
            #endregion
            {
                #region pre.12
                if (!auc.Value.IsValidAtATMs)
                #endregion
                {
                    #region pre.13
                    tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                    tvr.UpdateDB();
                    return;

                    #endregion
                }
            }
            else
            {
                #region pre.11
                if (!auc.Value.IsValidAtTerminalsOtherThanATMs)
                #endregion
                {
                    #region pre.13
                    tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                    tvr.UpdateDB();
                    return;

                    #endregion
                }
            }

            #region pre.14
            if (database.IsEmpty(EMVTagsEnum.ISSUER_COUNTRY_CODE_5F28_KRN.Tag))
            {
                tvr.UpdateDB();
                return;
            }
            #endregion

            string tcc = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.TERMINAL_COUNTRY_CODE_9F1A_KRN).Value);
            string icc = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.ISSUER_COUNTRY_CODE_5F28_KRN).Value);

            byte transactionType = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0];


            #region pre.15
            if (transactionType == (byte)TransactionTypeEnum.CashWithdrawal ||
                transactionType == (byte)TransactionTypeEnum.CashDisbursement)
            #endregion
            {
                #region pre.16
                if (tcc == icc)
                #endregion
                {
                    #region pre.17
                    if (!auc.Value.IsValidForDomesticCashTransactions)
                    #endregion
                    {
                        #region pre.19
                        tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                        #endregion
                    }
                }
                else
                {
                    #region pre.18
                    if (!auc.Value.IsValidForInternationalCashTransactions)
                    #endregion
                    {
                        #region pre.19
                        tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                        #endregion
                    }
                }
            }

            #region pre.20
            if (transactionType == (byte)TransactionTypeEnum.PurchaseGoodsAndServices ||
                transactionType == (byte)TransactionTypeEnum.PurchaseWithCashback)
            #endregion
            {
                #region pre.21
                if (tcc == icc)
                #endregion
                {
                    #region pre.22
                    if (!(auc.Value.IsValidForDomesticGoods || auc.Value.IsValidForDomesticServices))
                    #endregion
                    {
                        #region pre.24
                        tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                        #endregion
                    }
                }
                else
                {
                    #region pre.23
                    if (!(auc.Value.IsValidForInternationalGoods || auc.Value.IsValidForInternationalServices))
                    #endregion
                    {
                        #region pre.24
                        tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                        #endregion
                    }
                }
            }

            #region pre.25
            if (database.IsNotPresent(EMVTagsEnum.AMOUNT_OTHER_NUMERIC_9F03_KRN.Tag))
            {
                tvr.UpdateDB();
                return;
            }

            if (Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_OTHER_NUMERIC_9F03_KRN).Value) == 0)
            {
                tvr.UpdateDB();
                return;
            }
            #endregion

            #region pre.26
            if (tcc == icc)
            #endregion
            {
                #region pre.27
                if (auc.Value.IsDomesticCashbackAllowed)
                {
                    tvr.UpdateDB();
                    return;
                }
                #endregion
            }
            else
            {
                #region pre.28
                if (auc.Value.IsInternationalCashbackAllowed)
                {
                    tvr.UpdateDB();
                    return;
                }
                #endregion
            }

            #region pre.29
            tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
            tvr.UpdateDB();
            #endregion
        }
        private async void EmvTxCtl_TxCompleted(object sender, EventArgs e)
        {
            try
            {
                TransactionType transactionType;
                string          fromAccountNumber    = "";
                string          cardSerialNumberFrom = "";
                string          toAccountNumber      = "";
                string          cardSerialNumberTo   = "";

                if ((e as TxCompletedEventArgs).EMV_Data.IsPresent())
                {
                    if ((e as TxCompletedEventArgs).TxResult == TxResult.Approved || (e as TxCompletedEventArgs).TxResult == TxResult.ContactlessOnline)
                    {
                        TLV data = (e as TxCompletedEventArgs).EMV_Data.Get();

                        byte[] panBCD;
                        TLV    _5A = data.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag);
                        if (_5A != null)
                        {
                            panBCD = _5A.Value;
                        }
                        else
                        {
                            TLV _57 = data.Children.Get(EMVTagsEnum.TRACK_2_EQUIVALENT_DATA_57_KRN.Tag);
                            if (_57 == null)
                            {
                                throw new Exception("No PAN found");
                            }
                            String panString = Formatting.ByteArrayToHexString(_57.Value);
                            panBCD = Formatting.StringToBcd(panString.Split('D')[0], false);
                        }

                        TLV _9F02 = data.Children.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN.Tag);
                        if (_9F02 == null)
                        {
                            throw new Exception("No Amount found");
                        }

                        long amount = Formatting.BcdToLong(_9F02.Value);

                        switch (flowType)
                        {
                        case FlowType.SendMoneyFromCardToApp:
                            toAccountNumber      = SessionSingleton.Account.AccountNumberId;
                            cardSerialNumberFrom = Formatting.BcdToString(panBCD);
                            transactionType      = TransactionType.SendMoneyFromCardToApp;
                            break;

                        case FlowType.SendMoneyFromAppToCard:
                            fromAccountNumber  = SessionSingleton.Account.AccountNumberId;
                            cardSerialNumberTo = Formatting.BcdToString(panBCD);
                            transactionType    = TransactionType.SendMoneyFromAppToCard;
                            break;

                        default:
                            throw new Exception("Unknown flow type:" + flowType);
                        }

                        try
                        {
                            await CallTransactByCardWebService(fromAccountNumber, toAccountNumber, cardSerialNumberFrom, cardSerialNumberTo, amount, transactionType, data);

                            Device.BeginInvokeOnMainThread(() =>
                            {
                                lblTransactSummary.Text = "Transaction Completed Succesfully";
                                UpdateView(ViewState.StepSummary);
                            });
                        }
                        catch
                        {
                            Device.BeginInvokeOnMainThread(() =>
                            {
                                lblTransactSummary.Text = "Declined, could not go online.";
                                UpdateView(ViewState.StepSummary);
                            });
                        }
                    }
                    else
                    {
                        Device.BeginInvokeOnMainThread(() =>
                        {
                            lblTransactSummary.Text = (e as TxCompletedEventArgs).TxResult.ToString();
                            UpdateView(ViewState.StepSummary);
                        });
                    }
                }
                else if ((e as TxCompletedEventArgs).QR_Data.IsPresent())
                {
                    QRDEList data     = (e as TxCompletedEventArgs).QR_Data.Get();
                    QRDE     _26      = data.Get(EMVQRTagsEnum.MERCHANT_ACCOUNT_INFORMATION_TEMPLATE_26.Tag);
                    QRDE     _54      = data.Get(EMVQRTagsEnum.TRANSACTION_AMOUNT_54.Tag);
                    QRDE     gui      = _26.Children.Get(EMVQRTagsEnum.GLOBALLY_UNIQUE_IDENTIFIER_00.Tag);
                    QRDE     tracking = _26.Children.Get(TagId._05);

                    long amount = Convert.ToInt64(_54.Value);

                    if ((e as TxCompletedEventArgs).TxResult == TxResult.QRCodeScanned)
                    {
                        switch (flowType)
                        {
                        case FlowType.SendMoneyFromCardToApp:
                            throw new Exception("Invalid flow type for Scanned QR code");

                        case FlowType.SendMoneyFromAppToCard:
                            fromAccountNumber = SessionSingleton.Account.AccountNumberId;
                            toAccountNumber   = gui.Value;
                            transactionType   = TransactionType.SendMoneyFromAppToCard;
                            break;

                        default:
                            throw new Exception("Unknown flow type:" + flowType);
                        }
                        try
                        {
                            await CallTransactByQRCodeWebService(fromAccountNumber, toAccountNumber, amount, tracking.Value);

                            Device.BeginInvokeOnMainThread(() =>
                            {
                                lblTransactSummary.Text = "Transaction Completed Succesfully";
                                UpdateView(ViewState.StepSummary);
                            });
                        }
                        catch (Exception ex)
                        {
                            Device.BeginInvokeOnMainThread(() =>
                            {
                                lblTransactSummary.Text = "Declined, could not go online.";
                                UpdateView(ViewState.StepSummary);
                            });
                        }
                    }
                    else if ((e as TxCompletedEventArgs).TxResult == TxResult.QRCodeToPoll)
                    {
                        switch (flowType)
                        {
                        case FlowType.SendMoneyFromCardToApp:
                            break;

                        case FlowType.SendMoneyFromAppToCard:
                            throw new Exception("Invalid flow type for QR code");

                        default:
                            throw new Exception("Unknown flow type:" + flowType);
                        }

                        try
                        {
                            bool success = await CallTransactGetStateWebService(tracking.Value);

                            //bool success = await CallTransactGetStateWebService("929fa290b20647988f72f2ca762bc3e7");
                            if (success)
                            {
                                Device.BeginInvokeOnMainThread(() =>
                                {
                                    lblTransactSummary.Text = "Transaction Approved";
                                    UpdateView(ViewState.StepSummary);
                                });
                            }
                            else
                            {
                                Device.BeginInvokeOnMainThread(() =>
                                {
                                    App.Current.MainPage.DisplayAlert("Info", "Transaction not found, try again if you believe the transaction was approved", "OK");
                                });
                            }
                        }
                        catch
                        {
                            Device.BeginInvokeOnMainThread(() =>
                            {
                                App.Current.MainPage.DisplayAlert("Info", "Unknown, there is no connectivity to the server, try again if you believe the tx was approved", "OK");
                            });
                        }
                    }
                    else
                    {
                        Device.BeginInvokeOnMainThread(() =>
                        {
                            lblTransactSummary.Text = (e as TxCompletedEventArgs).TxResult.ToString();
                            UpdateView(ViewState.StepSummary);
                        });
                    }
                }
                else
                {
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        lblTransactSummary.Text = "Declined";
                        UpdateView(ViewState.StepSummary);
                    });
                }
            }
            catch (Exception ex)
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    lblTransactSummary.Text = ex.Message;
                    UpdateView(ViewState.StepSummary);
                });
            }
        }
        private static SignalsEnum EntryPointTRM(KernelDatabase database, KernelRequest kernel1Request, CardQ cardQManager, KernelQ qManager, EMVSelectApplicationResponse emvSelectApplicationResponse)
        {
            TERMINAL_VERIFICATION_RESULTS_95_KRN  tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
            TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database);

            tsi.Value.TerminalRiskmanagementWasPerformed = true;
            tsi.UpdateDB();

            //The state works as follows:
            //State_5_WaitingForCVMProcessing ends by possibly adding 2 messages to the card q
            //and 1 or 2 messages in the terminal q (get floor limit (optional) and do trm)
            //the card messages are processed by this state first, then the get floor limit by DEK if it
            //was in the q and then this method

            //Random Transaction Selection determined by terminal, not kernel
            //Terminal can also force transaction online
            //EMVTagsEnum.MAXIMUM_TARGET_PERCENTAGE_TO_BE_USED_FOR_BIASED_RANDOM_SELECTION_INTERNAL_KRN
            //EMVTagsEnum.THRESHOLD_VALUE_FOR_BIASED_RANDOM_SELECTION_INTERNAL_KRN
            //EMVTagsEnum.MAXIMUM_TARGET_PERCENTAGE_TO_BE_USED_FOR_BIASED_RANDOM_SELECTION_INTERNAL_KRN

            switch (((KernelTRMRequest)kernel1Request).KernelTRMRequestType)
            {
            case KernelTRMRequestType.GoOnlineForRandomSelection:
                tvr.Value.TransactionSelectedRandomlyForOnlineProcessing = true;
                tvr.UpdateDB();
                break;

            case KernelTRMRequestType.GoOnline:
                tvr.Value.MerchantForcedTransactionOnline = true;
                tvr.UpdateDB();
                break;
            }

            //Floor limit check done by kernel, no need for it to be done by terminal
            if (database.IsNotEmpty(EMVTagsEnum.TERMINAL_FLOOR_LIMIT_9F1B_KRN.Tag))
            {
                long aa = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);
                long fl = Formatting.BcdToLong(database.Get(EMVTagsEnum.TERMINAL_FLOOR_LIMIT_9F1B_KRN).Value);
                if (aa > fl)
                {
                    tvr.Value.TransactionExceedsFloorLimit = true;
                    tvr.UpdateDB();
                }
            }

            //Velocity Check
            TLV lcol   = database.Get(EMVTagsEnum.LOWER_CONSECUTIVE_OFFLINE_LIMIT_9F14_KRN);
            TLV ucol   = database.Get(EMVTagsEnum.UPPER_CONSECUTIVE_OFFLINE_LIMIT_9F23_KRN);
            TLV atcTLV = database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag);
            TLV lastOnlineATCRegisterTLV = database.Get(EMVTagsEnum.LAST_ONLINE_APPLICATION_TRANSACTION_COUNTER_ATC_REGISTER_9F13_KRN.Tag);

            bool doVelocity = false;

            if (lcol != null && ucol != null)
            {
                if (database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) != null &&
                    database.Get(EMVTagsEnum.LAST_ONLINE_APPLICATION_TRANSACTION_COUNTER_ATC_REGISTER_9F13_KRN.Tag) != null)
                {
                    if (Formatting.ConvertToInt32(atcTLV.Value) >
                        Formatting.ConvertToInt32(lastOnlineATCRegisterTLV.Value))
                    {
                        doVelocity = true;
                    }
                    else
                    {
                        // Set both the ‘Lower consecutive offline limit exceeded’ and the ‘Upper consecutive offline limit exceeded’ bits in the TVR to 1.
                        // Not set the ‘New card’ indicator in the TVR unless the Last Online ATC Register is returned and equals zero.
                        // End velocity checking for this transaction
                        tvr.Value.LowerConsecutiveOfflineLimitExceeded = true;
                        tvr.Value.UpperConsecutiveOfflineLimitExceeded = true;

                        if (lastOnlineATCRegisterTLV != null)
                        {
                            if (Formatting.ConvertToInt32(lastOnlineATCRegisterTLV.Value) == 0)
                            {
                                tvr.Value.NewCard = true;
                            }
                        }
                        tvr.UpdateDB();
                    }
                }
            }
            if (doVelocity == true)
            {
                uint atc     = Formatting.ConvertToInt32(atcTLV.Value);
                uint lastATC = Formatting.ConvertToInt32(lastOnlineATCRegisterTLV.Value);

                uint atcDiff = atc - lastATC;
                uint lcolInt = Formatting.ConvertToInt32(lcol.Value);
                uint ucolInt = Formatting.ConvertToInt32(ucol.Value);
                if (atcDiff > lcolInt)
                {
                    //set ‘Lower consecutive offline limit exceeded’ bit in the TVR to 1
                    tvr.Value.LowerConsecutiveOfflineLimitExceeded = true;
                    if (atcDiff > ucolInt)
                    {
                        //set the ‘Upper consecutive offline limit exceeded’ bit in the TVR to 1.
                        tvr.Value.UpperConsecutiveOfflineLimitExceeded = true;
                    }
                }
                if (lastATC == 0)
                {
                    //set ‘New card’ bit in the TVR to 1.
                    tvr.Value.NewCard = true;
                }
                tvr.UpdateDB();
            }

            #region Book 3 Section 10.7
            //Terminal Action Analysis of kernel 2 being used
            database.ACType.Value.DSACTypeEnum = TerminalActionAnalysis_7_8.TerminalActionAnalysis(database);
            #endregion

            #region Book 3 Section 10.8
            //Card Action Analysis
            return(CardActionAnalysis.InitiateCardActionAnalysis(database, qManager, cardQManager, emvSelectApplicationResponse));

            #endregion
        }
        internal bool ConditionsSatisfied(KernelDatabaseBase database, long amountX, long amountY)
        {
            byte tt = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0];

            TERMINAL_TYPE_9F35_KRN.TerminalType terminalType = new TERMINAL_TYPE_9F35_KRN(database).Value.TerminalType;
            bool isManual     = false;
            byte posEntryMode = database.Get(EMVTagsEnum.POINTOFSERVICE_POS_ENTRY_MODE_9F39_KRN).Value[0];

            if (posEntryMode == 0x01)
            {
                isManual = true;
            }

            long aa = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);

            bool tccEqualsacc = false;

            if (database.IsNotEmpty(EMVTagsEnum.TRANSACTION_CURRENCY_CODE_5F2A_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.APPLICATION_CURRENCY_CODE_9F42_KRN.Tag))
            {
                string tcc = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.TRANSACTION_CURRENCY_CODE_5F2A_KRN).Value);
                string acc = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_CURRENCY_CODE_9F42_KRN).Value);
                if (tcc == acc)
                {
                    tccEqualsacc = true;
                }
            }

            switch (CVMConditionCode)
            {
            case CVMConditionCode.Always:
                return(true);

            case CVMConditionCode.IfUnattendedCash:
                if (terminalType.AttendedUnattended == TERMINAL_TYPE_9F35_KRN.AttendedUnattended.Unattended &&
                    tt == (byte)TransactionTypeEnum.CashWithdrawal)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }

            case CVMConditionCode.IfManualCash:

                if (isManual && tt == (byte)TransactionTypeEnum.CashWithdrawal)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }

            case CVMConditionCode.IfNotUnattendedCashAndNotManualCashAndNotPurchaseWithCashBack:
                if (!(terminalType.AttendedUnattended == TERMINAL_TYPE_9F35_KRN.AttendedUnattended.Unattended &&
                      tt == (byte)TransactionTypeEnum.CashWithdrawal) &&
                    (!(isManual && tt == (byte)TransactionTypeEnum.CashWithdrawal)) &&
                    (!(tt == (byte)TransactionTypeEnum.PurchaseWithCashback))
                    )
                {
                    return(true);
                }
                else
                {
                    return(false);
                }

            case CVMConditionCode.IfTerminalSupportstheCVM:
                return(IsSupported(database));

            case CVMConditionCode.IfPurchaseWithCashBack:
                if ((tt == (byte)TransactionTypeEnum.PurchaseWithCashback))
                {
                    return(true);
                }
                else
                {
                    return(false);
                }

            case CVMConditionCode.IfTransactionIsInTheApplicationCurrencyAndIsUnderX:

                if (tccEqualsacc && aa <= amountX)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }

            case CVMConditionCode.IfTransactionIsInTheApplicationCurrencyAndIsOverX:
                if (tccEqualsacc && aa > amountX)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }

            case CVMConditionCode.IfTransactionIsInTheApplicationCurrencyAndIsUnderY:
                if (tccEqualsacc && aa <= amountY)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }

            case CVMConditionCode.IfTransactionIsInTheApplicationCurrencyAndIsOverY:
                if (tccEqualsacc && aa > amountY)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }

            default:
                throw new EMVProtocolException("invalid CVM ConditionCode in Rule");
            }
        }
        private static SignalsEnum DoMagMode(Kernel2Database database, KernelQ qManager, CardQ cardQManager)
        {
            KERNEL_CONFIGURATION_DF811B_KRN2 kc = new KERNEL_CONFIGURATION_DF811B_KRN2(database);

            TLV aflRaw = database.Get(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN);

            byte[] kcValCheck = new byte[4];
            Array.Copy(aflRaw.Value, 0, kcValCheck, 0, kcValCheck.Length);
            #region 3.70
            if (aflRaw.Value.Length >= 4 && Formatting.ByteArrayToHexString(kcValCheck) == "08010100")
            #endregion
            {
                #region 3.72
                byte[] activeAFLBytes = new byte[4];
                Array.Copy(aflRaw.Value, 0, activeAFLBytes, 0, activeAFLBytes.Length);

                List <byte[]> bytes = new List <byte[]>
                {
                    new byte[] { (byte)activeAFLBytes.Length },
                    activeAFLBytes
                };
                database.ActiveAFL.Value.Deserialize(bytes.SelectMany(a => a).ToArray(), 0);
                //database.ActiveAFL.Value.Entries.Add(new FILE_LOCATOR_ENTRY(activeAFLBytes));
                #endregion
            }
            else
            {
                #region 3.71
                List <byte[]> bytes = new List <byte[]>
                {
                    new byte[] { (byte)aflRaw.Value.Length },
                    aflRaw.Value
                };
                database.ActiveAFL.Value.Deserialize(bytes.SelectMany(a => a).ToArray(), 0);
                //database.ActiveAFL.Value.Entries.Add(new FILE_LOCATOR_ENTRY(aflRaw.Value));
                #endregion
            }

            #region 3.73
            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
            if (aip.Value.OnDeviceCardholderVerificationIsSupported && kc.Value.OnDeviceCardholderVerificationSupported)
            {
                #region 3.75
                database.ReaderContactlessTransactionLismit = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_TRANSACTION_LIMIT_ONDEVICE_CVM_DF8125_KRN2).Value);
                #endregion
            }
            else
            {
                #region 3.74
                database.ReaderContactlessTransactionLismit = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_TRANSACTION_LIMIT_NO_ONDEVICE_CVM_DF8124_KRN2).Value);
                #endregion
            }
            #endregion

            #region 3.76
            TLVList dataToSend   = database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children;
            TLVList tagsToRemove = new TLVList();
            foreach (TLV ttry in database.TagsToReadYet)
            {
                if (database.IsNotEmpty(ttry.Tag.TagLable))
                {
                    dataToSend.AddToList(ttry);
                    tagsToRemove.AddToList(ttry);
                }
            }
            foreach (TLV ttr in tagsToRemove)
            {
                database.TagsToReadYet.RemoveFromList(ttr);
            }
            #endregion

            #region 3.77
            if (database.IsNotEmptyList(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag) ||
                (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0))
            {
                #region 3.78
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
                #endregion
            }

            #region 3.80
            EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber);
            #endregion
            #region 3.81
            cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
            #endregion
            return(SignalsEnum.WAITING_FOR_MAG_STRIPE_READ_RECORD_RESPONSE);

            #endregion
        }
        private static SignalsEnum DoEMVMode(Kernel2Database database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse, Stopwatch sw)
        {
            #region 3.30
            KERNEL_CONFIGURATION_DF811B_KRN2 kc = new KERNEL_CONFIGURATION_DF811B_KRN2(database);

            TLV    aflRaw     = database.Get(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN);
            byte[] kcValCheck = new byte[4];
            Array.Copy(aflRaw.Value, 0, kcValCheck, 0, kcValCheck.Length);
            if (aflRaw.Value.Length >= 4 && Formatting.ByteArrayToHexString(kcValCheck) == "08010100" && !kc.Value.MagStripeModeContactlessTransactionsNotSupported)
            {
                #region 3.32
                byte[] activeAFLBytes = new byte[aflRaw.Value.Length - 4];
                Array.Copy(aflRaw.Value, 4, activeAFLBytes, 0, activeAFLBytes.Length);

                List <byte[]> bytes = new List <byte[]>
                {
                    new byte[] { (byte)activeAFLBytes.Length },
                    activeAFLBytes
                };
                database.ActiveAFL.Value.Deserialize(bytes.SelectMany(a => a).ToArray(), 0);

                //database.ActiveAFL.Value.Entries.Add(new FILE_LOCATOR_ENTRY(activeAFLBytes));
                #endregion
            }
            else
            {
                #region 3.31
                List <byte[]> bytes = new List <byte[]>
                {
                    new byte[] { (byte)aflRaw.Value.Length },
                    aflRaw.Value
                };
                database.ActiveAFL.Value.Deserialize(bytes.SelectMany(a => a).ToArray(), 0);

                //database.ActiveAFL.Value.Entries.Add(new FILE_LOCATOR_ENTRY(aflRaw.Value));
                #endregion
            }
            #endregion

            #region 3.33
            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
            if (aip.Value.OnDeviceCardholderVerificationIsSupported && kc.Value.OnDeviceCardholderVerificationSupported)
            {
                #region 3.35
                database.ReaderContactlessTransactionLismit = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_TRANSACTION_LIMIT_ONDEVICE_CVM_DF8125_KRN2).Value);
                #endregion
            }
            else
            {
                #region 3.34
                database.ReaderContactlessTransactionLismit = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_TRANSACTION_LIMIT_NO_ONDEVICE_CVM_DF8124_KRN2).Value);
                #endregion
            }
            #endregion

            #region 3.60
            if (kc.Value.RelayResistanceProtocolSupported && aip.Value.RelayResistanceProtocolIsSupported)
            #endregion
            {
                #region 3.61
                database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value = Formatting.GetRandomNumber();
                database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value;
                #endregion
                #region 3.62
                EMVExchangeRelayResistanceDataRequest request = new EMVExchangeRelayResistanceDataRequest(database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value);
                #endregion
                #region 3.63
                sw.Start();
                #endregion
                #region 3.64
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                #endregion
                return(SignalsEnum.WAITING_FOR_EXCHANGE_RELAY_RESISTANCE_DATA_RESPONSE);
            }
            else
            {
                #region 3.65
                TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                tvr.Value.RelayResistancePerformedEnum = RelayResistancePerformedEnum.RRP_NOT_PERFORMED;
                tvr.UpdateDB();
                #endregion
                return(State_3_R1_CommonProcessing.DoCommonProcessing("State_3_WaitingForGPOResponse", database, qManager, cardQManager, cardResponse));
            }
        }
Beispiel #10
0
        public static SignalsEnum DoCommonProcessing(string source, Kernel2Database database, KernelQ qManager, CardQ cardQManager, Stopwatch sw, TornTransactionLogManager tornTransactionLogManager)
        {
            #region 456.1
            if (database.NextCommandEnum == NextCommandEnum.READ_RECORD)
            #endregion
            {
                #region 456.2
                TLVList toRemove = new TLVList();
                foreach (TLV tlv in database.TagsToReadYet)
                {
                    if (database.IsNotEmpty(tlv.Tag.TagLable))
                    {
                        database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(tlv);
                        toRemove.AddToList(tlv);
                    }
                }
                foreach (TLV tlv in toRemove)
                {
                    database.TagsToReadYet.RemoveFromList(tlv);
                }
                #endregion

                #region 456.3
                if (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0)
                #endregion
                {
                    #region 456.4
                    CommonRoutines.PostDEK(database, qManager);
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                    database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
                    #endregion
                }
                return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE);
            }
            else
            {
                if (database.NextCommandEnum == NextCommandEnum.GET_DATA)
                {
                    return(SignalsEnum.WAITING_FOR_GET_DATA_RESPONSE);
                }
                else
                {
                    #region 456.5
                    if (database.IsEmpty(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag))
                    #endregion
                    {
                        DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
                        #region 456.6
                        dataNeeded.Value.Tags.Add(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag);
                        #endregion
                        dataNeeded.UpdateDB();

                        return(Do456_7_To_456_10(source, database, qManager, cardQManager, sw));
                    }
                    else
                    {
                        #region 456.11
                        if (database.IsPresent(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag) && database.Get(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2).Value[0] == 0x00)
                        #endregion
                        {
                            #region 456.7
                            return(Do456_7_To_456_10(source, database, qManager, cardQManager, sw));

                            #endregion
                        }
                    }
                }
            }

            #region 456.12
            if (database.IsEmpty(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN.Tag))
            #endregion
            {
                #region 456.13
                CommonRoutines.CreateEMVDiscretionaryData(database);
                return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, L1Enum.NOT_SET, L2Enum.NOT_SET, L3Enum.AMOUNT_NOT_PRESENT));

                #endregion
            }

            #region 456.14
            long aa   = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);
            long rctl = database.ReaderContactlessTransactionLismit;
            if (aa > rctl)
            #endregion
            {
                #region 456.15
                CommonRoutines.CreateEMVDiscretionaryData(database);
                return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.MAX_LIMIT_EXCEEDED, L3Enum.NOT_SET));

                #endregion
            }

            #region 456.16
            if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN.Tag) &&
                  database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag) &&
                  database.IsNotEmpty(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN.Tag)))
            #endregion
            {
                #region 456.17
                CommonRoutines.CreateEMVDiscretionaryData(database);
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  KernelStatusEnum.NOT_READY,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.N_A,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.CARD_DATA_MISSING,
                                                  L3Enum.NOT_SET));

                #endregion
            }

            #region 456.18
            IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database);
            if (ids.Value.IsRead)
            #endregion
            {
                #region 456.19
                string dsid      = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2).Value);
                string pan       = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value);
                string seqNumber = "00";
                if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag))
                {
                    seqNumber = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN).Value);
                }
                string concat = pan + seqNumber;
                if (concat.Length % 2 != 0)
                {
                    concat = "0" + concat;
                }
                if (concat.Length < 16)
                {
                    concat.PadLeft(16, '0');
                }
                if (dsid != concat)
                #endregion
                {
                    #region 456.20.1,456.20.2
                    CommonRoutines.CreateEMVDiscretionaryData(database);
                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                      KernelStatusEnum.NOT_READY,
                                                      null,
                                                      Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                      Kernel2StartEnum.N_A,
                                                      true,
                                                      KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                      L1Enum.NOT_SET,
                                                      null,
                                                      L2Enum.CARD_DATA_ERROR,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
            }

            #region 456.21
            TLVList toRemove2 = new TLVList();
            foreach (TLV tlv in database.TagsToReadYet)
            {
                if (database.IsPresent(tlv.Tag.TagLable))
                {
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(tlv);
                }
                else
                {
                    if (database.IsKnown(tlv.Tag.TagLable))
                    {
                        database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(TLV.Create(tlv.Tag.TagLable));
                    }
                }
                toRemove2.AddToList(tlv);
            }

            foreach (TLV tlv in toRemove2)
            {
                database.TagsToReadYet.RemoveFromList(tlv);
            }
            #endregion

            #region 456.22
            if (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag))
            #endregion
            {
                #region 456.23
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
                #endregion
            }

            #region 456.24
            if (database.ODAStatus == 0x80)
            #endregion
            {
                TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                #region 456.25
                if (!(
                        database.IsNotEmpty(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN.Tag) &&
                        database.IsNotEmpty(EMVTagsEnum.ISSUER_PUBLIC_KEY_CERTIFICATE_90_KRN.Tag) &&
                        database.IsNotEmpty(EMVTagsEnum.ISSUER_PUBLIC_KEY_EXPONENT_9F32_KRN.Tag) &&
                        database.IsNotEmpty(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_CERTIFICATE_9F46_KRN.Tag) &&
                        database.IsNotEmpty(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_EXPONENT_9F47_KRN.Tag) &&
                        database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN.Tag)
                        ))
                {
                    tvr.Value.ICCDataMissing = true;
                    tvr.Value.CDAFailed      = true;
                }

                if (database.PublicKeyCertificateManager.GetCAPK(RIDEnum.A000000004, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]) == null)
                {
                    tvr.Value.CDAFailed = true;
                }


                #endregion

                #region 456.26
                bool test = false;
                TLV  aip  = null;
                if (database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN.Tag))
                {
                    TLV     sdal = database.Get(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN);
                    TLVList list = TLV.DeserializeChildrenWithNoLV(sdal.Value, 0);
                    if (list.Count == 1)
                    {
                        aip = list.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag);
                        if (aip != null)
                        {
                            test = true;
                        }
                    }
                }

                if (test == false)
                {
                    #region 456.27.1 - 456.27.2
                    CommonRoutines.CreateEMVDiscretionaryData(database);
                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                      KernelStatusEnum.NOT_READY,
                                                      null,
                                                      Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                      Kernel2StartEnum.N_A,
                                                      true,
                                                      KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                      L1Enum.NOT_SET,
                                                      null,
                                                      L2Enum.CARD_DATA_ERROR,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
                #endregion

                #region 456.28
                int length = database.StaticDataToBeAuthenticated.Serialize().Length;
                if (2048 - length >= aip.Value.Length)
                {
                    database.StaticDataToBeAuthenticated.AddToList(database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN));
                }
                else
                {
                    tvr.Value.CDAFailed = true;
                }
                #endregion
                tvr.UpdateDB();
            }

            #region 456.30
            long cvmrl = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CVM_REQUIRED_LIMIT_DF8126_KRN2).Value);
            if (aa > cvmrl)
            #endregion
            {
                #region 456.31
                CommonRoutines.UpdateOutcomeParameterSet(database, true);
                #endregion

                #region 456.32
                database.Get(EMVTagsEnum.TERMINAL_CAPABILITIES_9F33_KRN).Value[1] = database.Get(EMVTagsEnum.CVM_CAPABILITY_CVM_REQUIRED_DF8118_KRN2).Value[0];
                #endregion
            }
            else
            {
                #region 456.33
                database.Get(EMVTagsEnum.TERMINAL_CAPABILITIES_9F33_KRN).Value[1] = database.Get(EMVTagsEnum.CVM_CAPABILITY_NO_CVM_REQUIRED_DF8119_KRN2).Value[0];
                #endregion
            }

            #region 456.34
            SignalsEnum se = PreGenACBalanceReading_7_1.PreGenACBalanceReading(database, qManager, cardQManager);
            if (se != SignalsEnum.NONE)
            {
                return(se);
            }
            #endregion

            #region 456.35
            ProcessingRestrictions_7_7.ProcessingRestrictions(database);
            #endregion

            #region 456.35
            CVMSelection_7_5.CVMSelection(database,
                                          new Func <bool>(() =>
            {
                return(new KERNEL_CONFIGURATION_DF811B_KRN2(database).Value.OnDeviceCardholderVerificationSupported);
            }));
            #endregion

            #region 456.36
            long rcfl = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_FLOOR_LIMIT_DF8123_KRN2).Value);
            if (aa > rcfl)
            #endregion
            {
                #region 456.38
                TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                tvr.Value.TransactionExceedsFloorLimit = true;
                tvr.UpdateDB();
                #endregion
            }

            #region 456.39
            database.ACType.Value.DSACTypeEnum = TerminalActionAnalysis_7_8.TerminalActionAnalysis(database);
            #endregion

            //#region support for Refunds pg 177
            //byte transactionType = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0];
            //if (transactionType == (byte)TransactionTypeEnum.Refund)
            //{
            //    database.ACType.Value.DSACTypeEnum = ACTypeEnum.AAC;
            //    database.ODAStatus = 0x00; //dont request CDA in first gen ac
            //}
            //#endregion


            #region 456.42
            if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2.Tag))
            #endregion
            {
                #region 456.50
                TLV tlvRemoved            = database.TagsToWriteBeforeGenACYet.GetFirstAndRemoveFromList();
                EMVPutDataRequest request = new EMVPutDataRequest(tlvRemoved);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_PUT_DATA_RESPONSE_BEFORE_GEN_AC);

                #endregion
            }
            else
            {
                TORN_RECORD_FF8101_KRN2 foundTTL = null;
                #region 456.43
                uint mnttl = Formatting.ConvertToInt32(database.GetDefault(EMVTagsEnum.MAX_NUMBER_OF_TORN_TRANSACTION_LOG_RECORDS_DF811D_KRN2).Value);
                if (database.IsNotEmpty(EMVTagsEnum.DRDOL_9F51_KRN2.Tag) && mnttl != 0)
                #endregion
                {
                    #region 456.44
                    foreach (TORN_RECORD_FF8101_KRN2 tlv in tornTransactionLogManager.TornTransactionLogs)
                    {
                        if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag))
                        {
                            if ((Formatting.ByteArrayToHexString(tlv.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag).Value) == Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value)) &&
                                (Formatting.ByteArrayToHexString(tlv.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag).Value) == Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN).Value)))
                            {
                                foundTTL = tlv;
                            }
                        }
                        else
                        {
                            if ((Formatting.ByteArrayToHexString(tlv.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag).Value) == Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value)) &&
                                (tlv.Children.IsNotPresent(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag)))
                            {
                                foundTTL = tlv;
                            }
                        }
                    }
                    #endregion
                    if (foundTTL == null)
                    {
                        #region 456.45
                        EMVGenerateACRequest request = PrepareGenACCommandProcedure_7_6.PrepareGenACCommand(database, qManager, cardQManager);
                        cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                        return(SignalsEnum.WAITING_FOR_GEN_AC_1);

                        #endregion
                    }
                    else
                    {
                        #region 456.47
                        database.TornTempRecord = foundTTL;
                        #endregion

                        #region 456.48
                        database.Get(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2).Value = database.TornTempRecord.Children.Get(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2.Tag).Value;
                        EMVRecoverACRequest requestRecover = new EMVRecoverACRequest(database.Get(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2));
                        cardQManager.EnqueueToInput(new CardRequest(requestRecover, CardinterfaceServiceRequestEnum.ADPU));
                        return(SignalsEnum.WAITING_FOR_RECOVER_AC);

                        #endregion
                    }
                }
                else
                {
                    #region 456.45
                    EMVGenerateACRequest request = PrepareGenACCommandProcedure_7_6.PrepareGenACCommand(database, qManager, cardQManager);
                    cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                    return(SignalsEnum.WAITING_FOR_GEN_AC_1);

                    #endregion
                }
            }
        }
Beispiel #11
0
        private async void EmvTxCtl_TxCompleted(object sender, EventArgs e)
        {
            try
            {
                if ((e as TxCompletedEventArgs).EMV_Data.IsPresent())
                {
                    if ((e as TxCompletedEventArgs).TxResult == TxResult.Approved ||
                        (e as TxCompletedEventArgs).TxResult == TxResult.ContactlessOnline)
                    {
                        TLV data = (e as TxCompletedEventArgs).EMV_Data.Get();

                        TLV _9F02 = data.Children.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN.Tag);
                        if (_9F02 == null)
                        {
                            throw new Exception("No Amount found");
                        }

                        long amount = Formatting.BcdToLong(_9F02.Value);
                        try
                        {
                            await CallTopUpWebService(SessionSingleton.Account.AccountNumberId, amount, "000", data);

                            Device.BeginInvokeOnMainThread(() =>
                            {
                                lblStatusTopUp.Text = "Transaction Completed Succesfully";
                                UpdateView(ViewState.StepSummary);
                            });
                        }
                        catch
                        {
                            Device.BeginInvokeOnMainThread(() =>
                            {
                                lblStatusTopUp.Text = "Declined, could not go online.";
                                UpdateView(ViewState.StepSummary);
                            });
                        }
                    }
                    else
                    {
                        Device.BeginInvokeOnMainThread(() =>
                        {
                            lblStatusTopUp.Text = (e as TxCompletedEventArgs).TxResult.ToString();
                            UpdateView(ViewState.StepSummary);
                        });
                    }
                }
                else
                {
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        lblStatusTopUp.Text = "Declined";
                        UpdateView(ViewState.StepSummary);
                    });
                }
            }
            catch (Exception ex)
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    lblStatusTopUp.Text = ex.Message;
                    UpdateView(ViewState.StepSummary);
                });
            }
        }
Beispiel #12
0
        public static void CVMSelection(KernelDatabaseBase database, Func <bool> kernelSupportedCallback)
        {
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvmResults = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);

            //#region support for Refunds pg 177
            //byte transactionType = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0];
            //if (transactionType == (byte)TransactionTypeEnum.Refund)
            //{
            //    Do_CVM_14(database, cvmResults);
            //    return;
            //}
            //#endregion

            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);

            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

            KernelCVMEnum cvmEnum = KernelCVMEnum.N_A;

            CardHolderVerificationRule cvrCurrentlySelected;

            if (aip.Value.OnDeviceCardholderVerificationIsSupported && kernelSupportedCallback.Invoke())
            {
                #region cvm.2
                long aa    = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);
                long rcvml = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CVM_REQUIRED_LIMIT_DF8126_KRN2).Value);
                if (aa > rcvml)
                #endregion
                {
                    #region cvm.4
                    cvmEnum = KernelCVMEnum.CONFIRMATION_CODE_VERIFIED;
                    cvmResults.Value.CVMPerformed = 0x01; //on-device cardholder verification performed
                    cvmResults.Value.CVMCondition = 0x00;
                    cvmResults.Value.CVMResult    = 0x02; //successful
                    CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum);
                    cvmResults.UpdateDB();
                    return;

                    #endregion
                }
                else
                {
                    #region cvm.3
                    cvmEnum = KernelCVMEnum.NO_CVM;
                    cvmResults.Value.CVMPerformed = 0x3F; //No CVM performed
                    cvmResults.Value.CVMCondition = 0x00;
                    cvmResults.Value.CVMResult    = 0x02; //successful
                    CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum);
                    cvmResults.UpdateDB();
                    return;

                    #endregion
                }
            }

            #region cvm.5
            if (!aip.Value.CardholderVerificationIsSupported)
            #endregion
            {
                #region cvm.6
                cvmEnum = KernelCVMEnum.NO_CVM;
                cvmResults.Value.CVMPerformed = 0x3F; //No CVM performed
                cvmResults.Value.CVMCondition = 0x00;
                cvmResults.Value.CVMResult    = 0x00; //unknown
                CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum);
                cvmResults.UpdateDB();
                return;

                #endregion
            }

            #region cvm.7
            if (database.IsNotPresent(EMVTagsEnum.CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN.Tag) ||
                database.IsEmpty(EMVTagsEnum.CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN.Tag))
            #endregion
            {
                #region cvm.8
                cvmEnum = KernelCVMEnum.NO_CVM;
                cvmResults.Value.CVMPerformed = 0x3F; //No CVM performed
                cvmResults.Value.CVMCondition = 0x00;
                cvmResults.Value.CVMResult    = 0x00; //unknown
                CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum);
                cvmResults.UpdateDB();
                tvr.Value.ICCDataMissing = true;
                tvr.UpdateDB();
                return;

                #endregion
            }

            #region cvm.9
            CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN cvl = new CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN(database);
            #endregion

BackToIterate:
            CVMListIterationReturn result;
            do
            {
                cvrCurrentlySelected = cvl.Value.CardHolderVerificationRules[database.CVMCurrentlySelectedCounter];
                #region cvm.10 cvm.11
                result = IterateCVM(database, cvrCurrentlySelected, cvl.Value.AmountX, cvl.Value.AmountY);
                #endregion
                database.CVMCurrentlySelectedCounter++;
                #region cvm.12 cvm.13
            } while (database.CVMCurrentlySelectedCounter < cvl.Value.CardHolderVerificationRules.Count &&
                     result != CVMListIterationReturn.ConditionsMet);
            #endregion

            if (result != CVMListIterationReturn.ConditionsMet)
            {
                Do_CVM_14(database, cvmResults);
                return;
            }

            #region cvm.15
            if (!cvrCurrentlySelected.IsCVMRecognised())
            #endregion
            {
                #region cvm.16
                tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                tvr.Value.UnrecognisedCVM = true;
                tvr.UpdateDB();
                #endregion
            }
            else
            {
                #region cvm.17
                if (cvrCurrentlySelected.IsSupported(database) && cvrCurrentlySelected.GetCVMCode() != (byte)CVMCode.FailCVMProcessing)
                #endregion
                {
                    #region cvm.18 and from EMV Book 3 Section 10.5
                    switch ((byte)(cvrCurrentlySelected.CVMRule & 0x3F))
                    {
                    //Pin processing (U,X,Z) continues in PinProcessing Procedure after CVM Selection
                    case (byte)CVMCode.EncipheredPINVerifiedOnline:
                        cvmEnum = KernelCVMEnum.ONLINE_PIN;
                        cvmResults.Value.CVMResult = 0x00;     //unknown
                        tvr.Value.OnlinePINEntered = true;
                        break;

                    case (byte)CVMCode.EncipheredPINVerificationPerformedByICC:
                    case (byte)CVMCode.PlaintextPINVerificationPerformedByICC:
                        cvmEnum = KernelCVMEnum.OFFLINE_PIN;
                        cvmResults.Value.CVMResult = 0x00;     //unknown
                        break;

                    case (byte)CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper:
                    case (byte)CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper:
                        cvmEnum = KernelCVMEnum.COMBO;
                        cvmResults.Value.CVMResult = 0x00;     //unknown
                        break;

                    //V in diagram
                    case (byte)CVMCode.Signature_Paper:
                        cvmEnum = KernelCVMEnum.OBTAIN_SIGNATURE;
                        cvmResults.Value.CVMResult = 0x00;     //unknown
                        CommonRoutines.UpdateOutcomeParameterSet(database, true);
                        break;

                    //W in diagram
                    case (byte)CVMCode.NoCVMRequired:
                        cvmEnum = KernelCVMEnum.NO_CVM;
                        cvmResults.Value.CVMResult = 0x02;     //successful
                        break;

                    case (byte)CVMCode.RFU:
                        cvmEnum = KernelCVMEnum.N_A;
                        tvr.Value.UnrecognisedCVM  = true;
                        cvmResults.Value.CVMResult = 0x01;     //failed
                        break;

                    default:
                        goto BackToIterate;
                    }
                    #endregion
                    cvmResults.Value.CVMPerformed = cvrCurrentlySelected.CVMRule;
                    cvmResults.Value.CVMCondition = (byte)cvrCurrentlySelected.CVMConditionCode;
                    cvmResults.UpdateDB();
                    int depth = 0;
                    Logger.Log(cvmResults.ToPrintString(ref depth));
                    CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum);
                    tvr.UpdateDB();
                    return;
                }
            }

            #region cvm.19
            if (((byte)cvrCurrentlySelected.CVMConditionCode & 0x40) == (byte)CVMFailureCondition.ApplySucceedingCVRuleIfThisCVMIsUnsuccessful)
            #endregion
            {
                #region cvm.20
                if (database.CVMCurrentlySelectedCounter < cvl.Value.CardHolderVerificationRules.Count)
                #endregion
                {
                    #region cvm.10
                    goto BackToIterate;
                    #endregion
                }
                else
                {
                    Do22_25(database, cvrCurrentlySelected);
                    return;
                }
            }
            else
            {
                Do22_25(database, cvrCurrentlySelected);
                return;
            }
        }