MX 2 anni fa
parent
commit
8f041019c4

+ 27 - 8
non_catalog_apps/uhf_rfid/README.md

@@ -1,19 +1,35 @@
 # [UHF]RFID App for FlipperZero
 # [UHF]RFID App for FlipperZero
 
 
-![FlipperZero](assets/img/uhf_demo_app2.jpg)
+<div style="
+display: flex;
+flex-direction: row;
+justify-content: space-evenly;
+align-items: center;
+">
+  <img style="
+    width: 350px;"
+    src="assets/img/uhf_demo_app2.jpg">
+  <img style="
+    border-radius: 10px;
+    width: 400px;"
+  src="assets/img/uhf_demo_app.jpg">
+</div>
 
 
 ## Overview
 ## Overview
 
 
 This repository contains a UHF RFID application developed for FlipperZero, a versatile multi-tool device. The app leverages the YRM100 module to enable UHF RFID functionality.
 This repository contains a UHF RFID application developed for FlipperZero, a versatile multi-tool device. The app leverages the YRM100 module to enable UHF RFID functionality.
 
 
+## What's Ongoing
+
+Working on the settings page to allow for changing of the module's settings.
+Adding options like settings the access password, baud rate, rf power, channel, etc.
+
 ## What's Changed
 ## What's Changed
 
 
-- A complete refractor from the concept code to covert to a framework. So that it's easy to refractor for different possible module's. See [module.h](uhf_module.h) for more info.
-- Reading bank now can automatically detect bank size, for cases that PC(protocol control) bits aren't properly written to tag.
-- Can now view tag from saved.
-- Can now write tags from saved.
-- Icon added by [@xMasterX](https://github.com/xMasterX)
-- App is now named `[(Q)M100] UHF RFID`, meaning for M100 and QM100 modules
+- Added a settings page to allow for changing of the module's settings.
+- Added options like baud rate, rf power, region; more to come.
+- Tx communication is much more stable and faster now; more improvements to come.
+- Bug fixes and improvements.
 
 
 ## Features
 ## Features
 
 
@@ -21,10 +37,13 @@ This repository contains a UHF RFID application developed for FlipperZero, a ver
 - [x] View saved UHF RFID tag.
 - [x] View saved UHF RFID tag.
 - [x] Write Single UHF RFID tag.
 - [x] Write Single UHF RFID tag.
 - [ ] Change Module setting parameters. **(In Progress)**
 - [ ] Change Module setting parameters. **(In Progress)**
+  - [x] Set Baudrates 
   - [ ] Set/Reset Access Password
   - [ ] Set/Reset Access Password
   - [ ] Set Kill Password
   - [ ] Set Kill Password
   - [ ] Kill Tag
   - [ ] Kill Tag
-  - [ ] TBD
+  - [x] Set RF Power
+  - [x] Set Region
+
 - [ ] Edit/Create new data to write.
 - [ ] Edit/Create new data to write.
 - Extras
 - Extras
   - [ ] Read multiple tags at once
   - [ ] Read multiple tags at once

+ 1 - 1
non_catalog_apps/uhf_rfid/application.fam

@@ -8,7 +8,7 @@ App(
         "storage",
         "storage",
         "gui",
         "gui",
     ],
     ],
-    stack_size=4 * 1024,
+    stack_size=8 * 1024,
     order=30,
     order=30,
     fap_icon="icons/uhf_10px.png",
     fap_icon="icons/uhf_10px.png",
     fap_category="RFID",
     fap_category="RFID",

+ 1 - 0
non_catalog_apps/uhf_rfid/scenes/uhf_scene_config.h

@@ -12,6 +12,7 @@ ADD_SCENE(uhf, delete, Delete)
 ADD_SCENE(uhf, delete_success, DeleteSuccess)
 ADD_SCENE(uhf, delete_success, DeleteSuccess)
 ADD_SCENE(uhf, write_tag, WriteTag)
 ADD_SCENE(uhf, write_tag, WriteTag)
 ADD_SCENE(uhf, write_tag_success, WriteTagSuccess)
 ADD_SCENE(uhf, write_tag_success, WriteTagSuccess)
+ADD_SCENE(uhf, settings, Settings)
 // ADD_SCENE(uhf, read_factory_success, ReadFactorySuccess)
 // ADD_SCENE(uhf, read_factory_success, ReadFactorySuccess)
 // ADD_SCENE(uhf, write_key, WriteKey)
 // ADD_SCENE(uhf, write_key, WriteKey)
 // ADD_SCENE(uhf, key_menu, KeyMenu)
 // ADD_SCENE(uhf, key_menu, KeyMenu)

+ 0 - 3
non_catalog_apps/uhf_rfid/scenes/uhf_scene_read_tag.c

@@ -6,9 +6,6 @@ void uhf_read_tag_worker_callback(UHFWorkerEvent event, void* ctx) {
     if(event == UHFWorkerEventSuccess) {
     if(event == UHFWorkerEventSuccess) {
         view_dispatcher_send_custom_event(uhf_app->view_dispatcher, UHFCustomEventWorkerExit);
         view_dispatcher_send_custom_event(uhf_app->view_dispatcher, UHFCustomEventWorkerExit);
     }
     }
-    // } else if(event == UHFWorkerEventAborted) {
-    //     scene_manager_search_and_switch_to_previous_scene(uhf_app->scene_manager, UHFSceneStart);
-    // }
 }
 }
 
 
 void uhf_scene_read_tag_on_enter(void* ctx) {
 void uhf_scene_read_tag_on_enter(void* ctx) {

+ 122 - 0
non_catalog_apps/uhf_rfid/scenes/uhf_scene_settings.c

@@ -0,0 +1,122 @@
+#include "../uhf_app_i.h"
+#include "../uhf_module.h"
+
+void uhf_settings_set_module_baudrate(VariableItem* item) {
+    M100Module* uhf_module = variable_item_get_context(item);
+    uint8_t index = variable_item_get_current_value_index(item);
+    if(index >= BAUD_RATES_COUNT) {
+        return;
+    }
+    uint32_t baudrate = BAUD_RATES[index];
+    m100_set_baudrate(uhf_module, baudrate);
+    char text_buf[10];
+    snprintf(text_buf, sizeof(text_buf), "%lu", uhf_module->baudrate);
+    variable_item_set_current_value_text(item, text_buf);
+}
+
+void uhf_settings_set_module_powerdb(VariableItem* item) {
+    M100Module* uhf_module = variable_item_get_context(item);
+    uint8_t index = variable_item_get_current_value_index(item);
+    if(index >= POWER_DBM_COUNT) {
+        return;
+    }
+    uint16_t power = POWER_DBM[index];
+    m100_set_transmitting_power(uhf_module, power);
+    char text_buf[10];
+    snprintf(text_buf, sizeof(text_buf), "%ddBm", uhf_module->transmitting_power);
+    variable_item_set_current_value_text(item, text_buf);
+}
+
+void uhf_settings_set_module_working_region(VariableItem* item) {
+    M100Module* uhf_module = variable_item_get_context(item);
+    uint8_t index = variable_item_get_current_value_index(item);
+    if(index >= WORKING_REGIONS_COUNT) {
+        return;
+    }
+    WorkingRegion region = WORKING_REGIONS[index];
+    m100_set_working_region(uhf_module, region);
+    variable_item_set_current_value_text(item, WORKING_REGIONS_STR[index]);
+}
+
+uint8_t uhf_settings_get_module_baudrate_index(M100Module* module) {
+    for(uint8_t i = 0; i < BAUD_RATES_COUNT; i++) {
+        if(BAUD_RATES[i] == module->baudrate) {
+            return i;
+        }
+    }
+    return 0;
+}
+
+uint8_t uhf_settings_get_module_power_index(M100Module* module) {
+    for(uint8_t i = 0; i < BAUD_RATES_COUNT; i++) {
+        if(POWER_DBM[i] == module->transmitting_power) {
+            return i;
+        }
+    }
+    return 0;
+}
+
+uint8_t uhf_settings_get_module_working_region_index(M100Module* module) {
+    for(uint8_t i = 0; i < WORKING_REGIONS_COUNT; i++) {
+        if(WORKING_REGIONS[i] == module->region) {
+            return i;
+        }
+    }
+    return 0;
+}
+
+void uhf_scene_settings_on_enter(void* ctx) {
+    UHFApp* uhf_app = ctx;
+    M100Module* uhf_module = uhf_app->worker->module;
+    VariableItem* item;
+    VariableItemList* variable_item_list = uhf_app->variable_item_list;
+
+    uint8_t value_index = uhf_settings_get_module_baudrate_index(uhf_module);
+    char text_buf[10];
+    snprintf(text_buf, sizeof(text_buf), "%lu", uhf_module->baudrate);
+    item = variable_item_list_add(
+        variable_item_list,
+        "Baudrate:",
+        BAUD_RATES_COUNT,
+        uhf_settings_set_module_baudrate,
+        uhf_module);
+
+    variable_item_set_current_value_text(item, text_buf);
+    variable_item_set_current_value_index(item, value_index);
+
+    value_index = uhf_settings_get_module_power_index(uhf_module);
+    item = variable_item_list_add(
+        variable_item_list,
+        "Power(DBM):",
+        POWER_DBM_COUNT,
+        uhf_settings_set_module_powerdb,
+        uhf_module);
+    snprintf(text_buf, sizeof(text_buf), "%ddBm", uhf_module->transmitting_power);
+    variable_item_set_current_value_text(item, text_buf);
+    variable_item_set_current_value_index(item, value_index);
+
+    value_index = uhf_settings_get_module_working_region_index(uhf_module);
+    item = variable_item_list_add(
+        variable_item_list,
+        "Region:",
+        WORKING_REGIONS_COUNT,
+        uhf_settings_set_module_working_region,
+        uhf_module);
+    variable_item_set_current_value_text(item, WORKING_REGIONS_STR[value_index]);
+    variable_item_set_current_value_index(item, value_index);
+
+    view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewVariableItemList);
+}
+
+bool uhf_scene_settings_on_event(void* ctx, SceneManagerEvent event) {
+    UHFApp* uhf_app = ctx;
+    UNUSED(uhf_app);
+    UNUSED(event);
+    return false;
+}
+
+void uhf_scene_settings_on_exit(void* ctx) {
+    UHFApp* uhf_app = ctx;
+    variable_item_list_set_selected_item(uhf_app->variable_item_list, 0);
+    variable_item_list_reset(uhf_app->variable_item_list);
+}

+ 5 - 7
non_catalog_apps/uhf_rfid/scenes/uhf_scene_start.c

@@ -38,14 +38,12 @@ bool uhf_scene_start_on_event(void* ctx, SceneManagerEvent event) {
                 uhf_app->scene_manager, UHFSceneStart, SubmenuIndexSaved);
                 uhf_app->scene_manager, UHFSceneStart, SubmenuIndexSaved);
             scene_manager_next_scene(uhf_app->scene_manager, UHFSceneFileSelect);
             scene_manager_next_scene(uhf_app->scene_manager, UHFSceneFileSelect);
             consumed = true;
             consumed = true;
