Exemple #1
0
        private static SignalsEnum EntryPointACT(KernelDatabaseBase database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            foreach (TLV tlv in kernel1Request.InputData)
            {
                if (tlv.Tag.TagLable == EMVTagsEnum.FILE_CONTROL_INFORMATION_FCI_TEMPLATE_6F_KRN.Tag)
                {
                    if (!database.ParseAndStoreCardResponse(tlv))
                    {
                        return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET));
                    }
                }
                else
                {
                    if ((database.IsKnown(tlv.Tag.TagLable) || database.IsPresent(tlv.Tag.TagLable)) && EMVTagsEnum.DoesTagIncludesPermission(tlv.Tag.TagLable, UpdatePermissionEnum.ACT))
                    {
                        database.AddToList(tlv);
                    }
                }
            }

            database.AddToList(TLV.Create(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN.Tag, new byte[] { 0x00, 0x00, 0x00, 0x00 }));
            database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value = Formatting.GetRandomNumber();

            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvmr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);

            cvmr.UpdateDB();

            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

            tvr.UpdateDB();

            TERMINAL_CAPABILITIES_9F33_KRN _9f33 = new TERMINAL_CAPABILITIES_9F33_KRN(database);

            _9f33.UpdateDB();

            database.Initialize(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag);
            database.Initialize(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag);

            DATA_NEEDED_DF8106_KRN2  dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
            DATA_TO_SEND_FF8104_KRN2 dataToSend = new DATA_TO_SEND_FF8104_KRN2(database);

            database.TagsToReadYet.Initialize();

            if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2.Tag))
            {
                database.TagsToReadYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2).Children);
            }
            else
            {
                dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2);
                dataNeeded.UpdateDB();
            }

            bool MissingPDOLDataFlag = false;

            TLV     _9f38    = database.Get(EMVTagsEnum.PROCESSING_OPTIONS_DATA_OBJECT_LIST_PDOL_9F38_KRN);
            TLVList pdolList = TLV.DeserializeChildrenWithNoV(_9f38.Value, 0);

            foreach (TLV tlv in pdolList)
            {
                if (database.IsEmpty(tlv.Tag.TagLable))
                {
                    MissingPDOLDataFlag = true;
                    dataNeeded.Value.AddTag(tlv.Tag.TagLable);
                }
            }
            dataNeeded.UpdateDB();

            if (!MissingPDOLDataFlag)
            {
                database.Initialize(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2.Tag);
                CommonRoutines.PackRelatedDataTag(database, EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2, pdolList);
                EMVGetProcessingOptionsRequest request = new EMVGetProcessingOptionsRequest(database.Get(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2));
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
            }

            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);
            }

            dataNeeded.UpdateDB();

            if (MissingPDOLDataFlag)
            {
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();

                sw.Restart();
                return(SignalsEnum.WAITING_FOR_PDOL_DATA);
            }

            return(SignalsEnum.WAITING_FOR_GPO_REPONSE);
        }
