From 371f458d9a1803571de37c2c131c52f745bde4d4 Mon Sep 17 00:00:00 2001 From: Edith Boles Date: Mon, 16 Mar 2026 01:58:49 -0700 Subject: [PATCH] Add tap demo --- Makefile | 2 +- inc/cvend.h | 11 ++-- inc/nfc.h | 12 ++++ inc/pm3-lvgl.h | 8 +++ src/cvend.c | 162 ++++++++++++++++++++++++++++------------------- src/cvend_test.c | 26 ++++---- src/nfc.c | 68 ++++++++++++++++++++ src/pm3-lvgl.c | 24 +++++++ src/screen.c | 4 +- 9 files changed, 231 insertions(+), 86 deletions(-) create mode 100644 inc/nfc.h create mode 100644 inc/pm3-lvgl.h create mode 100644 src/nfc.c diff --git a/Makefile b/Makefile index ecbb347..f2a0af3 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ API := x11 -CFLAGS := -MD -Wall -g -lm -lpthread -ldl -I ./inc/ +CFLAGS := -MD -Wall -g -lm -pthread -ldl -I ./inc/ ifeq ($(API), arm) CC := arm-cortexa9_neon-linux-gnueabihf-gcc diff --git a/inc/cvend.h b/inc/cvend.h index 991a7db..5a58425 100644 --- a/inc/cvend.h +++ b/inc/cvend.h @@ -39,7 +39,7 @@ enum message_type { MTYPE_SAM_CTRL_REPLY = 0xb7, MTYPE_DESFIRE_READ = 0xb9, MTYPE_DESFIRE_STATUS = 0xba, - MTYPE_DESFIRE_STATUS_REPLY = 0xbb, + MTYPE_DESFIRE_REMOVED = 0xbb, MTYPE_DESFIRE_COMMAND = 0xbc, MTYPE_DESFIRE_COMMAND_REPLY = 0xbd, MTYPE_UNHANDLED_CARD = 0xbe, @@ -77,10 +77,11 @@ typedef struct cvend_packet { const char *stringify_msg_type(uint8_t msg_type); -void print_packet(cvend_packet *packet); -cvend_packet *cvend_read(FILE *file); -void cvend_write(FILE *file, uint8_t msg_type, uint8_t *msg_data, - uint16_t msg_len); +void cvend_init(const char *path); +cvend_packet *cvend_read(); +cvend_packet *cvend_read_type(uint8_t msg_type); +void cvend_write(uint8_t msg_type, uint8_t *msg_data, uint16_t msg_len); void cvend_free(cvend_packet *packet); +void print_packet(cvend_packet *packet); #endif /* end of include guard: CVEND_H_WNGPTXM7 */ diff --git a/inc/nfc.h b/inc/nfc.h new file mode 100644 index 0000000..21babbc --- /dev/null +++ b/inc/nfc.h @@ -0,0 +1,12 @@ +#ifndef NFC_H_3196CYAP +#define NFC_H_3196CYAP + +#include + +typedef void (*nfc_cb)(uint8_t status, uint8_t *version, uint16_t version_size, + uint8_t *data, uint16_t data_size); + +void nfc_init(const char *path); +void *nfc_handle(void *data); + +#endif /* end of include guard: NFC_H_3196CYAP */ diff --git a/inc/pm3-lvgl.h b/inc/pm3-lvgl.h new file mode 100644 index 0000000..b91523c --- /dev/null +++ b/inc/pm3-lvgl.h @@ -0,0 +1,8 @@ +#ifndef PM3_LVGL_H_QCB6DVLD +#define PM3_LVGL_H_QCB6DVLD + +#include + +extern pthread_mutex_t lvgl_mutex; + +#endif /* end of include guard: PM3_LVGL_H_QCB6DVLD */ diff --git a/src/cvend.c b/src/cvend.c index cdb2032..4685887 100644 --- a/src/cvend.c +++ b/src/cvend.c @@ -2,10 +2,14 @@ #include #include #include +#include #include "crc8.h" #include "crc32.h" #include "cvend.h" +const char *cvend_path; +FILE *file; +pthread_mutex_t cvend_mutex = PTHREAD_MUTEX_INITIALIZER; int last_seq = 0; const char *stringify_msg_type(uint8_t msg_type) @@ -95,8 +99,8 @@ const char *stringify_msg_type(uint8_t msg_type) return "MTYPE_SECURITY_SERVICES_REPLY"; case MTYPE_DESFIRE_STATUS: return "MTYPE_DESFIRE_STATUS"; - case MTYPE_DESFIRE_STATUS_REPLY: - return "MTYPE_DESFIRE_STATUS_REPLY"; + case MTYPE_DESFIRE_REMOVED: + return "MTYPE_DESFIRE_REMOVED"; case MTYPE_DESFIRE_COMMAND: return "MTYPE_DESFIRE_COMMAND"; case MTYPE_DESFIRE_COMMAND_REPLY: @@ -108,7 +112,6 @@ const char *stringify_msg_type(uint8_t msg_type) } } - void calc_hdr_crc(cvend_packet *packet) { packet->magic = 0xbc; @@ -125,6 +128,98 @@ void calc_msg_crc(cvend_packet *packet) packet->msg_crc = 0; } +void cvend_init(const char *path) +{ + cvend_path = path; + file = fopen(path, "wb+"); +} + +cvend_packet *cvend_read() +{ + pthread_mutex_lock(&cvend_mutex); + uint8_t buf = 0x00; + uint8_t res = 0; + while (buf != 0xbc) { + res = fread(&buf, 1, 1, file); + if (res == 0) { + fclose(file); + file = fopen(cvend_path, "wb+"); + } + if (buf != 0xbc) { + printf("bad magic char: %x\n", buf); + } + } + + cvend_packet *packet = malloc(sizeof(cvend_packet)); + fread(&packet->seq, 1, 1, file); + fread(&packet->flags, 1, 1, file); + fread(&packet->msg_type, 1, 1, file); + fread((uint8_t *)&packet->msg_len + 1, 1, 1, file); + fread(&packet->msg_len, 1, 1, file); + fread(&packet->hdr_crc, 1, 1, file); + + packet->msg_data = malloc(packet->msg_len); + fread(packet->msg_data, 1, packet->msg_len, file); + if (packet->msg_type & 0x80) + fread(&packet->msg_crc, 1, 4, file); + else + packet->msg_crc = 0; + pthread_mutex_unlock(&cvend_mutex); + + if (packet->msg_type != MTYPE_HEARTBEAT) { + printf("RECEIVED:\n"); + print_packet(packet); + } + return packet; +} + +cvend_packet *cvend_read_type(uint8_t msg_type) +{ + cvend_packet *packet = NULL; + do { + if (packet) + cvend_free(packet); + packet = cvend_read(); + } while (packet->msg_type != msg_type); + return packet; +} + +void cvend_write(uint8_t msg_type, uint8_t *msg_data, + uint16_t msg_len) +{ + pthread_mutex_lock(&cvend_mutex); + cvend_packet packet; + packet.seq = ++last_seq; + packet.flags = 0; + packet.msg_type = msg_type; + packet.msg_data = msg_data; + packet.msg_len = msg_len; + calc_hdr_crc(&packet); + calc_msg_crc(&packet); + + int res = fwrite(&packet.magic, 1, 1, file); + printf("wrote %i\n", res); + fwrite(&packet.seq, 1, 1, file); + fwrite(&packet.flags, 1, 1, file); + fwrite(&packet.msg_type, 1, 1, file); + fwrite((uint8_t *)&packet.msg_len + 1, 1, 1, file); + fwrite(&packet.msg_len, 1, 1, file); + fwrite(&packet.hdr_crc, 1, 1, file); + fwrite(packet.msg_data, 1, packet.msg_len, file); + if (packet.msg_type & 0x80) + fwrite(&packet.msg_crc, 1, 4, file); + + pthread_mutex_unlock(&cvend_mutex); + printf("SENT:\n"); + print_packet(&packet); +} + +void cvend_free(cvend_packet *packet) +{ + free(packet->msg_data); + free(packet); +} + void print_packet(cvend_packet *packet) { printf("seq = %u\n", packet->seq); @@ -143,64 +238,3 @@ void print_packet(cvend_packet *packet) printf("\n"); printf("msg_crc = %u\n\n", packet->msg_crc); } - -cvend_packet *cvend_read(FILE *file) -{ - uint8_t buf; - fread(&buf, 1, 1, file); - if (buf != 0xbc) { - printf("failed: %x\n", buf); - exit(1); - return NULL; - } - - cvend_packet *packet = malloc(sizeof(cvend_packet)); - fread(&packet->seq, 1, 1, file); - fread(&packet->flags, 1, 1, file); - fread(&packet->msg_type, 1, 1, file); - fread((uint8_t *)&packet->msg_len + 1, 1, 1, file); - fread(&packet->msg_len, 1, 1, file); - fread(&packet->hdr_crc, 1, 1, file); - - packet->msg_data = malloc(packet->msg_len); - fread(packet->msg_data, 1, packet->msg_len, file); - if (packet->msg_type & 0x80) - fread(&packet->msg_crc, 1, 4, file); - else - packet->msg_crc = 0; - - return packet; -} - -void cvend_write(FILE *file, uint8_t msg_type, uint8_t *msg_data, - uint16_t msg_len) -{ - cvend_packet packet; - packet.seq = ++last_seq; - packet.flags = 0; - packet.msg_type = msg_type; - packet.msg_data = msg_data; - packet.msg_len = msg_len; - calc_hdr_crc(&packet); - calc_msg_crc(&packet); - - fwrite(&packet.magic, 1, 1, file); - fwrite(&packet.seq, 1, 1, file); - fwrite(&packet.flags, 1, 1, file); - fwrite(&packet.msg_type, 1, 1, file); - fwrite((uint8_t *)&packet.msg_len + 1, 1, 1, file); - fwrite(&packet.msg_len, 1, 1, file); - fwrite(&packet.hdr_crc, 1, 1, file); - fwrite(packet.msg_data, 1, packet.msg_len, file); - if (packet.msg_type & 0x80) - fwrite(&packet.msg_crc, 1, 4, file); - - fflush(file); - print_packet(&packet); -} - -void cvend_free(cvend_packet *packet) -{ - free(packet->msg_data); - free(packet); -} diff --git a/src/cvend_test.c b/src/cvend_test.c index ad71b52..8609750 100644 --- a/src/cvend_test.c +++ b/src/cvend_test.c @@ -2,7 +2,7 @@ int main(int argc, char *argv[]) { - FILE *file = fopen(argc > 1 ? argv[1] : "/dev/ttymxc3", "w+"); + char *file = argc > 1 ? argv[1] : "/dev/ttymxc3"; uint8_t desfire_enable[] = { 0x00, CTYPE_DESFIRE, 0x01, FUNC_ENABLE }; // uint8_t desfire_get_version[] = { 0x60 }; uint8_t desfire_select_application[] = { 0x5a, 0xF2, 0x10, 0xE0 }; @@ -10,33 +10,31 @@ int main(int argc, char *argv[]) uint8_t desfire_read[] = { 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t desfire_free[] = { 0x6e }; - cvend_write(file, MTYPE_PROX_CARD_FUNCTION, desfire_enable, 4); + cvend_init(file); + cvend_write(MTYPE_PROX_CARD_FUNCTION, desfire_enable, 4); while (1) { cvend_packet *packet; - do { - packet = cvend_read(file); - } while (!packet); + packet = cvend_read(); - if (packet->msg_type != MTYPE_HEARTBEAT) - print_packet(packet); + // if (packet->msg_type != MTYPE_HEARTBEAT) + print_packet(packet); if (packet->msg_type == MTYPE_DESFIRE_READ) { - //cvend_write(file, MTYPE_DESFIRE_INTERACT, desfire_get_version, 1); - cvend_write(file, MTYPE_DESFIRE_COMMAND, desfire_select_application, 4); + //cvend_write(MTYPE_DESFIRE_INTERACT, desfire_get_version, 1); + cvend_write(MTYPE_DESFIRE_COMMAND, desfire_select_application, 4); cvend_packet *response; do { - response = cvend_read(file); + response = cvend_read(); } while (!response); print_packet(response); - cvend_write(file, MTYPE_DESFIRE_COMMAND, desfire_fid_list, 1); + cvend_write(MTYPE_DESFIRE_COMMAND, desfire_fid_list, 1); cvend_free(response); - cvend_write(file, MTYPE_DESFIRE_COMMAND, desfire_read, 8); - cvend_write(file, MTYPE_DESFIRE_COMMAND, desfire_free, 1); + cvend_write(MTYPE_DESFIRE_COMMAND, desfire_read, 8); + cvend_write(MTYPE_DESFIRE_COMMAND, desfire_free, 1); } cvend_free(packet); } - fclose(file); return 0; } diff --git a/src/nfc.c b/src/nfc.c new file mode 100644 index 0000000..d1291e0 --- /dev/null +++ b/src/nfc.c @@ -0,0 +1,68 @@ +#include "cvend.h" +#include +#include +#include +#include "nfc.h" + +void nfc_init(const char *path) +{ + uint8_t desfire_enable[] = { 0x00, CTYPE_DESFIRE, 0x01, FUNC_ENABLE }; + + cvend_init(path); + cvend_write(MTYPE_PROX_CARD_FUNCTION, desfire_enable, 4); +} + +void *nfc_heartbeat(void *data) +{ + uint8_t heartbeat[2] = { 0x00, 0x00 }; + while (1) { + cvend_write(MTYPE_STATUS, heartbeat, 2); + sleep(10); + } + return NULL; +} + +void *nfc_handle(void *data) +{ + pthread_t heartbeat_thread; + pthread_create(&heartbeat_thread, NULL, nfc_heartbeat, NULL); + nfc_cb callback = data; + uint8_t desfire_select_application[] = { 0x5a, 0xF2, 0x10, 0xE0 }; + // uint8_t desfire_fid_list[] = { 0xf5, 0x00 }; + uint8_t desfire_get_version[] = { 0x60 }; + uint8_t desfire_read[] = { 0xbd, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; + while (1) { + cvend_packet *packet = cvend_read(); + + if (packet->msg_type != MTYPE_DESFIRE_READ) { + cvend_free(packet); + continue; + } + cvend_free(packet); + + cvend_write(MTYPE_DESFIRE_COMMAND, + desfire_select_application, 4); + cvend_free(cvend_read_type(MTYPE_DESFIRE_COMMAND_REPLY)); + + cvend_write(MTYPE_DESFIRE_COMMAND, desfire_get_version, + 1); + cvend_packet *resp_version = + cvend_read_type(MTYPE_DESFIRE_COMMAND_REPLY); + + if (resp_version->msg_len == 2 && resp_version->msg_data[1] == 0x6e) { + cvend_free(resp_version); + continue; + } + + cvend_write(MTYPE_DESFIRE_COMMAND, desfire_read, 8); + cvend_packet *resp_data = + cvend_read_type(MTYPE_DESFIRE_COMMAND_REPLY); + callback(resp_data->msg_data[0], resp_version->msg_data, + resp_version->msg_len, resp_data->msg_data, + resp_version->msg_len); + cvend_free(resp_version); + cvend_free(resp_data); + } + return NULL; +} diff --git a/src/pm3-lvgl.c b/src/pm3-lvgl.c index b46a65c..5855466 100644 --- a/src/pm3-lvgl.c +++ b/src/pm3-lvgl.c @@ -3,10 +3,17 @@ #include #include #include "screen.h" +#include "pm3-lvgl.h" + +#ifdef LV_TARGET_FB +#include "nfc.h" +#endif lv_display_t *display; uint32_t idle_time; +pthread_mutex_t lvgl_mutex = PTHREAD_MUTEX_INITIALIZER; + ma_result result; ma_engine engine; @@ -14,7 +21,18 @@ void key_pressed(lv_event_t *event) { lv_key_t key = lv_indev_get_key(lv_indev_active()); printf("%u\n", key); + pthread_mutex_lock(&lvgl_mutex); screen_response("Valid until 1:09pm", "$2.50", 0, 2000); + pthread_mutex_unlock(&lvgl_mutex); + ma_engine_play_sound(&engine, "assets/hop_adult.wav", NULL); +} + +void read_card(uint8_t status, uint8_t *version, uint16_t version_size, + uint8_t *data, uint16_t data_size) +{ + pthread_mutex_lock(&lvgl_mutex); + screen_response("Valid until 1:09pm", "$2.50", 0, 2000); + pthread_mutex_unlock(&lvgl_mutex); ma_engine_play_sound(&engine, "assets/hop_adult.wav", NULL); } @@ -29,6 +47,10 @@ int main(int argc, char *argv[]) #ifdef LV_TARGET_FB display = lv_linux_fbdev_create(); lv_linux_fbdev_set_file(display, "/dev/fb0"); + + pthread_t nfc_thread; + nfc_init("/dev/ttymxc3"); + pthread_create(&nfc_thread, NULL, nfc_handle, read_card); #else display = lv_x11_window_create("LVGL X11 Simulation", 800, 480); lv_obj_remove_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE); @@ -42,7 +64,9 @@ int main(int argc, char *argv[]) while (true) { /* Returns the time to the next timer execution */ + pthread_mutex_lock(&lvgl_mutex); idle_time = lv_timer_handler(); + pthread_mutex_unlock(&lvgl_mutex); usleep(idle_time * 1000); } } diff --git a/src/screen.c b/src/screen.c index d6a403a..44db653 100644 --- a/src/screen.c +++ b/src/screen.c @@ -208,14 +208,14 @@ void screen_create(lv_obj_t *screen) lv_label_set_text(label_date, "01-01-99"); lv_obj_set_style_text_font(label_date, &dejavu_28, 0); lv_obj_set_style_text_color(label_date, WHITE, 0); - lv_obj_align(label_date, LV_ALIGN_CENTER, -305, 226); + lv_obj_align(label_date, LV_ALIGN_CENTER, -265, 226); // time in bottom right label_time = lv_label_create(screen); lv_label_set_text(label_time, "12:59 a.m."); lv_obj_set_style_text_font(label_time, &dejavu_28, 0); lv_obj_set_style_text_color(label_time, WHITE, 0); - lv_obj_align(label_time, LV_ALIGN_CENTER, 305, 226); + lv_obj_align(label_time, LV_ALIGN_CENTER, 265, 226); // scan response large label_reply_big = lv_label_create(screen);