+        } else if(event.event == SubmenuIndexSettings) {
+            scene_manager_set_scene_state(
+                uhf_app->scene_manager, UHFSceneStart, SubmenuIndexSettings);
+            scene_manager_next_scene(uhf_app->scene_manager, UHFSceneSettings);
+            consumed = true;
         }
         }
-        // } else if(event.event == SubmenuIndexEliteDictAttack) {
-        //     scene_manager_set_scene_state(
-        //         uhf_app->scene_manager, UHFSceneStart, SubmenuIndexEliteDictAttack);
-        //     scene_manager_next_scene(uhf_app->scene_manager, UHFSceneEliteDictAttack);
-        //     consumed = true;
-        // }
-        // consumed = true;
     }
     }
     return consumed;
     return consumed;
 }
 }

+ 14 - 1
non_catalog_apps/uhf_rfid/uhf_app.c

@@ -54,6 +54,9 @@ UHFApp* uhf_alloc() {
     view_dispatcher_attach_to_gui(
     view_dispatcher_attach_to_gui(
         uhf_app->view_dispatcher, uhf_app->gui, ViewDispatcherTypeFullscreen);
         uhf_app->view_dispatcher, uhf_app->gui, ViewDispatcherTypeFullscreen);
 
 
+    // Variable Item List
+    uhf_app->variable_item_list = variable_item_list_alloc();
+
     //worker
     //worker
     uhf_app->worker = uhf_worker_alloc();
     uhf_app->worker = uhf_worker_alloc();
 
 
@@ -69,6 +72,13 @@ UHFApp* uhf_alloc() {
     // Open Notification record
     // Open Notification record
     uhf_app->notifications = furi_record_open(RECORD_NOTIFICATION);
     uhf_app->notifications = furi_record_open(RECORD_NOTIFICATION);
 
 
+    // Variable Item List
+    uhf_app->variable_item_list = variable_item_list_alloc();
+    view_dispatcher_add_view(
+        uhf_app->view_dispatcher,
+        UHFViewVariableItemList,
+        variable_item_list_get_view(uhf_app->variable_item_list));
+
     // Submenu
     // Submenu
     uhf_app->submenu = submenu_alloc();
     uhf_app->submenu = submenu_alloc();
     view_dispatcher_add_view(
     view_dispatcher_add_view(
@@ -140,6 +150,9 @@ void uhf_free(UHFApp* uhf_app) {
     furi_record_close(RECORD_GUI);
     furi_record_close(RECORD_GUI);
     uhf_app->gui = NULL;
     uhf_app->gui = NULL;
 
 
+    // Variable Item List
+    variable_item_list_free(uhf_app->variable_item_list);
+
     // Notifications
     // Notifications
     furi_record_close(RECORD_NOTIFICATION);
     furi_record_close(RECORD_NOTIFICATION);
     uhf_app->notifications = NULL;
     uhf_app->notifications = NULL;
@@ -189,7 +202,7 @@ int32_t uhf_app_main(void* ctx) {
     furi_hal_power_enable_otg();
     furi_hal_power_enable_otg();
     // init pin a2
     // init pin a2
     // furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull);
     // furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull);
-
+    furi_hal_uart_set_br(FuriHalUartIdUSART1, DEFAULT_BAUDRATE);
     scene_manager_next_scene(uhf_app->scene_manager, UHFSceneVerify);
     scene_manager_next_scene(uhf_app->scene_manager, UHFSceneVerify);
     view_dispatcher_run(uhf_app->view_dispatcher);
     view_dispatcher_run(uhf_app->view_dispatcher);
 
 

+ 4 - 0
non_catalog_apps/uhf_rfid/uhf_app_i.h

@@ -11,6 +11,7 @@
 #include <gui/modules/loading.h>
 #include <gui/modules/loading.h>
 #include <gui/modules/text_input.h>
 #include <gui/modules/text_input.h>
 #include <gui/modules/widget.h>
 #include <gui/modules/widget.h>
+#include <gui/modules/variable_item_list.h>
 
 
 #include <input/input.h>
 #include <input/input.h>
 
 
@@ -42,6 +43,7 @@ enum UHFCustomEvent {
     UHFCustomEventWorkerExit,
     UHFCustomEventWorkerExit,
     UHFCustomEventByteInputDone,
     UHFCustomEventByteInputDone,
     UHFCustomEventTextInputDone,
     UHFCustomEventTextInputDone,
+    UHFCustomEventSceneSettingLock,
 };
 };
 
 
 typedef enum {
 typedef enum {
@@ -55,6 +57,7 @@ struct UHFApp {
     Gui* gui;
     Gui* gui;
     NotificationApp* notifications;
     NotificationApp* notifications;
     SceneManager* scene_manager;
     SceneManager* scene_manager;
+    VariableItemList* variable_item_list;
     // Storage* storage;
     // Storage* storage;
     UHFDevice* uhf_device;
     UHFDevice* uhf_device;
     char text_store[UHF_TEXT_STORE_SIZE + 1];
     char text_store[UHF_TEXT_STORE_SIZE + 1];
@@ -73,6 +76,7 @@ typedef enum {
     UHFViewLoading,
     UHFViewLoading,
     UHFViewTextInput,
     UHFViewTextInput,
     UHFViewWidget,
     UHFViewWidget,
+    UHFViewVariableItemList,
 } UHFView;
 } UHFView;
 
 
 UHFApp* uhf_app_alloc();
 UHFApp* uhf_app_alloc();

+ 3 - 0
non_catalog_apps/uhf_rfid/uhf_buffer.c

@@ -56,6 +56,9 @@ void buffer_close(Buffer* buf) {
 }
 }
 
 
 void buffer_reset(Buffer* buf) {
 void buffer_reset(Buffer* buf) {
+    for(size_t i = 0; i < MAX_BUFFER_SIZE; i++) {
+        buf->data[i] = 0;
+    }
     buf->size = 0;
     buf->size = 0;
     buf->closed = false;
     buf->closed = false;
 }
 }

+ 1 - 1
non_catalog_apps/uhf_rfid/uhf_buffer.h

@@ -3,7 +3,7 @@
 #include <stdbool.h>
 #include <stdbool.h>
 #include <stddef.h>
 #include <stddef.h>
 
 
-#define MAX_BUFFER_SIZE 128
+#define MAX_BUFFER_SIZE 200
 
 
 typedef struct Buffer {
 typedef struct Buffer {
     uint8_t* data;
     uint8_t* data;

+ 0 - 0
non_catalog_apps/uhf_rfid/uhf_cmd.c


+ 0 - 114
non_catalog_apps/uhf_rfid/uhf_cmd.h

@@ -1,114 +0,0 @@
-// #ifndef UHF_CMD_H
-// #define UHF_CMD_H
-
-// #include <stdint.h>
-// #include <stdlib.h>
-
-// typedef struct UHF_RFID_CMD {
-//     uint8_t* cmd;
-//     size_t length;
-// }UHF_RFID_CMD;
-
-// typedef enum{
-//     COMMAND_FRAME = 0x00,
-//     RESPONSE_FRAME,
-//     NOTIFICATION_FRAME
-// }UHFFrameType;
-
-// typedef enum{
-//     RFU_BANK,
-//     EPC_BANK,
-//     TID_BANK,
-//     USER_BANK
-// }UHFBank;
-
-// typedef enum{
-//     CHINA_900MHZ = 1,
-//     CHINA_800MHZ = 4,
-//     US = 2,
-//     EU = 3,
-//     KOREA = 6
-// }UHFWorkArea;
-
-// #define DEFAULT_BAUD_RATE 115200
-// #define FRAME_START 0xBB
-// #define FRAME_END 0x7E
-// #define ERROR 0x15
-
-// UHF_RFID_CMD CMD_HARDWARE_VERSION = {.cmd = (uint8_t[]){0xBB, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x7E}, .length = 8};
-
-// UHF_RFID_CMD CMD_SOFTWARE_VERSION = {.cmd = (uint8_t[]){0xBB, 0x00, 0x03, 0x00, 0x01, 0x01, 0x05, 0x7E}, .length = 8};
-
-// UHF_RFID_CMD CMD_MANUFACTURERS = {.cmd = (uint8_t[]){0xBB, 0x00, 0x03, 0x00, 0x01, 0x02, 0x06, 0x7E}, .length = 8};
-
-// UHF_RFID_CMD CMD_SINGLE_POLLING = {.cmd = (uint8_t[]){0xBB, 0x00, 0x22, 0x00, 0x00, 0x22, 0x7E}, .length = 7};
-
-// UHF_RFID_CMD CMD_MULTIPLE_POLLING = {.cmd = (uint8_t[]){0xBB, 0x00, 0x27, 0x00, 0x03, 0x22, 0x27, 0x10, 0x83, 0x7E}, .length = 10};
-
-// UHF_RFID_CMD CMD_STOP_MULTIPLE_POLLING = {.cmd = (uint8_t[]){0xBB, 0x00, 0x28, 0x00, 0x00, 0x28, 0x7E}, .length = 7};
-
-// UHF_RFID_CMD CMD_SET_SELECT_PARAMETER = {.cmd = (uint8_t[]){0xBB, 0x00, 0x0C, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x20, 0x60, 0x00, 0x30, 0x75, 0x1F, 0xEB, 0x70, 0x5C, 0x59, 0x04, 0xE3, 0xD5, 0x0D, 0x70, 0xAD, 0x7E }, .length = 26};
-
-// UHF_RFID_CMD CMD_GET_SELECT_PARAMETER = {.cmd = (uint8_t[]){0xBB, 0x00, 0x0B, 0x00, 0x00, 0x0B, 0x7E}, .length = 7};
-
-// UHF_RFID_CMD CMD_SET_SELECT_MODE = {.cmd = (uint8_t[]){0xBB, 0x00, 0x12, 0x00, 0x01, 0x01, 0x14, 0x7E}, .length = 8};
-
-// UHF_RFID_CMD CMD_READ_LABEL_DATA_STORAGE = {.cmd = (uint8_t[]){0xBB, 0x00, 0x39, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x4D, 0x7E}, .length = 16};
-
-// UHF_RFID_CMD CMD_WRITE_LABEL_DATA_STORAGE = {.cmd = (uint8_t[]){0xBB, 0x00, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x71, 0x7E}, .length = 24};
-
-// UHF_RFID_CMD CMD_LOCK_LABEL_DATA_STORAGE = {.cmd = (uint8_t[]){0xBB, 0x00, 0x82, 0x00, 0x07, 0x00, 0x00, 0xFF, 0xFF, 0x02, 0x00, 0x80, 0x09, 0x7E}, .length = 13};
-
-// UHF_RFID_CMD CMD_INACTIVATE_KILL_TAG = {.cmd = (uint8_t[]){0xBB, 0x00, 0x65, 0x00, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0x67, 0x7E}, .length = 11};
-
-// UHF_RFID_CMD CMD_SET_COMMUNICATION_BAUD_RATE = {.cmd = (uint8_t[]){0xBB, 0x00, 0x11, 0x00, 0x02, 0x00, 0xC0, 0xD3, 0x7E}, .length = 9};
-
-// UHF_RFID_CMD CMD_GET_QUERY_PARAMETERS = {.cmd = (uint8_t[]){0xBB, 0x00, 0x0D, 0x00, 0x00, 0x0D, 0x7E}, .length = 7};
-
-// UHF_RFID_CMD CMD_SET_QUERY_PARAMETER = {.cmd = (uint8_t[]){0xBB, 0x00, 0x0E, 0x00, 0x02, 0x10, 0x20, 0x40, 0x7E}, .length = 9};
-
-// UHF_RFID_CMD CMD_SETUP_WORK_AREA = {.cmd = (uint8_t[]){0xBB, 0x00, 0x07, 0x00, 0x01, 0x01, 0x09, 0x7E}, .length = 8};
-
-// UHF_RFID_CMD CMD_ACQUIRE_WORK_LOCATIONS = {.cmd = (uint8_t[]){0xBB, 0x00, 0x08, 0x00, 0x00, 0x08, 0x7E}, .length = 7};
-
-// UHF_RFID_CMD CMD_SETUP_WORKING_CHANNEL = {.cmd = (uint8_t[]){0xBB, 0x00, 0xAB, 0x00, 0x01, 0x01, 0xAC, 0x7E}, .length = 8};
-
-// UHF_RFID_CMD CMD_GET_WORKING_CHANNEL = {.cmd = (uint8_t[]){0xBB, 0x00, 0xAA, 0x00, 0x00, 0xAA, 0x7E}, .length = 7};
-
-// UHF_RFID_CMD CMD_SET_AUTO_FREQUENCY_HOPPING = {.cmd = (uint8_t[]){0xBB, 0x00, 0xAD, 0x00, 0x01, 0xFF, 0xAD, 0x7E}, .length = 8};
-
-// UHF_RFID_CMD CMD_INSERT_WORKING_CHANNEL = {.cmd = (uint8_t[]){0xBB, 0x00, 0xA9, 0x00, 0x06, 0x05, 0x01, 0x02,0x03, 0x04, 0x05, 0xC3, 0x7E}, .length = 13};
-
-// UHF_RFID_CMD CMD_ACQUIRE_TRANSMITTING_POWER = {.cmd = (uint8_t[]){0xBB, 0x00, 0xB7, 0x00, 0x00, 0xB7, 0x7E}, .length = 7};
-
-// UHF_RFID_CMD CMD_SET_TRANSMITTING_POWER = {.cmd = (uint8_t[]){0xBB, 0x00, 0xB6, 0x00, 0x02, 0x07, 0xD0, 0x8F, 0x7E}, .length = 9};
-
-// UHF_RFID_CMD CMD_SET_CONTINUOUS_CARRIER = {.cmd = (uint8_t[]){0xBB, 0x00, 0xB0, 0x00, 0x01, 0xFF, 0xB0, 0x7E}, .length = 8};
-
-// UHF_RFID_CMD CMD_GET_DEMODULATOR_PARAMETERS = {.cmd = (uint8_t[]){0xBB, 0x00, 0xF1, 0x00, 0x00, 0xF1, 0x7E}, .length = 7};
-
-// UHF_RFID_CMD CMD_SET_DEMODULATOR_PARAMETERS = {.cmd = (uint8_t[]){0xBB, 0x00, 0xF0, 0x00, 0x04, 0x03, 0x06, 0x01, 0xB0, 0xAE, 0x7E}, .length = 11};
-
-// UHF_RFID_CMD CMD_TEST_RF_INPUT_BLOCK_SIGNAL = {.cmd = (uint8_t[]){0xBB, 0x00, 0xF2, 0x00, 0x00, 0xF2, 0x7E}, .length = 7};
-
-// UHF_RFID_CMD CMD_TEST_RSSI_SIGNAL = {.cmd = (uint8_t[]){0xBB, 0x00, 0xF3, 0x00, 0x00, 0xF3, 0x7E}, .length = 7};
-
-// UHF_RFID_CMD CMD_MODULE_HIBERNATION = {.cmd = (uint8_t[]){0xBB, 0x00, 0x17, 0x00, 0x00, 0x17, 0x7E}, .length = 7};
-
-// UHF_RFID_CMD CMD_IDLE_HIBERNATION_TIME = {.cmd = (uint8_t[]){0xBB, 0x00, 0x1D, 0x00, 0x01, 0x02, 0x20, 0x7E}, .length = 8};
-
-// UHF_RFID_CMD CMD_IDLE_MODE = {.cmd = (uint8_t[]){0xBB, 0x00, 0x04, 0x00, 0x03, 0x01, 0x01, 0x03, 0x0C, 0x7E}, .length = 10};
-
-// UHF_RFID_CMD CMD_NXP_READPROTECT = {.cmd = (uint8_t[]){0xBB, 0x00, 0xE1, 0x00, 0x05, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xE4, 0x7E}, .length = 12};
-
-// UHF_RFID_CMD CMD_NXP_CHANGE_EAS = {.cmd = (uint8_t[]){0xBB, 0x00, 0xE3, 0x00, 0x05, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0xE7, 0x7E}, .length = 12};
-
-// UHF_RFID_CMD CMD_NXP_EAS_ALARM = {.cmd = (uint8_t[]){0xBB, 0x00, 0xE4, 0x00, 0x00, 0xE4, 0x7E}, .length = 7};
-
-// UHF_RFID_CMD CMD_NXP_CONFIG_WORD = {.cmd = (uint8_t[]){0xBB, 0x00, 0xE0, 0x00, 0x06, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xE4, 0x7E}, .length = 13};
-
-// UHF_RFID_CMD CMD_IMPINJ_MONZA4_QT = {.cmd = (uint8_t[]){0xBB, 0x00, 0xE5, 0x00, 0x08, 0x00, 0x00, 0xFF, 0xFF, 0x01, 0x01, 0x40, 0x00, 0x2D, 0x7E}, .length = 15};
-
-// UHF_RFID_CMD CMD_BLOCK_PERMALOCK = {.cmd = (uint8_t[]){0xBB, 0x00, 0xD3, 0x00, 0x0B, 0x00, 0x00, 0xFF,0xFF, 0x01, 0x03, 0x00, 0x00, 0x01, 0x07, 0x00, 0xE8, 0x7E}, .length = 18};
-
-// #endif /* UHF_CMD_H */

+ 0 - 2
non_catalog_apps/uhf_rfid/uhf_data_i.h

@@ -1,2 +0,0 @@
-// todo : probably will move some of the uhf_data functions to internal only
-// once i figure out how to structure the method calls

+ 119 - 116
non_catalog_apps/uhf_rfid/uhf_module.c

@@ -2,19 +2,41 @@
 #include "uhf_module_cmd.h"
 #include "uhf_module_cmd.h"
 
 
 #define DELAY_MS 100
 #define DELAY_MS 100
+#define WAIT_TICK 8000 // max wait time in between each byte
+
+volatile uint16_t tick = 0;
 
 
 void rx_callback(UartIrqEvent event, uint8_t data, void* ctx) {
 void rx_callback(UartIrqEvent event, uint8_t data, void* ctx) {
     UNUSED(event);
     UNUSED(event);
-    Buffer* buf = ctx;
-    buffer_append_single(buf, data);
-    if(data == FRAME_END) buffer_close(buf);
+    Buffer* buffer = ctx;
+    if(buffer->closed) return; // buffer closed
+    buffer_append_single(buffer, data); // append data
+    if(data == FRAME_END) buffer_close(buffer); // end of frame
+    tick = WAIT_TICK; // reset tick
+}
+
+static M100ResponseType setup_and_send_rx(M100Module* module, uint8_t* cmd, size_t cmd_length) {
+    buffer_reset(module->buf);
+    tick = WAIT_TICK;
+    furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, cmd_length);
+    while(--tick) {
+        furi_delay_us(5);
+    }
+    buffer_close(module->buf);
+    // Validation Checks
+    uint8_t* data = buffer_get_data(module->buf);
+    size_t length = buffer_get_size(module->buf);
+    // check if size > 0
+    if(!length) return M100EmptyResponse;
+    // check if data is valid
+    if(data[0] != FRAME_START || data[length - 1] != FRAME_END) return M100ValidationFail;
+    // check if checksum is correct
+    if(checksum(data + 1, length - 3) != data[length - 2]) return M100ChecksumFail;
+    return M100SuccessResponse;
 }
 }
 
 
 M100ModuleInfo* m100_module_info_alloc() {
 M100ModuleInfo* m100_module_info_alloc() {
     M100ModuleInfo* module_info = (M100ModuleInfo*)malloc(sizeof(M100ModuleInfo));
     M100ModuleInfo* module_info = (M100ModuleInfo*)malloc(sizeof(M100ModuleInfo));
-    module_info->hw_version = NULL;
-    module_info->sw_version = NULL;
-    module_info->manufacturer = NULL;
     return module_info;
     return module_info;
 }
 }
 
 
@@ -27,9 +49,11 @@ void m100_module_info_free(M100ModuleInfo* module_info) {
 M100Module* m100_module_alloc() {
 M100Module* m100_module_alloc() {
     M100Module* module = (M100Module*)malloc(sizeof(M100Module));
     M100Module* module = (M100Module*)malloc(sizeof(M100Module));
     module->info = m100_module_info_alloc();
     module->info = m100_module_info_alloc();
-    module->buf = buffer_alloc(128);
-    furi_hal_uart_set_br(FuriHalUartIdUSART1, DEFAULT_BAUDRATE);
-    module->baudrate = (uint16_t)(DEFAULT_BAUDRATE);
+    module->buf = buffer_alloc(MAX_BUFFER_SIZE);
+    module->baudrate = DEFAULT_BAUDRATE;
+    module->transmitting_power = DEFAULT_TRANSMITTING_POWER;
+    module->region = DEFAULT_WORKING_REGION;
+    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, rx_callback, module->buf);
     return module;
     return module;
 }
 }
 
 
@@ -67,15 +91,7 @@ uint16_t crc16_genibus(const uint8_t* data, size_t length) {
     return crc ^ 0xFFFF; // Post-inversion
     return crc ^ 0xFFFF; // Post-inversion
 }
 }
 
 
-char* m100_get_hardware_version(M100Module* module) {
-    if(module->info->hw_version != NULL) {
-        free(module->info->hw_version);
-        module->info->hw_version = NULL;
-    }
-    buffer_reset(module->buf);
-    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, rx_callback, module->buf);
-    furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)&CMD_HW_VERSION.cmd[0], CMD_HW_VERSION.length);
-    furi_delay_ms(DELAY_MS);
+char* _m100_info_helper(M100Module* module, char** info) {
     if(!buffer_get_size(module->buf)) return NULL;
     if(!buffer_get_size(module->buf)) return NULL;
     uint8_t* data = buffer_get_data(module->buf);
     uint8_t* data = buffer_get_data(module->buf);
     uint16_t payload_len = data[3];
     uint16_t payload_len = data[3];
@@ -84,69 +100,37 @@ char* m100_get_hardware_version(M100Module* module) {
     for(int i = 0; i < payload_len; i++) {
     for(int i = 0; i < payload_len; i++) {
         furi_string_cat_printf(temp_str, "%c", data[6 + i]);
         furi_string_cat_printf(temp_str, "%c", data[6 + i]);
     }
     }
-    char* hw_version = (char*)malloc(sizeof(char) * payload_len);
-    memcpy(hw_version, furi_string_get_cstr(temp_str), payload_len);
-    module->info->hw_version = hw_version;
+    if(*info == NULL) {
+        *info = (char*)malloc(sizeof(char) * payload_len);
+    } else {
+        for(size_t i = 0; i < strlen(*info); i++) {
+            (*info)[i] = 0;
+        }
+    }
+    memcpy(*info, furi_string_get_cstr(temp_str), payload_len);
     furi_string_free(temp_str);
     furi_string_free(temp_str);
-    return module->info->hw_version;
+    return *info;
+}
+
+char* m100_get_hardware_version(M100Module* module) {
+    setup_and_send_rx(module, (uint8_t*)&CMD_HW_VERSION.cmd[0], CMD_HW_VERSION.length);
+    return _m100_info_helper(module, &module->info->hw_version);
 }
 }
 char* m100_get_software_version(M100Module* module) {
 char* m100_get_software_version(M100Module* module) {
-    if(module->info->sw_version != NULL) {
-        free(module->info->sw_version);
-        module->info->sw_version = NULL;
-    }
-    buffer_reset(module->buf);
-    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, rx_callback, module->buf);
-    furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)&CMD_SW_VERSION.cmd[0], CMD_SW_VERSION.length);
-    furi_delay_ms(DELAY_MS);
-    if(!buffer_get_size(module->buf)) return NULL;
-    uint8_t* data = buffer_get_data(module->buf);
-    uint16_t payload_len = data[3];
-    payload_len = (payload_len << 8) + data[4];
-    FuriString* temp_str = furi_string_alloc();
-    for(int i = 0; i < payload_len; i++) {
-        furi_string_cat_printf(temp_str, "%c", data[6 + i]);
-    }
-    char* sw_version = (char*)malloc(sizeof(char) * payload_len);
-    memcpy(sw_version, furi_string_get_cstr(temp_str), payload_len);
-    module->info->sw_version = sw_version;
-    furi_string_free(temp_str);
-    return module->info->sw_version;
+    setup_and_send_rx(module, (uint8_t*)&CMD_SW_VERSION.cmd[0], CMD_SW_VERSION.length);
+    return _m100_info_helper(module, &module->info->sw_version);
 }
 }
 char* m100_get_manufacturers(M100Module* module) {
 char* m100_get_manufacturers(M100Module* module) {
-    if(module->info->manufacturer != NULL) {
-        free(module->info->manufacturer);
-        module->info->manufacturer = NULL;
-    }
-    buffer_reset(module->buf);
-    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, rx_callback, module->buf);
-    furi_hal_uart_tx(
-        FuriHalUartIdUSART1, (uint8_t*)&CMD_MANUFACTURERS.cmd[0], CMD_MANUFACTURERS.length);
-    furi_delay_ms(DELAY_MS);
-    if(!buffer_get_size(module->buf)) return NULL;
-    uint8_t* data = buffer_get_data(module->buf);
-    uint16_t payload_len = data[3];
-    payload_len = (payload_len << 8) + data[4];
-    FuriString* temp_str = furi_string_alloc();
-    for(int i = 0; i < payload_len; i++) {
-        furi_string_cat_printf(temp_str, "%c", data[6 + i]);
-    }
-    char* manufacturer = (char*)malloc(sizeof(char) * payload_len);
-    memcpy(manufacturer, furi_string_get_cstr(temp_str), payload_len);
-    module->info->manufacturer = manufacturer;
-    furi_string_free(temp_str);
-    return module->info->manufacturer;
+    setup_and_send_rx(module, (uint8_t*)&CMD_MANUFACTURERS.cmd[0], CMD_MANUFACTURERS.length);
+    return _m100_info_helper(module, &module->info->manufacturer);
 }
 }
 
 
