Add tap demo

This commit is contained in:
Edith Boles
2026-03-16 01:58:49 -07:00
parent 2b15239f89
commit 371f458d9a
9 changed files with 231 additions and 86 deletions

View File

@@ -2,7 +2,7 @@
API := x11 API := x11
CFLAGS := -MD -Wall -g -lm -lpthread -ldl -I ./inc/ CFLAGS := -MD -Wall -g -lm -pthread -ldl -I ./inc/
ifeq ($(API), arm) ifeq ($(API), arm)
CC := arm-cortexa9_neon-linux-gnueabihf-gcc CC := arm-cortexa9_neon-linux-gnueabihf-gcc

View File

@@ -39,7 +39,7 @@ enum message_type {
MTYPE_SAM_CTRL_REPLY = 0xb7, MTYPE_SAM_CTRL_REPLY = 0xb7,
MTYPE_DESFIRE_READ = 0xb9, MTYPE_DESFIRE_READ = 0xb9,
MTYPE_DESFIRE_STATUS = 0xba, MTYPE_DESFIRE_STATUS = 0xba,
MTYPE_DESFIRE_STATUS_REPLY = 0xbb, MTYPE_DESFIRE_REMOVED = 0xbb,
MTYPE_DESFIRE_COMMAND = 0xbc, MTYPE_DESFIRE_COMMAND = 0xbc,
MTYPE_DESFIRE_COMMAND_REPLY = 0xbd, MTYPE_DESFIRE_COMMAND_REPLY = 0xbd,
MTYPE_UNHANDLED_CARD = 0xbe, MTYPE_UNHANDLED_CARD = 0xbe,
@@ -77,10 +77,11 @@ typedef struct cvend_packet {
const char *stringify_msg_type(uint8_t msg_type); const char *stringify_msg_type(uint8_t msg_type);
void print_packet(cvend_packet *packet); void cvend_init(const char *path);
cvend_packet *cvend_read(FILE *file); cvend_packet *cvend_read();
void cvend_write(FILE *file, uint8_t msg_type, uint8_t *msg_data, cvend_packet *cvend_read_type(uint8_t msg_type);
uint16_t msg_len); void cvend_write(uint8_t msg_type, uint8_t *msg_data, uint16_t msg_len);
void cvend_free(cvend_packet *packet); void cvend_free(cvend_packet *packet);
void print_packet(cvend_packet *packet);
#endif /* end of include guard: CVEND_H_WNGPTXM7 */ #endif /* end of include guard: CVEND_H_WNGPTXM7 */

12
inc/nfc.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef NFC_H_3196CYAP
#define NFC_H_3196CYAP
#include <stdint.h>
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 */

8
inc/pm3-lvgl.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef PM3_LVGL_H_QCB6DVLD
#define PM3_LVGL_H_QCB6DVLD
#include <pthread.h>
extern pthread_mutex_t lvgl_mutex;
#endif /* end of include guard: PM3_LVGL_H_QCB6DVLD */

View File

@@ -2,10 +2,14 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <pthread.h>
#include "crc8.h" #include "crc8.h"
#include "crc32.h" #include "crc32.h"
#include "cvend.h" #include "cvend.h"
const char *cvend_path;
FILE *file;
pthread_mutex_t cvend_mutex = PTHREAD_MUTEX_INITIALIZER;
int last_seq = 0; int last_seq = 0;
const char *stringify_msg_type(uint8_t msg_type) 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"; return "MTYPE_SECURITY_SERVICES_REPLY";
case MTYPE_DESFIRE_STATUS: case MTYPE_DESFIRE_STATUS:
return "MTYPE_DESFIRE_STATUS"; return "MTYPE_DESFIRE_STATUS";
case MTYPE_DESFIRE_STATUS_REPLY: case MTYPE_DESFIRE_REMOVED:
return "MTYPE_DESFIRE_STATUS_REPLY"; return "MTYPE_DESFIRE_REMOVED";
case MTYPE_DESFIRE_COMMAND: case MTYPE_DESFIRE_COMMAND:
return "MTYPE_DESFIRE_COMMAND"; return "MTYPE_DESFIRE_COMMAND";
case MTYPE_DESFIRE_COMMAND_REPLY: 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) void calc_hdr_crc(cvend_packet *packet)
{ {
packet->magic = 0xbc; packet->magic = 0xbc;
@@ -125,6 +128,98 @@ void calc_msg_crc(cvend_packet *packet)
packet->msg_crc = 0; 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) void print_packet(cvend_packet *packet)
{ {
printf("seq = %u\n", packet->seq); printf("seq = %u\n", packet->seq);
@@ -143,64 +238,3 @@ void print_packet(cvend_packet *packet)
printf("\n"); printf("\n");
printf("msg_crc = %u\n\n", packet->msg_crc); 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);
}

View File

@@ -2,7 +2,7 @@
int main(int argc, char *argv[]) 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_enable[] = { 0x00, CTYPE_DESFIRE, 0x01, FUNC_ENABLE };
// uint8_t desfire_get_version[] = { 0x60 }; // uint8_t desfire_get_version[] = { 0x60 };
uint8_t desfire_select_application[] = { 0x5a, 0xF2, 0x10, 0xE0 }; 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_read[] = { 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t desfire_free[] = { 0x6e }; 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) { while (1) {
cvend_packet *packet; cvend_packet *packet;
do { packet = cvend_read();
packet = cvend_read(file);
} while (!packet);
if (packet->msg_type != MTYPE_HEARTBEAT) // if (packet->msg_type != MTYPE_HEARTBEAT)
print_packet(packet); print_packet(packet);
if (packet->msg_type == MTYPE_DESFIRE_READ) { if (packet->msg_type == MTYPE_DESFIRE_READ) {
//cvend_write(file, MTYPE_DESFIRE_INTERACT, desfire_get_version, 1); //cvend_write(MTYPE_DESFIRE_INTERACT, desfire_get_version, 1);
cvend_write(file, MTYPE_DESFIRE_COMMAND, desfire_select_application, 4); cvend_write(MTYPE_DESFIRE_COMMAND, desfire_select_application, 4);
cvend_packet *response; cvend_packet *response;
do { do {
response = cvend_read(file); response = cvend_read();
} while (!response); } while (!response);
print_packet(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_free(response);
cvend_write(file, MTYPE_DESFIRE_COMMAND, desfire_read, 8); cvend_write(MTYPE_DESFIRE_COMMAND, desfire_read, 8);
cvend_write(file, MTYPE_DESFIRE_COMMAND, desfire_free, 1); cvend_write(MTYPE_DESFIRE_COMMAND, desfire_free, 1);
} }
cvend_free(packet); cvend_free(packet);
} }
fclose(file);
return 0; return 0;
} }

68
src/nfc.c Normal file
View File

@@ -0,0 +1,68 @@
#include "cvend.h"
#include <stdint.h>
#include <unistd.h>
#include <pthread.h>
#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;
}