Exemple #2
0
        /*
         * S1.1, S1.7 - S1.23
         */
        private static SignalsEnum EntryPointACT(Kernel2Database database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            #region S1.7
            foreach (TLV tlv in kernel1Request.InputData)
            {
                if (tlv.Tag.TagLable == EMVTagsEnum.FILE_CONTROL_INFORMATION_FCI_TEMPLATE_6F_KRN.Tag)
                {
                    if (!database.ParseAndStoreCardResponse(tlv))
                    {
                        return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET));
                    }
                }
                else
                {
                    if ((database.IsKnown(tlv.Tag.TagLable) || database.IsPresent(tlv.Tag.TagLable)) && EMVTagsEnum.DoesTagIncludesPermission(tlv.Tag.TagLable, UpdatePermissionEnum.ACT))
                    {
                        database.AddToList(tlv);
                    }
                }
            }

            if (database.IsNotEmpty(EMVTagsEnum.LANGUAGE_PREFERENCE_5F2D_KRN.Tag))
            {
                byte[] languagePrefFromCard       = database.Get(EMVTagsEnum.LANGUAGE_PREFERENCE_5F2D_KRN).Value;
                byte[] languagePrefFromCardPadded = new byte[8]; //will be padded with trailing 0's
                Array.Copy(languagePrefFromCard, languagePrefFromCardPadded, languagePrefFromCard.Length);
                CommonRoutines.UpdateUserInterfaceRequestData(database, languagePrefFromCardPadded);
            }

            #region S1.8
            if (database.IsNotPresent(EMVTagsEnum.DEDICATED_FILE_DF_NAME_84_KRN.Tag) || database.IsEmpty(EMVTagsEnum.DEDICATED_FILE_DF_NAME_84_KRN.Tag))
            {
                return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET));
            }
            #endregion

            if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag))
            {
                APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aciVal = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database);
                if (aciVal.Value.SupportForFieldOffDetection)
                {
                    byte[] holdTimeValue = database.GetDefault(EMVTagsEnum.HOLD_TIME_VALUE_DF8130_KRN2).Value;
                    CommonRoutines.UpdateOutcomeParameterSet(database, holdTimeValue[0]);
                }
            }
            #endregion

            #region S1.9
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvmr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);
            cvmr.UpdateDB();

            database.ACType = new DS_AC_TYPE_DF8108_KRN2(database);
            database.ACType.Value.DSACTypeEnum = ACTypeEnum.TC;

            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
            tvr.UpdateDB();

            database.ODAStatus = 0x00;

            database.AddToList(TLV.Create(EMVTagsEnum.RRP_COUNTER_DF8307_KRN2.Tag, new byte[] { 0x00 }));

            //CARD_DATA_INPUT_CAPABILITY_DF8117_KRN2 df8117 = new CARD_DATA_INPUT_CAPABILITY_DF8117_KRN2(database);
            //SECURITY_CAPABILITY_DF811F_KRN2 df811f = new SECURITY_CAPABILITY_DF811F_KRN2(database);

            TERMINAL_CAPABILITIES_9F33_KRN _9f33 = new TERMINAL_CAPABILITIES_9F33_KRN(database);
            //_9f33.Value.SetCardDataInputCapabilityValue(df8117);
            //_9f33.Value.SetSecurityCapabilityValue(df811f);
            _9f33.UpdateDB();

            database.StaticDataToBeAuthenticated.Initialize();

            database.AddToList(TLV.Create(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN.Tag, new byte[] { 0x00, 0x00, 0x00, 0x00 }));
            database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value = Formatting.GetRandomNumber();

            //REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcpv = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2();
            //rcpv.Value.ACTypeEnum = ACTypeEnum.TC;
            //rcpv.UpdateDB();
            #endregion

            #region S1.10
            database.Initialize(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag);
            database.Initialize(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag);

            DATA_NEEDED_DF8106_KRN2  dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
            DATA_TO_SEND_FF8104_KRN2 dataToSend = new DATA_TO_SEND_FF8104_KRN2(database);

            database.TagsToReadYet.Initialize();

            if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2.Tag))
            {
                database.TagsToReadYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2).Children);
            }
            else
            {
                dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2);
                dataNeeded.UpdateDB();
            }
            #endregion

            #region S1.11
            bool MissingPDOLDataFlag = false;
            #endregion

            #region S1.12
            TLV     _9f38    = database.Get(EMVTagsEnum.PROCESSING_OPTIONS_DATA_OBJECT_LIST_PDOL_9F38_KRN);
            TLVList pdolList = TLV.DeserializeChildrenWithNoV(_9f38.Value, 0);
            foreach (TLV tlv in pdolList)
            {
                if (database.IsEmpty(tlv.Tag.TagLable))
                {
                    MissingPDOLDataFlag = true;
                    dataNeeded.Value.AddTag(tlv.Tag.TagLable);
                }
            }
            dataNeeded.UpdateDB();

            #region S1.13 and S1.14
            if (!MissingPDOLDataFlag)
            {
                database.Initialize(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2.Tag);
                CommonRoutines.PackRelatedDataTag(database, EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2, pdolList);
                EMVGetProcessingOptionsRequest request = new EMVGetProcessingOptionsRequest(database.Get(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2));
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
            }
            #endregion

            #endregion

            #region S1.15
            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 S1.16
            database.Initialize(EMVTagsEnum.IDS_STATUS_DF8128_KRN2.Tag);
            database.Initialize(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2.Tag);
            database.Initialize(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2.Tag);
            database.Initialize(EMVTagsEnum.PREGEN_AC_PUT_DATA_STATUS_DF810F_KRN2.Tag);
            database.Initialize(EMVTagsEnum.DS_DIGEST_H_DF61_KRN2.Tag);

            database.Get(EMVTagsEnum.IDS_STATUS_DF8128_KRN2).Value                 = new byte[] { 0x00 };
            database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value          = new byte[] { 0x00 };
            database.Get(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2).Value = new byte[] { 0x00 };
            database.Get(EMVTagsEnum.PREGEN_AC_PUT_DATA_STATUS_DF810F_KRN2).Value  = new byte[] { 0x00 };
            database.Get(EMVTagsEnum.DS_DIGEST_H_DF61_KRN2).Value = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };

            database.TagsToWriteAfterGenACYet.Initialize();
            database.TagsToWriteBeforeGenACYet.Initialize();

            if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2.Tag))
            {
                database.TagsToWriteBeforeGenACYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2).Children);
            }
            if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2.Tag))
            {
                database.TagsToWriteAfterGenACYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2).Children);
            }

            if (database.IsEmptyList(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2.Tag))
            {
                dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2);
            }
            if (database.IsEmptyList(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2.Tag))
            {
                dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2);
            }

            dataNeeded.UpdateDB();
            #endregion

            #region S1.17
            if (database.IsNotEmpty(EMVTagsEnum.DSVN_TERM_DF810D_KRN2.Tag) && database.IsPresent(EMVTagsEnum.DS_REQUESTED_OPERATOR_ID_9F5C_KRN2.Tag))
            {
                #region S1.18
                if (database.IsPresent(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag))
                {
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2));
                }
                else
                {
                    TLV dsid = TLV.Create(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag);
                    dsid.Val.PackValue(EMVTagsEnum.DS_ID_9F5E_KRN2.DataFormatter.GetMaxLength());
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(dsid);
                }

                if (database.IsPresent(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag))
                {
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(database.Get(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2));
                }
                else
                {
                    TLV aci = TLV.Create(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag);
                    aci.Val.PackValue(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.DataFormatter.GetMaxLength());
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(aci);
                }
                #endregion

                #region S1.19
                if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag))
                {
                    APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aci = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database);
                    if ((aci.Value.DataStorageVersionNumberEnum == DataStorageVersionNumberEnum.VERSION_1 || aci.Value.DataStorageVersionNumberEnum == DataStorageVersionNumberEnum.VERSION_2) &&
                        database.IsNotEmpty(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag))
                    {
                        #region S1.20
                        IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database);
                        ids.Value.IsRead = true;
                        ids.UpdateDB();
                        #endregion
                    }
                }
                #endregion
            }
            #endregion

            #region S1.21
            if (MissingPDOLDataFlag)
            {
                #region S1.22
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
                #endregion

                #region S1.23
                sw.Restart();
                #endregion

                return(SignalsEnum.WAITING_FOR_PDOL_DATA);
            }
            #endregion

            return(SignalsEnum.WAITING_FOR_GPO_REPONSE);
        }
        protected virtual EMVTerminalProcessingOutcome StartServiceQPRocess(KernelBase kernel)
        {
            while (1 == 1)
            {
                try
                {
                    if (cancellationTokenForTerminalApplication.Token.IsCancellationRequested)
                    {
                        cancellationTokenForTerminalApplication.Dispose();
                        return(null);
                    }

                    if (kernel.KernelQ.GetOutputQCount() == 0)
                    {
                        Task.Run(async() => await Task.Delay(1)).Wait();
                        continue;
                    }

                    KernelResponseBase k2Response = kernel.KernelQ.DequeueFromOutput(true);
                    if (k2Response == null)
                    {
                        Task.Run(async() => await Task.Delay(1)).Wait();
                        continue;
                    }

                    Logger.Log("Terminal received signal:" + k2Response.KernelReaderTerminalServiceResponseEnum);

                    switch (k2Response.KernelReaderTerminalServiceResponseEnum)
                    {
                    case KernelReaderTerminalServiceResponseEnum.DEK:
                        DATA_NEEDED_DF8106_KRN2  dataNeeded = ((KernelDEKResponse)k2Response).DataNeeded;
                        DATA_TO_SEND_FF8104_KRN2 dataToSend = ((KernelDEKResponse)k2Response).DataToSend;

                        TLVList requestInput = new TLVList();

                        //Logger.Log("------------------DEK Request Start-------------------");
                        foreach (string tag in dataNeeded.Value.Tags)
                        {
                            TLV found = terminalConfigurationData.TerminalConfigurationDataObjects.Get(tag);
                            if (found == null)
                            {
                                Logger.Log("Tag Requested Of Terminal By Kernel Not Found:" + tag);
                                throw new EMVTerminalException("cound not find tag for data needed: " + tag);
                            }

                            requestInput.AddToList(found);

                            //int depth = 0;
                            //Logger.Log("Tag Requested From Terminal:" + found.ToPrintString(ref depth));
                        }
                        //Logger.Log("------------------DEK Request End-------------------");
                        KernelRequest request = new KernelRequest(KernelTerminalReaderServiceRequestEnum.DET, requestInput);
                        kernel.KernelQ.EnqueueToInput(request);
                        break;     //continue processing

                    case KernelReaderTerminalServiceResponseEnum.OUT:
                        KernelOUTResponse            outResponse          = (KernelOUTResponse)k2Response;
                        EMVTerminalProcessingOutcome processingOutcomeOUT = new EMVTerminalProcessingOutcome()
                        {
                            CVM = outResponse.OutcomeParameterSet_DF8129.Value.CVM
                        };
                        switch (outResponse.OutcomeParameterSet_DF8129.Value.Start)
                        {
                        case Kernel2StartEnum.A:
                            throw new Exception("Kernel2StartEnum.A Not Implemented");

                        case Kernel2StartEnum.B:
                            if (outResponse.UserInterfaceRequest_DF8116 != null)
                            {
                                OnUserInterfaceRequest(CreateUIMessageEventArgs(
                                                           outResponse.UserInterfaceRequest_DF8116.Value.KernelMessageidentifierEnum,
                                                           outResponse.UserInterfaceRequest_DF8116.Value.KernelStatusEnum,
                                                           Formatting.ConvertToInt32(outResponse.UserInterfaceRequest_DF8116.Value.HoldTime)));
                            }
                            else
                            {
                                OnUserInterfaceRequest(new UIMessageEventArgs(MessageIdentifiersEnum.TransmissionError, StatusEnum.EndProcessing));
                            }

                            processingOutcomeOUT.NextProcessState = EMVTerminalPreProcessingStateEnum.ProtocolActivation_StartB;
                            return(processingOutcomeOUT);

                        case Kernel2StartEnum.C:
                            processingOutcomeOUT.NextProcessState = EMVTerminalPreProcessingStateEnum.CombinationSelection_StartC;
                            return(processingOutcomeOUT);

                        case Kernel2StartEnum.D:
                            throw new Exception("Kernel2StartEnum.D Not Implemented");

                        case Kernel2StartEnum.N_A:
                            if (outResponse.UserInterfaceRequest_DF8116 != null)
                            {
                                string s1 = outResponse.UserInterfaceRequest_DF8116.Value.KernelMessageidentifierEnum.ToString();
                                string s2 = outResponse.UserInterfaceRequest_DF8116.Value.KernelStatusEnum.ToString();
                                string s3 = "";
                                if (outResponse.UserInterfaceRequest_DF8116.Value.ValueQualifierEnum != ValueQualifierEnum.NONE)
                                {
                                    s3 = outResponse.UserInterfaceRequest_DF8116.Value.ValueQualifierEnum + " : " + Formatting.BcdToString(outResponse.UserInterfaceRequest_DF8116.Value.ValueQualifier);
                                }
                                string s4 = "";
                                if (outResponse.OutcomeParameterSet_DF8129.Value.CVM != KernelCVMEnum.NO_CVM)
                                {
                                    s4 = outResponse.OutcomeParameterSet_DF8129.Value.CVM.ToString();
                                }
                                OnUserInterfaceRequest(CreateUIMessageEventArgs(
                                                           outResponse.UserInterfaceRequest_DF8116.Value.KernelMessageidentifierEnum,
                                                           outResponse.UserInterfaceRequest_DF8116.Value.KernelStatusEnum,
                                                           string.Format("{0}:{1}", s3, s4)));
                            }

                            processingOutcomeOUT.DataRecord        = outResponse.DataRecord_FF8105;
                            processingOutcomeOUT.DiscretionaryData = outResponse.DiscretionaryData_FF8106;

                            int depth = 0;
                            if (outResponse.UserInterfaceRequest_DF8116 != null)
                            {
                                Logger.Log(outResponse.UserInterfaceRequest_DF8116.ToPrintString(ref depth));
                            }
                            depth = 0;
                            Logger.Log(outResponse.OutcomeParameterSet_DF8129.ToPrintString(ref depth));
                            depth = 0;
                            if (outResponse.ErrorIndication_DF8115 != null)
                            {
                                Logger.Log(outResponse.ErrorIndication_DF8115.ToPrintString(ref depth));
                            }
                            depth = 0;
                            if (outResponse.DataRecord_FF8105 != null)
                            {
                                Logger.Log(outResponse.DataRecord_FF8105.ToPrintString(ref depth));
                            }
                            depth = 0;
                            if (outResponse.DiscretionaryData_FF8106 != null)
                            {
                                Logger.Log(outResponse.DiscretionaryData_FF8106.ToPrintString(ref depth));
                            }

                            processingOutcomeOUT.NextProcessState = EMVTerminalPreProcessingStateEnum.EndProcess;

                            return(processingOutcomeOUT);

                        default:
                            throw new Exception("Unknown outResponse.OutcomeParameterSet_DF8129.Value.Start:" + outResponse.OutcomeParameterSet_DF8129.Value.Start.ToString());
                        }

                    case KernelReaderTerminalServiceResponseEnum.UI:
                        KernelUIResponse uiResponse = (KernelUIResponse)k2Response;

                        if (uiResponse.UserInterfaceRequest_DF8116 != null)
                        {
                            string s1 = uiResponse.UserInterfaceRequest_DF8116.Value.KernelMessageidentifierEnum.ToString();
                            string s2 = uiResponse.UserInterfaceRequest_DF8116.Value.KernelStatusEnum.ToString();
                            OnUserInterfaceRequest(CreateUIMessageEventArgs(
                                                       uiResponse.UserInterfaceRequest_DF8116.Value.KernelMessageidentifierEnum,
                                                       uiResponse.UserInterfaceRequest_DF8116.Value.KernelStatusEnum,
                                                       Formatting.ConvertToInt32(uiResponse.UserInterfaceRequest_DF8116.Value.HoldTime)));
                        }

                        int depthUI = 0;
                        if (uiResponse.UserInterfaceRequest_DF8116 != null)
                        {
                            Logger.Log(uiResponse.UserInterfaceRequest_DF8116.ToPrintString(ref depthUI));
                        }
                        break;


                    case KernelReaderTerminalServiceResponseEnum.PIN:
                        // display pin screen
                        OnPinRequest(new EventArgs());
                        break;

                    case KernelReaderTerminalServiceResponseEnum.TRM:
                        OnTRMRequest(new EventArgs());
                        break;

                    case KernelReaderTerminalServiceResponseEnum.ONLINE:
                        KernelOnlineResponse onlineResponse = (KernelOnlineResponse)k2Response;
                        OnOnlineRequest(new OnlineEventArgs(onlineResponse.data, onlineResponse.discretionaryData));
                        break;

                    default:
                        throw new Exception("Unknown Kernel1ReaderTerminalServiceResponseEnum:" + k2Response.KernelReaderTerminalServiceResponseEnum);
                    }

                    kernel.KernelQ.DequeueFromOutput(false); //only remove message when finished processing
                }
                catch (Exception ex)
                {
                    OnExceptionOccured(ex);
                    return(null);
                }
            }
        }