Example #1
0
 internal static SignalsEnum PostOutcome(KernelDatabaseBase database, KernelQ qManager,
                                         KernelMessageidentifierEnum uiMessage,
                                         KernelStatusEnum uiStatus,
                                         byte[] holdTime,
                                         Kernel2OutcomeStatusEnum status,
                                         Kernel2StartEnum start,
                                         bool?isUIRequestOnOutcomePresent,
                                         KernelMessageidentifierEnum messageOnError,
                                         L1Enum l1Enum,
                                         byte[] SW12,
                                         L2Enum l2Enum,
                                         L3Enum l3Enum)
 {
     return(PostOutcome(database, qManager,
                        uiMessage,
                        uiStatus,
                        holdTime,
                        status,
                        start,
                        isUIRequestOnOutcomePresent,
                        messageOnError,
                        l1Enum,
                        SW12,
                        l2Enum,
                        l3Enum,
                        ValueQualifierEnum.NONE,
                        null,
                        null,
                        false,
                        KernelCVMEnum.N_A));
 }
Example #2
0
        public static SignalsEnum PostOutcomeWithError(KernelDatabaseBase database, KernelQ qManager,
                                                       Kernel2OutcomeStatusEnum status,
                                                       Kernel2StartEnum start,
                                                       L1Enum l1Enum,
                                                       L2Enum l2Enum,
                                                       L3Enum l3Enum)
        {
            if (l1Enum == L1Enum.NOT_SET && l2Enum == L2Enum.NOT_SET && l3Enum == L3Enum.NOT_SET)
            {
                throw new EMVProtocolException("Cannot post with all enum error not set");
            }

            return(PostOutcome(database, qManager,
                               KernelMessageidentifierEnum.N_A,
                               KernelStatusEnum.N_A,
                               null,
                               status,
                               start,
                               null,
                               KernelMessageidentifierEnum.N_A,
                               l1Enum,
                               null,
                               l2Enum,
                               l3Enum,
                               ValueQualifierEnum.NONE,
                               null,
                               null,
                               false,
                               KernelCVMEnum.N_A));
        }