-M100ResponseType m100_send_single_poll(M100Module* module, UHFTag* uhf_tag) {
-    buffer_reset(module->buf);
-    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, rx_callback, module->buf);
-    furi_hal_uart_tx(
-        FuriHalUartIdUSART1, (uint8_t*)&CMD_SINGLE_POLLING.cmd[0], CMD_SINGLE_POLLING.length);
-    furi_delay_ms(DELAY_MS);
+M100ResponseType m100_single_poll(M100Module* module, UHFTag* uhf_tag) {
+    M100ResponseType rp_type =
+        setup_and_send_rx(module, (uint8_t*)&CMD_SINGLE_POLLING.cmd[0], CMD_SINGLE_POLLING.length);
+    if(rp_type != M100SuccessResponse) return rp_type;
     uint8_t* data = buffer_get_data(module->buf);
     uint8_t* data = buffer_get_data(module->buf);
     size_t length = buffer_get_size(module->buf);
     size_t length = buffer_get_size(module->buf);
-    if(length <= 8 && data[2] == 0xFF) return M100NoTagResponse;
     uint16_t pc = data[6];
     uint16_t pc = data[6];
     uint16_t crc = 0;
     uint16_t crc = 0;
     // mask out epc length from protocol control
     // mask out epc length from protocol control
@@ -167,17 +151,16 @@ M100ResponseType m100_send_single_poll(M100Module* module, UHFTag* uhf_tag) {
     uhf_tag_set_epc_pc(uhf_tag, pc);
     uhf_tag_set_epc_pc(uhf_tag, pc);
     uhf_tag_set_epc_crc(uhf_tag, crc);
     uhf_tag_set_epc_crc(uhf_tag, crc);
     uhf_tag_set_epc(uhf_tag, data + 8, epc_len);
     uhf_tag_set_epc(uhf_tag, data + 8, epc_len);
-    return M100Success;
+    return M100SuccessResponse;
 }
 }
 
 
 M100ResponseType m100_set_select(M100Module* module, UHFTag* uhf_tag) {
 M100ResponseType m100_set_select(M100Module* module, UHFTag* uhf_tag) {
-    buffer_reset(module->buf);
     // Set select
     // Set select
     uint8_t cmd[MAX_BUFFER_SIZE];
     uint8_t cmd[MAX_BUFFER_SIZE];
     size_t cmd_length = CMD_SET_SELECT_PARAMETER.length;
     size_t cmd_length = CMD_SET_SELECT_PARAMETER.length;
     size_t mask_length_bytes = uhf_tag->epc->size;
     size_t mask_length_bytes = uhf_tag->epc->size;
     size_t mask_length_bits = mask_length_bytes * 8;
     size_t mask_length_bits = mask_length_bytes * 8;
-    // payload len = sel param len + ptr len + mask len + epc len
+    // payload len == sel param len + ptr len + mask len + epc len
     size_t payload_len = 7 + mask_length_bytes;
     size_t payload_len = 7 + mask_length_bytes;
     memcpy(cmd, CMD_SET_SELECT_PARAMETER.cmd, cmd_length);
     memcpy(cmd, CMD_SET_SELECT_PARAMETER.cmd, cmd_length);
     // set new length
     // set new length
@@ -200,15 +183,14 @@ M100ResponseType m100_set_select(M100Module* module, UHFTag* uhf_tag) {
     cmd[cmd_length - 2] = checksum(cmd + 1, 11 + mask_length_bytes);
     cmd[cmd_length - 2] = checksum(cmd + 1, 11 + mask_length_bytes);
     // end frame
     // end frame
     cmd[cmd_length - 1] = FRAME_END;
     cmd[cmd_length - 1] = FRAME_END;
-    furi_hal_uart_set_irq_cb(FuriHalUartIdLPUART1, rx_callback, module->buf);
-    furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, 12 + mask_length_bytes + 3);
-    furi_delay_ms(DELAY_MS);
+
+    setup_and_send_rx(module, cmd, 12 + mask_length_bytes + 3);
 
 
     uint8_t* data = buffer_get_data(module->buf);
     uint8_t* data = buffer_get_data(module->buf);
     if(checksum(data + 1, 5) != data[6]) return M100ValidationFail; // error in rx
     if(checksum(data + 1, 5) != data[6]) return M100ValidationFail; // error in rx
     if(data[5] != 0x00) return M100ValidationFail; // error if not 0
     if(data[5] != 0x00) return M100ValidationFail; // error if not 0
 
 
-    return M100Success;
+    return M100SuccessResponse;
 }
 }
 
 
 UHFTag* m100_get_select_param(M100Module* module) {
 UHFTag* m100_get_select_param(M100Module* module) {
@@ -223,6 +205,7 @@ UHFTag* m100_get_select_param(M100Module* module) {
     // uint8_t* data = buffer_get_data(module->buf);
     // uint8_t* data = buffer_get_data(module->buf);
     // size_t mask_length =
     // size_t mask_length =
     // uhf_tag_set_epc(uhf_tag, data + 12, )
     // uhf_tag_set_epc(uhf_tag, data + 12, )
+    // TODO : implement
     return NULL;
     return NULL;
 }
 }
 
 
@@ -233,10 +216,9 @@ M100ResponseType m100_read_label_data_storage(
     uint32_t access_pwd,
     uint32_t access_pwd,
     uint16_t word_count) {
     uint16_t word_count) {
     /*
     /*
-    Will probably remove UHFTag as param and get it from get selected tag
-        */
-    if(bank == EPCBank) return M100Success;
-    buffer_reset(module->buf);
+        Will probably remove UHFTag as param and get it from get selected tag
+    */
+    if(bank == EPCBank) return M100SuccessResponse;
     uint8_t cmd[MAX_BUFFER_SIZE];
     uint8_t cmd[MAX_BUFFER_SIZE];
     size_t cmd_length = CMD_READ_LABEL_DATA_STORAGE_AREA.length;
     size_t cmd_length = CMD_READ_LABEL_DATA_STORAGE_AREA.length;
     memcpy(cmd, CMD_READ_LABEL_DATA_STORAGE_AREA.cmd, cmd_length);
     memcpy(cmd, CMD_READ_LABEL_DATA_STORAGE_AREA.cmd, cmd_length);
@@ -252,24 +234,31 @@ M100ResponseType m100_read_label_data_storage(
     cmd[13] = word_count & 0xFF;
     cmd[13] = word_count & 0xFF;
     // calc checksum
     // calc checksum
     cmd[cmd_length - 2] = checksum(cmd + 1, cmd_length - 3);
     cmd[cmd_length - 2] = checksum(cmd + 1, cmd_length - 3);
-    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, rx_callback, module->buf);
-    furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, cmd_length);
-    furi_delay_ms(DELAY_MS);
+
+    M100ResponseType rp_type = setup_and_send_rx(module, cmd, cmd_length);
+    if(rp_type != M100SuccessResponse) return rp_type;
+
     uint8_t* data = buffer_get_data(module->buf);
     uint8_t* data = buffer_get_data(module->buf);
+
+    uint8_t rtn_command = data[2];
     uint16_t payload_len = data[3];
     uint16_t payload_len = data[3];
     payload_len = (payload_len << 8) + data[4];
     payload_len = (payload_len << 8) + data[4];
-    size_t ptr_offset = 5 /*<-ptr offset*/ + uhf_tag->epc->size + 3 /*<-pc + ul*/;
-    size_t bank_data_length = payload_len - (ptr_offset - 5 /*dont include the offset*/);
-    if(data[2] == 0xFF) {
-        if(payload_len == 0x0001) return M100NoTagResponse;
+
+    if(rtn_command == 0xFF) {
+        if(payload_len == 0x01) return M100NoTagResponse;
         return M100MemoryOverrun;
         return M100MemoryOverrun;
     }
     }
+
+    size_t ptr_offset = 5 /*<-ptr offset*/ + uhf_tag_get_epc_size(uhf_tag) + 3 /*<-pc + ul*/;
+    size_t bank_data_length = payload_len - (ptr_offset - 5 /*dont include the offset*/);
+
     if(bank == TIDBank) {
     if(bank == TIDBank) {
         uhf_tag_set_tid(uhf_tag, data + ptr_offset, bank_data_length);
         uhf_tag_set_tid(uhf_tag, data + ptr_offset, bank_data_length);
     } else if(bank == UserBank) {
     } else if(bank == UserBank) {
         uhf_tag_set_user(uhf_tag, data + ptr_offset, bank_data_length);
         uhf_tag_set_user(uhf_tag, data + ptr_offset, bank_data_length);
     }
     }
-    return M100Success;
+
+    return M100SuccessResponse;
 }
 }
 
 
 M100ResponseType m100_write_label_data_storage(
 M100ResponseType m100_write_label_data_storage(
@@ -279,7 +268,6 @@ M100ResponseType m100_write_label_data_storage(
     BankType bank,
     BankType bank,
     uint16_t source_address,
     uint16_t source_address,
     uint32_t access_pwd) {
     uint32_t access_pwd) {
-    buffer_reset(module->buf);
     uint8_t cmd[MAX_BUFFER_SIZE];
     uint8_t cmd[MAX_BUFFER_SIZE];
     size_t cmd_length = CMD_WRITE_LABEL_DATA_STORE.length;
     size_t cmd_length = CMD_WRITE_LABEL_DATA_STORE.length;
     memcpy(cmd, CMD_WRITE_LABEL_DATA_STORE.cmd, cmd_length);
     memcpy(cmd, CMD_WRITE_LABEL_DATA_STORE.cmd, cmd_length);
@@ -330,56 +318,71 @@ M100ResponseType m100_write_label_data_storage(
     cmd[cmd_length - 2] = checksum(cmd + 1, cmd_length - 3);
     cmd[cmd_length - 2] = checksum(cmd + 1, cmd_length - 3);
     cmd[cmd_length - 1] = FRAME_END;
     cmd[cmd_length - 1] = FRAME_END;
     // send cmd
     // send cmd
-    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, rx_callback, module->buf);
-    furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, cmd_length);
-    uint8_t max_wait = 25;
-    while(!buffer_get_size(module->buf)) {
-        furi_delay_ms(DELAY_MS);
-        if(!max_wait--) break;
-    }
+    // furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, rx_callback, module->buf);
+    // furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, cmd_length);
+    // unsigned int delay = DELAY_MS / 2;
+    // unsigned int timeout = 15;
+    // while(!buffer_get_size(module->buf)) {
+    //     furi_delay_ms(delay);
+    //     if(!timeout--) break;
+    // }
+    setup_and_send_rx(module, cmd, cmd_length);
     uint8_t* buff_data = buffer_get_data(module->buf);
     uint8_t* buff_data = buffer_get_data(module->buf);
     size_t buff_length = buffer_get_size(module->buf);
     size_t buff_length = buffer_get_size(module->buf);
     if(buff_data[2] == 0xFF && buff_length == 8)
     if(buff_data[2] == 0xFF && buff_length == 8)
         return M100NoTagResponse;
         return M100NoTagResponse;
     else if(buff_data[2] == 0xFF)
     else if(buff_data[2] == 0xFF)
         return M100ValidationFail;
         return M100ValidationFail;
-    return M100Success;
+    return M100SuccessResponse;
 }
 }
