private static TLVList ReadAllPSERecords(TLV sfi, CardQProcessor cardInterfaceManager)
        {
            byte    record = 1;
            TLVList _61    = new TLVList();

            while (record != 0)
            {
                EMVReadRecordRequest request = new EMVReadRecordRequest(sfi.Value[0], record);

                //do read record commands starting with record 1 untill the card returns 6A83
                ApduResponse cardResponse = cardInterfaceManager.SendCommand(request);
                if (cardResponse is EMVReadRecordResponse)
                {
                    if (cardResponse.Succeeded)
                    {
                        TLVList tags = (cardResponse as EMVReadRecordResponse).GetResponseTags();
                        foreach (TLV tlv in tags)
                        {
                            _61.AddToList(tlv, true);
                        }
                        record++;
                    }
                    else
                    {
                        record = 0;
                    }
                }
                else
                {
                    throw new EMVProtocolException("ReadAllRecords transmit error");
                }
            }
            return(_61);
        }
Beispiel #2
0
        private static SignalsEnum DoCommonProcessing(string source, KernelDatabase database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse)
        {
            TLV nextTLV = database.TagsToReadYet.GetNextGetDataTagFromList();

            if (nextTLV != null)
            {
                database.ActiveTag = nextTLV.Tag.TagLable;
            }
            else
            {
                database.ActiveTag = null;
            }

            if (database.ActiveTag != null)
            {
                EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(database.ActiveTag));
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                database.NextCommandEnum = NextCommandEnum.GET_DATA;
            }
            else
            {
                if (database.ActiveAFL == null)
                {
                    return(DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET));
                }
                else
                {
                    EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber);
                    cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                    database.NextCommandEnum = NextCommandEnum.READ_RECORD;
                }
            }

            TLVList dataToSend = database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children;

            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
            TERMINAL_CAPABILITIES_9F33_KRN         tc  = new TERMINAL_CAPABILITIES_9F33_KRN(database);

            return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE);
        }
        public static SignalsEnum DoCommonProcessing(string source, KernelDatabaseBase database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse)
        {
            if (database.ActiveAFL == null)
            {
                return(DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET));
            }
            else
            {
                EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                database.NextCommandEnum = NextCommandEnum.READ_RECORD;
            }

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

            return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE);
        }
        /*
         * S4.3
         */
        private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, TornTransactionLogManager tornTransactionLogManager, Stopwatch sw)
        {
            bool signedFlag;
            byte sfi;

            #region 4.9
            if (!cardResponse.ApduResponse.Succeeded)
            #endregion
            {
                #region 4.10
                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,
                                                  cardResponse.ApduResponse.SW12,
                                                  L2Enum.STATUS_BYTES,
                                                  L3Enum.NOT_SET));

                #endregion
            }

            #region 4.11
            if (database.ActiveAFL.Value.Entries[0].OfflineDataAuthenticationRecordLength > 0)
            #endregion
            {
                #region 4.12
                signedFlag = true;
                #endregion
            }
            else
            {
                #region 4.13
                signedFlag = false;
                #endregion
            }

            #region 4.14
            sfi = database.ActiveAFL.Value.Entries[0].SFI;
            database.ActiveAFL.Value.Entries.RemoveAt(0);
            #endregion

            #region 4.15
            TLV nextTLV = database.TagsToReadYet.GetNextGetDataTagFromList();
            if (nextTLV != null)
            {
                database.ActiveTag = nextTLV.Tag.TagLable;
            }
            else
            {
                database.ActiveTag = null;
            }
            #endregion
            if (database.ActiveTag != null)
            {
                #region 4.16 - 4.19
                EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(database.ActiveTag));
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                database.NextCommandEnum = NextCommandEnum.GET_DATA;
                #endregion
            }
            else
            {
                #region 4.19
                if (database.ActiveAFL.Value.Entries.Count == 0)
                #endregion
                {
                    #region 4.20
                    database.NextCommandEnum = NextCommandEnum.NONE;
                    #endregion
                }
                else
                {
                    #region 4.21 - 4.23
                    EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber);
                    cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                    database.NextCommandEnum = NextCommandEnum.READ_RECORD;
                    #endregion
                }
            }

            bool parsingResult;
            #region 4.24
            if (sfi <= 10)
            #endregion
            {
                if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x70)
                {
                    parsingResult = database.ParseAndStoreCardResponse(cardResponse.ApduResponse.ResponseData);
                }
                else
                {
                    parsingResult = false;
                }
            }
            else //Processing of records in proprietary files is beyond the scope of thisspecification
            {
                parsingResult = false;
            }

            #region 4.25
            if (!parsingResult)
            #endregion
            {
                #region 4.26
                if (database.NextCommandEnum == NextCommandEnum.NONE)
                #endregion
                {
                    #region 4.27.1 - 4.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.PARSING_ERROR,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
                else
                {
                    return(SignalsEnum.TEMINATE_ON_NEXT_RA);
                }
            }

            TLVList responseTags;
            if (cardResponse.ApduResponse is EMVReadRecordResponse)
            {
                responseTags = (cardResponse.ApduResponse as EMVReadRecordResponse).GetResponseTags();
            }
            else if (cardResponse.ApduResponse is EMVGetDataResponse)
            {
                responseTags = (cardResponse.ApduResponse as EMVGetDataResponse).GetResponseTags();
            }
            else
            {
                throw new EMVProtocolException("Invalid card response in State4");
            }

            #region 4.28
            TLVList cdols = responseTags.FindAll(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN.Tag);
            if (cdols.Count > 0)
            #endregion
            {
                TLVList cdolList = TLV.DeserializeChildrenWithNoV(cdols.GetFirst().Value, 0);
                DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
                #region 4.29
                foreach (TLV tlv in cdolList)
                {
                    if (database.IsEmpty(tlv.Tag.TagLable))
                    {
                        dataNeeded.Value.Tags.Add(tlv.Tag.TagLable);
                    }
                }
                dataNeeded.UpdateDB();
                #endregion
            }

            #region 4.30
            TLVList dsdols = responseTags.FindAll(EMVTagsEnum.DSDOL_9F5B_KRN2.Tag);
            if (dsdols.Count > 0)
            #endregion
            {
                #region 4.31
                IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database);
                if (ids.Value.IsRead)
                #endregion
                {
                    #region 4.32
                    if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2.Tag) && new DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2(database).Value.LockedSlot)
                    #endregion
                    {
                        DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
                        #region 4.33
                        foreach (TLV tlv in dsdols.GetFirst().Children)
                        {
                            if (database.IsEmpty(tlv.Tag.TagLable))
                            {
                                dataNeeded.Value.Tags.Add(tlv.Tag.TagLable);
                            }
                        }
                        dataNeeded.UpdateDB();
                        #endregion
                    }
                    else
                    {
                        #region 4.34
                        Do434(database, signedFlag, sfi, cardResponse, responseTags);
                        #endregion
                    }
                }
                else
                {
                    #region 4.34
                    Do434(database, signedFlag, sfi, cardResponse, responseTags);
                    #endregion
                }
            }
            else
            {
                #region 4.34
                Do434(database, signedFlag, sfi, cardResponse, responseTags);
                #endregion
            }

            return(State_4_5_6_CommonProcessing.DoCommonProcessing("State_4_WaitingForEMVReadRecord", database, qManager, cardQManager, sw, tornTransactionLogManager));
        }
        /*
         * 7.3
         */
        private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, TornTransactionLogManager tornTransactionLogManager, Stopwatch sw)
        {
            #region 7.9
            if (!cardResponse.ApduResponse.Succeeded)
            #endregion
            {
                #region 7.10.1 - 7.10.2
                CommonRoutines.CreateMSDiscretionaryDataRecord(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,
                                                  cardResponse.ApduResponse.SW12,
                                                  L2Enum.STATUS_BYTES,
                                                  L3Enum.NOT_SET));

                #endregion
            }

            #region 7.11
            bool parsingResult = false;
            if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x70)
            {
                parsingResult = database.ParseAndStoreCardResponse(cardResponse.ApduResponse.ResponseData);
            }
            else
            {
                parsingResult = false;
            }
            #endregion

            if (!parsingResult)
            {
                #region 7.13.1
                CommonRoutines.CreateMSDiscretionaryDataRecord(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.PARSING_ERROR,
                                                  L3Enum.NOT_SET));

                #endregion
            }

            #region 7.14
            if ((cardResponse.ApduResponse as EMVReadRecordResponse).GetResponseTags().IsPresent(EMVTagsEnum.UDOL_9F69_KRN2.Tag))
            #endregion
            {
                #region 7.15
                TLV udol = (cardResponse.ApduResponse as EMVReadRecordResponse).GetResponseTags().Get(EMVTagsEnum.UDOL_9F69_KRN2.Tag);
                foreach (TLV tlv in udol.Children)
                {
                    if (database.IsEmpty(tlv.Tag.TagLable))
                    {
                        database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Children.AddToList(tlv);
                    }
                }
                #endregion
            }

            #region 7.16
            database.ActiveAFL.Value.Entries.RemoveAt(0);
            #endregion

            #region 7.17
            if (database.ActiveAFL.Value.Entries.Count != 0)
            #endregion
            {
                #region 7.18 - 7.19
                EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_MAG_STRIPE_READ_RECORD_RESPONSE);

                #endregion
            }

            #region 7.20
            if (database.IsEmpty(EMVTagsEnum.TRACK_2_DATA_9F6B_KRN2.Tag) ||
                database.IsEmpty(EMVTagsEnum.PUNATC_TRACK2_9F66_KRN2.Tag) ||
                database.IsEmpty(EMVTagsEnum.PCVC3_TRACK2_9F65_KRN2.Tag) ||
                database.IsEmpty(EMVTagsEnum.NATC_TRACK2_9F67_KRN2.Tag))
            #endregion
            {
                #region 7.21.1
                CommonRoutines.CreateMSDiscretionaryDataRecord(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_MISSING,
                                                  L3Enum.NOT_SET));

                #endregion
            }

            #region 7.22
            TLV punatc2     = database.Get(EMVTagsEnum.PUNATC_TRACK2_9F66_KRN2);
            int natc2       = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.NATC_TRACK2_9F67_KRN2).Value);
            int nonZeroBits = 0;
            for (int i = 0; i < 8; i++)
            {
                if (((punatc2.Value[0] >> i) & 0x01) == 0x01)
                {
                    nonZeroBits++;
                }
                if (((punatc2.Value[1] >> i) & 0x01) == 0x01)
                {
                    nonZeroBits++;
                }
            }
            int check2 = nonZeroBits - natc2;
            database.NUN = check2;
            if (check2 < 0 && check2 > 8)
            {
                #region 7.24.1
                return(DoInvalidResponse(database, qManager));

                #endregion
            }

            if (database.IsNotEmpty(EMVTagsEnum.TRACK_1_DATA_56_KRN2.Tag))
            {
                int check1 = 0;
                if (database.IsNotEmpty(EMVTagsEnum.NATC_TRACK1_9F64_KRN2.Tag) && database.IsNotEmpty(EMVTagsEnum.PUNATC_TRACK1_9F63_KRN2.Tag))
                {
                    TLV punatc1      = database.Get(EMVTagsEnum.PUNATC_TRACK1_9F63_KRN2);
                    int natc1        = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.NATC_TRACK1_9F64_KRN2).Value);
                    int nonZeroBits1 = 0;
                    for (int i = 0; i < 8; i++)
                    {
                        if (((punatc1.Value[0] >> i) & 0x01) == 0x01)
                        {
                            nonZeroBits1++;
                        }
                        if (((punatc1.Value[1] >> i) & 0x01) == 0x01)
                        {
                            nonZeroBits1++;
                        }
                        if (((punatc1.Value[2] >> i) & 0x01) == 0x01)
                        {
                            nonZeroBits1++;
                        }
                        if (((punatc1.Value[3] >> i) & 0x01) == 0x01)
                        {
                            nonZeroBits1++;
                        }
                        if (((punatc1.Value[4] >> i) & 0x01) == 0x01)
                        {
                            nonZeroBits1++;
                        }
                        if (((punatc1.Value[5] >> i) & 0x01) == 0x01)
                        {
                            nonZeroBits1++;
                        }
                    }
                    check1 = nonZeroBits1 - natc1;
                }
                else
                {
                    #region 7.24.1
                    return(DoInvalidResponse(database, qManager));

                    #endregion
                }

                if ((database.IsNotPresent(EMVTagsEnum.NATC_TRACK1_9F64_KRN2.Tag) || database.IsEmpty(EMVTagsEnum.NATC_TRACK1_9F64_KRN2.Tag)) ||
                    (database.IsNotPresent(EMVTagsEnum.PCVC3_TRACK1_9F62_KRN2.Tag) || database.IsEmpty(EMVTagsEnum.PCVC3_TRACK1_9F62_KRN2.Tag)) ||
                    (database.IsNotPresent(EMVTagsEnum.PUNATC_TRACK1_9F63_KRN2.Tag) || database.IsEmpty(EMVTagsEnum.PUNATC_TRACK1_9F63_KRN2.Tag)) ||
                    check1 != check2
                    )
                {
                    #region 7.24.1
                    return(DoInvalidResponse(database, qManager));

                    #endregion
                }
            }
            #region 7.23
            TRACK_2_DATA_9F6B_KRN2 t2d = new TRACK_2_DATA_9F6B_KRN2(database);
            TLV ddCardT2 = database.Get(EMVTagsEnum.DD_CARD_TRACK2_DF812B_KRN2);
            if (ddCardT2 == null)
            {
                ddCardT2 = TLV.Create(EMVTagsEnum.DD_CARD_TRACK2_DF812B_KRN2.Tag);
            }
            ddCardT2.Value = t2d.Value.DiscretionaryData;
            if (database.IsNotEmpty(EMVTagsEnum.TRACK_1_DATA_56_KRN2.Tag))
            {
                TRACK_1_DATA_56_KRN2 t1d = new TRACK_1_DATA_56_KRN2(database);

                TLV ddCardT1 = database.Get(EMVTagsEnum.DD_CARD_TRACK1_DF812A_KRN2);
                if (ddCardT1 == null)
                {
                    ddCardT1 = TLV.Create(EMVTagsEnum.DD_CARD_TRACK1_DF812A_KRN2.Tag);
                }

                ddCardT1.Value = t1d.Value.DiscretionaryData;
            }
            return(State_7_8_CommonProcessing.DoCommonProcessing("State_7_WaitingForMagStripeReadRecordResponse", database, qManager, cardQManager, sw));

            #endregion

            #endregion
        }
