private static SignalsEnum DoProcessingRestrictions(Kernel3Database database, KernelQ qManager, CardExceptionManager cardExceptionManager)
        {
            #region 5.5.1.1
            DateTime transactionDate = EMVTagsEnum.TRANSACTION_DATE_9A_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.TRANSACTION_DATE_9A_KRN).Value);
            DateTime appExpiryDate   = DateTime.Now;
            TLV      appExiryDateTLV = database.Get(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN);
            if (appExiryDateTLV != null)
            {
                appExpiryDate = EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN.FormatAsDateTime(appExiryDateTLV.Value);
            }
            if (appExiryDateTLV == null || (transactionDate > appExpiryDate))
            {
                CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3 ctq = new CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3(database);
                if (ctq.Value.GoOnlineIfApplicationExpired)
                {
                    database.OnlineRequiredByReaderIndicator = true;
                }
                else
                {
                    database.DeclineRequiredByReaderIndicator = true;
                    return(SignalsEnum.NONE);
                }
            }
            #endregion

            #region 5.5.1.2
            string pan = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value);
            if (database.Kernel3Configuration.ExceptionFileEnabled && cardExceptionManager.CheckForCardException(pan))
            {
                database.DeclineRequiredByReaderIndicator = true;
                return(SignalsEnum.NONE);
            }
            #endregion

            TransactionTypeEnum tt = (TransactionTypeEnum)Formatting.GetEnum(typeof(TransactionTypeEnum), database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0]);

            #region 5.5.1.3
            if (tt == TransactionTypeEnum.CashWithdrawal || tt == TransactionTypeEnum.CashDisbursement && database.Kernel3Configuration.AUCManualCheckSupported)
            {
                TLV icc = database.Get(EMVTagsEnum.ISSUER_COUNTRY_CODE_5F28_KRN);
                if (icc == null)
                {
                    database.DeclineRequiredByReaderIndicator = true;
                    return(SignalsEnum.NONE);
                }
                TLV tcc = database.Get(EMVTagsEnum.TERMINAL_COUNTRY_CODE_9F1A_KRN);
                APPLICATION_USAGE_CONTROL_9F07_KRN auc = new APPLICATION_USAGE_CONTROL_9F07_KRN(database);

                if (!((Formatting.ByteArrayToHexString(icc.Value) == Formatting.ByteArrayToHexString(tcc.Value) && auc.Value.IsValidForDomesticCashTransactions) ||
                      (Formatting.ByteArrayToHexString(icc.Value) != Formatting.ByteArrayToHexString(tcc.Value) && auc.Value.IsValidForInternationalCashTransactions)))
                {
                    CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3 ctq = new CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3(database);
                    if (database.IsEmpty(EMVTagsEnum.CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3.Tag) || ctq.Value.SwitchInterfaceForCashTransactions)
                    {
                        return(CommonRoutines.PostOutcome(database, qManager,
                                                          KernelMessageidentifierEnum.N_A,
                                                          KernelStatusEnum.PROCESSING_ERROR,
                                                          null,
                                                          Kernel2OutcomeStatusEnum.TRY_ANOTHER_INTERFACE,
                                                          Kernel2StartEnum.N_A,
                                                          true,
                                                          KernelMessageidentifierEnum.N_A,
                                                          L1Enum.NOT_SET,
                                                          null,
                                                          L2Enum.STATUS_BYTES,
                                                          L3Enum.NOT_SET));
                    }
                    else
                    {
                        database.DeclineRequiredByReaderIndicator = true;
                        return(SignalsEnum.NONE);
                    }
                }
            }
            #endregion

            #region 5.5.1.4
            if (tt == TransactionTypeEnum.PurchaseWithCashback && database.Kernel3Configuration.AUCCashbackCheckSupported)
            {
                TLV icc = database.Get(EMVTagsEnum.ISSUER_COUNTRY_CODE_5F28_KRN);
                if (icc == null)
                {
                    database.DeclineRequiredByReaderIndicator = true;
                    return(SignalsEnum.NONE);
                }
                TLV tcc = database.Get(EMVTagsEnum.TERMINAL_COUNTRY_CODE_9F1A_KRN);

                APPLICATION_USAGE_CONTROL_9F07_KRN auc = new APPLICATION_USAGE_CONTROL_9F07_KRN(database);

                if (!((Formatting.ByteArrayToHexString(icc.Value) == Formatting.ByteArrayToHexString(tcc.Value) && auc.Value.IsValidForDomesticCashTransactions) ||
                      (Formatting.ByteArrayToHexString(icc.Value) != Formatting.ByteArrayToHexString(tcc.Value) && auc.Value.IsValidForInternationalCashTransactions)))
                {
                    CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3 ctq = new CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3(database);
                    if (database.IsEmpty(EMVTagsEnum.CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3.Tag) || ctq.Value.SwitchInterfaceForCashBackTransactions)
                    {
                        return(CommonRoutines.PostOutcome(database, qManager,
                                                          KernelMessageidentifierEnum.N_A,
                                                          KernelStatusEnum.PROCESSING_ERROR,
                                                          null,
                                                          Kernel2OutcomeStatusEnum.TRY_ANOTHER_INTERFACE,
                                                          Kernel2StartEnum.N_A,
                                                          true,
                                                          KernelMessageidentifierEnum.N_A,
                                                          L1Enum.NOT_SET,
                                                          null,
                                                          L2Enum.STATUS_BYTES,
                                                          L3Enum.NOT_SET));
                    }
                    else
                    {
                        database.DeclineRequiredByReaderIndicator = true;
                        return(SignalsEnum.NONE);
                    }
                }
            }
            #endregion

            #region 5.5.1.5
            if (database.Kernel3Configuration.ATMOfflineCheck)
            {
                TERMINAL_TYPE_9F35_KRN termType = new TERMINAL_TYPE_9F35_KRN(database);
                if (termType.Value.TerminalType.Code == 0x14 || termType.Value.TerminalType.Code == 0x15 || termType.Value.TerminalType.Code == 0x16)
                {
                    if (database.IsEmpty(EMVTagsEnum.CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3.Tag))
                    {
                        database.DeclineRequiredByReaderIndicator = true;
                        return(SignalsEnum.NONE);
                    }
                    else
                    {
                        CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3 ctq = new CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3(database);
                        if (!ctq.Value.ValidForContactlessATMTransactions)
                        {
                            database.OnlineRequiredByReaderIndicator = true;
                        }
                        else
                        {
                            APPLICATION_USAGE_CONTROL_9F07_KRN auc = new APPLICATION_USAGE_CONTROL_9F07_KRN(database);
                            if (auc == null)
                            {
                                database.OnlineRequiredByReaderIndicator = true;
                            }
                            else if (!auc.Value.IsValidAtATMs)
                            {
                                database.DeclineRequiredByReaderIndicator = true;
                                return(SignalsEnum.NONE);
                            }
                            else
                            {
                                return(CommonRoutines.PostOutcome(database, qManager,
                                                                  KernelMessageidentifierEnum.N_A,
                                                                  KernelStatusEnum.PROCESSING_ERROR,
                                                                  null,
                                                                  Kernel2OutcomeStatusEnum.TRY_ANOTHER_INTERFACE,
                                                                  Kernel2StartEnum.N_A,
                                                                  true,
                                                                  KernelMessageidentifierEnum.N_A,
                                                                  L1Enum.NOT_SET,
                                                                  null,
                                                                  L2Enum.STATUS_BYTES,
                                                                  L3Enum.NOT_SET));
                            }
                        }
                    }
                }
            }
            #endregion

            return(SignalsEnum.NONE);
        }
        public static KernelCVMEnum DoCVMProcessing(Kernel3Database database, ACTypeEnum acType)
        {
            KernelCVMEnum cvm = KernelCVMEnum.N_A;
            TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN ttq = new TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN(database);

            if (!database.DeclineRequiredByReaderIndicator)
            {
                #region 5.7.1.1
                if (database.IsEmpty(EMVTagsEnum.CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3.Tag) && ttq.Value.CVMRequired)
                #endregion
                {
                    if (ttq.Value.SignatureSupported)
                    {
                        cvm = KernelCVMEnum.OBTAIN_SIGNATURE;
                    }
                    else if (ttq.Value.ConsumerDeviceCVMSupported && ttq.Value.OnlinePINSupported)
                    {
                        cvm = KernelCVMEnum.ONLINE_PIN;
                    }
                    else// only ttq.Value.ConsumerDeviceCVMSupported
                    {
                        database.DeclineRequiredByReaderIndicator = true;
                    }
                }
                if (database.IsNotEmpty(EMVTagsEnum.CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3.Tag))
                {
                    #region 5.7.1.2
                    CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3 ctq = new CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3(database);
                    if (ctq.Value.OnlinePINRequired && ttq.Value.OnlinePINSupported)
                    {
                        cvm = KernelCVMEnum.ONLINE_PIN;
                        database.OnlineRequiredByReaderIndicator = true;
                    }
                    else
                    {
                        if (ctq.Value.ConsumerDeviceCVMPerformed)
                        {
                            TLV card = database.Get(EMVTagsEnum.CARD_AUTHENTICATION_RELATED_DATA_9F69_KRN3);
                            if (card != null)
                            {
                                byte[] card67 = new byte[2];
                                byte[] ctq12  = new byte[2];
                                Array.Copy(card.Value, 6, card67, 0, 2);
                                Array.Copy(ctq.Value.Value, 0, ctq12, 0, 2);
                                if (Formatting.ByteArrayToHexString(card67) == Formatting.ByteArrayToHexString(ctq12))
                                {
                                    cvm = KernelCVMEnum.CONFIRMATION_CODE_VERIFIED;
                                }
                                else
                                {
                                    database.DeclineRequiredByReaderIndicator = true;
                                }
                            }
                            else
                            {
                                if (acType == ACTypeEnum.ARQC)
                                {
                                    cvm = KernelCVMEnum.CONFIRMATION_CODE_VERIFIED;
                                }
                                else
                                {
                                    database.DeclineRequiredByReaderIndicator = true;
                                }
                            }
                        }
                    }

                    if (!ctq.Value.OnlinePINRequired && !ctq.Value.ConsumerDeviceCVMPerformed)
                    {
                        if (ttq.Value.SignatureSupported && ctq.Value.SignatureRequired)
                        {
                            cvm = KernelCVMEnum.OBTAIN_SIGNATURE;
                        }
                    }

                    #endregion
                }
            }
            if (cvm == KernelCVMEnum.N_A && ttq.Value.CVMRequired)
            {
                cvm = KernelCVMEnum.NO_CVM;
                database.DeclineRequiredByReaderIndicator = true;
            }
            if (cvm == KernelCVMEnum.N_A)
            {
                cvm = KernelCVMEnum.NO_CVM;
            }

            return(cvm);
        }