-void m100_set_baudrate(M100Module* module, uint16_t baudrate) {
+void m100_set_baudrate(M100Module* module, uint32_t baudrate) {
     size_t length = CMD_SET_COMMUNICATION_BAUD_RATE.length;
     size_t length = CMD_SET_COMMUNICATION_BAUD_RATE.length;
     uint8_t cmd[length];
     uint8_t cmd[length];
     memcpy(cmd, CMD_SET_COMMUNICATION_BAUD_RATE.cmd, length);
     memcpy(cmd, CMD_SET_COMMUNICATION_BAUD_RATE.cmd, length);
     uint16_t br_mod = baudrate / 100; // module format
     uint16_t br_mod = baudrate / 100; // module format
     cmd[6] = 0xFF & br_mod; // pow LSB
     cmd[6] = 0xFF & br_mod; // pow LSB
-    cmd[5] = 0xFF & (br_mod >> 4); // pow MSB
+    cmd[5] = 0xFF & (br_mod >> 8); // pow MSB
+    cmd[length - 2] = checksum(cmd + 1, length - 3);
     furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, length);
     furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, length);
     furi_hal_uart_set_br(FuriHalUartIdUSART1, baudrate);
     furi_hal_uart_set_br(FuriHalUartIdUSART1, baudrate);
     module->baudrate = baudrate;
     module->baudrate = baudrate;
 }
 }