Example #3
0
 //may be a response to a clean request in which case it will contain the torn record, if any, removed
 public static SignalsEnum PostOutcomeOnly(KernelDatabaseBase database, KernelQ qManager,
                                           Kernel2OutcomeStatusEnum k2OutcomeStatus,
                                           Kernel2StartEnum start)
 {
     return(PostOutcome(database, qManager,
                        KernelMessageidentifierEnum.N_A,
                        KernelStatusEnum.N_A,
                        null,
                        k2OutcomeStatus,
                        start,
                        null,
                        KernelMessageidentifierEnum.N_A,
                        L1Enum.NOT_SET,
                        null,
                        L2Enum.NOT_SET,
                        L3Enum.NOT_SET,
                        ValueQualifierEnum.NONE,
                        null,
                        null,
                        false,
                        KernelCVMEnum.N_A));
 }
        private static SignalsEnum DoPart_E(Kernel2Database database, KernelQ qManager, CardQ cardQManager)
        {
            #region 9_10.70
            CommonRoutines.CreateEMVDataRecord(database);

            Kernel2OutcomeStatusEnum    k2OutcomeStatus     = Kernel2OutcomeStatusEnum.N_A;
            Kernel2StartEnum            k2StartStatus       = Kernel2StartEnum.N_A;
            KernelStatusEnum            k2Status            = KernelStatusEnum.N_A;
            KernelMessageidentifierEnum k2MessageIdentifier = KernelMessageidentifierEnum.N_A;
            byte[]             holdTime           = new byte[] { 0x00, 0x00, 0x00 };
            ValueQualifierEnum valueQualifierEnum = ValueQualifierEnum.NONE;
            KernelCVMEnum      cvmEnum            = new OUTCOME_PARAMETER_SET_DF8129_KRN2(database).Value.CVM;
            byte[]             currencyCode       = new byte[2];
            byte[]             valueQualifier     = new byte[6];
            bool uiRequestOnOutcomePresent;

            #endregion

            #region 9_10.71
            if (database.IsNotEmpty(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2.Tag) &&
                ((int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value) & 0x0000030F) != 0x00000000)
            #endregion
            {
                #region 9_10.72
                k2OutcomeStatus = Kernel2OutcomeStatusEnum.END_APPLICATION;
                k2StartStatus   = Kernel2StartEnum.B;
                #endregion

                #region 9_10.73
                PHONE_MESSAGE_TABLE_DF8131_KRN2 pmt = new 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
            }
            else
            {
                string tt = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value);
                #region 9_10.74
                if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40)
                #endregion
                {
                    k2OutcomeStatus = Kernel2OutcomeStatusEnum.APPROVED;
                }
                else
                {
                    if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x80)
                    {
                        k2OutcomeStatus = Kernel2OutcomeStatusEnum.ONLINE_REQUEST;
                    }
                    else
                    {
                        /*
                         * Check if Transaction Type indicates a cash transaction (cash
                         * withdrawal or cash disbursement) or a purchase transaction (purchase
                         * or purchase with cashback).
                         */
                        if (tt == "01" || tt == "17" || tt == "00" || tt == "09")
                        {
                            if (database.IsNotEmpty(EMVTagsEnum.THIRD_PARTY_DATA_9F6E_KRN2.Tag))
                            {
                                THIRD_PARTY_DATA_9F6E_KRN      tpd = new THIRD_PARTY_DATA_9F6E_KRN(database);
                                TERMINAL_CAPABILITIES_9F33_KRN tc  = new TERMINAL_CAPABILITIES_9F33_KRN(database);
                                ushort uid = Formatting.ConvertToInt16(tpd.Value.UniqueIdentifier);
                                ushort dt  = Formatting.ConvertToInt16(tpd.Value.DeviceType);
                                if ((uid & 0x8000) == 0x0000 && dt != 0x3030 || tc.Value.ICWithContactsCapable)
                                {
                                    k2OutcomeStatus = Kernel2OutcomeStatusEnum.DECLINED;
                                }
                                else
                                {
                                    k2OutcomeStatus = Kernel2OutcomeStatusEnum.TRY_ANOTHER_INTERFACE;
                                }
                            }
                            else
                            {
                                k2OutcomeStatus = Kernel2OutcomeStatusEnum.TRY_ANOTHER_INTERFACE;
                            }
                        }
                        else
                        {
                            k2OutcomeStatus = Kernel2OutcomeStatusEnum.END_APPLICATION;
                        }
                    }
                }

                #region 9_10.75
                k2Status = KernelStatusEnum.NOT_READY;

                if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40)
                {
                    holdTime = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value;

                    if (database.IsNotEmpty(EMVTagsEnum.BALANCE_READ_AFTER_GEN_AC_DF8105_KRN2.Tag))
                    {
                        valueQualifierEnum = ValueQualifierEnum.BALANCE;
                        valueQualifier     = database.Get(EMVTagsEnum.BALANCE_READ_AFTER_GEN_AC_DF8105_KRN2).Value;
                        if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CURRENCY_CODE_9F42_KRN.Tag))
                        {
                            currencyCode = database.Get(EMVTagsEnum.APPLICATION_CURRENCY_CODE_9F42_KRN).Value;
                        }
                    }

                    if (cvmEnum == KernelCVMEnum.OBTAIN_SIGNATURE)
                    {
                        k2MessageIdentifier = KernelMessageidentifierEnum.APPROVED_SIGN;
                    }
                    else
                    {
                        k2MessageIdentifier = KernelMessageidentifierEnum.APPROVED;
                    }
                }
                else
                {
                    if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x80)
                    {
                        holdTime            = new byte[] { 0x00, 0x00, 0x00 };
                        k2MessageIdentifier = KernelMessageidentifierEnum.AUTHORISING_PLEASE_WAIT;
                    }
                    else
                    {
                        if (tt == "01" || tt == "17" || tt == "00" || tt == "09")
                        {
                            holdTime = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value;


                            if (database.IsNotEmpty(EMVTagsEnum.THIRD_PARTY_DATA_9F6E_KRN2.Tag))
                            {
                                THIRD_PARTY_DATA_9F6E_KRN      tpd = new THIRD_PARTY_DATA_9F6E_KRN(database);
                                TERMINAL_CAPABILITIES_9F33_KRN tc  = new TERMINAL_CAPABILITIES_9F33_KRN(database);
                                ushort uid = Formatting.ConvertToInt16(tpd.Value.UniqueIdentifier);
                                ushort dt  = Formatting.ConvertToInt16(tpd.Value.DeviceType);
                                if ((uid & 0x8000) == 0x0000 && dt != 0x3030 || tc.Value.ICWithContactsCapable)
                                {
                                    k2MessageIdentifier = KernelMessageidentifierEnum.DECLINED;
                                }
                                else
                                {
                                    k2MessageIdentifier = KernelMessageidentifierEnum.INSERT_CARD;
                                }
                            }
                            else
                            {
                                k2MessageIdentifier = KernelMessageidentifierEnum.INSERT_CARD;
                            }
                        }
                        else
                        {
                            holdTime            = new byte[] { 0x00, 0x00, 0x00 };
                            k2MessageIdentifier = KernelMessageidentifierEnum.CLEAR_DISPLAY;
                        }
                    }
                }

                #endregion
            }

            #region 9_10.76
            if (database.IsNotEmpty(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2.Tag))
            #endregion
            {
                #region 9_10.77
                TLV tagToPut = database.TagsToWriteAfterGenACYet.GetFirstAndRemoveFromList();
                EMVPutDataRequest request = new EMVPutDataRequest(tagToPut);
                #endregion
                #region 9_10.78
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_PUT_DATA_RESPONSE_AFTER_GEN_AC);

                #endregion
            }

            CommonRoutines.CreateEMVDiscretionaryData(database);

            #region 9_10.78.1
            if (database.IsNotEmpty(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2.Tag) &&
                ((int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value) & 0x0000030F) != 0x00000000)
            #endregion
            {
                #region 9_10.79
                CommonRoutines.PostUIOnly(database, qManager, k2MessageIdentifier, k2Status, true, holdTime);
                #endregion

                #region 9_10.80
                uiRequestOnOutcomePresent = false;
                k2Status = KernelStatusEnum.READY_TO_READ;
                holdTime = new byte[] { 0x00, 0x00, 0x00 };
                #endregion
            }
            else
            {
                #region 9_10.81
                uiRequestOnOutcomePresent = true;
                #endregion
            }
            return(CommonRoutines.PostOutcome(database, qManager,
                                              k2MessageIdentifier,
                                              k2Status,
                                              holdTime,
                                              k2OutcomeStatus,
                                              k2StartStatus,
                                              uiRequestOnOutcomePresent,
                                              KernelMessageidentifierEnum.N_A,
                                              L1Enum.NOT_SET,
                                              null,
                                              L2Enum.NOT_SET,
                                              L3Enum.NOT_SET,
                                              valueQualifierEnum,
                                              valueQualifier,
                                              currencyCode,
                                              false,
                                              cvmEnum));
        }
