[FL-1643] NFC emv assets (#661)
* assets: add EMV AID table for NFC app * file-worker: add searching for value by the key * nfc: add emv parser helpers * assets: add country and currency codes * nfc: add country and currency code parsing * emv_decoder: add country and currency code support * nfc: add AID. currency and country display * nfc: rework bank_card view * nfc: add currency and country save * assets: change emv chip asset * nfc: change asset in bank card * gui: add frame element to widget * nfc: add bank card frame, add documentation * rfal: fix long APDU command emulation * nfc: fix typos * Scripts ReadMe: assets delivery command Co-authored-by: あく <alleteam@gmail.com> Co-authored-by: DrZlo13 <who.just.the.doctor@gmail.com>
This commit is contained in:
		
							parent
							
								
									b1bbf1730c
								
							
						
					
					
						commit
						ecff31d228
					
				| @ -150,3 +150,15 @@ void widget_add_icon_element(Widget* widget, uint8_t x, uint8_t y, const Icon* i | |||||||
|     WidgetElement* icon_element = widget_element_icon_create(x, y, icon); |     WidgetElement* icon_element = widget_element_icon_create(x, y, icon); | ||||||
|     widget_add_element(widget, icon_element); |     widget_add_element(widget, icon_element); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void widget_add_frame_element( | ||||||
|  |     Widget* widget, | ||||||
|  |     uint8_t x, | ||||||
|  |     uint8_t y, | ||||||
|  |     uint8_t width, | ||||||
|  |     uint8_t height, | ||||||
|  |     uint8_t radius) { | ||||||
|  |     furi_assert(widget); | ||||||
|  |     WidgetElement* frame_element = widget_element_frame_create(x, y, width, height, radius); | ||||||
|  |     widget_add_element(widget, frame_element); | ||||||
|  | } | ||||||
|  | |||||||
| @ -59,8 +59,24 @@ void widget_add_button_element( | |||||||
| 
 | 
 | ||||||
| /** Add Icon Element
 | /** Add Icon Element
 | ||||||
|  * @param widget Widget instance |  * @param widget Widget instance | ||||||
|  * @param x - x coordinate |  * @param x top left x coordinate | ||||||
|  * @param y - y coordinate |  * @param y top left y coordinate | ||||||
|  * @param icon Icon instance |  * @param icon Icon instance | ||||||
|  */ |  */ | ||||||
| void widget_add_icon_element(Widget* widget, uint8_t x, uint8_t y, const Icon* icon); | void widget_add_icon_element(Widget* widget, uint8_t x, uint8_t y, const Icon* icon); | ||||||
|  | 
 | ||||||
|  | /** Add Frame Element
 | ||||||
|  |  * @param widget Widget instance | ||||||
|  |  * @param x top left x coordinate | ||||||
|  |  * @param y top left y coordinate | ||||||
|  |  * @param width frame width | ||||||
|  |  * @param height frame height | ||||||
|  |  * @param radius frame radius | ||||||
|  |  */ | ||||||
|  | void widget_add_frame_element( | ||||||
|  |     Widget* widget, | ||||||
|  |     uint8_t x, | ||||||
|  |     uint8_t y, | ||||||
|  |     uint8_t width, | ||||||
|  |     uint8_t height, | ||||||
|  |     uint8_t radius); | ||||||
|  | |||||||
							
								
								
									
										48
									
								
								applications/gui/modules/widget_elements/widget_element_frame.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										48
									
								
								applications/gui/modules/widget_elements/widget_element_frame.c
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | #include "widget_element_i.h" | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     uint8_t x; | ||||||
|  |     uint8_t y; | ||||||
|  |     uint8_t width; | ||||||
|  |     uint8_t height; | ||||||
|  |     uint8_t radius; | ||||||
|  | } GuiFrameModel; | ||||||
|  | 
 | ||||||
|  | static void gui_frame_draw(Canvas* canvas, WidgetElement* element) { | ||||||
|  |     furi_assert(canvas); | ||||||
|  |     furi_assert(element); | ||||||
|  |     GuiFrameModel* model = element->model; | ||||||
|  |     canvas_draw_rframe(canvas, model->x, model->y, model->width, model->height, model->radius); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void gui_frame_free(WidgetElement* gui_frame) { | ||||||
|  |     furi_assert(gui_frame); | ||||||
|  | 
 | ||||||
|  |     free(gui_frame->model); | ||||||
|  |     free(gui_frame); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | WidgetElement* widget_element_frame_create( | ||||||
|  |     uint8_t x, | ||||||
|  |     uint8_t y, | ||||||
|  |     uint8_t width, | ||||||
|  |     uint8_t height, | ||||||
|  |     uint8_t radius) { | ||||||
|  |     // Allocate and init model
 | ||||||
|  |     GuiFrameModel* model = furi_alloc(sizeof(GuiFrameModel)); | ||||||
|  |     model->x = x; | ||||||
|  |     model->y = y; | ||||||
|  |     model->width = width; | ||||||
|  |     model->height = height; | ||||||
|  |     model->radius = radius; | ||||||
|  | 
 | ||||||
|  |     // Allocate and init Element
 | ||||||
|  |     WidgetElement* gui_frame = furi_alloc(sizeof(WidgetElement)); | ||||||
|  |     gui_frame->parent = NULL; | ||||||
|  |     gui_frame->input = NULL; | ||||||
|  |     gui_frame->draw = gui_frame_draw; | ||||||
|  |     gui_frame->free = gui_frame_free; | ||||||
|  |     gui_frame->model = model; | ||||||
|  | 
 | ||||||
|  |     return gui_frame; | ||||||
|  | } | ||||||
| @ -44,5 +44,13 @@ WidgetElement* widget_element_button_create( | |||||||
|     ButtonCallback callback, |     ButtonCallback callback, | ||||||
|     void* context); |     void* context); | ||||||
| 
 | 
 | ||||||
| /* Create icon element element */ | /* Create icon element */ | ||||||
| WidgetElement* widget_element_icon_create(uint8_t x, uint8_t y, const Icon* icon); | WidgetElement* widget_element_icon_create(uint8_t x, uint8_t y, const Icon* icon); | ||||||
|  | 
 | ||||||
|  | /* Create frame element */ | ||||||
|  | WidgetElement* widget_element_frame_create( | ||||||
|  |     uint8_t x, | ||||||
|  |     uint8_t y, | ||||||
|  |     uint8_t width, | ||||||
|  |     uint8_t height, | ||||||
|  |     uint8_t radius); | ||||||
| @ -1,5 +1,4 @@ | |||||||
| #include "widget_element_i.h" | #include "widget_element_i.h" | ||||||
| #include <m-string.h> |  | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     uint8_t x; |     uint8_t x; | ||||||
|  | |||||||
							
								
								
									
										49
									
								
								applications/nfc/helpers/nfc_emv_parser.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										49
									
								
								applications/nfc/helpers/nfc_emv_parser.c
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,49 @@ | |||||||
|  | #include "nfc_emv_parser.h" | ||||||
|  | 
 | ||||||
|  | #include <file-worker.h> | ||||||
|  | 
 | ||||||
|  | static bool | ||||||
|  |     nfc_emv_parser_get_value(const char* file_path, string_t key, char delimiter, string_t value) { | ||||||
|  |     bool found = false; | ||||||
|  |     FileWorker* file_worker = file_worker_alloc(true); | ||||||
|  | 
 | ||||||
|  |     if(file_worker_open(file_worker, file_path, FSAM_READ, FSOM_OPEN_EXISTING)) { | ||||||
|  |         if(file_worker_get_value_from_key(file_worker, key, delimiter, value)) { | ||||||
|  |             found = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     file_worker_close(file_worker); | ||||||
|  |     file_worker_free(file_worker); | ||||||
|  |     return found; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool nfc_emv_parser_get_aid_name(uint8_t* aid, uint8_t aid_len, string_t aid_name) { | ||||||
|  |     bool result = false; | ||||||
|  |     string_t key; | ||||||
|  |     string_init(key); | ||||||
|  |     for(uint8_t i = 0; i < aid_len; i++) { | ||||||
|  |         string_cat_printf(key, "%02X", aid[i]); | ||||||
|  |     } | ||||||
|  |     result = nfc_emv_parser_get_value("/ext/nfc/emv/aid.nfc", key, ' ', aid_name); | ||||||
|  |     string_clear(key); | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool nfc_emv_parser_get_country_name(uint16_t country_code, string_t country_name) { | ||||||
|  |     bool result = false; | ||||||
|  |     string_t key; | ||||||
|  |     string_init_printf(key, "%04X", country_code); | ||||||
|  |     result = nfc_emv_parser_get_value("/ext/nfc/emv/country_code.nfc", key, ' ', country_name); | ||||||
|  |     string_clear(key); | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool nfc_emv_parser_get_currency_name(uint16_t currency_code, string_t currency_name) { | ||||||
|  |     bool result = false; | ||||||
|  |     string_t key; | ||||||
|  |     string_init_printf(key, "%04X", currency_code); | ||||||
|  |     result = nfc_emv_parser_get_value("/ext/nfc/emv/currency_code.nfc", key, ' ', currency_name); | ||||||
|  |     string_clear(key); | ||||||
|  |     return result; | ||||||
|  | } | ||||||
							
								
								
									
										27
									
								
								applications/nfc/helpers/nfc_emv_parser.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										27
									
								
								applications/nfc/helpers/nfc_emv_parser.h
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <m-string.h> | ||||||
|  | 
 | ||||||
|  | /** Get EMV application name by number
 | ||||||
|  |  * @param aid - AID number array | ||||||
|  |  * @param aid_len - AID length | ||||||
|  |  * @param aid_name - string to keep AID name | ||||||
|  |  * @return - true if AID found, false otherwies | ||||||
|  |  */ | ||||||
|  | bool nfc_emv_parser_get_aid_name(uint8_t* aid, uint8_t aid_len, string_t aid_name); | ||||||
|  | 
 | ||||||
|  | /** Get country name by country code
 | ||||||
|  |  * @param country_code - ISO 3166 country code | ||||||
|  |  * @param country_name - string to keep country name | ||||||
|  |  * @return - true if country found, false otherwies | ||||||
|  |  */ | ||||||
|  | bool nfc_emv_parser_get_country_name(uint16_t country_code, string_t country_name); | ||||||
|  | 
 | ||||||
|  | /** Get currency name by currency code
 | ||||||
|  |  * @param currency_code - ISO 3166 currency code | ||||||
|  |  * @param currency_name - string to keep currency name | ||||||
|  |  * @return - true if currency found, false otherwies | ||||||
|  |  */ | ||||||
|  | bool nfc_emv_parser_get_currency_name(uint16_t currency_code, string_t currency_name); | ||||||
| @ -10,7 +10,7 @@ static const char* nfc_app_folder = "/any/nfc"; | |||||||
| static const char* nfc_app_extension = ".nfc"; | static const char* nfc_app_extension = ".nfc"; | ||||||
| static const char* nfc_app_shadow_extension = ".shd"; | static const char* nfc_app_shadow_extension = ".shd"; | ||||||
| 
 | 
 | ||||||
| static bool nfc_device_read_hex(string_t str, uint8_t* buff, uint16_t len) { | static bool nfc_device_read_hex(string_t str, uint8_t* buff, uint16_t len, uint8_t delim_len) { | ||||||
|     string_strim(str); |     string_strim(str); | ||||||
|     uint8_t nibble_high = 0; |     uint8_t nibble_high = 0; | ||||||
|     uint8_t nibble_low = 0; |     uint8_t nibble_low = 0; | ||||||
| @ -20,7 +20,7 @@ static bool nfc_device_read_hex(string_t str, uint8_t* buff, uint16_t len) { | |||||||
|         if(hex_char_to_hex_nibble(string_get_char(str, 0), &nibble_high) && |         if(hex_char_to_hex_nibble(string_get_char(str, 0), &nibble_high) && | ||||||
|            hex_char_to_hex_nibble(string_get_char(str, 1), &nibble_low)) { |            hex_char_to_hex_nibble(string_get_char(str, 1), &nibble_low)) { | ||||||
|             buff[i] = (nibble_high << 4) | nibble_low; |             buff[i] = (nibble_high << 4) | nibble_low; | ||||||
|             string_right(str, 3); |             string_right(str, delim_len + 2); | ||||||
|         } else { |         } else { | ||||||
|             parsed = false; |             parsed = false; | ||||||
|             break; |             break; | ||||||
| @ -81,22 +81,22 @@ bool nfc_device_parse_uid_string(NfcDevice* dev, string_t uid_string) { | |||||||
|     do { |     do { | ||||||
|         // strlen("UID len: ") = 9
 |         // strlen("UID len: ") = 9
 | ||||||
|         string_right(uid_string, 9); |         string_right(uid_string, 9); | ||||||
|         if(!nfc_device_read_hex(uid_string, &uid_data->uid_len, 1)) { |         if(!nfc_device_read_hex(uid_string, &uid_data->uid_len, 1, 1)) { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         // strlen("UID: ") = 5
 |         // strlen("UID: ") = 5
 | ||||||
|         string_right(uid_string, 5); |         string_right(uid_string, 5); | ||||||
|         if(!nfc_device_read_hex(uid_string, uid_data->uid, uid_data->uid_len)) { |         if(!nfc_device_read_hex(uid_string, uid_data->uid, uid_data->uid_len, 1)) { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         // strlen("ATQA: ") = 6
 |         // strlen("ATQA: ") = 6
 | ||||||
|         string_right(uid_string, 6); |         string_right(uid_string, 6); | ||||||
|         if(!nfc_device_read_hex(uid_string, uid_data->atqa, 2)) { |         if(!nfc_device_read_hex(uid_string, uid_data->atqa, 2, 1)) { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         // strlen("SAK: ") = 5
 |         // strlen("SAK: ") = 5
 | ||||||
|         string_right(uid_string, 5); |         string_right(uid_string, 5); | ||||||
|         if(!nfc_device_read_hex(uid_string, &uid_data->sak, 1)) { |         if(!nfc_device_read_hex(uid_string, &uid_data->sak, 1, 1)) { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         parsed = true; |         parsed = true; | ||||||
| @ -149,13 +149,13 @@ bool nfc_device_parse_mifare_ul_string(NfcDevice* dev, string_t mifare_ul_string | |||||||
|     do { |     do { | ||||||
|         // strlen("Signature: ") = 11
 |         // strlen("Signature: ") = 11
 | ||||||
|         string_right(mifare_ul_string, 11); |         string_right(mifare_ul_string, 11); | ||||||
|         if(!nfc_device_read_hex(mifare_ul_string, data->signature, sizeof(data->signature))) { |         if(!nfc_device_read_hex(mifare_ul_string, data->signature, sizeof(data->signature), 1)) { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         // strlen("Version: ") = 9
 |         // strlen("Version: ") = 9
 | ||||||
|         string_right(mifare_ul_string, 9); |         string_right(mifare_ul_string, 9); | ||||||
|         if(!nfc_device_read_hex( |         if(!nfc_device_read_hex( | ||||||
|                mifare_ul_string, (uint8_t*)&data->version, sizeof(data->version))) { |                mifare_ul_string, (uint8_t*)&data->version, sizeof(data->version), 1)) { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         string_strim(mifare_ul_string); |         string_strim(mifare_ul_string); | ||||||
| @ -184,7 +184,7 @@ bool nfc_device_parse_mifare_ul_string(NfcDevice* dev, string_t mifare_ul_string | |||||||
|         string_right(mifare_ul_string, ws + 1); |         string_right(mifare_ul_string, ws + 1); | ||||||
|         // Read data
 |         // Read data
 | ||||||
|         for(uint16_t i = 0; i < data->data_size; i += 4) { |         for(uint16_t i = 0; i < data->data_size; i += 4) { | ||||||
|             if(!nfc_device_read_hex(mifare_ul_string, &data->data[i], 4)) { |             if(!nfc_device_read_hex(mifare_ul_string, &data->data[i], 4, 1)) { | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @ -208,6 +208,12 @@ uint16_t nfc_device_prepare_bank_card_string(NfcDevice* dev, string_t bank_card_ | |||||||
|         string_cat_printf( |         string_cat_printf( | ||||||
|             bank_card_string, "\nExp date: %02X/%02X", data->exp_mon, data->exp_year); |             bank_card_string, "\nExp date: %02X/%02X", data->exp_mon, data->exp_year); | ||||||
|     } |     } | ||||||
|  |     if(data->country_code) { | ||||||
|  |         string_cat_printf(bank_card_string, "\nCountry code: %04X", data->country_code); | ||||||
|  |     } | ||||||
|  |     if(data->currency_code) { | ||||||
|  |         string_cat_printf(bank_card_string, "\nCurrency code: %04X", data->currency_code); | ||||||
|  |     } | ||||||
|     return string_size(bank_card_string); |     return string_size(bank_card_string); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -215,6 +221,7 @@ bool nfc_device_parse_bank_card_string(NfcDevice* dev, string_t bank_card_string | |||||||
|     NfcEmvData* data = &dev->dev_data.emv_data; |     NfcEmvData* data = &dev->dev_data.emv_data; | ||||||
|     bool parsed = false; |     bool parsed = false; | ||||||
|     int res = 0; |     int res = 0; | ||||||
|  |     uint8_t code[2] = {}; | ||||||
|     memset(data, 0, sizeof(NfcEmvData)); |     memset(data, 0, sizeof(NfcEmvData)); | ||||||
| 
 | 
 | ||||||
|     do { |     do { | ||||||
| @ -226,7 +233,7 @@ bool nfc_device_parse_bank_card_string(NfcDevice* dev, string_t bank_card_string | |||||||
|         string_right(bank_card_string, 9); |         string_right(bank_card_string, 9); | ||||||
|         size_t ws = string_search_char(bank_card_string, ':'); |         size_t ws = string_search_char(bank_card_string, ':'); | ||||||
|         string_right(bank_card_string, ws + 1); |         string_right(bank_card_string, ws + 1); | ||||||
|         if(!nfc_device_read_hex(bank_card_string, data->aid, data->aid_len)) { |         if(!nfc_device_read_hex(bank_card_string, data->aid, data->aid_len, 1)) { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         res = sscanf(string_get_cstr(bank_card_string), "Name: %s\n", data->name); |         res = sscanf(string_get_cstr(bank_card_string), "Name: %s\n", data->name); | ||||||
| @ -237,7 +244,7 @@ bool nfc_device_parse_bank_card_string(NfcDevice* dev, string_t bank_card_string | |||||||
|         string_right(bank_card_string, ws + 1); |         string_right(bank_card_string, ws + 1); | ||||||
|         // strlen("Number: ") = 8
 |         // strlen("Number: ") = 8
 | ||||||
|         string_right(bank_card_string, 8); |         string_right(bank_card_string, 8); | ||||||
|         if(!nfc_device_read_hex(bank_card_string, data->number, sizeof(data->number))) { |         if(!nfc_device_read_hex(bank_card_string, data->number, sizeof(data->number), 1)) { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         parsed = true; |         parsed = true; | ||||||
| @ -246,8 +253,24 @@ bool nfc_device_parse_bank_card_string(NfcDevice* dev, string_t bank_card_string | |||||||
|         if(ws != STRING_FAILURE) { |         if(ws != STRING_FAILURE) { | ||||||
|             // strlen("Exp date: ") = 10
 |             // strlen("Exp date: ") = 10
 | ||||||
|             string_right(bank_card_string, 10); |             string_right(bank_card_string, 10); | ||||||
|             nfc_device_read_hex(bank_card_string, &data->exp_mon, 1); |             nfc_device_read_hex(bank_card_string, &data->exp_mon, 1, 1); | ||||||
|             nfc_device_read_hex(bank_card_string, &data->exp_year, 1); |             nfc_device_read_hex(bank_card_string, &data->exp_year, 1, 1); | ||||||
|  |         } | ||||||
|  |         // Check country code presence
 | ||||||
|  |         ws = string_search_str(bank_card_string, "Country code: "); | ||||||
|  |         if(ws != STRING_FAILURE) { | ||||||
|  |             // strlen("Country code: ") = 14
 | ||||||
|  |             string_right(bank_card_string, 14); | ||||||
|  |             nfc_device_read_hex(bank_card_string, code, 2, 0); | ||||||
|  |             data->country_code = code[0] << 8 | code[1]; | ||||||
|  |         } | ||||||
|  |         // Check currency code presence
 | ||||||
|  |         ws = string_search_str(bank_card_string, "Currency code: "); | ||||||
|  |         if(ws != STRING_FAILURE) { | ||||||
|  |             // strlen("Currency code: ") = 15
 | ||||||
|  |             string_right(bank_card_string, 15); | ||||||
|  |             nfc_device_read_hex(bank_card_string, code, 2, 0); | ||||||
|  |             data->currency_code = code[0] << 8 | code[1]; | ||||||
|         } |         } | ||||||
|     } while(0); |     } while(0); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -43,7 +43,8 @@ typedef struct { | |||||||
|     uint8_t number[8]; |     uint8_t number[8]; | ||||||
|     uint8_t exp_mon; |     uint8_t exp_mon; | ||||||
|     uint8_t exp_year; |     uint8_t exp_year; | ||||||
|     char cardholder[32]; |     uint16_t country_code; | ||||||
|  |     uint16_t currency_code; | ||||||
| } NfcEmvData; | } NfcEmvData; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|  | |||||||
| @ -328,6 +328,12 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { | |||||||
|                             result->emv_data.exp_mon = emv_app.exp_month; |                             result->emv_data.exp_mon = emv_app.exp_month; | ||||||
|                             result->emv_data.exp_year = emv_app.exp_year; |                             result->emv_data.exp_year = emv_app.exp_year; | ||||||
|                         } |                         } | ||||||
|  |                         if(emv_app.country_code) { | ||||||
|  |                             result->emv_data.country_code = emv_app.country_code; | ||||||
|  |                         } | ||||||
|  |                         if(emv_app.currency_code) { | ||||||
|  |                             result->emv_data.currency_code = emv_app.currency_code; | ||||||
|  |                         } | ||||||
|                         // Notify caller and exit
 |                         // Notify caller and exit
 | ||||||
|                         if(nfc_worker->callback) { |                         if(nfc_worker->callback) { | ||||||
|                             nfc_worker->callback(nfc_worker->context); |                             nfc_worker->callback(nfc_worker->context); | ||||||
|  | |||||||
							
								
								
									
										31
									
								
								applications/nfc/scenes/nfc_scene_device_info.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										31
									
								
								applications/nfc/scenes/nfc_scene_device_info.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @ -1,6 +1,6 @@ | |||||||
| #include "../nfc_i.h" | #include "../nfc_i.h" | ||||||
| 
 | 
 | ||||||
| #define NFC_SCENE_DEVICE_INFO_TEXTBOX_CUSTOM_EVENT (0UL) | #define NFC_SCENE_DEVICE_INFO_BACK_EVENT (0UL) | ||||||
| 
 | 
 | ||||||
| enum { | enum { | ||||||
|     NfcSceneDeviceInfoUid, |     NfcSceneDeviceInfoUid, | ||||||
| @ -8,26 +8,27 @@ enum { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void nfc_scene_device_info_widget_callback(GuiButtonType result, void* context) { | void nfc_scene_device_info_widget_callback(GuiButtonType result, void* context) { | ||||||
|     Nfc* nfc = (Nfc*)context; |     Nfc* nfc = context; | ||||||
| 
 |  | ||||||
|     view_dispatcher_send_custom_event(nfc->view_dispatcher, result); |     view_dispatcher_send_custom_event(nfc->view_dispatcher, result); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_scene_device_info_dialog_callback(DialogExResult result, void* context) { | void nfc_scene_device_info_dialog_callback(DialogExResult result, void* context) { | ||||||
|     Nfc* nfc = (Nfc*)context; |     Nfc* nfc = context; | ||||||
| 
 |  | ||||||
|     view_dispatcher_send_custom_event(nfc->view_dispatcher, result); |     view_dispatcher_send_custom_event(nfc->view_dispatcher, result); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_scene_device_info_text_box_callback(void* context) { | void nfc_scene_device_info_text_box_callback(void* context) { | ||||||
|     Nfc* nfc = (Nfc*)context; |     Nfc* nfc = context; | ||||||
|  |     view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_SCENE_DEVICE_INFO_BACK_EVENT); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|     view_dispatcher_send_custom_event( | void nfc_scene_device_info_bank_card_callback(GuiButtonType result, void* context) { | ||||||
|         nfc->view_dispatcher, NFC_SCENE_DEVICE_INFO_TEXTBOX_CUSTOM_EVENT); |     Nfc* nfc = context; | ||||||
|  |     view_dispatcher_send_custom_event(nfc->view_dispatcher, NFC_SCENE_DEVICE_INFO_BACK_EVENT); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_scene_device_info_on_enter(void* context) { | void nfc_scene_device_info_on_enter(void* context) { | ||||||
|     Nfc* nfc = (Nfc*)context; |     Nfc* nfc = context; | ||||||
| 
 | 
 | ||||||
|     // Setup Custom Widget view
 |     // Setup Custom Widget view
 | ||||||
|     widget_add_string_element( |     widget_add_string_element( | ||||||
| @ -107,19 +108,23 @@ void nfc_scene_device_info_on_enter(void* context) { | |||||||
|         BankCard* bank_card = nfc->bank_card; |         BankCard* bank_card = nfc->bank_card; | ||||||
|         bank_card_set_name(bank_card, emv_data->name); |         bank_card_set_name(bank_card, emv_data->name); | ||||||
|         bank_card_set_number(bank_card, emv_data->number); |         bank_card_set_number(bank_card, emv_data->number); | ||||||
|         if(!strcmp(emv_data->name, "")) { |         bank_card_set_back_callback(bank_card, nfc_scene_device_info_bank_card_callback, nfc); | ||||||
|             bank_card_set_cardholder_name(bank_card, emv_data->cardholder); |  | ||||||
|         } |  | ||||||
|         if(emv_data->exp_mon) { |         if(emv_data->exp_mon) { | ||||||
|             bank_card_set_exp_date(bank_card, emv_data->exp_mon, emv_data->exp_year); |             bank_card_set_exp_date(bank_card, emv_data->exp_mon, emv_data->exp_year); | ||||||
|         } |         } | ||||||
|  |         if(emv_data->country_code) { | ||||||
|  |             bank_card_set_country_name(bank_card, emv_data->country_code); | ||||||
|  |         } | ||||||
|  |         if(emv_data->currency_code) { | ||||||
|  |             bank_card_set_currency_name(bank_card, emv_data->currency_code); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     scene_manager_set_scene_state(nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoUid); |     scene_manager_set_scene_state(nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoUid); | ||||||
|     view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); |     view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const bool nfc_scene_device_info_on_event(void* context, SceneManagerEvent event) { | const bool nfc_scene_device_info_on_event(void* context, SceneManagerEvent event) { | ||||||
|     Nfc* nfc = (Nfc*)context; |     Nfc* nfc = context; | ||||||
|     bool consumed = false; |     bool consumed = false; | ||||||
|     uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneDeviceInfo); |     uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneDeviceInfo); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| #include "../nfc_i.h" | #include "../nfc_i.h" | ||||||
|  | #include "../helpers/nfc_emv_parser.h" | ||||||
| 
 | 
 | ||||||
| #define NFC_SCENE_READ_SUCCESS_SHIFT "              " | #define NFC_SCENE_READ_SUCCESS_SHIFT "              " | ||||||
| 
 | 
 | ||||||
| @ -21,10 +22,13 @@ void nfc_scene_read_emv_app_success_on_enter(void* context) { | |||||||
|     dialog_ex_set_icon(dialog_ex, 8, 13, &I_Medium_chip_22x21); |     dialog_ex_set_icon(dialog_ex, 8, 13, &I_Medium_chip_22x21); | ||||||
|     // Display UID and AID
 |     // Display UID and AID
 | ||||||
|     string_t aid; |     string_t aid; | ||||||
|     string_init_printf(aid, "AID:"); |     string_init(aid); | ||||||
|  |     bool aid_found = nfc_emv_parser_get_aid_name(emv_data->aid, emv_data->aid_len, aid); | ||||||
|  |     if(!aid_found) { | ||||||
|         for(uint8_t i = 0; i < emv_data->aid_len; i++) { |         for(uint8_t i = 0; i < emv_data->aid_len; i++) { | ||||||
|             string_cat_printf(aid, " %02X", emv_data->aid[i]); |             string_cat_printf(aid, " %02X", emv_data->aid[i]); | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|     nfc_text_store_set( |     nfc_text_store_set( | ||||||
|         nfc, |         nfc, | ||||||
|         NFC_SCENE_READ_SUCCESS_SHIFT "UID: %02X %02X %02X %02X \n\n%s", |         NFC_SCENE_READ_SUCCESS_SHIFT "UID: %02X %02X %02X %02X \n\n%s", | ||||||
|  | |||||||
| @ -16,6 +16,8 @@ const void nfc_scene_read_emv_data_on_enter(void* context) { | |||||||
|     popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); |     popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); | ||||||
| 
 | 
 | ||||||
|     view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); |     view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); | ||||||
|  |     // Clear emv data
 | ||||||
|  |     memset(&nfc->dev.dev_data.emv_data, 0, sizeof(nfc->dev.dev_data.emv_data)); | ||||||
|     // Start worker
 |     // Start worker
 | ||||||
|     nfc_worker_start( |     nfc_worker_start( | ||||||
|         nfc->worker, |         nfc->worker, | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| #include "../nfc_i.h" | #include "../nfc_i.h" | ||||||
|  | #include "../helpers/nfc_emv_parser.h" | ||||||
| 
 | 
 | ||||||
| void nfc_scene_read_emv_data_success_widget_callback(GuiButtonType result, void* context) { | void nfc_scene_read_emv_data_success_widget_callback(GuiButtonType result, void* context) { | ||||||
|     Nfc* nfc = (Nfc*)context; |     Nfc* nfc = (Nfc*)context; | ||||||
| @ -15,6 +16,9 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { | |||||||
|     nfc_device_set_name(&nfc->dev, ""); |     nfc_device_set_name(&nfc->dev, ""); | ||||||
| 
 | 
 | ||||||
|     // Setup Custom Widget view
 |     // Setup Custom Widget view
 | ||||||
|  |     // Add frame
 | ||||||
|  |     widget_add_frame_element(nfc->widget, 0, 0, 128, 64, 6); | ||||||
|  |     // Add buttons
 | ||||||
|     widget_add_button_element( |     widget_add_button_element( | ||||||
|         nfc->widget, |         nfc->widget, | ||||||
|         GuiButtonTypeLeft, |         GuiButtonTypeLeft, | ||||||
| @ -27,8 +31,10 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { | |||||||
|         "Save", |         "Save", | ||||||
|         nfc_scene_read_emv_data_success_widget_callback, |         nfc_scene_read_emv_data_success_widget_callback, | ||||||
|         nfc); |         nfc); | ||||||
|  |     // Add card name
 | ||||||
|     widget_add_string_element( |     widget_add_string_element( | ||||||
|         nfc->widget, 64, 3, AlignCenter, AlignTop, FontSecondary, nfc->dev.dev_data.emv_data.name); |         nfc->widget, 64, 3, AlignCenter, AlignTop, FontSecondary, nfc->dev.dev_data.emv_data.name); | ||||||
|  |     // Add cad number
 | ||||||
|     char pan_str[32]; |     char pan_str[32]; | ||||||
|     snprintf( |     snprintf( | ||||||
|         pan_str, |         pan_str, | ||||||
| @ -43,9 +49,41 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { | |||||||
|         emv_data->number[6], |         emv_data->number[6], | ||||||
|         emv_data->number[7]); |         emv_data->number[7]); | ||||||
|     widget_add_string_element(nfc->widget, 64, 13, AlignCenter, AlignTop, FontSecondary, pan_str); |     widget_add_string_element(nfc->widget, 64, 13, AlignCenter, AlignTop, FontSecondary, pan_str); | ||||||
|  |     // Parse country code
 | ||||||
|  |     string_t country_name; | ||||||
|  |     string_init(country_name); | ||||||
|  |     if((emv_data->country_code) && | ||||||
|  |        nfc_emv_parser_get_country_name(emv_data->country_code, country_name)) { | ||||||
|  |         string_t disp_country; | ||||||
|  |         string_init_printf(disp_country, "Reg:%s", country_name); | ||||||
|  |         widget_add_string_element( | ||||||
|  |             nfc->widget, 7, 23, AlignLeft, AlignTop, FontSecondary, string_get_cstr(disp_country)); | ||||||
|  |         string_clear(disp_country); | ||||||
|  |     } | ||||||
|  |     string_clear(country_name); | ||||||
|  |     // Parse currency code
 | ||||||
|  |     string_t currency_name; | ||||||
|  |     string_init(currency_name); | ||||||
|  |     if((emv_data->currency_code) && | ||||||
|  |        nfc_emv_parser_get_currency_name(emv_data->currency_code, currency_name)) { | ||||||
|  |         string_t disp_currency; | ||||||
|  |         string_init_printf(disp_currency, "Cur:%s", currency_name); | ||||||
|  |         widget_add_string_element( | ||||||
|  |             nfc->widget, | ||||||
|  |             121, | ||||||
|  |             23, | ||||||
|  |             AlignRight, | ||||||
|  |             AlignTop, | ||||||
|  |             FontSecondary, | ||||||
|  |             string_get_cstr(disp_currency)); | ||||||
|  |         string_clear(disp_currency); | ||||||
|  |     } | ||||||
|  |     string_clear(currency_name); | ||||||
|  |     // Add ATQA
 | ||||||
|     char atqa_str[16]; |     char atqa_str[16]; | ||||||
|     snprintf(atqa_str, sizeof(atqa_str), "ATQA: %02X%02X", nfc_data->atqa[0], nfc_data->atqa[1]); |     snprintf(atqa_str, sizeof(atqa_str), "ATQA: %02X%02X", nfc_data->atqa[0], nfc_data->atqa[1]); | ||||||
|     widget_add_string_element(nfc->widget, 121, 32, AlignRight, AlignTop, FontSecondary, atqa_str); |     widget_add_string_element(nfc->widget, 121, 32, AlignRight, AlignTop, FontSecondary, atqa_str); | ||||||
|  |     // Add UID
 | ||||||
|     char uid_str[32]; |     char uid_str[32]; | ||||||
|     snprintf( |     snprintf( | ||||||
|         uid_str, |         uid_str, | ||||||
| @ -56,9 +94,11 @@ void nfc_scene_read_emv_data_success_on_enter(void* context) { | |||||||
|         nfc_data->uid[2], |         nfc_data->uid[2], | ||||||
|         nfc_data->uid[3]); |         nfc_data->uid[3]); | ||||||
|     widget_add_string_element(nfc->widget, 7, 42, AlignLeft, AlignTop, FontSecondary, uid_str); |     widget_add_string_element(nfc->widget, 7, 42, AlignLeft, AlignTop, FontSecondary, uid_str); | ||||||
|  |     // Add SAK
 | ||||||
|     char sak_str[16]; |     char sak_str[16]; | ||||||
|     snprintf(sak_str, sizeof(sak_str), "SAK: %02X", nfc_data->sak); |     snprintf(sak_str, sizeof(sak_str), "SAK: %02X", nfc_data->sak); | ||||||
|     widget_add_string_element(nfc->widget, 121, 42, AlignRight, AlignTop, FontSecondary, sak_str); |     widget_add_string_element(nfc->widget, 121, 42, AlignRight, AlignTop, FontSecondary, sak_str); | ||||||
|  |     // Add expiration date
 | ||||||
|     if(emv_data->exp_mon) { |     if(emv_data->exp_mon) { | ||||||
|         char exp_str[16]; |         char exp_str[16]; | ||||||
|         snprintf( |         snprintf( | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| #include "bank_card.h" | #include "bank_card.h" | ||||||
| #include <gui/modules/widget.h> | #include "../helpers/nfc_emv_parser.h" | ||||||
| #include <m-string.h> | #include <m-string.h> | ||||||
| 
 | 
 | ||||||
| struct BankCard { | struct BankCard { | ||||||
| @ -43,10 +43,20 @@ void bank_card_set_number(BankCard* bank_card, uint8_t* number) { | |||||||
|     for(uint8_t i = 0; i < 8; i += 2) { |     for(uint8_t i = 0; i < 8; i += 2) { | ||||||
|         string_cat_printf(num_str, "%02X%02X ", number[i], number[i + 1]); |         string_cat_printf(num_str, "%02X%02X ", number[i], number[i + 1]); | ||||||
|     } |     } | ||||||
|  |     // Add number
 | ||||||
|     widget_add_string_element( |     widget_add_string_element( | ||||||
|         bank_card->widget, 25, 22, AlignLeft, AlignTop, FontSecondary, string_get_cstr(num_str)); |         bank_card->widget, 64, 32, AlignCenter, AlignTop, FontSecondary, string_get_cstr(num_str)); | ||||||
|     widget_add_icon_element(bank_card->widget, 6, 20, &I_EMV_Chip_14x11); |  | ||||||
|     string_clear(num_str); |     string_clear(num_str); | ||||||
|  |     // Add icon
 | ||||||
|  |     widget_add_icon_element(bank_card->widget, 8, 15, &I_Detailed_chip_17x13); | ||||||
|  |     // Add frame
 | ||||||
|  |     widget_add_frame_element(bank_card->widget, 0, 0, 128, 64, 6); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void bank_card_set_back_callback(BankCard* bank_card, ButtonCallback callback, void* context) { | ||||||
|  |     furi_assert(bank_card); | ||||||
|  |     furi_assert(callback); | ||||||
|  |     widget_add_button_element(bank_card->widget, GuiButtonTypeLeft, "Back", callback, context); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint8_t year) { | void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint8_t year) { | ||||||
| @ -57,8 +67,42 @@ void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint8_t year) { | |||||||
|         bank_card->widget, 122, 54, AlignRight, AlignBottom, FontSecondary, exp_date_str); |         bank_card->widget, 122, 54, AlignRight, AlignBottom, FontSecondary, exp_date_str); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void bank_card_set_cardholder_name(BankCard* bank_card, char* name) { | void bank_card_set_country_name(BankCard* bank_card, uint16_t country_code) { | ||||||
|     furi_assert(bank_card); |     furi_assert(bank_card); | ||||||
|     furi_assert(name); |     string_t country_name; | ||||||
|     widget_add_string_element(bank_card->widget, 6, 37, AlignLeft, AlignTop, FontSecondary, name); |     string_init(country_name); | ||||||
|  |     if(nfc_emv_parser_get_country_name(country_code, country_name)) { | ||||||
|  |         string_t disp_country; | ||||||
|  |         string_init_printf(disp_country, "Reg:%s", country_name); | ||||||
|  |         widget_add_string_element( | ||||||
|  |             bank_card->widget, | ||||||
|  |             120, | ||||||
|  |             18, | ||||||
|  |             AlignRight, | ||||||
|  |             AlignTop, | ||||||
|  |             FontSecondary, | ||||||
|  |             string_get_cstr(disp_country)); | ||||||
|  |         string_clear(disp_country); | ||||||
|  |     } | ||||||
|  |     string_clear(country_name); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void bank_card_set_currency_name(BankCard* bank_card, uint16_t currency_code) { | ||||||
|  |     furi_assert(bank_card); | ||||||
|  |     string_t currency_name; | ||||||
|  |     string_init(currency_name); | ||||||
|  |     if(nfc_emv_parser_get_currency_name(currency_code, currency_name)) { | ||||||
|  |         string_t disp_currency; | ||||||
|  |         string_init_printf(disp_currency, "Cur:%s", currency_name); | ||||||
|  |         widget_add_string_element( | ||||||
|  |             bank_card->widget, | ||||||
|  |             31, | ||||||
|  |             18, | ||||||
|  |             AlignLeft, | ||||||
|  |             AlignTop, | ||||||
|  |             FontSecondary, | ||||||
|  |             string_get_cstr(disp_currency)); | ||||||
|  |         string_clear(disp_currency); | ||||||
|  |     } | ||||||
|  |     string_clear(currency_name); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,11 +1,10 @@ | |||||||
| #pragma once | #pragma once | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <gui/view.h> | #include <gui/view.h> | ||||||
|  | #include <gui/modules/widget.h> | ||||||
| 
 | 
 | ||||||
| typedef struct BankCard BankCard; | typedef struct BankCard BankCard; | ||||||
| 
 | 
 | ||||||
| typedef void (*BankCardBackCallback)(void); |  | ||||||
| 
 |  | ||||||
| BankCard* bank_card_alloc(); | BankCard* bank_card_alloc(); | ||||||
| 
 | 
 | ||||||
| void bank_card_free(BankCard* bank_card); | void bank_card_free(BankCard* bank_card); | ||||||
| @ -14,10 +13,14 @@ void bank_card_clear(BankCard* bank_card); | |||||||
| 
 | 
 | ||||||
| View* bank_card_get_view(BankCard* bank_card); | View* bank_card_get_view(BankCard* bank_card); | ||||||
| 
 | 
 | ||||||
|  | void bank_card_set_back_callback(BankCard* bank_card, ButtonCallback callback, void* context); | ||||||
|  | 
 | ||||||
| void bank_card_set_name(BankCard* bank_card, char* name); | void bank_card_set_name(BankCard* bank_card, char* name); | ||||||
| 
 | 
 | ||||||
| void bank_card_set_number(BankCard* bank_card, uint8_t* number); | void bank_card_set_number(BankCard* bank_card, uint8_t* number); | ||||||
| 
 | 
 | ||||||
| void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint8_t year); | void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint8_t year); | ||||||
| 
 | 
 | ||||||
| void bank_card_set_cardholder_name(BankCard* bank_card, char* name); | void bank_card_set_country_name(BankCard* bank_card, uint16_t country_code); | ||||||
|  | 
 | ||||||
|  | void bank_card_set_currency_name(BankCard* bank_card, uint16_t currency_code); | ||||||
|  | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -3,61 +3,61 @@ | |||||||
| 
 | 
 | ||||||
| extern const Icon A_WatchingTV_128x64; | extern const Icon A_WatchingTV_128x64; | ||||||
| extern const Icon A_Wink_128x64; | extern const Icon A_Wink_128x64; | ||||||
| extern const Icon I_dir_10px; |  | ||||||
| extern const Icon I_Nfc_10px; | extern const Icon I_Nfc_10px; | ||||||
| extern const Icon I_sub1_10px; |  | ||||||
| extern const Icon I_ir_10px; | extern const Icon I_ir_10px; | ||||||
| extern const Icon I_ibutt_10px; |  | ||||||
| extern const Icon I_unknown_10px; |  | ||||||
| extern const Icon I_ble_10px; | extern const Icon I_ble_10px; | ||||||
|  | extern const Icon I_sub1_10px; | ||||||
|  | extern const Icon I_dir_10px; | ||||||
|  | extern const Icon I_unknown_10px; | ||||||
|  | extern const Icon I_ibutt_10px; | ||||||
| extern const Icon I_125_10px; | extern const Icon I_125_10px; | ||||||
| extern const Icon I_ButtonRightSmall_3x5; |  | ||||||
| extern const Icon I_ButtonLeft_4x7; | extern const Icon I_ButtonLeft_4x7; | ||||||
| extern const Icon I_ButtonLeftSmall_3x5; |  | ||||||
| extern const Icon I_Warning_30x23; |  | ||||||
| extern const Icon I_ButtonRight_4x7; | extern const Icon I_ButtonRight_4x7; | ||||||
|  | extern const Icon I_Warning_30x23; | ||||||
|  | extern const Icon I_ButtonRightSmall_3x5; | ||||||
| extern const Icon I_ButtonCenter_7x7; | extern const Icon I_ButtonCenter_7x7; | ||||||
|  | extern const Icon I_ButtonLeftSmall_3x5; | ||||||
| extern const Icon I_DolphinOkay_41x43; | extern const Icon I_DolphinOkay_41x43; | ||||||
| extern const Icon I_DolphinFirstStart4_67x53; |  | ||||||
| extern const Icon I_DolphinFirstStart2_59x51; |  | ||||||
| extern const Icon I_DolphinFirstStart5_54x49; |  | ||||||
| extern const Icon I_DolphinFirstStart0_70x53; |  | ||||||
| extern const Icon I_DolphinFirstStart6_58x54; |  | ||||||
| extern const Icon I_DolphinFirstStart1_59x53; |  | ||||||
| extern const Icon I_DolphinFirstStart8_56x51; |  | ||||||
| extern const Icon I_DolphinFirstStart7_61x51; | extern const Icon I_DolphinFirstStart7_61x51; | ||||||
| extern const Icon I_Flipper_young_80x60; | extern const Icon I_DolphinFirstStart4_67x53; | ||||||
| extern const Icon I_DolphinFirstStart3_57x48; | extern const Icon I_DolphinFirstStart3_57x48; | ||||||
| extern const Icon I_PassportBottom_128x17; | extern const Icon I_Flipper_young_80x60; | ||||||
| extern const Icon I_DoorLeft_8x56; | extern const Icon I_DolphinFirstStart0_70x53; | ||||||
|  | extern const Icon I_DolphinFirstStart2_59x51; | ||||||
|  | extern const Icon I_DolphinFirstStart6_58x54; | ||||||
|  | extern const Icon I_DolphinFirstStart5_54x49; | ||||||
|  | extern const Icon I_DolphinFirstStart8_56x51; | ||||||
|  | extern const Icon I_DolphinFirstStart1_59x53; | ||||||
|  | extern const Icon I_DoorRight_70x55; | ||||||
| extern const Icon I_DoorLocked_10x56; | extern const Icon I_DoorLocked_10x56; | ||||||
| extern const Icon I_DoorRight_8x56; |  | ||||||
| extern const Icon I_DoorLeft_70x55; | extern const Icon I_DoorLeft_70x55; | ||||||
| extern const Icon I_PassportLeft_6x47; | extern const Icon I_PassportLeft_6x47; | ||||||
| extern const Icon I_DoorRight_70x55; | extern const Icon I_DoorRight_8x56; | ||||||
|  | extern const Icon I_DoorLeft_8x56; | ||||||
| extern const Icon I_LockPopup_100x49; | extern const Icon I_LockPopup_100x49; | ||||||
| extern const Icon I_Mute_25x27; | extern const Icon I_PassportBottom_128x17; | ||||||
| extern const Icon I_IrdaArrowUp_4x8; |  | ||||||
| extern const Icon I_Up_hvr_25x27; |  | ||||||
| extern const Icon I_Mute_hvr_25x27; |  | ||||||
| extern const Icon I_Vol_down_25x27; |  | ||||||
| extern const Icon I_Down_25x27; |  | ||||||
| extern const Icon I_Power_hvr_25x27; |  | ||||||
| extern const Icon I_IrdaLearnShort_128x31; |  | ||||||
| extern const Icon I_IrdaArrowDown_4x8; |  | ||||||
| extern const Icon I_Vol_down_hvr_25x27; |  | ||||||
| extern const Icon I_IrdaLearn_128x64; |  | ||||||
| extern const Icon I_Down_hvr_25x27; |  | ||||||
| extern const Icon I_Fill_marker_7x7; |  | ||||||
| extern const Icon I_Power_25x27; |  | ||||||
| extern const Icon I_Vol_up_25x27; | extern const Icon I_Vol_up_25x27; | ||||||
| extern const Icon I_Up_25x27; | extern const Icon I_Fill_marker_7x7; | ||||||
| extern const Icon I_Back_15x10; | extern const Icon I_IrdaArrowUp_4x8; | ||||||
| extern const Icon I_IrdaSend_128x64; | extern const Icon I_Down_hvr_25x27; | ||||||
| extern const Icon I_IrdaSendShort_128x34; |  | ||||||
| extern const Icon I_Vol_up_hvr_25x27; | extern const Icon I_Vol_up_hvr_25x27; | ||||||
| extern const Icon I_KeySave_24x11; | extern const Icon I_Power_25x27; | ||||||
|  | extern const Icon I_Vol_down_25x27; | ||||||
|  | extern const Icon I_IrdaSend_128x64; | ||||||
|  | extern const Icon I_Up_hvr_25x27; | ||||||
|  | extern const Icon I_Back_15x10; | ||||||
|  | extern const Icon I_IrdaSendShort_128x34; | ||||||
|  | extern const Icon I_Mute_hvr_25x27; | ||||||
|  | extern const Icon I_IrdaLearnShort_128x31; | ||||||
|  | extern const Icon I_Down_25x27; | ||||||
|  | extern const Icon I_Up_25x27; | ||||||
|  | extern const Icon I_Mute_25x27; | ||||||
|  | extern const Icon I_Vol_down_hvr_25x27; | ||||||
|  | extern const Icon I_Power_hvr_25x27; | ||||||
|  | extern const Icon I_IrdaLearn_128x64; | ||||||
|  | extern const Icon I_IrdaArrowDown_4x8; | ||||||
| extern const Icon I_KeyBackspaceSelected_16x9; | extern const Icon I_KeyBackspaceSelected_16x9; | ||||||
|  | extern const Icon I_KeySave_24x11; | ||||||
| extern const Icon I_KeySaveSelected_24x11; | extern const Icon I_KeySaveSelected_24x11; | ||||||
| extern const Icon I_KeyBackspace_16x9; | extern const Icon I_KeyBackspace_16x9; | ||||||
| extern const Icon A_125khz_14; | extern const Icon A_125khz_14; | ||||||
| @ -76,38 +76,38 @@ extern const Icon A_Tamagotchi_14; | |||||||
| extern const Icon A_U2F_14; | extern const Icon A_U2F_14; | ||||||
| extern const Icon A_iButton_14; | extern const Icon A_iButton_14; | ||||||
| extern const Icon I_Medium_chip_22x21; | extern const Icon I_Medium_chip_22x21; | ||||||
| extern const Icon I_EMV_Chip_14x11; | extern const Icon I_Detailed_chip_17x13; | ||||||
| extern const Icon I_Health_16x16; | extern const Icon I_Health_16x16; | ||||||
| extern const Icon I_FaceCharging_29x14; | extern const Icon I_FaceNopower_29x14; | ||||||
|  | extern const Icon I_Battery_16x16; | ||||||
| extern const Icon I_BatteryBody_52x28; | extern const Icon I_BatteryBody_52x28; | ||||||
|  | extern const Icon I_FaceConfused_29x14; | ||||||
|  | extern const Icon I_FaceCharging_29x14; | ||||||
|  | extern const Icon I_FaceNormal_29x14; | ||||||
| extern const Icon I_Voltage_16x16; | extern const Icon I_Voltage_16x16; | ||||||
| extern const Icon I_Temperature_16x16; | extern const Icon I_Temperature_16x16; | ||||||
| extern const Icon I_FaceNopower_29x14; |  | ||||||
| extern const Icon I_FaceNormal_29x14; |  | ||||||
| extern const Icon I_Battery_16x16; |  | ||||||
| extern const Icon I_FaceConfused_29x14; |  | ||||||
| extern const Icon I_RFIDDolphinSuccess_108x57; |  | ||||||
| extern const Icon I_RFIDBigChip_37x36; |  | ||||||
| extern const Icon I_RFIDDolphinSend_97x61; |  | ||||||
| extern const Icon I_RFIDDolphinReceive_97x61; | extern const Icon I_RFIDDolphinReceive_97x61; | ||||||
|  | extern const Icon I_RFIDDolphinSend_97x61; | ||||||
|  | extern const Icon I_RFIDBigChip_37x36; | ||||||
|  | extern const Icon I_RFIDDolphinSuccess_108x57; | ||||||
| extern const Icon I_SDQuestion_35x43; | extern const Icon I_SDQuestion_35x43; | ||||||
| extern const Icon I_SDError_43x35; | extern const Icon I_SDError_43x35; | ||||||
| extern const Icon I_BadUsb_9x8; |  | ||||||
| extern const Icon I_PlaceholderR_30x13; |  | ||||||
| extern const Icon I_Background_128x8; |  | ||||||
| extern const Icon I_Lock_8x8; |  | ||||||
| extern const Icon I_Battery_26x8; | extern const Icon I_Battery_26x8; | ||||||
| extern const Icon I_PlaceholderL_11x13; | extern const Icon I_PlaceholderL_11x13; | ||||||
| extern const Icon I_Battery_19x8; |  | ||||||
| extern const Icon I_SDcardMounted_11x8; |  | ||||||
| extern const Icon I_SDcardFail_11x8; |  | ||||||
| extern const Icon I_USBConnected_15x8; |  | ||||||
| extern const Icon I_Bluetooth_5x8; | extern const Icon I_Bluetooth_5x8; | ||||||
|  | extern const Icon I_BadUsb_9x8; | ||||||
|  | extern const Icon I_PlaceholderR_30x13; | ||||||
|  | extern const Icon I_USBConnected_15x8; | ||||||
|  | extern const Icon I_Battery_19x8; | ||||||
|  | extern const Icon I_Lock_8x8; | ||||||
| extern const Icon I_Background_128x11; | extern const Icon I_Background_128x11; | ||||||
| extern const Icon I_DolphinMafia_115x62; | extern const Icon I_Background_128x8; | ||||||
| extern const Icon I_DolphinExcited_64x63; | extern const Icon I_SDcardFail_11x8; | ||||||
| extern const Icon I_iButtonDolphinSuccess_109x60; | extern const Icon I_SDcardMounted_11x8; | ||||||
| extern const Icon I_iButtonDolphinVerySuccess_108x52; | extern const Icon I_iButtonDolphinVerySuccess_108x52; | ||||||
| extern const Icon I_iButtonKey_49x44; | extern const Icon I_DolphinMafia_115x62; | ||||||
|  | extern const Icon I_iButtonDolphinSuccess_109x60; | ||||||
|  | extern const Icon I_DolphinExcited_64x63; | ||||||
| extern const Icon I_DolphinNice_96x59; | extern const Icon I_DolphinNice_96x59; | ||||||
|  | extern const Icon I_iButtonKey_49x44; | ||||||
| extern const Icon I_DolphinWait_61x59; | extern const Icon I_DolphinWait_61x59; | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								assets/icons/NFC/Detailed_chip_17x13.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/icons/NFC/Detailed_chip_17x13.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 981 B | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 3.6 KiB | 
							
								
								
									
										148
									
								
								assets/resources/nfc/emv/aid.nfc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								assets/resources/nfc/emv/aid.nfc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,148 @@ | |||||||
|  | A00000000305076010 VISA ELO Credit | ||||||
|  | A0000000031010 VISA Debit/Credit (Classic) | ||||||
|  | A000000003101001 VISA Credit | ||||||
|  | A000000003101002 VISA Debit | ||||||
|  | A0000000032010 VISA Electron | ||||||
|  | A0000000032020 VISA | ||||||
|  | A0000000033010 VISA Interlink | ||||||
|  | A0000000034010 VISA Specific | ||||||
|  | A0000000035010 VISA Specific | ||||||
|  | A0000000036010 Domestic Visa Cash | ||||||
|  | A0000000036020 International Visa Cash | ||||||
|  | A0000000038002 VISA Auth EMV-CAP (DPA) | ||||||
|  | A0000000038010 VISA Plus | ||||||
|  | A0000000039010 VISA Loyalty | ||||||
|  | A000000003999910 VISA Proprietary ATM | ||||||
|  | A00000000401 MasterCard PayPass | ||||||
|  | A0000000041010 MasterCard Global | ||||||
|  | A00000000410101213 MasterCard Credit | ||||||
|  | A00000000410101215 MasterCard Credit | ||||||
|  | A0000000042010 MasterCard Specific | ||||||
|  | A0000000043010 MasterCard Specific | ||||||
|  | A0000000043060 Maestro (Debit) | ||||||
|  | A000000004306001 Maestro (Debit) | ||||||
|  | A0000000044010 MasterCard Specific | ||||||
|  | A0000000045010 MasterCard Specific | ||||||
|  | A0000000046000 Cirrus | ||||||
|  | A0000000048002 SecureCode EMV-CAP | ||||||
|  | A0000000049999 MasterCard PayPass | ||||||
|  | A0000000050001 Maestro UK | ||||||
|  | A0000000050002 Solo | ||||||
|  | A00000002401 Self Service | ||||||
|  | A000000025 American Express | ||||||
|  | A0000000250000 American Express | ||||||
|  | A00000002501 American Express | ||||||
|  | A000000025010402 American Express | ||||||
|  | A000000025010701 ExpressPay | ||||||
|  | A000000025010801 American Express | ||||||
|  | A0000000291010 Link / American Express | ||||||
|  | A0000000421010 Cartes Bancaire EMV Card | ||||||
|  | A0000000426010 Apple Pay | ||||||
|  | A00000006510 JCB | ||||||
|  | A0000000651010 JCB J Smart Credit | ||||||
|  | A00000006900 Moneo | ||||||
|  | A000000077010000021000000000003B Visa AEPN | ||||||
|  | A000000098 Debit Card | ||||||
|  | A0000000980848 Debit Card | ||||||
|  | A0000001211010 Dankort VISA GEM Vision | ||||||
|  | A0000001410001 PagoBANCOMAT | ||||||
|  | A0000001523010 Discover, Pulse D Pas | ||||||
|  | A0000001524010 Discover | ||||||
|  | A0000001544442 Banricompras Debito | ||||||
|  | A000000172950001 BAROC Taiwan | ||||||
|  | A0000002281010 SPAN (M/Chip) | ||||||
|  | A0000002282010 SPAN (VIS) | ||||||
|  | A0000002771010 INTERAC | ||||||
|  | A00000031510100528 Currence PuC | ||||||
|  | A0000003156020 Chipknip | ||||||
|  | A0000003591010028001 Girocard EAPS | ||||||
|  | A0000003710001 InterSwitch Verve Card | ||||||
|  | A0000004540010 Etranzact Genesis Card | ||||||
|  | A0000004540011 Etranzact Genesis Card 2 | ||||||
|  | A0000004766C GOOGLE_PAYMENT | ||||||
|  | A0000005241010 RuPay | ||||||
|  | A0000006723010 TROY chip credit card | ||||||
|  | A0000006723020 TROY chip debit card | ||||||
|  | A0000007705850 XTRAPOWER | ||||||
|  | B012345678 Maestro TEST | ||||||
|  | D27600002545500100 Girocard | ||||||
|  | D5780000021010 Bankaxept | ||||||
|  | F0000000030001 BRADESCO | ||||||
|  | A000000003000000 (VISA) Card Manager | ||||||
|  | A000000003534441 Schlumberger SD | ||||||
|  | A0000000035350 Security Domain | ||||||
|  | A000000003535041 Security Domain | ||||||
|  | A0000000040000 MasterCard Card Manager | ||||||
|  | A000000018434D Gemplus card manager | ||||||
|  | A000000018434D00 Gemplus Security Domain | ||||||
|  | A0000000960200 Proton WISD | ||||||
|  | A0000001510000 Global Platform SD | ||||||
|  | A00000015153504341534400 CASD_AID | ||||||
|  | A000000476A010 GSD_MANAGER_AID | ||||||
|  | A000000476A110 GSD_MANAGER_AID | ||||||
|  | 315041592E5359532E4444463031 Visa PSE  | ||||||
|  | 325041592E5359532E4444463031 Visa PPSE | ||||||
|  | A0000000042203 MasterCard Specific | ||||||
|  | A0000000045555 APDULogger | ||||||
|  | A0000000090001FF44FF1289 Orange | ||||||
|  | A0000000101030 Maestro-CH | ||||||
|  | A00000001800 Gemplus | ||||||
|  | A0000000181001 gemplus util packages | ||||||
|  | A000000025010104 American Express | ||||||
|  | A00000002949034010100001 HSBC | ||||||
|  | A00000002949282010100000 Barclay | ||||||
|  | A00000005945430100 Girocard Electronic Cash | ||||||
|  | A0000000980840 Visa Common Debit | ||||||
|  | A0000001570010 AMEX | ||||||
|  | A0000001570020 MasterCard | ||||||
|  | A0000001570021 Maestro | ||||||
|  | A0000001570022 Maestro | ||||||
|  | A0000001570023 CASH | ||||||
|  | A0000001570030 VISA | ||||||
|  | A0000001570031 VISA | ||||||
|  | A0000001570040 JCB | ||||||
|  | A0000001570050 Postcard | ||||||
|  | A0000001570051 Postcard | ||||||
|  | A0000001570100 MCard | ||||||
|  | A0000001570104 MyOne | ||||||
|  | A000000157010C WIRCard | ||||||
|  | A000000157010D Power Card | ||||||
|  | A0000001574443 DINERS CLUB | ||||||
|  | A0000001574444 Supercard Plus | ||||||
|  | A00000022820101010 SPAN | ||||||
|  | A000000308000010000100 ID-ONE PIV BIO | ||||||
|  | A0000003241010 Discover Zip | ||||||
|  | A000000333010101 UnionPay Debit | ||||||
|  | A000000333010102 UnionPay Credit | ||||||
|  | A000000333010103 UnionPay Quasi Credit | ||||||
|  | A000000333010106 UnionPay Electronic Cash | ||||||
|  | A000000333010108 U.S. UnionPay Common Debit | ||||||
|  | A000000337102000 Classic | ||||||
|  | A000000337101001 Prepaye Online | ||||||
|  | A000000337102001 Prepaye Possibile Offiline | ||||||
|  | A000000337601001 Porte Monnaie Electronique | ||||||
|  | A0000006581010 MIR Credit | ||||||
|  | A0000006581011 MIR Credit | ||||||
|  | A0000006582010 MIR Debit | ||||||
|  | D040000001000002 Paylife Quick IEP | ||||||
|  | D040000002000002 RFU | ||||||
|  | D040000003000002 POS | ||||||
|  | D040000004000002 ATM | ||||||
|  | D04000000B000002 Retail | ||||||
|  | D04000000C000002 Bank_Data | ||||||
|  | D04000000D000002 Shopping | ||||||
|  | D040000013000001 DF_UNI_Kepler1 | ||||||
|  | D040000013000001 DF_Schüler1 | ||||||
|  | D040000013000002 DF_UNI_Kepler2 | ||||||
|  | D040000013000002 DF_Schüler2 | ||||||
|  | D040000014000001 DF_Mensa | ||||||
|  | D040000015000001 DF_UNI_Ausweis | ||||||
|  | D040000015000001 DF_Ausweis | ||||||
|  | D0400000190001 EMV ATM Maestro | ||||||
|  | D0400000190002 EMV POS Maestro | ||||||
|  | D0400000190003 EMV ATM MasterCard | ||||||
|  | D0400000190004 EMV POS MasterCard | ||||||
|  | D276000025 Girocard | ||||||
|  | D27600002547410100 Girocard ATM | ||||||
|  | D7560000010101 Reka Card | ||||||
|  | D7560000300101 M Budget | ||||||
							
								
								
									
										249
									
								
								assets/resources/nfc/emv/country_code.nfc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								assets/resources/nfc/emv/country_code.nfc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,249 @@ | |||||||
|  | 0004 AFG | ||||||
|  | 0008 ALB | ||||||
|  | 0010 ATA | ||||||
|  | 0012 DZA | ||||||
|  | 0016 ASM | ||||||
|  | 0020 AND | ||||||
|  | 0024 AGO | ||||||
|  | 0028 ATG | ||||||
|  | 0031 AZE | ||||||
|  | 0032 ARG | ||||||
|  | 0036 AUS | ||||||
|  | 0040 AUT | ||||||
|  | 0044 BHS | ||||||
|  | 0048 BHR | ||||||
|  | 0050 BGD | ||||||
|  | 0051 ARM | ||||||
|  | 0052 BRB | ||||||
|  | 0056 BEL | ||||||
|  | 0060 BMU | ||||||
|  | 0064 BTN | ||||||
|  | 0068 BOL | ||||||
|  | 0070 BIH | ||||||
|  | 0072 BWA | ||||||
|  | 0074 BVT | ||||||
|  | 0076 BRA | ||||||
|  | 0084 BLZ | ||||||
|  | 0086 IOT | ||||||
|  | 0090 SLB | ||||||
|  | 0092 VGB | ||||||
|  | 0096 BRN | ||||||
|  | 0100 BGR | ||||||
|  | 0104 MMR | ||||||
|  | 0108 BDI | ||||||
|  | 0112 BLR | ||||||
|  | 0116 KHM | ||||||
|  | 0120 CMR | ||||||
|  | 0124 CAN | ||||||
|  | 0132 CPV | ||||||
|  | 0136 CYM | ||||||
|  | 0140 CAF | ||||||
|  | 0144 LKA | ||||||
|  | 0148 TCD | ||||||
|  | 0152 CHL | ||||||
|  | 0156 CHN | ||||||
|  | 0158 TWN | ||||||
|  | 0162 CXR | ||||||
|  | 0166 CCK | ||||||
|  | 0170 COL | ||||||
|  | 0174 COM | ||||||
|  | 0175 MYT | ||||||
|  | 0178 COG | ||||||
|  | 0180 COD | ||||||
|  | 0184 COK | ||||||
|  | 0188 CRI | ||||||
|  | 0191 HRV | ||||||
|  | 0192 CUB | ||||||
|  | 0196 CYP | ||||||
|  | 0203 CZE | ||||||
|  | 0204 BEN | ||||||
|  | 0208 DNK | ||||||
|  | 0212 DMA | ||||||
|  | 0214 DOM | ||||||
|  | 0218 ECU | ||||||
|  | 0222 SLV | ||||||
|  | 0226 GNQ | ||||||
|  | 0231 ETH | ||||||
|  | 0232 ERI | ||||||
|  | 0233 EST | ||||||
|  | 0234 FRO | ||||||
|  | 0238 FLK | ||||||
|  | 0239 SGS | ||||||
|  | 0242 FJI | ||||||
|  | 0246 FIN | ||||||
|  | 0248 ALA | ||||||
|  | 0250 FRA | ||||||
|  | 0254 GUF | ||||||
|  | 0258 PYF | ||||||
|  | 0260 ATF | ||||||
|  | 0262 DJI | ||||||
|  | 0266 GAB | ||||||
|  | 0268 GEO | ||||||
|  | 0270 GMB | ||||||
|  | 0275 PSE | ||||||
|  | 0276 DEU | ||||||
|  | 0288 GHA | ||||||
|  | 0292 GIB | ||||||
|  | 0296 KIR | ||||||
|  | 0300 GRC | ||||||
|  | 0304 GRL | ||||||
|  | 0308 GRD | ||||||
|  | 0312 GLP | ||||||
|  | 0316 GUM | ||||||
|  | 0320 GTM | ||||||
|  | 0324 GIN | ||||||
|  | 0328 GUY | ||||||
|  | 0332 HTI | ||||||
|  | 0334 HMD | ||||||
|  | 0336 VAT | ||||||
|  | 0340 HND | ||||||
|  | 0344 HKG | ||||||
|  | 0348 HUN | ||||||
|  | 0352 ISL | ||||||
|  | 0356 IND | ||||||
|  | 0360 IDN | ||||||
|  | 0364 IRN | ||||||
|  | 0368 IRQ | ||||||
|  | 0372 IRL | ||||||
|  | 0376 ISR | ||||||
|  | 0380 ITA | ||||||
|  | 0384 CIV | ||||||
|  | 0388 JAM | ||||||
|  | 0392 JPN | ||||||
|  | 0398 KAZ | ||||||
|  | 0400 JOR | ||||||
|  | 0404 KEN | ||||||
|  | 0408 PRK | ||||||
|  | 0410 KOR | ||||||
|  | 0414 KWT | ||||||
|  | 0417 KGZ | ||||||
|  | 0418 LAO | ||||||
|  | 0422 LBN | ||||||
|  | 0426 LSO | ||||||
|  | 0428 LVA | ||||||
|  | 0430 LBR | ||||||
|  | 0434 LBY | ||||||
|  | 0438 LIE | ||||||
|  | 0440 LTU | ||||||
|  | 0442 LUX | ||||||
|  | 0446 MAC | ||||||
|  | 0450 MDG | ||||||
|  | 0454 MWI | ||||||
|  | 0458 MYS | ||||||
|  | 0462 MDV | ||||||
|  | 0466 MLI | ||||||
|  | 0470 MLT | ||||||
|  | 0474 MTQ | ||||||
|  | 0478 MRT | ||||||
|  | 0480 MUS | ||||||
|  | 0484 MEX | ||||||
|  | 0492 MCO | ||||||
|  | 0496 MNG | ||||||
|  | 0498 MDA | ||||||
|  | 0499 MNE | ||||||
|  | 0500 MSR | ||||||
|  | 0504 MAR | ||||||
|  | 0508 MOZ | ||||||
|  | 0512 OMN | ||||||
|  | 0516 NAM | ||||||
|  | 0520 NRU | ||||||
|  | 0524 NPL | ||||||
|  | 0528 NLD | ||||||
|  | 0531 CUW | ||||||
|  | 0533 ABW | ||||||
|  | 0534 SXM | ||||||
|  | 0535 BES | ||||||
|  | 0540 NCL | ||||||
|  | 0548 VUT | ||||||
|  | 0554 NZL | ||||||
|  | 0558 NIC | ||||||
|  | 0562 NER | ||||||
|  | 0566 NGA | ||||||
|  | 0570 NIU | ||||||
|  | 0574 NFK | ||||||
|  | 0578 NOR | ||||||
|  | 0580 MNP | ||||||
|  | 0581 UMI | ||||||
|  | 0583 FSM | ||||||
|  | 0584 MHL | ||||||
|  | 0585 PLW | ||||||
|  | 0586 PAK | ||||||
|  | 0591 PAN | ||||||
|  | 0598 PNG | ||||||
|  | 0600 PRY | ||||||
|  | 0604 PER | ||||||
|  | 0608 PHL | ||||||
|  | 0612 PCN | ||||||
|  | 0616 POL | ||||||
|  | 0620 PRT | ||||||
|  | 0624 GNB | ||||||
|  | 0626 TLS | ||||||
|  | 0630 PRI | ||||||
|  | 0634 QAT | ||||||
|  | 0638 REU | ||||||
|  | 0642 ROU | ||||||
|  | 0643 RUS | ||||||
|  | 0646 RWA | ||||||
|  | 0652 BLM | ||||||
|  | 0654 SHN | ||||||
|  | 0659 KNA | ||||||
|  | 0660 AIA | ||||||
|  | 0662 LCA | ||||||
|  | 0663 MAF | ||||||
|  | 0666 SPM | ||||||
|  | 0670 VCT | ||||||
|  | 0674 SMR | ||||||
|  | 0678 STP | ||||||
|  | 0682 SAU | ||||||
|  | 0686 SEN | ||||||
|  | 0688 SRB | ||||||
|  | 0690 SYC | ||||||
|  | 0694 SLE | ||||||
|  | 0702 SGP | ||||||
|  | 0703 SVK | ||||||
|  | 0704 VNM | ||||||
|  | 0705 SVN | ||||||
|  | 0706 SOM | ||||||
|  | 0710 ZAF | ||||||
|  | 0716 ZWE | ||||||
|  | 0724 ESP | ||||||
|  | 0728 SSD | ||||||
|  | 0729 SDN | ||||||
|  | 0732 ESH | ||||||
|  | 0740 SUR | ||||||
|  | 0744 SJM | ||||||
|  | 0748 SWZ | ||||||
|  | 0752 SWE | ||||||
|  | 0756 CHE | ||||||
|  | 0760 SYR | ||||||
|  | 0762 TJK | ||||||
|  | 0764 THA | ||||||
|  | 0768 TGO | ||||||
|  | 0772 TKL | ||||||
|  | 0776 TON | ||||||
|  | 0780 TTO | ||||||
|  | 0784 ARE | ||||||
|  | 0788 TUN | ||||||
|  | 0792 TUR | ||||||
|  | 0795 TKM | ||||||
|  | 0796 TCA | ||||||
|  | 0798 TUV | ||||||
|  | 0800 UGA | ||||||
|  | 0804 UKR | ||||||
|  | 0807 MKD | ||||||
|  | 0818 EGY | ||||||
|  | 0826 GBR | ||||||
|  | 0831 GGY | ||||||
|  | 0832 JEY | ||||||
|  | 0833 IMN | ||||||
|  | 0834 TZA | ||||||
|  | 0840 USA | ||||||
|  | 0850 VIR | ||||||
|  | 0854 BFA | ||||||
|  | 0858 URY | ||||||
|  | 0860 UZB | ||||||
|  | 0862 VEN | ||||||
|  | 0876 WLF | ||||||
|  | 0882 WSM | ||||||
|  | 0887 YEM | ||||||
|  | 0894 ZMB | ||||||
							
								
								
									
										168
									
								
								assets/resources/nfc/emv/currency_code.nfc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								assets/resources/nfc/emv/currency_code.nfc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,168 @@ | |||||||
|  | 0997 USN | ||||||
|  | 0994 XSU | ||||||
|  | 0990 CLF | ||||||
|  | 0986 BRL | ||||||
|  | 0985 PLN | ||||||
|  | 0984 BOV | ||||||
|  | 0981 GEL | ||||||
|  | 0980 UAH | ||||||
|  | 0979 MXV | ||||||
|  | 0978 EUR | ||||||
|  | 0977 BAM | ||||||
|  | 0976 CDF | ||||||
|  | 0975 BGN | ||||||
|  | 0973 AOA | ||||||
|  | 0972 TJS | ||||||
|  | 0971 AFN | ||||||
|  | 0970 COU | ||||||
|  | 0969 MGA | ||||||
|  | 0968 SRD | ||||||
|  | 0967 ZMW | ||||||
|  | 0965 XUA | ||||||
|  | 0960 XDR | ||||||
|  | 0953 XPF | ||||||
|  | 0952 XOF | ||||||
|  | 0951 XCD | ||||||
|  | 0950 XAF | ||||||
|  | 0949 TRY | ||||||
|  | 0948 CHW | ||||||
|  | 0947 CHE | ||||||
|  | 0946 RON | ||||||
|  | 0944 AZN | ||||||
|  | 0943 MZN | ||||||
|  | 0941 RSD | ||||||
|  | 0940 UYI | ||||||
|  | 0938 SDG | ||||||
|  | 0937 VEF | ||||||
|  | 0936 GHS | ||||||
|  | 0934 TMT | ||||||
|  | 0933 BYN | ||||||
|  | 0932 ZWL | ||||||
|  | 0931 CUC | ||||||
|  | 0930 STN | ||||||
|  | 0929 MRU | ||||||
|  | 0901 TWD | ||||||
|  | 0886 YER | ||||||
|  | 0882 WST | ||||||
|  | 0860 UZS | ||||||
|  | 0858 UYU | ||||||
|  | 0840 USD | ||||||
|  | 0834 TZS | ||||||
|  | 0826 GBP | ||||||
|  | 0818 EGP | ||||||
|  | 0807 MKD | ||||||
|  | 0800 UGX | ||||||
|  | 0788 TND | ||||||
|  | 0784 AED | ||||||
|  | 0780 TTD | ||||||
|  | 0776 TOP | ||||||
|  | 0764 THB | ||||||
|  | 0760 SYP | ||||||
|  | 0756 CHF | ||||||
|  | 0752 SEK | ||||||
|  | 0748 SZL | ||||||
|  | 0728 SSP | ||||||
|  | 0710 ZAR | ||||||
|  | 0706 SOS | ||||||
|  | 0704 VND | ||||||
|  | 0702 SGD | ||||||
|  | 0694 SLL | ||||||
|  | 0690 SCR | ||||||
|  | 0682 SAR | ||||||
|  | 0654 SHP | ||||||
|  | 0646 RWF | ||||||
|  | 0643 RUB | ||||||
|  | 0634 QAR | ||||||
|  | 0608 PHP | ||||||
|  | 0604 PEN | ||||||
|  | 0600 PYG | ||||||
|  | 0598 PGK | ||||||
|  | 0590 PAB | ||||||
|  | 0586 PKR | ||||||
|  | 0578 NOK | ||||||
|  | 0566 NGN | ||||||
|  | 0558 NIO | ||||||
|  | 0554 NZD | ||||||
|  | 0548 VUV | ||||||
|  | 0533 AWG | ||||||
|  | 0532 ANG | ||||||
|  | 0524 NPR | ||||||
|  | 0516 NAD | ||||||
|  | 0512 OMR | ||||||
|  | 0504 MAD | ||||||
|  | 0498 MDL | ||||||
|  | 0496 MNT | ||||||
|  | 0484 MXN | ||||||
|  | 0480 MUR | ||||||
|  | 0462 MVR | ||||||
|  | 0458 MYR | ||||||
|  | 0454 MWK | ||||||
|  | 0446 MOP | ||||||
|  | 0434 LYD | ||||||
|  | 0430 LRD | ||||||
|  | 0426 LSL | ||||||
|  | 0422 LBP | ||||||
|  | 0418 LAK | ||||||
|  | 0417 KGS | ||||||
|  | 0414 KWD | ||||||
|  | 0410 KRW | ||||||
|  | 0408 KPW | ||||||
|  | 0404 KES | ||||||
|  | 0400 JOD | ||||||
|  | 0398 KZT | ||||||
|  | 0392 JPY | ||||||
|  | 0388 JMD | ||||||
|  | 0376 ILS | ||||||
|  | 0368 IQD | ||||||
|  | 0364 IRR | ||||||
|  | 0360 IDR | ||||||
|  | 0356 INR | ||||||
|  | 0352 ISK | ||||||
|  | 0348 HUF | ||||||
|  | 0344 HKD | ||||||
|  | 0340 HNL | ||||||
|  | 0332 HTG | ||||||
|  | 0328 GYD | ||||||
|  | 0324 GNF | ||||||
|  | 0320 GTQ | ||||||
|  | 0292 GIP | ||||||
|  | 0270 GMD | ||||||
|  | 0262 DJF | ||||||
|  | 0242 FJD | ||||||
|  | 0238 FKP | ||||||
|  | 0232 ERN | ||||||
|  | 0230 ETB | ||||||
|  | 0222 SVC | ||||||
|  | 0214 DOP | ||||||
|  | 0208 DKK | ||||||
|  | 0203 CZK | ||||||
|  | 0192 CUP | ||||||
|  | 0191 HRK | ||||||
|  | 0188 CRC | ||||||
|  | 0174 KMF | ||||||
|  | 0170 COP | ||||||
|  | 0156 CNY | ||||||
|  | 0152 CLP | ||||||
|  | 0144 LKR | ||||||
|  | 0136 KYD | ||||||
|  | 0132 CVE | ||||||
|  | 0124 CAD | ||||||
|  | 0116 KHR | ||||||
|  | 0108 BIF | ||||||
|  | 0104 MMK | ||||||
|  | 0096 BND | ||||||
|  | 0090 SBD | ||||||
|  | 0084 BZD | ||||||
|  | 0072 BWP | ||||||
|  | 0068 BOB | ||||||
|  | 0064 BTN | ||||||
|  | 0060 BMD | ||||||
|  | 0052 BBD | ||||||
|  | 0051 AMD | ||||||
|  | 0050 BDT | ||||||
|  | 0048 BHD | ||||||
|  | 0044 BSD | ||||||
|  | 0036 AUD | ||||||
|  | 0032 ARS | ||||||
|  | 0012 DZD | ||||||
|  | 0008 ALL | ||||||
| @ -575,7 +575,9 @@ ReturnCode rfalNfcDataExchangeStart( uint8_t *txData, uint16_t txDataLen, uint8_ | |||||||
|             *rvdLen = (uint16_t*)&gNfcDev.rxLen; |             *rvdLen = (uint16_t*)&gNfcDev.rxLen; | ||||||
|             *rxData = (uint8_t*)(  (gNfcDev.activeDev->rfInterface == RFAL_NFC_INTERFACE_ISODEP) ? gNfcDev.rxBuf.isoDepBuf.apdu :  |             *rxData = (uint8_t*)(  (gNfcDev.activeDev->rfInterface == RFAL_NFC_INTERFACE_ISODEP) ? gNfcDev.rxBuf.isoDepBuf.apdu :  | ||||||
|                                   ((gNfcDev.activeDev->rfInterface == RFAL_NFC_INTERFACE_NFCDEP) ? gNfcDev.rxBuf.nfcDepBuf.pdu  : gNfcDev.rxBuf.rfBuf)); |                                   ((gNfcDev.activeDev->rfInterface == RFAL_NFC_INTERFACE_NFCDEP) ? gNfcDev.rxBuf.nfcDepBuf.pdu  : gNfcDev.rxBuf.rfBuf)); | ||||||
|  |             if(gNfcDev.disc.activate_after_sak) { | ||||||
|                 gNfcDev.state = RFAL_NFC_STATE_DATAEXCHANGE_DONE; |                 gNfcDev.state = RFAL_NFC_STATE_DATAEXCHANGE_DONE; | ||||||
|  |             } | ||||||
|             return ERR_NONE; |             return ERR_NONE; | ||||||
|         } |         } | ||||||
|          |          | ||||||
|  | |||||||
| @ -71,6 +71,10 @@ bool FileWorkerCpp::read_until_buffered(string_t str_result, char* file_buf, siz | |||||||
|     return file_worker_read_until_buffered(file_worker, str_result, file_buf, file_buf_cnt, max_length, separator); |     return file_worker_read_until_buffered(file_worker, str_result, file_buf, file_buf_cnt, max_length, separator); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool FileWorkerCpp::get_value_from_key(string_t key, char delimiter, string_t value) { | ||||||
|  |     return file_worker_get_value_from_key(file_worker, key, delimiter, value); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool FileWorkerCpp::is_file_exist(const char* filename, bool* exist) { | bool FileWorkerCpp::is_file_exist(const char* filename, bool* exist) { | ||||||
|     return file_worker_is_file_exist(file_worker, filename, exist); |     return file_worker_is_file_exist(file_worker, filename, exist); | ||||||
| } | } | ||||||
|  | |||||||
| @ -143,6 +143,17 @@ public: | |||||||
|      */ |      */ | ||||||
|     bool read_until_buffered(string_t str_result, char* file_buf, size_t* file_buf_cnt, size_t max_length, char separator = '\n'); |     bool read_until_buffered(string_t str_result, char* file_buf, size_t* file_buf_cnt, size_t max_length, char separator = '\n'); | ||||||
| 
 | 
 | ||||||
|  |     /**
 | ||||||
|  |      * @brief Gets value from key | ||||||
|  |      * | ||||||
|  |      * @param file_worker FileWorker instance | ||||||
|  |      * @param key key | ||||||
|  |      * @param delimeter key-value delimeter | ||||||
|  |      * @param value value for given key | ||||||
|  |      * @return true on success | ||||||
|  |      */ | ||||||
|  |     bool get_value_from_key(string_t key, char delimiter, string_t value); | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * @brief Check whether file exist or not |      * @brief Check whether file exist or not | ||||||
|      * |      * | ||||||
|  | |||||||
| @ -355,6 +355,34 @@ bool file_worker_read_until_buffered( | |||||||
|     return string_size(str_result) || *file_buf_cnt; |     return string_size(str_result) || *file_buf_cnt; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool file_worker_get_value_from_key(FileWorker* file_worker, string_t key, char delimiter, string_t value) { | ||||||
|  |     bool found = false; | ||||||
|  |     string_t next_line; | ||||||
|  |     string_t next_key; | ||||||
|  |     string_init(next_line); | ||||||
|  |     string_init(next_key); | ||||||
|  |     size_t delim_pos = 0; | ||||||
|  | 
 | ||||||
|  |     while(file_worker_read_until(file_worker, next_line, '\n')) { | ||||||
|  |         delim_pos = string_search_char(next_line, delimiter); | ||||||
|  |         if(delim_pos == STRING_FAILURE) { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         string_set_n(next_key, next_line, 0, delim_pos); | ||||||
|  |         if(string_equal_p(next_key, key)) { | ||||||
|  |             string_right(next_line, delim_pos); | ||||||
|  |             string_strim(next_line); | ||||||
|  |             string_set(value, next_line); | ||||||
|  |             found = true; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     string_clear(next_line); | ||||||
|  |     string_clear(next_key); | ||||||
|  |     return found; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool file_worker_rename(FileWorker* file_worker, const char* old_path, const char* new_path) { | bool file_worker_rename(FileWorker* file_worker, const char* old_path, const char* new_path) { | ||||||
|     FS_Error fs_result = storage_common_rename(file_worker->api, old_path, new_path); |     FS_Error fs_result = storage_common_rename(file_worker->api, old_path, new_path); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -185,6 +185,17 @@ bool file_worker_read_until_buffered( | |||||||
|     size_t max_length, |     size_t max_length, | ||||||
|     char separator); |     char separator); | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Gets value from key | ||||||
|  |  * | ||||||
|  |  * @param file_worker FileWorker instance | ||||||
|  |  * @param key key | ||||||
|  |  * @param delimeter key-value delimeter | ||||||
|  |  * @param value value for given key | ||||||
|  |  * @return true on success | ||||||
|  |  */ | ||||||
|  | bool file_worker_get_value_from_key(FileWorker* file_worker, string_t key, char delimiter, string_t value); | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * @brief Check whether file exist or not |  * @brief Check whether file exist or not | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -63,6 +63,14 @@ static uint16_t emv_parse_TLV(uint8_t* dest, uint8_t* src, uint16_t* idx) { | |||||||
|     return len; |     return len; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static bool emv_decode_search_tag_u16_r(uint16_t tag, uint8_t* buff, uint16_t* idx) { | ||||||
|  |     if((buff[*idx] << 8 | buff[*idx + 1]) == tag) { | ||||||
|  |         *idx = *idx + 3; | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| uint16_t emv_prepare_select_ppse(uint8_t* dest) { | uint16_t emv_prepare_select_ppse(uint8_t* dest) { | ||||||
|     const uint8_t emv_select_ppse[] = { |     const uint8_t emv_select_ppse[] = { | ||||||
|         0x00, 0xA4, // SELECT ppse
 |         0x00, 0xA4, // SELECT ppse
 | ||||||
| @ -219,10 +227,15 @@ bool emv_decode_read_sfi_record(uint8_t* buff, uint16_t len, EmvApplication* app | |||||||
|         if(buff[i] == EMV_TAG_PAN) { |         if(buff[i] == EMV_TAG_PAN) { | ||||||
|             memcpy(app->card_number, &buff[i + 2], 8); |             memcpy(app->card_number, &buff[i + 2], 8); | ||||||
|             pan_parsed = true; |             pan_parsed = true; | ||||||
|         } else if((buff[i] << 8 | buff[i + 1]) == EMV_TAG_EXP_DATE) { |         } else if(emv_decode_search_tag_u16_r(EMV_TAG_EXP_DATE, buff, &i)) { | ||||||
|             i += 3; |  | ||||||
|             app->exp_year = buff[i++]; |             app->exp_year = buff[i++]; | ||||||
|             app->exp_month = buff[i++]; |             app->exp_month = buff[i++]; | ||||||
|  |         } else if(emv_decode_search_tag_u16_r(EMV_TAG_CURRENCY_CODE, buff, &i)) { | ||||||
|  |             app->currency_code = (buff[i] << 8) | buff[i + 1]; | ||||||
|  |             i += 2; | ||||||
|  |         } else if(emv_decode_search_tag_u16_r(EMV_TAG_COUNTRY_CODE, buff, &i)) { | ||||||
|  |             app->country_code = (buff[i] << 8) | buff[i + 1]; | ||||||
|  |             i += 2; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return pan_parsed; |     return pan_parsed; | ||||||
|  | |||||||
| @ -17,6 +17,8 @@ | |||||||
| #define EMV_TAG_PAN 0x5A | #define EMV_TAG_PAN 0x5A | ||||||
| #define EMV_TAG_AFL 0x94 | #define EMV_TAG_AFL 0x94 | ||||||
| #define EMV_TAG_EXP_DATE 0x5F24 | #define EMV_TAG_EXP_DATE 0x5F24 | ||||||
|  | #define EMV_TAG_COUNTRY_CODE 0x5F28 | ||||||
|  | #define EMV_TAG_CURRENCY_CODE 0x9F42 | ||||||
| #define EMV_TAG_CARDHOLDER_NAME 0x5F20 | #define EMV_TAG_CARDHOLDER_NAME 0x5F20 | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
| @ -39,7 +41,8 @@ typedef struct { | |||||||
|     uint8_t card_number[8]; |     uint8_t card_number[8]; | ||||||
|     uint8_t exp_month; |     uint8_t exp_month; | ||||||
|     uint8_t exp_year; |     uint8_t exp_year; | ||||||
|     char crdholder_name[32]; |     uint16_t country_code; | ||||||
|  |     uint16_t currency_code; | ||||||
|     APDU pdol; |     APDU pdol; | ||||||
|     APDU afl; |     APDU afl; | ||||||
| } EmvApplication; | } EmvApplication; | ||||||
|  | |||||||
| @ -53,3 +53,11 @@ Setting option bytes: | |||||||
| ```bash | ```bash | ||||||
| ob.py set | ob.py set | ||||||
| ``` | ``` | ||||||
|  | 
 | ||||||
|  | # Assets delivery | ||||||
|  | 
 | ||||||
|  | Run in the root folder of the repo: | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | python scripts/storage.py -p <flipper_cli_port> send assets/resources /ext | ||||||
|  | ``` | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 gornekich
						gornekich