-bool m100_set_working_area(M100Module* module, WorkingArea area) {
+
+bool m100_set_working_region(M100Module* module, WorkingRegion region) {
     size_t length = CMD_SET_WORK_AREA.length;
     size_t length = CMD_SET_WORK_AREA.length;
     uint8_t cmd[length];
     uint8_t cmd[length];
     memcpy(cmd, CMD_SET_WORK_AREA.cmd, length);
     memcpy(cmd, CMD_SET_WORK_AREA.cmd, length);
-    cmd[5] = area;
-    Buffer* buf = buffer_alloc(12);
-    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, rx_callback, buf);
-    furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, length);
-    buffer_free(buf);
-    module->area = area;
-    return true;
-}
-bool m100_set_working_channel(M100Module* module, WorkingChannel channel) {
-    UNUSED(module);
-    UNUSED(channel);
+    cmd[5] = (uint8_t)region;
+    cmd[length - 2] = checksum(cmd + 1, length - 3);
+    setup_and_send_rx(module, cmd, length);
+    module->region = region;
     return true;
     return true;
 }
 }
+
 bool m100_set_transmitting_power(M100Module* module, uint16_t power) {
 bool m100_set_transmitting_power(M100Module* module, uint16_t power) {
-    UNUSED(module);
-    UNUSED(power);
+    size_t length = CMD_SET_TRANSMITTING_POWER.length;
+    uint8_t cmd[length];
+    memcpy(cmd, CMD_SET_TRANSMITTING_POWER.cmd, length);
+    cmd[5] = (power >> 8) & 0xFF;
+    cmd[6] = power & 0xFF;
+    cmd[length - 2] = checksum(cmd + 1, length - 3);
+    setup_and_send_rx(module, cmd, length);
+    module->transmitting_power = power;
     return true;
     return true;
 }
 }