Example #5
0
        public static SignalsEnum EndOnTCorAAC(KernelDatabase database, KernelQ qManager, CardQ cardQManager)
        {
            CommonRoutines.CreateEMVDataRecord(database);

            Kernel2OutcomeStatusEnum    k2OutcomeStatus     = Kernel2OutcomeStatusEnum.N_A;
            Kernel2StartEnum            k2StartStatus       = Kernel2StartEnum.N_A;
            KernelStatusEnum            k2Status            = KernelStatusEnum.N_A;
            KernelMessageidentifierEnum k2MessageIdentifier = KernelMessageidentifierEnum.N_A;

            byte[]             holdTime           = new byte[] { 0x00, 0x00, 0x00 };
            ValueQualifierEnum valueQualifierEnum = ValueQualifierEnum.NONE;
            KernelCVMEnum      cvmEnum            = new OUTCOME_PARAMETER_SET_DF8129_KRN2(database).Value.CVM;

            byte[] currencyCode   = new byte[2];
            byte[] valueQualifier = new byte[6];
            bool   uiRequestOnOutcomePresent;

            string tt = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value);

            if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40)
            {
                k2OutcomeStatus = Kernel2OutcomeStatusEnum.APPROVED;
            }
            else
            {
                if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x80)
                {
                    throw new EMVProtocolException("Invalid state in EndOnTCorAAC");
                }
                else
                {
                    k2OutcomeStatus = Kernel2OutcomeStatusEnum.DECLINED;
                }
            }

            k2Status = KernelStatusEnum.NOT_READY;

            if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40)
            {
                holdTime = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value;

                if (cvmEnum == KernelCVMEnum.OBTAIN_SIGNATURE)
                {
                    k2MessageIdentifier = KernelMessageidentifierEnum.APPROVED_SIGN;
                }
                else
                {
                    k2MessageIdentifier = KernelMessageidentifierEnum.APPROVED;
                }
            }
            else
            {
                if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x80)
                {
                    throw new EMVProtocolException("Invalid state in EndOnTCorAAC");
                }
                else
                {
                    k2MessageIdentifier = KernelMessageidentifierEnum.DECLINED;
                }
            }

            CommonRoutines.CreateEMVDiscretionaryData(database);

            uiRequestOnOutcomePresent = true;

            return(CommonRoutines.PostOutcome(database, qManager,
                                              k2MessageIdentifier,
                                              k2Status,
                                              holdTime,
                                              k2OutcomeStatus,
                                              k2StartStatus,
                                              uiRequestOnOutcomePresent,
                                              KernelMessageidentifierEnum.N_A,
                                              L1Enum.NOT_SET,
                                              null,
                                              L2Enum.NOT_SET,
                                              L3Enum.NOT_SET,
                                              valueQualifierEnum,
                                              valueQualifier,
                                              currencyCode,
                                              false,
                                              cvmEnum));
        }
