diff --git a/src/emv_fields.h b/src/emv_fields.h index 517f556..bfb7629 100644 --- a/src/emv_fields.h +++ b/src/emv_fields.h @@ -205,6 +205,13 @@ __BEGIN_DECLS #define EMV_AUC_INTERNATIONAL_CASHBACK (0x40) ///< Application Usage Control: International cashback allowed #define EMV_AUC_RFU (0x3F) ///< Application Usage Control: RFU +// Account Type (field 5F57) +// See EMV 4.4 Book 3, Annex G, Table 56 +#define EMV_ACCOUNT_TYPE_DEFAULT (0x00) ///< Account Type: Default +#define EMV_ACCOUNT_TYPE_SAVINGS (0x10) ///< Account Type: Savings +#define EMV_ACCOUNT_TYPE_CHEQUE_OR_DEBIT (0x20) ///< Account Type: Cheque/Debit +#define EMV_ACCOUNT_TYPE_CREDIT (0x30) ///< Account Type: Credit + // Cardholder Verification (CV) Rule byte 1, CVM Codes // See EMV 4.4 Book 3, Annex C3, Table 43 #define EMV_CV_RULE_APPLY_NEXT_IF_UNSUCCESSFUL (0x40) ///< Apply succeeding CV Rule if this CVM is unsuccessful diff --git a/src/emv_strings.c b/src/emv_strings.c index 29285de..1201200 100644 --- a/src/emv_strings.c +++ b/src/emv_strings.c @@ -487,6 +487,20 @@ int emv_tlv_get_info( } return 0; + case EMV_TAG_5F57_ACCOUNT_TYPE: + info->tag_name = "Account Type"; + info->tag_desc = + "Indicates the type of account selected on the " + "terminal, coded as specified in Annex G"; + info->format = EMV_FORMAT_N; + if (!tlv->value) { + // Cannot use tlv->value[0], even if value_str is NULL. + // This is typically for Data Object List (DOL) entries that + // have been packed into TLV entries for this function to use. + return 0; + } + return emv_account_type_get_string(tlv->value[0], value_str, value_str_len); + case EMV_TAG_9F01_ACQUIRER_IDENTIFIER: info->tag_name = "Acquirer Identifier"; info->tag_desc = @@ -3004,6 +3018,45 @@ int emv_language_preference_get_string_list( return 0; } +int emv_account_type_get_string( + uint8_t account_type, + char* str, + size_t str_len +) +{ + if (!str || !str_len) { + // Caller didn't want the value string + return 0; + } + + // Account Type (field 5F57) + // See EMV 4.4 Book 3, Annex G, Table 56 + switch (account_type) { + case EMV_ACCOUNT_TYPE_DEFAULT: + strncpy(str, "Default", str_len); + str[str_len - 1] = 0; + return 0; + + case EMV_ACCOUNT_TYPE_SAVINGS: + strncpy(str, "Savings", str_len); + str[str_len - 1] = 0; + return 0; + + case EMV_ACCOUNT_TYPE_CHEQUE_OR_DEBIT: + strncpy(str, "Cheque/Debit", str_len); + str[str_len - 1] = 0; + return 0; + + case EMV_ACCOUNT_TYPE_CREDIT: + strncpy(str, "Credit", str_len); + str[str_len - 1] = 0; + return 0; + + default: + return 1; + } +} + static const char* emv_cvm_code_get_string(uint8_t cvm_code) { const char* cvm_str; diff --git a/src/emv_strings.h b/src/emv_strings.h index 45b4595..57fa9bb 100644 --- a/src/emv_strings.h +++ b/src/emv_strings.h @@ -492,6 +492,19 @@ int emv_language_preference_get_string_list( size_t str_len ); +/** + * Stringify Account Type (field 5F57) + * @param account_type Account Type field + * @param str String buffer output + * @param str_len Length of string buffer in bytes + * @return Zero for success. Less than zero for internal error. Greater than zero for parse error. + */ +int emv_account_type_get_string( + uint8_t account_type, + char* str, + size_t str_len +); + /** * Stringify Cardholder Verification Method (CVM) List (field 8E) * @note Strings in output buffer are delimited using "\n", including the last string diff --git a/src/emv_tags.h b/src/emv_tags.h index af9def7..f8fa29b 100644 --- a/src/emv_tags.h +++ b/src/emv_tags.h @@ -178,6 +178,9 @@ __BEGIN_DECLS /// EMV tag 5F56 Issuer Country Code (alpha3 format). Template BF0C or 73. #define EMV_TAG_5F56_ISSUER_COUNTRY_CODE_ALPHA3 (0x5F56) +/// EMV tag 5F57 Account Type +#define EMV_TAG_5F57_ACCOUNT_TYPE (0x5F57) + /// EMV tag 9F01 Acquirer Identifier #define EMV_TAG_9F01_ACQUIRER_IDENTIFIER (0x9F01)