Beispiel #6
0
        private static SignalsEnum EntryPointRA(KernelDatabaseBase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager,
                                                Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, CardExceptionManager cardExceptionManager,
                                                Func <string, KernelDatabaseBase, KernelQ, CardQ, Stopwatch, PublicKeyCertificateManager, CardExceptionManager, SignalsEnum> ReadRecordCompleteCallback)
        {
            byte sfi;
            bool signedFlag;

            if (!cardResponse.ApduResponse.Succeeded)
            {
                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,
                                                  cardResponse.ApduResponse.SW12,
                                                  L2Enum.STATUS_BYTES,
                                                  L3Enum.NOT_SET));
            }

            if (database.ActiveAFL.Value.Entries[0].OfflineDataAuthenticationRecordLength > 0)
            {
                signedFlag = true;
            }
            else
            {
                signedFlag = false;
            }

            sfi = database.ActiveAFL.Value.Entries[0].SFI;
            database.ActiveAFL.Value.Entries.RemoveAt(0);

            if (database.ActiveAFL.Value.Entries.Count == 0)
            {
                database.NextCommandEnum = NextCommandEnum.NONE;
            }
            else
            {
                EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                database.NextCommandEnum = NextCommandEnum.READ_RECORD;
            }

            bool parsingResult;

            if (sfi <= 10)
            {
                if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x70)
                {
                    parsingResult = database.ParseAndStoreCardResponse(cardResponse.ApduResponse.ResponseData);
                }
                else
                {
                    parsingResult = false;
                }
            }
            else //Processing of records in proprietary files is beyond the scope of thisspecification
            {
                parsingResult = false;
            }

            if (!parsingResult)
            {
                if (database.NextCommandEnum == NextCommandEnum.NONE)
                {
                    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.PARSING_ERROR,
                                                      L3Enum.NOT_SET));
                }
                else
                {
                    return(SignalsEnum.TEMINATE_ON_NEXT_RA);
                }
            }

            TLVList responseTags;

            if (cardResponse.ApduResponse is EMVReadRecordResponse)
            {
                responseTags = (cardResponse.ApduResponse as EMVReadRecordResponse).GetResponseTags();
            }
            else if (cardResponse.ApduResponse is EMVGetDataResponse)
            {
                responseTags = (cardResponse.ApduResponse as EMVGetDataResponse).GetResponseTags();
            }
            else
            {
                throw new EMVProtocolException("Invalid card response in State4");
            }

            TLVList cdols = responseTags.FindAll(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN.Tag);

            if (cdols.Count > 0)
            {
                TLVList cdolList = TLV.DeserializeChildrenWithNoV(cdols.GetFirst().Value, 0);
                DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
                foreach (TLV tlv in cdolList)
                {
                    if (database.IsEmpty(tlv.Tag.TagLable))
                    {
                        dataNeeded.Value.Tags.Add(tlv.Tag.TagLable);
                    }
                }
                dataNeeded.UpdateDB();
            }

            Do434(database, signedFlag, sfi, cardResponse, responseTags);

            return(ReadRecordCompleteCallback("State_4_WaitingForEMVReadRecord", database, qManager, cardQManager, sw, publicKeyCertificateManager, cardExceptionManager));
            //return State_4_5_6_CommonProcessing.DoCommonProcessing("State_4_WaitingForEMVReadRecord", database, qManager, cardQManager, sw, publicKeyCertificateManager);
        }
        public static SignalsEnum DoCommonProcessing(string source, Kernel2Database database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse)
        {
            #region S3R1.1
            TLV nextTLV = database.TagsToReadYet.GetNextGetDataTagFromList();
            if (nextTLV != null)
            {
                database.ActiveTag = nextTLV.Tag.TagLable;
            }
            else
            {
                database.ActiveTag = null;
            }

            if (database.ActiveTag != null)
            {
                #region S3R1.2
                EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(database.ActiveTag));
                #endregion
                #region S3R1.3
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                #endregion
                #region S3R1.3
                database.NextCommandEnum = NextCommandEnum.GET_DATA;
                #endregion
            }
            #endregion
            else
            {
                #region S3R1.5
                if (database.ActiveAFL == null)
                #endregion
                {
                    #region S3R1.6
                    return(DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET));

                    #endregion
                }
                else
                {
                    #region S3R1.7
                    EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber);
                    #endregion
                    #region S3R1.8
                    cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                    #endregion
                    #region S3R1.9
                    database.NextCommandEnum = NextCommandEnum.READ_RECORD;
                    #endregion
                }
            }

            #region S3R1.10
            TLVList dataToSend         = database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children;
            IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database);
            if (ids.Value.IsRead)
            #endregion
            {
                #region S3R1.11
                if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_AVAILABILITY_9F5F_KRN2.Tag))
                {
                    dataToSend.AddToList(database.Get(EMVTagsEnum.DS_SLOT_AVAILABILITY_9F5F_KRN2));
                }
                if (database.IsNotEmpty(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2.Tag))
                {
                    dataToSend.AddToList(database.Get(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2));
                }
                if (database.IsNotEmpty(EMVTagsEnum.DS_UNPREDICTABLE_NUMBER_9F7F_KRN2.Tag))
                {
                    dataToSend.AddToList(database.Get(EMVTagsEnum.DS_UNPREDICTABLE_NUMBER_9F7F_KRN2));
                }
                if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2.Tag))
                {
                    dataToSend.AddToList(database.Get(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2));
                }
                if (database.IsNotEmpty(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2.Tag))
                {
                    dataToSend.AddToList(database.Get(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2));
                }
                dataToSend.AddToList(database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN));
                #endregion
                #region S3R1.12
                if (!((database.IsNotEmpty(EMVTagsEnum.DS_SLOT_AVAILABILITY_9F5F_KRN2.Tag) &&
                       database.IsNotEmpty(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2.Tag) &&
                       database.IsNotEmpty(EMVTagsEnum.DS_UNPREDICTABLE_NUMBER_9F7F_KRN2.Tag) &&
                       database.IsNotPresent(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2.Tag))
                      ||
                      (database.IsNotEmpty(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2.Tag) &&
                       database.IsPresent(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2.Tag))
                      ))
                {
                    #region S3R1.13
                    ids = new IDS_STATUS_DF8128_KRN2(database);
                    ids.Value.IsRead = false;
                    ids.UpdateDB();
                    #endregion
                }
                #endregion
            }

            #region S3R1.14
            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 S3R1.15
            if (database.IsNotEmptyList(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag) ||
                (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0))
            {
                #region S3R1.16
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
                #endregion
            }
            #endregion

            #region S3R1.17
            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
            TERMINAL_CAPABILITIES_9F33_KRN         tc  = new TERMINAL_CAPABILITIES_9F33_KRN(database);

            if (!(aip.Value.CDASupported && tc.Value.CDACapable))
            {
                #region S3R1.18
                ids = new IDS_STATUS_DF8128_KRN2(database);
                if (!ids.Value.IsRead)
                {
                    #region S3R1.20
                    TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                    tvr.Value.OfflineDataAuthenticationWasNotPerformed = true;
                    tvr.UpdateDB();
                    #endregion
                }
                else
                {
                    #region S3R1.19
                    database.ODAStatus = 0x80;
                    #endregion
                }
                #endregion
            }
            else
            {
                #region S3R1.19
                database.ODAStatus = 0x80;
                #endregion
            }
            #endregion

            if (database.NextCommandEnum == NextCommandEnum.READ_RECORD)
            {
                return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE);
            }
            else
            {
                return(SignalsEnum.WAITING_FOR_GET_DATA_RESPONSE);
            }
        }
        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
        }
        /*
         * S5.3
         */
        private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, TornTransactionLogManager tornTransactionLogManager, Stopwatch sw)
        {
            #region 5.9
            string currentTag = database.ActiveTag;
            #endregion
            TLV nextTLV = database.TagsToReadYet.GetNextGetDataTagFromList();
            if (nextTLV != null)
            {
                database.ActiveTag = nextTLV.Tag.TagLable;
            }
            else
            {
                database.ActiveTag = null;
            }
            #region 5.10
            if (database.ActiveTag != null)
            #endregion
            {
                #region 5.11 - 5.13
                EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(database.ActiveTag));
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                database.NextCommandEnum = NextCommandEnum.GET_DATA;
                #endregion
            }
            else
            {
                #region 5.14
                if (database.ActiveAFL == null)
                #endregion
                {
                    #region 5.15
                    database.NextCommandEnum = NextCommandEnum.NONE;
                    #endregion
                }
                else
                {
                    #region 5.16 - 5.18
                    EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber);
                    cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                    #endregion
                }
            }

            #region 5.19
            if (!cardResponse.ApduResponse.Succeeded)
            #endregion
            {
                #region 5.20
                bool parsingResult = false;
                EMVGetProcessingOptionsResponse response = cardResponse.ApduResponse as EMVGetProcessingOptionsResponse;
                parsingResult = database.ParseAndStoreCardResponse(response.ResponseData);
                #endregion
                #region 5.21
                if (parsingResult)
                {
                    #region 5.22
                    if (currentTag == response.GetResponseTags().GetFirst().Tag.TagLable)
                    {
                        #region 5.23
                        database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(response.GetResponseTags().GetFirst());
                        #endregion
                    }
                    else
                    {
                        #region 5.24
                        database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(TLV.Create(currentTag));
                        #endregion
                    }
                    #endregion
                }
                else
                {
                    #region 5.24
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(TLV.Create(currentTag));
                    #endregion
                }
                #endregion
            }
            else
            {
                #region 5.24
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(TLV.Create(currentTag));
                #endregion
            }

            return(State_4_5_6_CommonProcessing.DoCommonProcessing("State_5_WaitingForGetDataResponse", database, qManager, cardQManager, sw, tornTransactionLogManager));
        }