| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- // Creator: Hummus@FlipperGang
- #include "../mag_i.h"
- #include "../helpers/mag_helpers.h"
- #include "mag_scene_read.h"
- #define TAG "MagSceneRead"
- void uart_callback(FuriHalSerialHandle* handle, FuriHalSerialRxEvent event, void* context) {
- Mag* mag = context;
- if(event == FuriHalSerialRxEventData) {
- uint8_t data = furi_hal_serial_async_rx(handle);
- furi_stream_buffer_send(mag->uart_rx_stream, &data, 1, 0);
- furi_thread_flags_set(furi_thread_get_id(mag->uart_rx_thread), WorkerEvtRxDone);
- }
- }
- static int32_t uart_worker(void* context) {
- Mag* mag = context;
- mag->uart_rx_stream = furi_stream_buffer_alloc(UART_RX_BUF_SIZE, 1);
- mag->uart_text_box_store_strlen = 0;
- while(1) {
- uint32_t events =
- furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
- // furi_check((events & FuriFlagError) == 0);
- if(events & WorkerEvtStop) break;
- if(events & WorkerEvtRxDone) {
- FURI_LOG_D(TAG, "WorkerEvtRxDone");
- // notification_message(mag->notifications, &sequence_success);
- size_t len = furi_stream_buffer_receive(
- mag->uart_rx_stream, mag->uart_rx_buf, UART_RX_BUF_SIZE, 200);
- FURI_LOG_D(TAG, "UART RX len: %d", len);
- if(len > 0) {
- // If text box store gets too big, then truncate it
- mag->uart_text_box_store_strlen += len;
- if(mag->uart_text_box_store_strlen >= UART_TERMINAL_TEXT_BOX_STORE_SIZE - 1) {
- furi_string_right(
- mag->uart_text_box_store, mag->uart_text_box_store_strlen / 2);
- mag->uart_text_box_store_strlen =
- furi_string_size(mag->uart_text_box_store) + len;
- }
- // Add '\0' to the end of the string, and then add the new data
- mag->uart_rx_buf[len] = '\0';
- furi_string_cat_printf(mag->uart_text_box_store, "%s", mag->uart_rx_buf);
- FURI_LOG_D(TAG, "UART RX buf: %*.s", len, mag->uart_rx_buf);
- FURI_LOG_D(
- TAG, "UART RX store: %s", furi_string_get_cstr(mag->uart_text_box_store));
- }
- FURI_LOG_D(TAG, "UARTEventRxData");
- view_dispatcher_send_custom_event(mag->view_dispatcher, UARTEventRxData);
- }
- }
- furi_stream_buffer_free(mag->uart_rx_stream);
- return 0;
- }
- void update_widgets(Mag* mag) {
- // Clear widget from all elements
- widget_reset(mag->widget);
- // Titlebar
- widget_add_icon_element(mag->widget, 38, -1, &I_mag_file_10px);
- widget_add_string_element(mag->widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "READ");
- widget_add_icon_element(mag->widget, 81, -1, &I_mag_file_10px);
- // Text box
- widget_add_text_scroll_element(
- mag->widget, 0, 10, 128, 40, furi_string_get_cstr(mag->uart_text_box_store));
- // Buttons
- widget_add_button_element(mag->widget, GuiButtonTypeLeft, "Clear", mag_widget_callback, mag);
- widget_add_button_element(mag->widget, GuiButtonTypeRight, "Parse", mag_widget_callback, mag);
- }
- void mag_scene_read_on_enter(void* context) {
- Mag* mag = context;
- FuriString* message = furi_string_alloc();
- furi_string_printf(message, "Please swipe a card!\n");
- mag->uart_text_box_store = message;
- view_dispatcher_switch_to_view(mag->view_dispatcher, MagViewWidget);
- update_widgets(mag);
- // Initialize UART
- mag->serial_handle = furi_hal_serial_control_acquire(FuriHalSerialIdUsart);
- furi_check(mag->serial_handle);
- furi_hal_serial_init(mag->serial_handle, 9600);
- furi_hal_serial_async_rx_start(mag->serial_handle, uart_callback, mag, false);
- FURI_LOG_D(TAG, "UART initialized");
- mag->uart_rx_thread = furi_thread_alloc();
- furi_thread_set_name(mag->uart_rx_thread, "UartRx");
- furi_thread_set_stack_size(mag->uart_rx_thread, 1024);
- furi_thread_set_context(mag->uart_rx_thread, mag);
- furi_thread_set_callback(mag->uart_rx_thread, uart_worker);
- furi_thread_start(mag->uart_rx_thread);
- FURI_LOG_D(TAG, "UART worker started");
- }
- bool mag_scene_read_on_event(void* context, SceneManagerEvent event) {
- Mag* mag = context;
- bool consumed = false;
- if(event.type == SceneManagerEventTypeCustom) {
- FURI_LOG_D(TAG, "Custom event: %ld", event.event);
- switch(event.event) {
- case GuiButtonTypeLeft: // Clear
- consumed = true;
- // Clear text box store
- furi_string_reset(mag->uart_text_box_store);
- mag->uart_text_box_store_strlen = 0;
- break;
- case GuiButtonTypeRight: // Parse
- consumed = true;
- FURI_LOG_D(TAG, "Trying to parse");
- MagDevice* mag_dev = mag->mag_dev;
- bool res = mag_device_parse_card_string(mag_dev, mag->uart_text_box_store);
- furi_string_reset(mag->uart_text_box_store);
- if(res) {
- notification_message(mag->notifications, &sequence_success);
- furi_string_printf(
- mag->uart_text_box_store,
- "Track 1: %.*s\nTrack 2: %.*s\nTrack 3: %.*s",
- mag_dev->dev_data.track[0].len,
- furi_string_get_cstr(mag_dev->dev_data.track[0].str),
- mag_dev->dev_data.track[1].len,
- furi_string_get_cstr(mag_dev->dev_data.track[1].str),
- mag_dev->dev_data.track[2].len,
- furi_string_get_cstr(mag_dev->dev_data.track[2].str));
- // Switch to saved menu scene
- scene_manager_next_scene(mag->scene_manager, MagSceneSavedMenu);
- } else {
- furi_string_printf(mag->uart_text_box_store, "Failed to parse! Try again\n");
- notification_message(mag->notifications, &sequence_error);
- }
- break;
- }
- update_widgets(mag);
- }
- return consumed;
- }
- void mag_scene_read_on_exit(void* context) {
- Mag* mag = context;
- // notification_message(mag->notifications, &sequence_blink_stop);
- widget_reset(mag->widget);
- // view_dispatcher_remove_view(mag->view_dispatcher, MagViewWidget);
- // Stop UART worker
- FURI_LOG_D(TAG, "Stopping UART worker");
- furi_thread_flags_set(furi_thread_get_id(mag->uart_rx_thread), WorkerEvtStop);
- furi_thread_join(mag->uart_rx_thread);
- furi_thread_free(mag->uart_rx_thread);
- FURI_LOG_D(TAG, "UART worker stopped");
- furi_string_free(mag->uart_text_box_store);
- furi_hal_serial_deinit(mag->serial_handle);
- furi_hal_serial_control_release(mag->serial_handle);
- notification_message(mag->notifications, &sequence_blink_stop);
- }
|