+
 bool m100_set_freq_hopping(M100Module* module, bool hopping) {
 bool m100_set_freq_hopping(M100Module* module, bool hopping) {
     UNUSED(module);
     UNUSED(module);
     UNUSED(hopping);
     UNUSED(hopping);
     return true;
     return true;
 }
 }
+
+bool m100_set_power(M100Module* module, uint8_t* power) {
+    UNUSED(module);
+    UNUSED(power);
+    return true;
+}
+
+uint32_t m100_get_baudrate(M100Module* module) {
+    return module->baudrate;
+}

+ 23 - 28
non_catalog_apps/uhf_rfid/uhf_module.h

@@ -1,14 +1,20 @@
 #pragma once
 #pragma once
 
 
+#include <stddef.h>
 #include <stdint.h>
 #include <stdint.h>
 #include <stdbool.h>
 #include <stdbool.h>
-#include <stddef.h>
+#include <furi_hal.h>
+#include "uhf_tag.h"
 #include "uhf_buffer.h"
 #include "uhf_buffer.h"
 #include "uhf_tag.h"
 #include "uhf_tag.h"
 #include <furi_hal.h>
 #include <furi_hal.h>
+#include "uhf_module_settings.h"
 
 
+#define FRAME_START 0xBB
 #define FRAME_END 0x7E
 #define FRAME_END 0x7E