Example #6
0
        internal static SignalsEnum PostOutcome(KernelDatabaseBase database, KernelQ qManager,
                                                KernelMessageidentifierEnum uiMessage,
                                                KernelStatusEnum uiStatus,
                                                byte[] holdTime,
                                                Kernel2OutcomeStatusEnum status,
                                                Kernel2StartEnum start,
                                                bool?isUIRequestOnOutcomePresent,
                                                KernelMessageidentifierEnum messageOnError,
                                                L1Enum l1Enum,
                                                byte[] SW12,
                                                L2Enum l2Enum,
                                                L3Enum l3Enum,
                                                ValueQualifierEnum valueQualifierEnum,
                                                byte[] valueQualifier,
                                                byte[] currencyCode,
                                                bool receipt,
                                                KernelCVMEnum cvmStatus)
        {
            if (messageOnError != KernelMessageidentifierEnum.N_A || l1Enum != L1Enum.NOT_SET || l2Enum != L2Enum.NOT_SET || l3Enum != L3Enum.NOT_SET)
            {
                TLV disc = InitializeDiscretionaryData(database);

                ERROR_INDICATION_DF8115_KRN2 kei = new ERROR_INDICATION_DF8115_KRN2(database);
                kei.Value.MsgOnError = messageOnError;
                kei.Value.L1Enum     = l1Enum;
                kei.Value.L2Enum     = l2Enum;
                kei.Value.L3Enum     = l3Enum;
                if (SW12 != null)
                {
                    kei.Value.SW12 = SW12;
                }
                kei.UpdateDB();

                disc.Children.AddToList(kei);
                disc.Serialize();
            }

            if (uiMessage != KernelMessageidentifierEnum.N_A || uiStatus != KernelStatusEnum.N_A)
            {
                USER_INTERFACE_REQUEST_DATA_DF8116_KRN2 uird = new USER_INTERFACE_REQUEST_DATA_DF8116_KRN2(database);
                uird.Value.KernelMessageidentifierEnum = uiMessage;
                uird.Value.KernelStatusEnum            = uiStatus;
                if (holdTime == null)
                {
                    TLV holdTimeTLV = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2);
                    if (holdTimeTLV != null)
                    {
                        holdTime = holdTimeTLV.Value;
                    }
                    else
                    {
                        holdTime = new byte[] { 0x00, 0x00, 0x00 }
                    };
                }
                uird.Value.HoldTime = holdTime;
                if (valueQualifier != null)
                {
                    uird.Value.ValueQualifier = valueQualifier;
                }
                uird.Value.ValueQualifierEnum = valueQualifierEnum;
                if (currencyCode != null)
                {
                    uird.Value.CurrencyCode = currencyCode;
                }
                uird.UpdateDB();
            }

            OUTCOME_PARAMETER_SET_DF8129_KRN2 kops = new OUTCOME_PARAMETER_SET_DF8129_KRN2(database);

            kops.Value.Status = status;
            kops.Value.Start  = start;
            if (isUIRequestOnOutcomePresent == null)
            {
                kops.Value.UIRequestOnOutcomePresent = isUIRequestOnOutcomePresent == false;
                kops.Value.UIRequestOnRestartPresent = isUIRequestOnOutcomePresent == false;
            }
            else
            {
                kops.Value.UIRequestOnOutcomePresent = isUIRequestOnOutcomePresent == true ? true : false;
                kops.Value.UIRequestOnRestartPresent = isUIRequestOnOutcomePresent == true ? false : true;
            }
            kops.Value.DataRecordPresent        = database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2) != null ? true : false;
            kops.Value.DiscretionaryDataPresent = database.Get(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2) != null ? true : false;
            //kops.Value.Receipt = receipt;
            kops.Value.CVM = cvmStatus;
            kops.UpdateDB();

            qManager.EnqueueToOutput(new KernelOUTResponse(
                                         database.Get(EMVTagsEnum.OUTCOME_PARAMETER_SET_DF8129_KRN2),
                                         database.Get(EMVTagsEnum.ERROR_INDICATION_DF8115_KRN2),
                                         database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2),
                                         database.Get(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2),
                                         database.Get(EMVTagsEnum.USER_INTERFACE_REQUEST_DATA_DF8116_KRN2)));

            return(SignalsEnum.STOP);
        }