View File

@@ -3,10 +3,17 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include "screen.h" #include "screen.h"
#include "pm3-lvgl.h"
#ifdef LV_TARGET_FB
#include "nfc.h"
#endif
lv_display_t *display; lv_display_t *display;
uint32_t idle_time; uint32_t idle_time;
pthread_mutex_t lvgl_mutex = PTHREAD_MUTEX_INITIALIZER;
ma_result result; ma_result result;
ma_engine engine; 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()); lv_key_t key = lv_indev_get_key(lv_indev_active());
printf("%u\n", key); printf("%u\n", key);
pthread_mutex_lock(&lvgl_mutex);
screen_response("Valid until 1:09pm", "$2.50", 0, 2000); 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); ma_engine_play_sound(&engine, "assets/hop_adult.wav", NULL);
} }
@@ -29,6 +47,10 @@ int main(int argc, char *argv[])
#ifdef LV_TARGET_FB #ifdef LV_TARGET_FB
display = lv_linux_fbdev_create(); display = lv_linux_fbdev_create();
lv_linux_fbdev_set_file(display, "/dev/fb0"); 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 #else
display = lv_x11_window_create("LVGL X11 Simulation", 800, 480); display = lv_x11_window_create("LVGL X11 Simulation", 800, 480);
lv_obj_remove_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE); lv_obj_remove_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);
@@ -42,7 +64,9 @@ int main(int argc, char *argv[])
while (true) { while (true) {
/* Returns the time to the next timer execution */ /* Returns the time to the next timer execution */
pthread_mutex_lock(&lvgl_mutex);
idle_time = lv_timer_handler(); idle_time = lv_timer_handler();
pthread_mutex_unlock(&lvgl_mutex);
usleep(idle_time * 1000); usleep(idle_time * 1000);
} }
} }

View File

@@ -208,14 +208,14 @@ void screen_create(lv_obj_t *screen)
lv_label_set_text(label_date, "01-01-99"); 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_font(label_date, &dejavu_28, 0);
lv_obj_set_style_text_color(label_date, WHITE, 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 // time in bottom right
label_time = lv_label_create(screen); label_time = lv_label_create(screen);
lv_label_set_text(label_time, "12:59 a.m."); 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_font(label_time, &dejavu_28, 0);
lv_obj_set_style_text_color(label_time, WHITE, 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 // scan response large
label_reply_big = lv_label_create(screen); label_reply_big = lv_label_create(screen);