-#define DEFAULT_BAUDRATE 115200
+#define DEFAULT_BAUDRATE BAUD_RATES[BAUD_RATES_COUNT - 1]
+#define DEFAULT_TRANSMITTING_POWER POWER_DBM[POWER_DBM_COUNT - 1]
+#define DEFAULT_WORKING_REGION WR_US
 
 
 typedef struct {
 typedef struct {
     char* hw_version;
     char* hw_version;
@@ -17,33 +23,19 @@ typedef struct {
 } M100ModuleInfo;
 } M100ModuleInfo;
 
 
 typedef enum {
 typedef enum {
-    WA_CHINA_900 = 1,   // Freq_CH-920.125M
-    WA_US,              // Freq_CH-902.25M
-    WA_EU,              // Freq_CH-865.1M
-    WA_CHINA_800,       // Freq_CH-840.125M
-    WA_KOREA = 6        // Freq_CH-917.1M
-} WorkingArea;
-
-typedef enum {
-    WC_CHINA_900 = 1,   // CH_Index(CN,900MHz) = (Freq_CH-920.125M)/0.25M
-    WC_US,              // CH_Index(US) = (Freq_CH-902.25M)/0.5M
-    WC_EU,              // CH_Index(EU) = (Freq_CH-865.1M)/0.2M
-    WC_CHINA_800,       // CH_Index(CN,800MHz) = (Freq_CH-840.125M)/0.25M
-    WC_KOREA = 6        // CH_Index(Korea) = (Freq_CH-917.1M)/0.2M
-} WorkingChannel;
-
-typedef enum {
-    M100Success,
+    M100SuccessResponse,
     M100ValidationFail,
     M100ValidationFail,
     M100NoTagResponse,
     M100NoTagResponse,
-    M100MemoryOverrun
+    M100MemoryOverrun,
+    M100EmptyResponse,
+    M100ChecksumFail
 } M100ResponseType;
 } M100ResponseType;
 
 
 typedef struct {
 typedef struct {
     M100ModuleInfo* info;
     M100ModuleInfo* info;
-    uint16_t baudrate;
-    WorkingArea area;
-    WorkingChannel channel;
+    uint32_t baudrate;
+    WorkingRegion region;
+    uint16_t region_frequency;
     uint16_t transmitting_power;
     uint16_t transmitting_power;
     bool freq_hopping;
     bool freq_hopping;
     Buffer* buf;
     Buffer* buf;
@@ -56,20 +48,21 @@ M100Module* m100_module_alloc();
 void m100_module_free(M100Module* module);
 void m100_module_free(M100Module* module);
 uint16_t crc16_genibus(const uint8_t* data, size_t length);
 uint16_t crc16_genibus(const uint8_t* data, size_t length);
 uint8_t checksum(const uint8_t* data, size_t length);
 uint8_t checksum(const uint8_t* data, size_t length);
+uint8_t get_baudrate_count();
 
 
 // Function prototypes
 // Function prototypes
 char* m100_get_hardware_version(M100Module* module);
 char* m100_get_hardware_version(M100Module* module);
 char* m100_get_software_version(M100Module* module);
 char* m100_get_software_version(M100Module* module);
 char* m100_get_manufacturers(M100Module* module);
 char* m100_get_manufacturers(M100Module* module);
 
 
-void m100_set_baudrate(M100Module* module, uint16_t baudrate);
-bool m100_set_working_area(M100Module* module, WorkingArea area);
-bool m100_set_working_channel(M100Module* module, WorkingChannel channel);
+void m100_set_baudrate(M100Module* module, uint32_t baudrate);
+bool m100_set_working_region(M100Module* module, WorkingRegion region);
 bool m100_set_transmitting_power(M100Module* module, uint16_t power);
 bool m100_set_transmitting_power(M100Module* module, uint16_t power);
 bool m100_set_freq_hopping(M100Module* module, bool hopping);
 bool m100_set_freq_hopping(M100Module* module, bool hopping);
+bool m100_set_power(M100Module* module, uint8_t* power);
 
 
 // gen2 cmds
 // gen2 cmds
-M100ResponseType m100_send_single_poll(M100Module* module, UHFTag* uhf_tag);
+M100ResponseType m100_single_poll(M100Module* module, UHFTag* uhf_tag);
 M100ResponseType m100_set_select(M100Module* module, UHFTag* uhf_tag);
 M100ResponseType m100_set_select(M100Module* module, UHFTag* uhf_tag);
 M100ResponseType m100_read_label_data_storage(
 M100ResponseType m100_read_label_data_storage(
     M100Module* module,
     M100Module* module,
@@ -84,4 +77,6 @@ M100ResponseType m100_write_label_data_storage(
     UHFTag* selected_tag,
     UHFTag* selected_tag,
     BankType bank,
     BankType bank,
     uint16_t source_address,
     uint16_t source_address,
-    uint32_t access_pwd);
+    uint32_t access_pwd);
+
+uint32_t m100_get_baudrate(M100Module* module);

+ 2 - 0
non_catalog_apps/uhf_rfid/uhf_module_cmd.h

@@ -26,6 +26,7 @@ static const uint8_t CMD_SET_COMMUNICATION_BAUD_RATE_DATA[] = {0xBB, 0x00, 0x11,
 static const uint8_t CMD_GET_QUERY_PARAMETERS_DATA[] = {0xBB, 0x00, 0x0D, 0x00, 0x00, 0x0D, 0x7E};
 static const uint8_t CMD_GET_QUERY_PARAMETERS_DATA[] = {0xBB, 0x00, 0x0D, 0x00, 0x00, 0x0D, 0x7E};
 static const uint8_t CMD_SET_QUERY_PARAMETER_DATA[] = {0xBB, 0x00, 0x0E, 0x00, 0x02, 0x10, 0x20, 0x40, 0x7E};
 static const uint8_t CMD_SET_QUERY_PARAMETER_DATA[] = {0xBB, 0x00, 0x0E, 0x00, 0x02, 0x10, 0x20, 0x40, 0x7E};
 static const uint8_t CMD_SET_WORK_AREA_DATA[] = {0xBB, 0x00, 0x07, 0x00, 0x01, 0x01, 0x09, 0x7E};
 static const uint8_t CMD_SET_WORK_AREA_DATA[] = {0xBB, 0x00, 0x07, 0x00, 0x01, 0x01, 0x09, 0x7E};
+static const uint8_t CMD_SET_TRANSMITTING_POWER_DATA[] = {0xBB, 0x00, 0xB6, 0x00, 0x02, 0x07, 0xD0, 0x8F, 0x7E};
 
 
 
 
 // Define the Command structs
 // Define the Command structs
@@ -46,3 +47,4 @@ static const Command CMD_SET_COMMUNICATION_BAUD_RATE = {CMD_SET_COMMUNICATION_BA
 static const Command CMD_GET_QUERY_PARAMETERS = {CMD_GET_QUERY_PARAMETERS_DATA, sizeof(CMD_GET_QUERY_PARAMETERS_DATA)};
 static const Command CMD_GET_QUERY_PARAMETERS = {CMD_GET_QUERY_PARAMETERS_DATA, sizeof(CMD_GET_QUERY_PARAMETERS_DATA)};
 static const Command CMD_SET_QUERY_PARAMETER = {CMD_SET_QUERY_PARAMETER_DATA, sizeof(CMD_SET_QUERY_PARAMETER_DATA)};
 static const Command CMD_SET_QUERY_PARAMETER = {CMD_SET_QUERY_PARAMETER_DATA, sizeof(CMD_SET_QUERY_PARAMETER_DATA)};
 static const Command CMD_SET_WORK_AREA = {CMD_SET_WORK_AREA_DATA, sizeof(CMD_SET_WORK_AREA_DATA)};
 static const Command CMD_SET_WORK_AREA = {CMD_SET_WORK_AREA_DATA, sizeof(CMD_SET_WORK_AREA_DATA)};
+static const Command CMD_SET_TRANSMITTING_POWER = {CMD_SET_TRANSMITTING_POWER_DATA, sizeof(CMD_SET_TRANSMITTING_POWER_DATA)};

+ 29 - 0
non_catalog_apps/uhf_rfid/uhf_module_settings.h

@@ -0,0 +1,29 @@
+#pragma once
+
+#include <stdint.h>
+
+// UHF module regions
+typedef enum {
+    WR_CHINA_900 = 1, // Freq_CH-920.125M
+    WR_US, // Freq_CH-902.25M
+    WR_EU, // Freq_CH-865.1M
+    WR_CHINA_800, // Freq_CH-840.125M
+    WR_KOREA = 6 // Freq_CH-917.1M
+} WorkingRegion;
+
+// UHF module baudrates
+static const uint32_t BAUD_RATES[] = {9600, 19200, 115200};
+static const uint8_t BAUD_RATES_COUNT = sizeof(BAUD_RATES) / sizeof(BAUD_RATES[0]);
+// RF Power Setting
+static const uint8_t POWER_DBM[] = {12, 14, 17, 20}; // To be determined ...
+static const uint8_t POWER_DBM_COUNT = sizeof(POWER_DBM) / sizeof(POWER_DBM[0]);
+// UHF WorkingArea
+static const char* WORKING_REGIONS_STR[] = {"CN1", "US", "EU", "CN2", "KR"};
+static const uint8_t __working_region_str =
+    sizeof(WORKING_REGIONS_STR) / sizeof(WORKING_REGIONS_STR[0]);
+static const WorkingRegion WORKING_REGIONS[] = {WR_CHINA_900, WR_US, WR_EU, WR_CHINA_800, WR_KOREA};
+static const uint8_t WORKING_REGIONS_COUNT = sizeof(WORKING_REGIONS) / sizeof(WORKING_REGIONS[0]);
+// UHF WorkingChannel
+// static const string WORKING_CHANNELS_STR[] = {"China 900MHz", "US", "EU", "China 800MHz", "Korea"};
+// static const WorkingChannel WORKING_CHANNELS[] = {WC_CHINA_900, WC_US, WC_EU, WC_CHINA_800, WC_KOREA};
+// static const uint8_t WORKING_CHANNELS_COUNT = sizeof(WORKING_CHANNELS) / sizeof(WORKING_CHANNELS[0]);

+ 1 - 1
non_catalog_apps/uhf_rfid/uhf_tag.c

@@ -113,4 +113,4 @@ uint8_t* uhf_tag_get_user(UHFTag* uhf_tag) {
 
 
 size_t uhf_tag_get_user_size(UHFTag* uhf_tag) {
 size_t uhf_tag_get_user_size(UHFTag* uhf_tag) {
     return uhf_tag->user->size;
     return uhf_tag->user->size;
-}
+}

+ 4 - 3
non_catalog_apps/uhf_rfid/uhf_tag.h

@@ -4,6 +4,7 @@
 #include <stdbool.h>
 #include <stdbool.h>
 #include <stddef.h>
 #include <stddef.h>
 
 
+#define MAX_BANK_SIZE 256
 // storage enum
 // storage enum
 typedef enum { ReservedBank, EPCBank, TIDBank, UserBank } BankType;
 typedef enum { ReservedBank, EPCBank, TIDBank, UserBank } BankType;
 
 
@@ -16,7 +17,7 @@ typedef struct {
 // EPC Memory Bank
 // EPC Memory Bank
 typedef struct {
 typedef struct {
     size_t size; // Size of EPC memory data
     size_t size; // Size of EPC memory data
-    uint8_t data[18]; // 2 bytes for CRC16, 2 bytes for PC, and max 14 bytes for EPC
+    uint8_t data[MAX_BANK_SIZE]; // 2 bytes for CRC16, 2 bytes for PC, and max 14 bytes for EPC
     uint16_t pc;
     uint16_t pc;
     uint16_t crc;
     uint16_t crc;
 } EPCMemoryBank;
 } EPCMemoryBank;
@@ -24,13 +25,13 @@ typedef struct {
 // TID Memory Bank
 // TID Memory Bank
 typedef struct {
 typedef struct {
     size_t size; // Size of TID memory data
     size_t size; // Size of TID memory data
-    uint8_t data[16]; // 4 bytes for Class ID and max 12 bytes for TID data
+    uint8_t data[MAX_BANK_SIZE]; // 4 bytes for Class ID
 } TIDMemoryBank;
 } TIDMemoryBank;
 
 
 // User Memory Bank
 // User Memory Bank
 typedef struct {
 typedef struct {
     size_t size; // Size of user memory data
     size_t size; // Size of user memory data
-    uint8_t data[64]; // Assuming max 512 bits (64 bytes) for User Memory
+    uint8_t data[MAX_BANK_SIZE]; // Assuming max 512 bits (64 bytes) for User Memory
 } UserMemoryBank;
 } UserMemoryBank;
 
 
 // EPC Gen 2 Tag containing all memory banks
 // EPC Gen 2 Tag containing all memory banks

+ 13 - 15
non_catalog_apps/uhf_rfid/uhf_worker.c

@@ -15,20 +15,18 @@ UHFTag* send_polling_command(UHFWorker* uhf_worker) {
     // read epc bank
     // read epc bank
     UHFTag* uhf_tag = uhf_tag_alloc();
     UHFTag* uhf_tag = uhf_tag_alloc();
     while(true) {
     while(true) {
-        M100ResponseType status = m100_send_single_poll(uhf_worker->module, uhf_tag);
-        furi_delay_ms(100);
+        M100ResponseType status = m100_single_poll(uhf_worker->module, uhf_tag);
         if(uhf_worker->state == UHFWorkerStateStop) {
         if(uhf_worker->state == UHFWorkerStateStop) {
             uhf_tag_free(uhf_tag);
             uhf_tag_free(uhf_tag);
             return NULL;
             return NULL;
         }
         }
-        if(status == M100Success) break;
+        if(status == M100SuccessResponse) break;
     }
     }
     return uhf_tag;
     return uhf_tag;
 }
 }
 
 
-static UHFWorkerEvent
-    read_bank_till_max_length(UHFWorker* uhf_worker, UHFTag* uhf_tag, BankType bank) {
-    unsigned int retry = 3, word_low = 5, word_high = 100;
+UHFWorkerEvent read_bank_till_max_length(UHFWorker* uhf_worker, UHFTag* uhf_tag, BankType bank) {
+    unsigned int word_low = 0, word_high = 64;
     unsigned int word_size;
     unsigned int word_size;
     M100ResponseType status;
     M100ResponseType status;
     do {
     do {
@@ -36,14 +34,12 @@ static UHFWorkerEvent
         if(word_low >= word_high) return UHFWorkerEventSuccess;
         if(word_low >= word_high) return UHFWorkerEventSuccess;
         word_size = (word_low + word_high) / 2;
         word_size = (word_low + word_high) / 2;
         status = m100_read_label_data_storage(uhf_worker->module, uhf_tag, bank, 0, word_size);
         status = m100_read_label_data_storage(uhf_worker->module, uhf_tag, bank, 0, word_size);
-        if(status == M100Success) {
+        if(status == M100SuccessResponse) {
             word_low = word_size + 1;
             word_low = word_size + 1;
         } else if(status == M100MemoryOverrun) {
         } else if(status == M100MemoryOverrun) {
             word_high = word_size - 1;
             word_high = word_size - 1;
-        } else if(status == M100NoTagResponse) {
-            retry--;
         }
         }
-    } while(retry);
+    } while(true);
     return UHFWorkerEventSuccess;
     return UHFWorkerEventSuccess;
 }
 }
 
 
@@ -51,8 +47,9 @@ UHFWorkerEvent read_single_card(UHFWorker* uhf_worker) {
     UHFTag* uhf_tag = send_polling_command(uhf_worker);
     UHFTag* uhf_tag = send_polling_command(uhf_worker);
     if(uhf_tag == NULL) return UHFWorkerEventAborted;
     if(uhf_tag == NULL) return UHFWorkerEventAborted;
     uhf_tag_wrapper_set_tag(uhf_worker->uhf_tag_wrapper, uhf_tag);
     uhf_tag_wrapper_set_tag(uhf_worker->uhf_tag_wrapper, uhf_tag);
-    // Todo : set select here
-    if(m100_set_select(uhf_worker->module, uhf_tag) != M100Success) return UHFWorkerEventFail;
+    // set select
+    if(m100_set_select(uhf_worker->module, uhf_tag) != M100SuccessResponse)
+        return UHFWorkerEventFail;
     // read tid
     // read tid
     UHFWorkerEvent event;
     UHFWorkerEvent event;
     event = read_bank_till_max_length(uhf_worker, uhf_tag, TIDBank);
     event = read_bank_till_max_length(uhf_worker, uhf_tag, TIDBank);
@@ -67,18 +64,19 @@ UHFWorkerEvent write_single_card(UHFWorker* uhf_worker) {
     UHFTag* uhf_tag_des = send_polling_command(uhf_worker);
     UHFTag* uhf_tag_des = send_polling_command(uhf_worker);
     if(uhf_tag_des == NULL) return UHFWorkerEventAborted;
     if(uhf_tag_des == NULL) return UHFWorkerEventAborted;
     UHFTag* uhf_tag_from = uhf_worker->uhf_tag_wrapper->uhf_tag;
     UHFTag* uhf_tag_from = uhf_worker->uhf_tag_wrapper->uhf_tag;
-    if(m100_set_select(uhf_worker->module, uhf_tag_des) != M100Success) return UHFWorkerEventFail;
+    if(m100_set_select(uhf_worker->module, uhf_tag_des) != M100SuccessResponse)
+        return UHFWorkerEventFail;
     do {
     do {
         M100ResponseType rp_type = m100_write_label_data_storage(
         M100ResponseType rp_type = m100_write_label_data_storage(
             uhf_worker->module, uhf_tag_from, uhf_tag_des, UserBank, 0, 0);
             uhf_worker->module, uhf_tag_from, uhf_tag_des, UserBank, 0, 0);
         if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted;
         if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted;
-        if(rp_type == M100Success) break;
+        if(rp_type == M100SuccessResponse) break;
     } while(true);
     } while(true);
     do {
     do {
         M100ResponseType rp_type = m100_write_label_data_storage(
         M100ResponseType rp_type = m100_write_label_data_storage(
             uhf_worker->module, uhf_tag_from, uhf_tag_des, EPCBank, 0, 0);
             uhf_worker->module, uhf_tag_from, uhf_tag_des, EPCBank, 0, 0);
         if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted;
         if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted;
-        if(rp_type == M100Success) break;
+        if(rp_type == M100SuccessResponse) break;
     } while(true);
     } while(true);
     return UHFWorkerEventSuccess;
     return UHFWorkerEventSuccess;
 }
 }