Просмотр исходного кода

update picopass, uhf rfid

uhf rfid switched to refactor branch
MX 2 лет назад
Родитель
Сommit
c5f3905624
29 измененных файлов с 1113 добавлено и 563 удалено
  1. 1 1
      ReadMe.md
  2. 2 1
      base_pack/picopass/scenes/picopass_scene_save_name.c
  3. 16 6
      base_pack/picopass/scenes/picopass_scene_saved_menu.c
  4. BIN
      non_catalog_apps/uhf_rfid/assets/img/uhf_demo_app.jpg
  5. 3 3
      non_catalog_apps/uhf_rfid/scenes/uhf_scene_config.h
  6. 7 7
      non_catalog_apps/uhf_rfid/scenes/uhf_scene_device_info.c
  7. 28 11
      non_catalog_apps/uhf_rfid/scenes/uhf_scene_read_tag_success.c
  8. 2 2
      non_catalog_apps/uhf_rfid/scenes/uhf_scene_save_success.c
  9. 3 4
      non_catalog_apps/uhf_rfid/scenes/uhf_scene_saved_menu.c
  10. 9 13
      non_catalog_apps/uhf_rfid/scenes/uhf_scene_tag_menu.c
  11. 5 15
      non_catalog_apps/uhf_rfid/scenes/uhf_scene_verify.c
  12. 49 0
      non_catalog_apps/uhf_rfid/scenes/uhf_scene_write_tag.c
  13. 94 0
      non_catalog_apps/uhf_rfid/scenes/uhf_scene_write_tag_success.c
  14. 11 14
      non_catalog_apps/uhf_rfid/uhf_app.c
  15. 2 2
      non_catalog_apps/uhf_rfid/uhf_app_i.h
  16. 66 0
      non_catalog_apps/uhf_rfid/uhf_buffer.c
  17. 22 0
      non_catalog_apps/uhf_rfid/uhf_buffer.h
  18. 69 69
      non_catalog_apps/uhf_rfid/uhf_cmd.h
  19. 0 148
      non_catalog_apps/uhf_rfid/uhf_data.c
  20. 0 64
      non_catalog_apps/uhf_rfid/uhf_data.h
  21. 19 16
      non_catalog_apps/uhf_rfid/uhf_device.c
  22. 2 4
      non_catalog_apps/uhf_rfid/uhf_device.h
  23. 280 0
      non_catalog_apps/uhf_rfid/uhf_module.c
  24. 68 0
      non_catalog_apps/uhf_rfid/uhf_module.h
  25. 48 0
      non_catalog_apps/uhf_rfid/uhf_module_cmd.h
  26. 57 0
      non_catalog_apps/uhf_rfid/uhf_tag.c
  27. 74 0
      non_catalog_apps/uhf_rfid/uhf_tag.h
  28. 173 180
      non_catalog_apps/uhf_rfid/uhf_worker.c
  29. 3 3
      non_catalog_apps/uhf_rfid/uhf_worker.h

+ 1 - 1
ReadMe.md

@@ -13,7 +13,7 @@ Apps contains changes needed to compile them on latest firmware, fixes has been
 
 
 The Flipper and its community wouldn't be as rich as it is without your contributions and support. Thank you for all you have done.
 The Flipper and its community wouldn't be as rich as it is without your contributions and support. Thank you for all you have done.
 
 
-### Apps checked & updated at `18 Aug 20:55 GMT +3`
+### Apps checked & updated at `19 Aug 02:18 GMT +3`
 
 
 
 
 # Default pack
 # Default pack

+ 2 - 1
base_pack/picopass/scenes/picopass_scene_save_name.c

@@ -52,8 +52,9 @@ bool picopass_scene_save_name_on_event(void* context, SceneManagerEvent event) {
 
 
     if(event.type == SceneManagerEventTypeCustom) {
     if(event.type == SceneManagerEventTypeCustom) {
         if(event.event == PicopassCustomEventTextInputDone) {
         if(event.event == PicopassCustomEventTextInputDone) {
+            // Delete old file if renaming
             if(strcmp(picopass->dev->dev_name, "") != 0) {
             if(strcmp(picopass->dev->dev_name, "") != 0) {
-                // picopass_device_delete(picopass->dev, true);
+                picopass_device_delete(picopass->dev, true);
             }
             }
             strlcpy(
             strlcpy(
                 picopass->dev->dev_name, picopass->text_store, strlen(picopass->text_store) + 1);
                 picopass->dev->dev_name, picopass->text_store, strlen(picopass->text_store) + 1);

+ 16 - 6
base_pack/picopass/scenes/picopass_scene_saved_menu.c

@@ -5,6 +5,7 @@ enum SubmenuIndex {
     SubmenuIndexInfo,
     SubmenuIndexInfo,
     SubmenuIndexWrite,
     SubmenuIndexWrite,
     SubmenuIndexEmulate,
     SubmenuIndexEmulate,
+    SubmenuIndexRename,
 };
 };
 
 
 void picopass_scene_saved_menu_submenu_callback(void* context, uint32_t index) {
 void picopass_scene_saved_menu_submenu_callback(void* context, uint32_t index) {
@@ -17,12 +18,6 @@ void picopass_scene_saved_menu_on_enter(void* context) {
     Picopass* picopass = context;
     Picopass* picopass = context;
     Submenu* submenu = picopass->submenu;
     Submenu* submenu = picopass->submenu;
 
 
-    submenu_add_item(
-        submenu,
-        "Delete",
-        SubmenuIndexDelete,
-        picopass_scene_saved_menu_submenu_callback,
-        picopass);
     submenu_add_item(
     submenu_add_item(
         submenu, "Info", SubmenuIndexInfo, picopass_scene_saved_menu_submenu_callback, picopass);
         submenu, "Info", SubmenuIndexInfo, picopass_scene_saved_menu_submenu_callback, picopass);
     submenu_add_item(
     submenu_add_item(
@@ -33,6 +28,18 @@ void picopass_scene_saved_menu_on_enter(void* context) {
         SubmenuIndexEmulate,
         SubmenuIndexEmulate,
         picopass_scene_saved_menu_submenu_callback,
         picopass_scene_saved_menu_submenu_callback,
         picopass);
         picopass);
+    submenu_add_item(
+        submenu,
+        "Rename",
+        SubmenuIndexRename,
+        picopass_scene_saved_menu_submenu_callback,
+        picopass);
+    submenu_add_item(
+        submenu,
+        "Delete",
+        SubmenuIndexDelete,
+        picopass_scene_saved_menu_submenu_callback,
+        picopass);
 
 
     submenu_set_selected_item(
     submenu_set_selected_item(
         picopass->submenu,
         picopass->submenu,
@@ -61,6 +68,9 @@ bool picopass_scene_saved_menu_on_event(void* context, SceneManagerEvent event)
         } else if(event.event == SubmenuIndexEmulate) {
         } else if(event.event == SubmenuIndexEmulate) {
             scene_manager_next_scene(picopass->scene_manager, PicopassSceneEmulate);
             scene_manager_next_scene(picopass->scene_manager, PicopassSceneEmulate);
             consumed = true;
             consumed = true;
+        } else if(event.event == SubmenuIndexRename) {
+            scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName);
+            consumed = true;
         }
         }
     }
     }
 
 

BIN
non_catalog_apps/uhf_rfid/assets/img/uhf_demo_app.jpg


+ 3 - 3
non_catalog_apps/uhf_rfid/scenes/uhf_scene_config.h

@@ -2,7 +2,7 @@ ADD_SCENE(uhf, verify, Verify)
 ADD_SCENE(uhf, start, Start)
 ADD_SCENE(uhf, start, Start)
 ADD_SCENE(uhf, read_tag, ReadTag)
 ADD_SCENE(uhf, read_tag, ReadTag)
 ADD_SCENE(uhf, read_tag_success, ReadTagSuccess)
 ADD_SCENE(uhf, read_tag_success, ReadTagSuccess)
-ADD_SCENE(uhf, card_menu, CardMenu)
+ADD_SCENE(uhf, tag_menu, TagMenu)
 ADD_SCENE(uhf, save_name, SaveName)
 ADD_SCENE(uhf, save_name, SaveName)
 ADD_SCENE(uhf, save_success, SaveSuccess)
 ADD_SCENE(uhf, save_success, SaveSuccess)
 ADD_SCENE(uhf, saved_menu, SavedMenu)
 ADD_SCENE(uhf, saved_menu, SavedMenu)
@@ -10,8 +10,8 @@ ADD_SCENE(uhf, file_select, FileSelect)
 ADD_SCENE(uhf, device_info, DeviceInfo)
 ADD_SCENE(uhf, device_info, DeviceInfo)
 ADD_SCENE(uhf, delete, Delete)
 ADD_SCENE(uhf, delete, Delete)
 ADD_SCENE(uhf, delete_success, DeleteSuccess)
 ADD_SCENE(uhf, delete_success, DeleteSuccess)
-// ADD_SCENE(uhf, write_card, WriteCard)
-// ADD_SCENE(uhf, write_card_success, WriteCardSuccess)
+ADD_SCENE(uhf, write_tag, WriteTag)
+ADD_SCENE(uhf, write_tag_success, WriteTagSuccess)
 // 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)

+ 7 - 7
non_catalog_apps/uhf_rfid/scenes/uhf_scene_device_info.c

@@ -40,7 +40,7 @@ void uhf_scene_device_info_widget_callback(GuiButtonType result, InputType type,
 }
 }
 
 
 void change_view_on_event(UHFApp* uhf_app) {
 void change_view_on_event(UHFApp* uhf_app) {
-    UHFTag* uhf_tag = uhf_app->uhf_device->uhf_tag;
+    UHFTag* uhf_tag = uhf_app->uhf_device->uhf_tag_wrapper->uhf_tag;
     FuriString* furi_temp_str;
     FuriString* furi_temp_str;
     furi_temp_str = furi_string_alloc();
     furi_temp_str = furi_string_alloc();
     char* temp_str;
     char* temp_str;
@@ -52,16 +52,16 @@ void change_view_on_event(UHFApp* uhf_app) {
 
 
     switch(current_info) {
     switch(current_info) {
     case EPC_INFO:
     case EPC_INFO:
-        temp_str = convertToHexString(uhf_tag->epc, uhf_tag->epc_length);
-        length = uhf_tag->epc_length;
+        temp_str = convertToHexString(uhf_tag->epc->data, uhf_tag->epc->size);
+        length = uhf_tag->epc->size;
         break;
         break;
     case TID_INFO:
     case TID_INFO:
-        temp_str = convertToHexString(uhf_tag->tid, uhf_tag->tid_length);
-        length = uhf_tag->tid_length;
+        temp_str = convertToHexString(uhf_tag->tid->data, uhf_tag->tid->size);
+        length = uhf_tag->tid->size;
         break;
         break;
     case USER_INFO:
     case USER_INFO:
-        temp_str = convertToHexString(uhf_tag->user, uhf_tag->user_length);
-        length = uhf_tag->user_length;
+        temp_str = convertToHexString(uhf_tag->user->data, uhf_tag->user->size);
+        length = uhf_tag->user->size;
         break;
         break;
     default:
     default:
         temp_str = NULL;
         temp_str = NULL;

+ 28 - 11
non_catalog_apps/uhf_rfid/scenes/uhf_scene_read_tag_success.c

@@ -17,7 +17,8 @@ void uhf_scene_read_card_success_widget_callback(GuiButtonType result, InputType
 
 
 void uhf_scene_read_tag_success_on_enter(void* ctx) {
 void uhf_scene_read_tag_success_on_enter(void* ctx) {
     UHFApp* uhf_app = ctx;
     UHFApp* uhf_app = ctx;
-    UHFTag* uhf_tag = uhf_app->worker->uhf_tag;
+    UHFTag* uhf_tag = uhf_app->worker->uhf_tag_wrapper->uhf_tag;
+    FuriString* temp_str = furi_string_alloc();
 
 
     dolphin_deed(DolphinDeedNfcReadSuccess);
     dolphin_deed(DolphinDeedNfcReadSuccess);
 
 
@@ -35,13 +36,30 @@ void uhf_scene_read_tag_success_on_enter(void* ctx) {
     widget_add_string_element(
     widget_add_string_element(
         uhf_app->widget, 3, 32, AlignLeft, AlignCenter, FontPrimary, "EPC :");
         uhf_app->widget, 3, 32, AlignLeft, AlignCenter, FontPrimary, "EPC :");
 
 
-    char* pc = convertToHexString(uhf_tag->pc, 2);
-    widget_add_string_element(uhf_app->widget, 26, 19, AlignLeft, AlignCenter, FontKeyboard, pc);
-    char* crc = convertToHexString(uhf_tag->crc, 2);
-    widget_add_string_element(uhf_app->widget, 96, 19, AlignLeft, AlignCenter, FontKeyboard, crc);
-    char* epc = convertToHexString(uhf_tag->epc + 2, uhf_tag->epc_length - 2);
-    widget_add_string_multiline_element(
-        uhf_app->widget, 34, 29, AlignLeft, AlignTop, FontKeyboard, epc);
+    furi_string_cat_printf(temp_str, "%04X", uhf_tag->epc->pc);
+    widget_add_string_element(
+        uhf_app->widget,
+        26,
+        19,
+        AlignLeft,
+        AlignCenter,
+        FontKeyboard,
+        furi_string_get_cstr(temp_str));
+    furi_string_reset(temp_str);
+    furi_string_cat_printf(temp_str, "%04X", uhf_tag->epc->crc);
+    widget_add_string_element(
+        uhf_app->widget,
+        96,
+        19,
+        AlignLeft,
+        AlignCenter,
+        FontKeyboard,
+        furi_string_get_cstr(temp_str));
+    char* epc = convertToHexString(uhf_tag->epc->data, uhf_tag->epc->size);
+    if(epc != NULL) {
+        widget_add_string_multiline_element(
+            uhf_app->widget, 34, 29, AlignLeft, AlignTop, FontKeyboard, epc);
+    }
     widget_add_button_element(
     widget_add_button_element(
         uhf_app->widget,
         uhf_app->widget,
         GuiButtonTypeRight,
         GuiButtonTypeRight,
@@ -55,9 +73,8 @@ void uhf_scene_read_tag_success_on_enter(void* ctx) {
         uhf_scene_read_card_success_widget_callback,
         uhf_scene_read_card_success_widget_callback,
         uhf_app);
         uhf_app);
     view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewWidget);
     view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewWidget);
-    free(pc);
-    free(crc);
     free(epc);
     free(epc);
+    furi_string_free(temp_str);
 }
 }
 
 
 bool uhf_scene_read_tag_success_on_event(void* ctx, SceneManagerEvent event) {
 bool uhf_scene_read_tag_success_on_event(void* ctx, SceneManagerEvent event) {
@@ -72,7 +89,7 @@ bool uhf_scene_read_tag_success_on_event(void* ctx, SceneManagerEvent event) {
             consumed = scene_manager_search_and_switch_to_previous_scene(
             consumed = scene_manager_search_and_switch_to_previous_scene(
                 uhf_app->scene_manager, UHFSceneStart);
                 uhf_app->scene_manager, UHFSceneStart);
         } else if(event.event == GuiButtonTypeRight) {
         } else if(event.event == GuiButtonTypeRight) {
-            scene_manager_next_scene(uhf_app->scene_manager, UHFSceneCardMenu);
+            scene_manager_next_scene(uhf_app->scene_manager, UHFSceneTagMenu);
             consumed = true;
             consumed = true;
         } else if(event.event == GuiButtonTypeCenter) {
         } else if(event.event == GuiButtonTypeCenter) {
             // consumed = scene_manager_search_and_switch_to_another_scene(
             // consumed = scene_manager_search_and_switch_to_another_scene(

+ 2 - 2
non_catalog_apps/uhf_rfid/scenes/uhf_scene_save_success.c

@@ -27,9 +27,9 @@ bool uhf_scene_save_success_on_event(void* context, SceneManagerEvent event) {
 
 
     if(event.type == SceneManagerEventTypeCustom) {
     if(event.type == SceneManagerEventTypeCustom) {
         if(event.event == UHFCustomEventViewExit) {
         if(event.event == UHFCustomEventViewExit) {
-            if(scene_manager_has_previous_scene(uhf_app->scene_manager, UHFSceneCardMenu)) {
+            if(scene_manager_has_previous_scene(uhf_app->scene_manager, UHFSceneTagMenu)) {
                 consumed = scene_manager_search_and_switch_to_previous_scene(
                 consumed = scene_manager_search_and_switch_to_previous_scene(
-                    uhf_app->scene_manager, UHFSceneCardMenu);
+                    uhf_app->scene_manager, UHFSceneTagMenu);
             } else {
             } else {
                 consumed = scene_manager_search_and_switch_to_previous_scene(
                 consumed = scene_manager_search_and_switch_to_previous_scene(
                     uhf_app->scene_manager, UHFSceneStart);
                     uhf_app->scene_manager, UHFSceneStart);

+ 3 - 4
non_catalog_apps/uhf_rfid/scenes/uhf_scene_saved_menu.c

@@ -43,11 +43,10 @@ bool uhf_scene_saved_menu_on_event(void* context, SceneManagerEvent event) {
         } else if(event.event == SubmenuIndexInfo) {
         } else if(event.event == SubmenuIndexInfo) {
             scene_manager_next_scene(uhf_app->scene_manager, UHFSceneDeviceInfo);
             scene_manager_next_scene(uhf_app->scene_manager, UHFSceneDeviceInfo);
             consumed = true;
             consumed = true;
+        } else if(event.event == SubmenuIndexWrite) {
+            scene_manager_next_scene(uhf_app->scene_manager, UHFSceneWriteTag);
+            consumed = true;
         }
         }
-        // } else if(event.event == SubmenuIndexWrite) {
-        //     scene_manager_next_scene(uhf_app->scene_manager, UHFSceneWriteCard);
-        //     consumed = true;
-        // }
     }
     }
 
 
     return consumed;
     return consumed;

+ 9 - 13
non_catalog_apps/uhf_rfid/scenes/uhf_scene_card_menu.c → non_catalog_apps/uhf_rfid/scenes/uhf_scene_tag_menu.c

@@ -5,45 +5,41 @@ enum SubmenuIndex {
     SubmenuIndexChangeKey,
     SubmenuIndexChangeKey,
 };
 };
 
 
-void uhf_scene_card_menu_submenu_callback(void* ctx, uint32_t index) {
+void uhf_scene_tag_menu_submenu_callback(void* ctx, uint32_t index) {
     UHFApp* uhf_app = ctx;
     UHFApp* uhf_app = ctx;
     view_dispatcher_send_custom_event(uhf_app->view_dispatcher, index);
     view_dispatcher_send_custom_event(uhf_app->view_dispatcher, index);
 }
 }
 
 
-void uhf_scene_card_menu_on_enter(void* ctx) {
+void uhf_scene_tag_menu_on_enter(void* ctx) {
     UHFApp* uhf_app = ctx;
     UHFApp* uhf_app = ctx;
 
 
     Submenu* submenu = uhf_app->submenu;
     Submenu* submenu = uhf_app->submenu;
 
 
     submenu_add_item(
     submenu_add_item(
-        submenu, "Save", SubmenuIndexSave, uhf_scene_card_menu_submenu_callback, uhf_app);
+        submenu, "Save", SubmenuIndexSave, uhf_scene_tag_menu_submenu_callback, uhf_app);
     submenu_add_item(
     submenu_add_item(
-        submenu,
-        "Change Key",
-        SubmenuIndexChangeKey,
-        uhf_scene_card_menu_submenu_callback,
-        uhf_app);
+        submenu, "Change Key", SubmenuIndexChangeKey, uhf_scene_tag_menu_submenu_callback, uhf_app);
 
 
     submenu_set_selected_item(
     submenu_set_selected_item(
-        submenu, scene_manager_get_scene_state(uhf_app->scene_manager, UHFSceneCardMenu));
+        submenu, scene_manager_get_scene_state(uhf_app->scene_manager, UHFSceneTagMenu));
 
 
     view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewMenu);
     view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewMenu);
 }
 }
 
 
-bool uhf_scene_card_menu_on_event(void* ctx, SceneManagerEvent event) {
+bool uhf_scene_tag_menu_on_event(void* ctx, SceneManagerEvent event) {
     UHFApp* uhf_app = ctx;
     UHFApp* uhf_app = ctx;
     bool consumed = false;
     bool consumed = false;
 
 
     if(event.type == SceneManagerEventTypeCustom) {
     if(event.type == SceneManagerEventTypeCustom) {
         if(event.event == SubmenuIndexSave) {
         if(event.event == SubmenuIndexSave) {
             scene_manager_set_scene_state(
             scene_manager_set_scene_state(
-                uhf_app->scene_manager, UHFSceneCardMenu, SubmenuIndexSave);
+                uhf_app->scene_manager, UHFSceneTagMenu, SubmenuIndexSave);
             scene_manager_next_scene(uhf_app->scene_manager, UHFSceneSaveName);
             scene_manager_next_scene(uhf_app->scene_manager, UHFSceneSaveName);
             consumed = true;
             consumed = true;
         }
         }
         // else if(event.event == SubmenuIndexChangeKey) {
         // else if(event.event == SubmenuIndexChangeKey) {
         //     scene_manager_set_scene_state(
         //     scene_manager_set_scene_state(
-        //         picopass->scene_manager, UHFSceneCardMenu, SubmenuIndexChangeKey);
+        //         picopass->scene_manager, UHFSceneTagMenu, SubmenuIndexChangeKey);
         //     scene_manager_next_scene(picopass->scene_manager, PicopassSceneKeyMenu);
         //     scene_manager_next_scene(picopass->scene_manager, PicopassSceneKeyMenu);
         //     consumed = true;
         //     consumed = true;
         // }
         // }
@@ -55,7 +51,7 @@ bool uhf_scene_card_menu_on_event(void* ctx, SceneManagerEvent event) {
     return consumed;
     return consumed;
 }
 }
 
 
-void uhf_scene_card_menu_on_exit(void* ctx) {
+void uhf_scene_tag_menu_on_exit(void* ctx) {
     UHFApp* uhf_app = ctx;
     UHFApp* uhf_app = ctx;
 
 
     submenu_reset(uhf_app->submenu);
     submenu_reset(uhf_app->submenu);

+ 5 - 15
non_catalog_apps/uhf_rfid/scenes/uhf_scene_verify.c

@@ -52,18 +52,12 @@ bool uhf_scene_verify_on_event(void* ctx, SceneManagerEvent event) {
             if(verify_success) {
             if(verify_success) {
                 widget_reset(uhf_app->widget);
                 widget_reset(uhf_app->widget);
                 furi_string_reset(temp_str);
                 furi_string_reset(temp_str);
-                UHFResponseData* uhf_response_data = uhf_app->worker->response_data;
-                UHFData* hardware_version = uhf_response_data_get_uhf_data(uhf_response_data, 0);
-                UHFData* software_version = uhf_response_data_get_uhf_data(uhf_response_data, 1);
-                UHFData* manufacturer = uhf_response_data_get_uhf_data(uhf_response_data, 2);
-                uint offset = 6;
+                M100Module* module = uhf_app->worker->module;
                 widget_add_string_element(
                 widget_add_string_element(
                     uhf_app->widget, 64, 5, AlignCenter, AlignCenter, FontPrimary, "Module Info");
                     uhf_app->widget, 64, 5, AlignCenter, AlignCenter, FontPrimary, "Module Info");
                 // hardware info
                 // hardware info
                 furi_string_cat_str(temp_str, "HW Version: ");
                 furi_string_cat_str(temp_str, "HW Version: ");
-                for(int i = 0; i < (int)hardware_version->data[4]; i++) {
-                    furi_string_cat_printf(temp_str, "%c", hardware_version->data[offset + i]);
-                }
+                furi_string_cat_str(temp_str, module->info->hw_version);
                 widget_add_string_element(
                 widget_add_string_element(
                     uhf_app->widget,
                     uhf_app->widget,
                     1,
                     1,
@@ -75,9 +69,7 @@ bool uhf_scene_verify_on_event(void* ctx, SceneManagerEvent event) {
                 furi_string_reset(temp_str);
                 furi_string_reset(temp_str);
                 // software info
                 // software info
                 furi_string_cat_str(temp_str, "SW Version: ");
                 furi_string_cat_str(temp_str, "SW Version: ");
-                for(int i = 0; i < (int)software_version->data[4]; i++) {
-                    furi_string_cat_printf(temp_str, "%c", software_version->data[offset + i]);
-                }
+                furi_string_cat_str(temp_str, module->info->sw_version);
                 widget_add_string_element(
                 widget_add_string_element(
                     uhf_app->widget,
                     uhf_app->widget,
                     1,
                     1,
@@ -89,9 +81,7 @@ bool uhf_scene_verify_on_event(void* ctx, SceneManagerEvent event) {
                 furi_string_reset(temp_str);
                 furi_string_reset(temp_str);
                 // manufacturer info
                 // manufacturer info
                 furi_string_cat_str(temp_str, "Manufacturer: ");
                 furi_string_cat_str(temp_str, "Manufacturer: ");
-                for(int i = 0; i < (int)manufacturer->data[4]; i++) {
-                    furi_string_cat_printf(temp_str, "%c", manufacturer->data[offset + i]);
-                }
+                furi_string_cat_str(temp_str, module->info->manufacturer);
                 widget_add_string_element(
                 widget_add_string_element(
                     uhf_app->widget,
                     uhf_app->widget,
                     1,
                     1,
@@ -123,7 +113,7 @@ bool uhf_scene_verify_on_event(void* ctx, SceneManagerEvent event) {
                     AlignCenter,
                     AlignCenter,
                     AlignCenter,
                     AlignCenter,
                     FontSecondary,
                     FontSecondary,
-                    "Please connect your module.\nPlease refer to the frux-c/uhf_rfid for help.");
+                    "Please connect your module.\nPlease refer to the git@frux-c/uhf_rfid for help.");
                 widget_add_button_element(
                 widget_add_button_element(
                     uhf_app->widget,
                     uhf_app->widget,
                     GuiButtonTypeLeft,
                     GuiButtonTypeLeft,

+ 49 - 0
non_catalog_apps/uhf_rfid/scenes/uhf_scene_write_tag.c

@@ -0,0 +1,49 @@
+#include "../uhf_app_i.h"
+#include <dolphin/dolphin.h>
+
+void uhf_write_tag_worker_callback(UHFWorkerEvent event, void* ctx) {
+    UHFApp* uhf_app = ctx;
+    if(event == UHFWorkerEventSuccess) {
+        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_write_tag_on_enter(void* ctx) {
+    UHFApp* uhf_app = ctx;
+    dolphin_deed(DolphinDeedNfcRead);
+
+    // Setup view
+    Popup* popup = uhf_app->popup;
+    popup_set_header(popup, "Writing\n[UHF] RFID\nTag", 68, 30, AlignLeft, AlignTop);
+    popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61);
+
+    // Start worker
+    view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewPopup);
+    uhf_worker_start(
+        uhf_app->worker, UHFWorkerStateWriteSingle, uhf_write_tag_worker_callback, uhf_app);
+
+    uhf_blink_start(uhf_app);
+}
+
+bool uhf_scene_write_tag_on_event(void* ctx, SceneManagerEvent event) {
+    UHFApp* uhf_app = ctx;
+    bool consumed = false;
+    if(event.event == UHFCustomEventWorkerExit) {
+        scene_manager_next_scene(uhf_app->scene_manager, UHFSceneWriteTagSuccess);
+        consumed = true;
+    }
+    return consumed;
+}
+
+void uhf_scene_write_tag_on_exit(void* ctx) {
+    UHFApp* uhf_app = ctx;
+    // Stop worker
+    uhf_worker_stop(uhf_app->worker);
+    // Clear view
+    popup_reset(uhf_app->popup);
+
+    uhf_blink_stop(uhf_app);
+}

+ 94 - 0
non_catalog_apps/uhf_rfid/scenes/uhf_scene_write_tag_success.c

@@ -0,0 +1,94 @@
+#include "../uhf_app_i.h"
+#include <dolphin/dolphin.h>
+
+void uhf_write_tag_success_worker_callback(UHFWorkerEvent event, void* ctx) {
+    UNUSED(event);
+    UNUSED(ctx);
+}
+
+void uhf_scene_write_tag_success_widget_callback(GuiButtonType result, InputType type, void* ctx) {
+    furi_assert(ctx);
+    UHFApp* uhf_app = ctx;
+
+    if(type == InputTypeShort) {
+        view_dispatcher_send_custom_event(uhf_app->view_dispatcher, result);
+    }
+}
+
+void uhf_scene_write_tag_success_on_enter(void* ctx) {
+    UHFApp* uhf_app = ctx;
+
+    dolphin_deed(DolphinDeedNfcReadSuccess);
+
+    // Send notification
+    notification_message(uhf_app->notifications, &sequence_success);
+
+    widget_add_string_element(
+        uhf_app->widget, 32, 5, AlignLeft, AlignCenter, FontPrimary, "Write Success");
+
+    // widget_add_string_element(uhf_app->widget, 3, 18, AlignLeft, AlignCenter, FontPrimary, "PC :");
+
+    // widget_add_string_element(
+    //     uhf_app->widget, 66, 18, AlignLeft, AlignCenter, FontPrimary, "CRC :");
+
+    // widget_add_string_element(
+    //     uhf_app->widget, 3, 32, AlignLeft, AlignCenter, FontPrimary, "EPC :");
+
+    // char* pc = convertToHexString(uhf_tag->pc, 2);
+    // widget_add_string_element(uhf_app->widget, 26, 19, AlignLeft, AlignCenter, FontKeyboard, pc);
+    // char* crc = convertToHexString(uhf_tag->crc, 2);
+    // widget_add_string_element(uhf_app->widget, 96, 19, AlignLeft, AlignCenter, FontKeyboard, crc);
+    // char* epc = convertToHexString(uhf_tag->epc + 2, uhf_tag->epc_length - 2);
+    // widget_add_string_multiline_element(
+    //     uhf_app->widget, 34, 29, AlignLeft, AlignTop, FontKeyboard, epc);
+
+    widget_add_button_element(
+        uhf_app->widget,
+        GuiButtonTypeRight,
+        "More",
+        uhf_scene_write_tag_success_widget_callback,
+        uhf_app);
+    widget_add_button_element(
+        uhf_app->widget,
+        GuiButtonTypeLeft,
+        "Exit",
+        uhf_scene_write_tag_success_widget_callback,
+        uhf_app);
+    view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewWidget);
+    // free(pc);
+    // free(crc);
+    // free(epc);
+}
+
+bool uhf_scene_write_tag_success_on_event(void* ctx, SceneManagerEvent event) {
+    UHFApp* uhf_app = ctx;
+    bool consumed = false;
+    if(event.event == SceneManagerEventTypeBack) {
+        uhf_app->worker->state = UHFWorkerStateStop;
+    }
+    if(event.type == SceneManagerEventTypeCustom) {
+        // if 'exit' is pressed go back to home screen
+        if(event.event == GuiButtonTypeLeft) {
+            consumed = scene_manager_search_and_switch_to_previous_scene(
+                uhf_app->scene_manager, UHFSceneStart);
+        } else if(event.event == GuiButtonTypeRight) {
+            scene_manager_next_scene(uhf_app->scene_manager, UHFSceneTagMenu);
+            consumed = true;
+        } else if(event.event == GuiButtonTypeCenter) {
+            // consumed = scene_manager_search_and_switch_to_another_scene(
+            //     picopass->scene_manager, PicopassSceneStart);
+        }
+    }
+    return consumed;
+}
+
+void uhf_scene_write_tag_success_on_exit(void* ctx) {
+    UHFApp* uhf_app = ctx;
+
+    // // Stop worker
+    uhf_worker_stop(uhf_app->worker);
+    // Clear view
+    popup_reset(uhf_app->popup);
+    // clear widget
+    widget_reset(uhf_app->widget);
+}

+ 11 - 14
non_catalog_apps/uhf_rfid/uhf_app.c

@@ -1,6 +1,6 @@
 #include "uhf_app_i.h"
 #include "uhf_app_i.h"
 
 
-char* convertToHexString(const uint8_t* array, size_t length) {
+char* convertToHexString(uint8_t* array, size_t length) {
     if(array == NULL || length == 0) {
     if(array == NULL || length == 0) {
         return " ";
         return " ";
     }
     }
@@ -60,10 +60,11 @@ UHFApp* uhf_alloc() {
     // device
     // device
     uhf_app->uhf_device = uhf_device_alloc();
     uhf_app->uhf_device = uhf_device_alloc();
 
 
-    UHFTag* uhf_tag = uhf_tag_alloc();
-    // point tag object to worker
-    uhf_app->worker->uhf_tag = uhf_tag;
-    uhf_app->uhf_device->uhf_tag = uhf_tag;
+    UHFTagWrapper* uhf_tag_wrapper = uhf_tag_wrapper_alloc();
+
+    // // point tag object to worker
+    uhf_app->worker->uhf_tag_wrapper = uhf_tag_wrapper;
+    uhf_app->uhf_device->uhf_tag_wrapper = uhf_tag_wrapper;
 
 
     // Open Notification record
     // Open Notification record
     uhf_app->notifications = furi_record_open(RECORD_NOTIFICATION);
     uhf_app->notifications = furi_record_open(RECORD_NOTIFICATION);
@@ -119,12 +120,15 @@ void uhf_free(UHFApp* uhf_app) {
     view_dispatcher_remove_view(uhf_app->view_dispatcher, UHFViewWidget);
     view_dispatcher_remove_view(uhf_app->view_dispatcher, UHFViewWidget);
     widget_free(uhf_app->widget);
     widget_free(uhf_app->widget);
 
 
+    // Tag
+    uhf_tag_wrapper_free(uhf_app->worker->uhf_tag_wrapper);
+
     // Worker
     // Worker
     uhf_worker_stop(uhf_app->worker);
     uhf_worker_stop(uhf_app->worker);
     uhf_worker_free(uhf_app->worker);
     uhf_worker_free(uhf_app->worker);
 
 
-    // Tag
-    uhf_tag_free(uhf_app->worker->uhf_tag);
+    // Device
+    uhf_device_free(uhf_app->uhf_device);
 
 
     // View Dispatcher
     // View Dispatcher
     view_dispatcher_free(uhf_app->view_dispatcher);
     view_dispatcher_free(uhf_app->view_dispatcher);
@@ -136,9 +140,6 @@ void uhf_free(UHFApp* uhf_app) {
     furi_record_close(RECORD_GUI);
     furi_record_close(RECORD_GUI);
     uhf_app->gui = NULL;
     uhf_app->gui = NULL;
 
 
-    // UHFDevice
-    uhf_device_free(uhf_app->uhf_device);
-
     // Notifications
     // Notifications
     furi_record_close(RECORD_NOTIFICATION);
     furi_record_close(RECORD_NOTIFICATION);
     uhf_app->notifications = NULL;
     uhf_app->notifications = NULL;
@@ -184,8 +185,6 @@ int32_t uhf_app_main(void* ctx) {
     UNUSED(ctx);
     UNUSED(ctx);
     UHFApp* uhf_app = uhf_alloc();
     UHFApp* uhf_app = uhf_alloc();
 
 
-    furi_hal_uart_resume(FuriHalUartIdUSART1);
-
     // enable 5v pin
     // enable 5v pin
     furi_hal_power_enable_otg();
     furi_hal_power_enable_otg();
 
 
@@ -195,8 +194,6 @@ int32_t uhf_app_main(void* ctx) {
     // disable 5v pin
     // disable 5v pin
     furi_hal_power_disable_otg();
     furi_hal_power_disable_otg();
 
 
-    furi_hal_uart_suspend(FuriHalUartIdUSART1);
-
     // exit app
     // exit app
     uhf_free(uhf_app);
     uhf_free(uhf_app);
     return 0;
     return 0;

+ 2 - 2
non_catalog_apps/uhf_rfid/uhf_app_i.h

@@ -99,6 +99,6 @@ void uhf_show_loading_popup(void* context, bool show);
  */
  */
 bool uhf_is_memset(const uint8_t* data, const uint8_t pattern, size_t size);
 bool uhf_is_memset(const uint8_t* data, const uint8_t pattern, size_t size);
 
 
-char* convertToHexString(const uint8_t* array, size_t length);
+char* convertToHexString(uint8_t* array, size_t length);
 
 
-bool uhf_save_read_data(UHFResponseData* uhf_response_data, Storage* storage, const char* filename);
+// bool uhf_save_read_data(UHFResponseData* uhf_response_data, Storage* storage, const char* filename);

+ 66 - 0
non_catalog_apps/uhf_rfid/uhf_buffer.c

@@ -0,0 +1,66 @@
+#include "uhf_buffer.h"
+#include <stdlib.h>
+#include <string.h>
+
+Buffer* buffer_alloc(size_t initial_capacity) {
+    Buffer* buf = (Buffer*)malloc(sizeof(Buffer));
+    buf->data = (uint8_t*)malloc(sizeof(uint8_t) * initial_capacity);
+    if(!buf->data) {
+        free(buf);
+        return NULL;
+    }
+    buf->size = 0;
+    buf->capacity = initial_capacity;
+    return buf;
+}
+
+bool buffer_append_single(Buffer* buf, uint8_t data) {
+    if(buf->closed) return false;
+    if(buf->size + 1 > buf->capacity) {
+        size_t new_capacity = buf->capacity * 2;
+        uint8_t* new_data = (uint8_t*)realloc(buf->data, sizeof(uint8_t) * new_capacity);
+        if(!new_data) return false;
+        buf->data = new_data;
+        buf->capacity = new_capacity;
+    }
+    buf->data[buf->size++] = data;
+    return true;
+}
+
+bool buffer_append(Buffer* buf, uint8_t* data, size_t data_size) {
+    if(buf->closed) return false;
+    if(buf->size + data_size > buf->capacity) {
+        size_t new_capacity = buf->capacity * 2;
+        uint8_t* new_data = (uint8_t*)realloc(buf->data, new_capacity);
+        if(!new_data) return false;
+
+        buf->data = new_data;
+        buf->capacity = new_capacity;
+    }
+
+    memcpy((void*)&buf->data[buf->size], data, data_size);
+    buf->size += data_size;
+    return true;
+}
+
+uint8_t* buffer_get_data(Buffer* buf) {
+    return buf->data;
+}
+
+size_t buffer_get_size(Buffer* buf) {
+    return buf->size;
+}
+
+void buffer_close(Buffer* buf) {
+    buf->closed = true;
+}
+
+void buffer_reset(Buffer* buf) {
+    buf->size = 0;
+    buf->closed = false;
+}
+
+void buffer_free(Buffer* buf) {
+    free(buf->data);
+    free(buf);
+}

+ 22 - 0
non_catalog_apps/uhf_rfid/uhf_buffer.h

@@ -0,0 +1,22 @@
+#pragma once
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#define MAX_BUFFER_SIZE 128
+
+typedef struct Buffer {
+    uint8_t* data;
+    size_t size;
+    size_t capacity;
+    bool closed;
+} Buffer;
+
+Buffer* buffer_alloc(size_t inital_capacity);
+bool buffer_append_single(Buffer* buf, uint8_t value);
+bool buffer_append(Buffer* buf, uint8_t* data, size_t size);
+uint8_t* buffer_get_data(Buffer* buf);
+size_t buffer_get_size(Buffer* buf);
+void buffer_close(Buffer* buf);
+void buffer_reset(Buffer* buf);
+void buffer_free(Buffer* buf);

+ 69 - 69
non_catalog_apps/uhf_rfid/uhf_cmd.h

@@ -1,114 +1,114 @@
-#ifndef UHF_CMD_H
-#define UHF_CMD_H
+// #ifndef UHF_CMD_H
+// #define UHF_CMD_H
 
 
-#include <stdint.h>
-#include <stdlib.h>
+// #include <stdint.h>
+// #include <stdlib.h>
 
 
-typedef struct UHF_RFID_CMD {
-    uint8_t* cmd;
-    size_t length;
-}UHF_RFID_CMD;
+// 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{
+//     COMMAND_FRAME = 0x00,
+//     RESPONSE_FRAME,
+//     NOTIFICATION_FRAME
+// }UHFFrameType;
 
 
-typedef enum{
-    RFU_BANK,
-    EPC_BANK,
-    TID_BANK,
-    USER_BANK
-}UHFBank;
+// 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;
+// 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
+// #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_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_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_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_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_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_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_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_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_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_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, 0x11, 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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};
+// 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 */
+// #endif /* UHF_CMD_H */

+ 0 - 148
non_catalog_apps/uhf_rfid/uhf_data.c

@@ -1,148 +0,0 @@
-#include "uhf_data.h"
-
-UHFData* uhf_data_alloc() {
-    UHFData* uhf_data = (UHFData*)malloc(sizeof(UHFData));
-    uhf_data->word_length = 0;
-    uhf_data->length = 0;
-    uhf_data->start = false;
-    uhf_data->end = false;
-    uhf_data->next = NULL;
-    return uhf_data;
-}
-
-int uhf_data_append(UHFData* uhf_data, uint8_t data) {
-    if(data == 0xBB) {
-        uhf_data->start = true;
-    }
-    if(!uhf_data->start) return 0;
-    if(uhf_data->end) return 0;
-    if(uhf_data->length >= MAX_DATA_SIZE) return 0;
-    if(data == 0x7E) {
-        uhf_data->end = true;
-    }
-    uhf_data->data[uhf_data->length++] = data;
-    return 1;
-}
-
-void uhf_data_reset(UHFData* uhf_data) {
-    for(size_t i = 0; i < uhf_data->length; i++) {
-        uhf_data->data[i] = 0x00;
-    }
-    uhf_data->start = false;
-    uhf_data->end = false;
-    uhf_data->length = 0;
-    uhf_data->next = NULL;
-}
-
-uint8_t uhf_data_calculate_checksum(UHFData* uhf_data) {
-    // CheckSum8 Modulo 256
-    // Sum of Bytes % 256
-    uint8_t sum_val = 0x00;
-    size_t length = uhf_data->length - 2;
-    for(size_t i = 1; i < length; i++) {
-        sum_val += uhf_data->data[i];
-    }
-    return sum_val % 256;
-}
-
-bool uhf_data_verfiy_checksum(UHFData* uhf_data) {
-    uint8_t data_checksum = uhf_data->data[uhf_data->length - 2];
-    uint8_t actual_checksum = uhf_data_calculate_checksum(uhf_data);
-    return data_checksum == actual_checksum;
-}
-
-void uhf_data_free(UHFData* uhf_data) {
-    if(uhf_data == NULL) return;
-    while(uhf_data != NULL) {
-        UHFData* next = uhf_data->next;
-        free(uhf_data);
-        uhf_data = next;
-    }
-}
-
-UHFResponseData* uhf_response_data_alloc() {
-    UHFResponseData* uhf_response_data = (UHFResponseData*)malloc(sizeof(UHFResponseData));
-    uhf_response_data->head = uhf_data_alloc();
-    uhf_response_data->tail = uhf_response_data->head;
-    uhf_response_data->size = 1;
-    return uhf_response_data;
-}
-
-UHFData* uhf_response_data_add_new_uhf_data(UHFResponseData* uhf_response_data) {
-    UHFData* temp = uhf_response_data->head;
-    while(temp->next != NULL) {
-        temp = temp->next;
-    }
-    temp->next = uhf_data_alloc();
-    uhf_response_data->size++;
-    uhf_response_data->tail = temp->next;
-    return temp->next;
-}
-
-UHFData* uhf_response_data_get_uhf_data(UHFResponseData* uhf_response_data, uint index) {
-    if(uhf_response_data == NULL || uhf_response_data->size <= index) return NULL;
-    UHFData* uhf_data = uhf_response_data->head;
-    if(index == 0) return uhf_data;
-    while(uhf_data != NULL && index >= 1) {
-        uhf_data = uhf_data->next;
-        index--;
-    }
-    return uhf_data;
-}
-
-void uhf_response_data_reset(UHFResponseData* uhf_response_data) {
-    uhf_data_reset(uhf_response_data->head);
-    if(uhf_response_data->size == 1) {
-        return;
-    }
-    uhf_data_free(uhf_response_data->head->next);
-    uhf_response_data->size = 1;
-}
-
-void uhf_response_data_free(UHFResponseData* uhf_response_data) {
-    uhf_data_free(uhf_response_data->head);
-    free(uhf_response_data);
-}
-
-UHFTag* uhf_tag_alloc() {
-    UHFTag* uhf_tag = (UHFTag*)malloc(sizeof(UHFTag));
-    return uhf_tag;
-}
-
-void uhf_tag_set_epc(UHFTag* uhf_tag, uint8_t* data, size_t length) {
-    memcpy(uhf_tag->crc, data, 2);
-    data += 2;
-    memcpy(uhf_tag->pc, data, 2);
-    memcpy(uhf_tag->epc, data, length);
-    uhf_tag->epc_length = length;
-}
-
-void uhf_tag_reset(UHFTag* uhf_tag) {
-    for(int i = 0; i < 2; i++) {
-        uhf_tag->crc[i] = 0;
-        uhf_tag->pc[i] = 0;
-        uhf_tag->xpc[i] = 0;
-    }
-    for(int i = 0; i < MAX_BANK_SIZE; i++) {
-        uhf_tag->epc[i] = 0;
-        uhf_tag->tid[i] = 0;
-        uhf_tag->user[i] = 0;
-    }
-    uhf_tag->epc_length = 0;
-    uhf_tag->tid_length = 0;
-    uhf_tag->user_length = 0;
-}
-
-void uhf_tag_set_tid(UHFTag* uhf_tag, uint8_t* data, size_t length) {
-    memcpy(uhf_tag->tid, data, length);
-    uhf_tag->tid_length = length;
-}
-
-void uhf_tag_set_user(UHFTag* uhf_tag, uint8_t* data, size_t length) {
-    memcpy(uhf_tag->user, data, length);
-    uhf_tag->user_length = length;
-}
-
-void uhf_tag_free(UHFTag* uhf_tag) {
-    free(uhf_tag);
-}

+ 0 - 64
non_catalog_apps/uhf_rfid/uhf_data.h

@@ -1,64 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-
-#define MAX_DATA_SIZE 128
-#define MAX_BANK_SIZE 64
-typedef unsigned int uint;
-
-typedef struct UHFData {
-    uint8_t data[MAX_DATA_SIZE];
-    size_t word_length;
-    size_t length;
-    bool start;
-    bool end;
-    struct UHFData* next;
-} UHFData;
-
-typedef struct UHFResponseData {
-    UHFData* head;
-    UHFData* tail;
-    size_t size;
-} UHFResponseData;
-
-typedef struct UHFTag {
-    // RESERVED BANK (RFU) (00)
-    uint8_t kill_pwd[2]; // 0x00-0x10
-    uint8_t access_pwd[2]; // 0x10-0x20
-    // EPC Bank
-    uint8_t crc[2]; // 0x00-0x10
-    uint8_t pc[2]; // 0x10-0x20
-    uint8_t epc[MAX_BANK_SIZE]; // 0x20-0x210
-    size_t epc_length;
-    uint8_t xpc[2]; // 0x210-0x21F
-    size_t xpc_length;
-    // TID Bank
-    uint8_t tid[MAX_BANK_SIZE]; // 0x00-END
-    size_t tid_length;
-    // USER Bank
-    uint8_t user[MAX_BANK_SIZE]; // 0x00-END
-    size_t user_length;
-} UHFTag;
-
-UHFData* uhf_data_alloc();
-int uhf_data_append(UHFData* uhf_data, uint8_t data);
-void uhf_data_reset(UHFData* uhf_data);
-uint8_t uhf_data_calculate_checksum(UHFData* uhf_data);
-bool uhf_data_verfiy_checksum(UHFData* uhf_data);
-void uhf_data_free(UHFData* uhf_data);
-
-UHFResponseData* uhf_response_data_alloc();
-UHFData* uhf_response_data_add_new_uhf_data(UHFResponseData* uhf_response_data);
-UHFData* uhf_response_data_get_uhf_data(UHFResponseData* uhf_response_data, uint index);
-void uhf_response_data_reset(UHFResponseData* uhf_response_data);
-void uhf_response_data_free(UHFResponseData* uhf_response_data);
-
-UHFTag* uhf_tag_alloc();
-void uhf_tag_reset(UHFTag* uhf_tag);
-void uhf_tag_set_epc(UHFTag* uhf_tag, uint8_t* data, size_t length);
-void uhf_tag_set_tid(UHFTag* uhf_tag, uint8_t* data, size_t length);
-void uhf_tag_set_user(UHFTag* uhf_tag, uint8_t* data, size_t length);
-void uhf_tag_free(UHFTag* uhf_tag);

+ 19 - 16
non_catalog_apps/uhf_rfid/uhf_device.c

@@ -1,5 +1,4 @@
 #include "uhf_device.h"
 #include "uhf_device.h"
-
 #include <toolbox/path.h>
 #include <toolbox/path.h>
 #include <flipper_format/flipper_format.h>
 #include <flipper_format/flipper_format.h>
 #include <uhf_rfid_icons.h>
 #include <uhf_rfid_icons.h>
@@ -21,7 +20,6 @@ UHFDevice* uhf_device_alloc() {
 
 
 void uhf_device_set_name(UHFDevice* dev, const char* name) {
 void uhf_device_set_name(UHFDevice* dev, const char* name) {
     furi_assert(dev);
     furi_assert(dev);
-
     strlcpy(dev->dev_name, name, UHF_DEV_NAME_MAX_LEN);
     strlcpy(dev->dev_name, name, UHF_DEV_NAME_MAX_LEN);
 }
 }
 
 
@@ -33,7 +31,7 @@ static bool uhf_device_save_file(
     bool use_load_path) {
     bool use_load_path) {
     furi_assert(dev);
     furi_assert(dev);
 
 
-    UHFTag* uhf_tag = dev->uhf_tag;
+    UHFTag* uhf_tag = dev->uhf_tag_wrapper->uhf_tag;
     bool saved = false;
     bool saved = false;
     FlipperFormat* file = flipper_format_file_alloc(dev->storage);
     FlipperFormat* file = flipper_format_file_alloc(dev->storage);
     FuriString* temp_str;
     FuriString* temp_str;
@@ -58,20 +56,22 @@ static bool uhf_device_save_file(
         // todo : maybe
         // todo : maybe
         uint32_t temp_arr[1];
         uint32_t temp_arr[1];
         // write epc
         // write epc
-        temp_arr[0] = uhf_tag->epc_length;
+        temp_arr[0] = uhf_tag->epc->size;
         if(!flipper_format_write_uint32(file, UHF_EPC_BANK_LENGTH_LABEL, temp_arr, 1)) break;
         if(!flipper_format_write_uint32(file, UHF_EPC_BANK_LENGTH_LABEL, temp_arr, 1)) break;
-        if(!flipper_format_write_hex(file, UHF_EPC_BANK_LABEL, uhf_tag->epc, uhf_tag->epc_length))
+        if(!flipper_format_write_hex(
+               file, UHF_EPC_BANK_LABEL, uhf_tag->epc->data, uhf_tag->epc->size))
             break;
             break;
         // write tid
         // write tid
-        temp_arr[0] = uhf_tag->tid_length;
+        temp_arr[0] = uhf_tag->tid->size;
         if(!flipper_format_write_uint32(file, UHF_TID_BANK_LENGTH_LABEL, temp_arr, 1)) break;
         if(!flipper_format_write_uint32(file, UHF_TID_BANK_LENGTH_LABEL, temp_arr, 1)) break;
-        if(!flipper_format_write_hex(file, UHF_TID_BANK_LABEL, uhf_tag->tid, uhf_tag->tid_length))
+        if(!flipper_format_write_hex(
+               file, UHF_TID_BANK_LABEL, uhf_tag->tid->data, uhf_tag->tid->size))
             break;
             break;
         // write user
         // write user
-        temp_arr[0] = uhf_tag->user_length;
+        temp_arr[0] = uhf_tag->user->size;
         if(!flipper_format_write_uint32(file, UHF_USER_BANK_LENGTH_LABEL, temp_arr, 1)) break;
         if(!flipper_format_write_uint32(file, UHF_USER_BANK_LENGTH_LABEL, temp_arr, 1)) break;
         if(!flipper_format_write_hex(
         if(!flipper_format_write_hex(
-               file, UHF_USER_BANK_LABEL, uhf_tag->user, uhf_tag->user_length))
+               file, UHF_USER_BANK_LABEL, uhf_tag->user->data, uhf_tag->user->size))
             break;
             break;
         saved = true;
         saved = true;
     } while(0);
     } while(0);
@@ -99,7 +99,7 @@ static bool uhf_device_load_data(UHFDevice* dev, FuriString* path, bool show_dia
     FuriString* temp_str;
     FuriString* temp_str;
     temp_str = furi_string_alloc();
     temp_str = furi_string_alloc();
     bool deprecated_version = false;
     bool deprecated_version = false;
-    UHFTag* uhf_tag = dev->uhf_tag;
+    UHFTag* uhf_tag = dev->uhf_tag_wrapper->uhf_tag;
     uhf_tag_reset(uhf_tag);
     uhf_tag_reset(uhf_tag);
     uint32_t temp_arr[1];
     uint32_t temp_arr[1];
     if(dev->loading_cb) {
     if(dev->loading_cb) {
@@ -118,20 +118,23 @@ static bool uhf_device_load_data(UHFDevice* dev, FuriString* path, bool show_dia
         }
         }
         // read epc
         // read epc
         if(!flipper_format_read_uint32(file, UHF_EPC_BANK_LENGTH_LABEL, temp_arr, 1)) break;
         if(!flipper_format_read_uint32(file, UHF_EPC_BANK_LENGTH_LABEL, temp_arr, 1)) break;
-        uhf_tag->epc_length = temp_arr[0];
-        if(!flipper_format_read_hex(file, UHF_EPC_BANK_LABEL, uhf_tag->epc, uhf_tag->epc_length))
+        uhf_tag->epc->size = temp_arr[0];
+        if(!flipper_format_read_hex(
+               file, UHF_EPC_BANK_LABEL, uhf_tag->epc->data, uhf_tag->epc->size))
             break;
             break;
 
 
         // read tid
         // read tid
         if(!flipper_format_read_uint32(file, UHF_TID_BANK_LENGTH_LABEL, temp_arr, 1)) break;
         if(!flipper_format_read_uint32(file, UHF_TID_BANK_LENGTH_LABEL, temp_arr, 1)) break;
-        uhf_tag->tid_length = temp_arr[0];
-        if(!flipper_format_read_hex(file, UHF_TID_BANK_LABEL, uhf_tag->tid, uhf_tag->tid_length))
+        uhf_tag->tid->size = temp_arr[0];
+        if(!flipper_format_read_hex(
+               file, UHF_TID_BANK_LABEL, uhf_tag->tid->data, uhf_tag->tid->size))
             break;
             break;
 
 
         // read user
         // read user
         if(!flipper_format_read_uint32(file, UHF_USER_BANK_LENGTH_LABEL, temp_arr, 1)) break;
         if(!flipper_format_read_uint32(file, UHF_USER_BANK_LENGTH_LABEL, temp_arr, 1)) break;
-        uhf_tag->user_length = temp_arr[0];
-        if(!flipper_format_read_hex(file, UHF_USER_BANK_LABEL, uhf_tag->user, uhf_tag->user_length))
+        uhf_tag->user->size = temp_arr[0];
+        if(!flipper_format_read_hex(
+               file, UHF_USER_BANK_LABEL, uhf_tag->user->data, uhf_tag->user->size))
             break;
             break;
 
 
         parsed = true;
         parsed = true;

+ 2 - 4
non_catalog_apps/uhf_rfid/uhf_device.h

@@ -5,7 +5,7 @@
 #include <storage/storage.h>
 #include <storage/storage.h>
 #include <dialogs/dialogs.h>
 #include <dialogs/dialogs.h>
 #include <mbedtls/des.h>
 #include <mbedtls/des.h>
-#include "uhf_data.h"
+#include "uhf_tag.h"
 
 
 // #include "rfal_picopass.h"
 // #include "rfal_picopass.h"
 
 
@@ -28,15 +28,13 @@
 #define UHF_USER_BANK_LABEL "USER"
 #define UHF_USER_BANK_LABEL "USER"
 
 
 #define UHF_APP_EXTENSION ".uhf"
 #define UHF_APP_EXTENSION ".uhf"
-// #define PICOPASS_APP_SHADOW_EXTENSION ".pas"
 
 
 typedef void (*UHFLoadingCallback)(void* context, bool state);
 typedef void (*UHFLoadingCallback)(void* context, bool state);
 
 
 typedef struct {
 typedef struct {
     Storage* storage;
     Storage* storage;
     DialogsApp* dialogs;
     DialogsApp* dialogs;
-    // UHFResponseData* dev_data;
-    UHFTag* uhf_tag;
+    UHFTagWrapper* uhf_tag_wrapper;
     char dev_name[UHF_DEV_NAME_MAX_LEN + 1];
     char dev_name[UHF_DEV_NAME_MAX_LEN + 1];
     FuriString* load_path;
     FuriString* load_path;
     UHFLoadingCallback loading_cb;
     UHFLoadingCallback loading_cb;

+ 280 - 0
non_catalog_apps/uhf_rfid/uhf_module.c

@@ -0,0 +1,280 @@
+#include "uhf_module.h"
+#include "uhf_module_cmd.h"
+
+#define DELAY_MS 50
+
+void rx_callback(UartIrqEvent event, uint8_t data, void* ctx) {
+    UNUSED(event);
+    Buffer* buf = ctx;
+    buffer_append_single(buf, data);
+    if(data == FRAME_END) buffer_close(buf);
+}
+
+M100ModuleInfo* m100_module_info_alloc() {
+    M100ModuleInfo* module_info = (M100ModuleInfo*)malloc(sizeof(M100ModuleInfo));
+    module_info->hw_version = NULL;
+    module_info->sw_version = NULL;
+    module_info->manufacturer = NULL;
+    return module_info;
+}
+
+void m100_module_info_free(M100ModuleInfo* module_info) {
+    free(module_info->hw_version);
+    free(module_info->sw_version);
+    free(module_info->manufacturer);
+    free(module_info);
+}
+M100Module* m100_module_alloc() {
+    M100Module* module = (M100Module*)malloc(sizeof(M100Module));
+    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);
+    return module;
+}
+
+void m100_module_free(M100Module* module) {
+    m100_module_info_free(module->info);
+    buffer_free(module->buf);
+    free(module);
+}
+
+uint8_t checksum(const uint8_t* data, size_t length) {
+    // CheckSum8 Modulo 256
+    // Sum of Bytes % 256
+    uint64_t sum_val = 0x00;
+    for(size_t i = 0; i < length; i++) {
+        sum_val += data[i];
+    }
+    return (uint8_t)(sum_val % 0x100);
+}
+
+uint16_t crc16_genibus(const uint8_t* data, size_t length) {
+    uint16_t crc = 0xFFFF; // Initial value
+    uint16_t polynomial = 0x1021; // CRC-16/GENIBUS polynomial
+
+    for(size_t i = 0; i < length; i++) {
+        crc ^= (data[i] << 8); // Move byte into MSB of 16bit CRC
+        for(int j = 0; j < 8; j++) {
+            if(crc & 0x8000) {
+                crc = (crc << 1) ^ polynomial;
+            } else {
+                crc <<= 1;
+            }
+        }
+    }
+
+    return crc ^ 0xFFFF; // Post-inversion
+}
+
+char* m100_get_hardware_version(M100Module* module) {
+    if(module->info->hw_version != NULL) return module->info->hw_version;
+    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);
+    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* 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;
+    furi_string_free(temp_str);
+    return module->info->hw_version;
+}
+char* m100_get_software_version(M100Module* module) {
+    if(module->info->sw_version != NULL) return module->info->sw_version;
+    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;
+}
+char* m100_get_manufacturers(M100Module* module) {
+    if(module->info->manufacturer != NULL) return module->info->manufacturer;
+    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;
+}
+
+UHFTag* m100_send_single_poll(M100Module* module) {
+    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);
+    uint8_t* data = buffer_get_data(module->buf);
+    size_t length = buffer_get_size(module->buf);
+    if(length <= 8 && data[2] == 0xFF) return NULL;
+    uint16_t pc = data[6];
+    uint16_t crc = 0;
+    // mask out epc length from protocol control
+    size_t epc_len = pc;
+    epc_len >>= 3;
+    epc_len *= 2;
+    // get protocol control
+    pc <<= 8;
+    pc += data[7];
+    // get cyclic redundency check
+    crc = data[8 + epc_len];
+    crc <<= 8;
+    crc += data[8 + epc_len + 1];
+    // validate checksum
+    uint8_t cs = checksum(data + 1, length - 3);
+    for(size_t i = 0; i < length; i++){
+        FURI_LOG_E("m100", "data[%d]=%02X", i, data[i]);
+    }
+    if(cs != data[length - 2]) return NULL;
+    FURI_LOG_E("m100", "checksum pass");
+    // validate crc
+    uint16_t ccrc = crc16_genibus(data + 6, epc_len + 2);
+    FURI_LOG_E("m100", "crc found = %04X, calculated crc = %04X", crc, ccrc);
+    if(ccrc != crc) return NULL;
+    FURI_LOG_E("m100", "crc pass");
+    UHFTag* uhf_tag = uhf_tag_alloc();
+    uhf_tag_set_epc_pc(uhf_tag, pc);
+    uhf_tag_set_epc_crc(uhf_tag, crc);
+    uhf_tag_set_epc(uhf_tag, data + 8, epc_len);
+    FURI_LOG_E("m100", "returning tag");
+    return uhf_tag;
+}
+
+bool m100_set_select(M100Module* module, UHFTag* uhf_tag) {
+    buffer_reset(module->buf);
+    // Set select
+    uint8_t cmd[MAX_BUFFER_SIZE];
+    size_t cmd_length = CMD_SET_SELECT_PARAMETER.length;
+    size_t mask_length_bytes = uhf_tag->epc->size;
+    size_t mask_length_bits = mask_length_bytes * 8;
+    // payload len = sel param len + ptr len + mask len + epc len
+    size_t payload_len = 7 + mask_length_bytes;
+    memcpy(cmd, CMD_SET_SELECT_PARAMETER.cmd, cmd_length);
+    // set payload length
+    cmd[3] = (payload_len >> 8) & 0xFF;
+    cmd[4] = payload_len & 0xFF;
+    // set select param
+    cmd[5] = 0x01; // 0x00=rfu, 0x01=epc, 0x10=tid, 0x11=user
+    // set ptr
+    cmd[9] = 0x20; // epc data begins after 0x20
+    // set mask length
+    cmd[10] = mask_length_bits;
+    // truncate
+    cmd[11] = false;
+    // set mask
+    memcpy((void*)&cmd[12], uhf_tag->epc->data, mask_length_bytes);
+    // set checksum
+    cmd[12 + mask_length_bytes + 1] = checksum(cmd + 1, 11 + mask_length_bytes);
+    // end frame
+    cmd[12 + mask_length_bytes + 2] = 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);
+
+    uint8_t* data = buffer_get_data(module->buf);
+    if(checksum(data + 1, 5) != data[6]) return false; // error in rx
+    if(data[5] != 0x00) return false; // error if not 0
+
+    return true;
+}
+
+UHFTag* m100_get_select_param(M100Module module) {
+    UNUSED(module);
+    return NULL;
+}
+
+bool m100_read_label_data_storage(
+    M100Module* module,
+    UHFTag* uhf_tag,
+    BankType bank,
+    uint32_t access_pwd) {
+    UNUSED(uhf_tag);
+    buffer_reset(module->buf);
+    uint8_t cmd[MAX_BUFFER_SIZE];
+    size_t length = CMD_READ_LABEL_DATA_STORAGE_AREA.length;
+    memcpy(cmd, CMD_READ_LABEL_DATA_STORAGE_AREA.cmd, length);
+    // set access password
+    cmd[5] = (access_pwd >> 24) & 0xFF;
+    cmd[6] = (access_pwd >> 16) & 0xFF;
+    cmd[7] = (access_pwd >> 8) & 0xFF;
+    cmd[8] = access_pwd & 0xFF;
+    // set mem bank
+    cmd[9] = (uint8_t)bank;
+    // recalc checksum
+    cmd[length - 2] = checksum(cmd + 1, length - 3);
+    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, rx_callback, module->buf);
+    furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, length);
+    furi_delay_ms(DELAY_MS);
+    return true;
+}
+
+void m100_set_baudrate(M100Module* module, uint16_t baudrate) {
+    size_t length = CMD_SET_COMMUNICATION_BAUD_RATE.length;
+    uint8_t cmd[length];
+    memcpy(cmd, CMD_SET_COMMUNICATION_BAUD_RATE.cmd, length);
+    uint16_t br_mod = baudrate / 100; // module format
+    cmd[6] = 0xFF & br_mod; // pow LSB
+    cmd[5] = 0xFF & (br_mod >> 4); // pow MSB
+    // furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, NULL, NULL);
+    furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, length);
+    furi_hal_uart_set_br(FuriHalUartIdUSART1, baudrate);
+    module->baudrate = baudrate;
+}
+bool m100_set_working_area(M100Module* module, WorkingArea area) {
+    size_t length = CMD_SET_WORK_AREA.length;
+    uint8_t 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);
+    return true;
+}
+bool m100_set_transmitting_power(M100Module* module, uint16_t power) {
+    UNUSED(module);
+    UNUSED(power);
+    return true;
+}
+bool m100_set_freq_hopping(M100Module* module, bool hopping) {
+    UNUSED(module);
+    UNUSED(hopping);
+    return true;
+}

+ 68 - 0
non_catalog_apps/uhf_rfid/uhf_module.h

@@ -0,0 +1,68 @@
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "uhf_buffer.h"
+#include "uhf_tag.h"
+#include <furi_hal.h>
+
+#define FRAME_END 0x7E
+#define DEFAULT_BAUDRATE 115200
+
+typedef struct{
+    char* hw_version;
+    char* sw_version;
+    char* manufacturer;
+}M100ModuleInfo;
+
+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 struct{
+    M100ModuleInfo* info;
+    uint16_t baudrate;
+    WorkingArea area;
+    WorkingChannel channel;
+    uint16_t transmitting_power;
+    bool freq_hopping;
+    Buffer* buf;
+} M100Module;
+
+M100ModuleInfo* m100_module_info_alloc();
+void m100_module_info_free(M100ModuleInfo* module_info);
+
+M100Module* m100_module_alloc();
+void m100_module_free(M100Module* module);
+uint16_t crc16_genibus(const uint8_t* data, size_t length);
+uint8_t checksum(const uint8_t* data, size_t length);
+
+// Function prototypes
+char* m100_get_hardware_version(M100Module* module);
+char* m100_get_software_version(M100Module* module);
+char* m100_get_manufacturers(M100Module* module);
+
+// set attrs
+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);
+bool m100_set_transmitting_power(M100Module* module, uint16_t power);
+bool m100_set_freq_hopping(M100Module* module, bool hopping);
+
+// gen2 cmds
+UHFTag* m100_send_single_poll(M100Module* module);
+bool m100_set_select(M100Module* module, UHFTag* uhf_tag);
+bool m100_read_label_data_storage(M100Module* module, UHFTag* uhf_tag, BankType bank, uint32_t access_pwd);

+ 48 - 0
non_catalog_apps/uhf_rfid/uhf_module_cmd.h

@@ -0,0 +1,48 @@
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef struct {
+    const uint8_t* cmd;
+    size_t length;
+} Command;
+
+// Define the command data arrays
+static const uint8_t CMD_HW_VERSION_DATA[] = {0xBB, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x7E};
+static const uint8_t CMD_SW_VERSION_DATA[] = {0xBB, 0x00, 0x03, 0x00, 0x01, 0x01, 0x05, 0x7E};
+static const uint8_t CMD_MANUFACTURERS_DATA[] = {0xBB, 0x00, 0x03, 0x00, 0x01, 0x02, 0x06, 0x7E};
+static const uint8_t CMD_SINGLE_POLLING_DATA[] = {0xBB, 0x00, 0x22, 0x00, 0x00, 0x22, 0x7E};
+static const uint8_t CMD_MULTIPLE_POLLING_DATA[] = {0xBB, 0x00, 0x27, 0x00, 0x03, 0x22, 0x27, 0x10, 0x83, 0x7E};
+static const uint8_t CMD_STOP_MULTIPLE_POLLING_DATA[] = {0xBB, 0x00, 0x28, 0x00, 0x00, 0x28, 0x7E};
+static const uint8_t CMD_SET_SELECT_PARAMETER_DATA[] = {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};
+static const uint8_t CMD_GET_SELECT_PARAMETER_DATA[] = {0xBB, 0x00, 0x0B, 0x00, 0x00, 0x0B, 0x7E};
+static const uint8_t CMD_SET_SELECT_MODE_DATA[] = {0xBB, 0x00, 0x12, 0x00, 0x01, 0x01, 0x14, 0x7E};
+static const uint8_t CMD_READ_LABEL_DATA_STORAGE_AREA_DATA[] = {0xBB, 0x00, 0x39, 0x00, 0x09, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x02, 0x45, 0x7E};
+static const uint8_t CMD_WRITE_LABEL_DATA_STORE_DATA[] = {0xBB, 0x00, 0x49, 0x00, 0x0D, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x02, 0x12, 0x34, 0x56, 0x78, 0x6D, 0x7E};
+static const uint8_t CMD_LOCK_LABEL_DATA_STORE_DATA[] = {0xBB, 0x00, 0x82, 0x00, 0x07, 0x00, 0x00, 0xFF, 0xFF, 0x02, 0x00, 0x80, 0x09, 0x7E};
+static const uint8_t CMD_INACTIVATE_KILL_TAG_DATA[] = {0xBB, 0x00, 0x65, 0x00, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0x67, 0x7E};
+static const uint8_t CMD_SET_COMMUNICATION_BAUD_RATE_DATA[] = {0xBB, 0x00, 0x11, 0x00, 0x02, 0x00, 0xC0, 0xD3, 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_WORK_AREA_DATA[] = {0xBB, 0x00, 0x07, 0x00, 0x01, 0x01, 0x09, 0x7E};
+
+
+// Define the Command structs
+static const Command CMD_HW_VERSION = {CMD_HW_VERSION_DATA, sizeof(CMD_HW_VERSION_DATA)};
+static const Command CMD_SW_VERSION = {CMD_SW_VERSION_DATA, sizeof(CMD_SW_VERSION_DATA)};
+static const Command CMD_MANUFACTURERS = {CMD_MANUFACTURERS_DATA, sizeof(CMD_MANUFACTURERS_DATA)};
+static const Command CMD_SINGLE_POLLING = {CMD_SINGLE_POLLING_DATA, sizeof(CMD_SINGLE_POLLING_DATA)};
+static const Command CMD_MULTIPLE_POLLING = {CMD_MULTIPLE_POLLING_DATA, sizeof(CMD_MULTIPLE_POLLING_DATA)};
+static const Command CMD_STOP_MULTIPLE_POLLING = {CMD_STOP_MULTIPLE_POLLING_DATA, sizeof(CMD_STOP_MULTIPLE_POLLING_DATA)};
+static const Command CMD_SET_SELECT_PARAMETER = {CMD_SET_SELECT_PARAMETER_DATA, sizeof(CMD_SET_SELECT_PARAMETER_DATA)};
+static const Command CMD_GET_SELECT_PARAMETER = {CMD_GET_SELECT_PARAMETER_DATA, sizeof(CMD_GET_SELECT_PARAMETER_DATA)};
+static const Command CMD_SET_SELECT_MODE = {CMD_SET_SELECT_MODE_DATA, sizeof(CMD_SET_SELECT_MODE_DATA)};
+static const Command CMD_READ_LABEL_DATA_STORAGE_AREA = {CMD_READ_LABEL_DATA_STORAGE_AREA_DATA, sizeof(CMD_READ_LABEL_DATA_STORAGE_AREA_DATA)};
+static const Command CMD_WRITE_LABEL_DATA_STORE = {CMD_WRITE_LABEL_DATA_STORE_DATA, sizeof(CMD_WRITE_LABEL_DATA_STORE_DATA)};
+static const Command CMD_LOCK_LABEL_DATA_STORE = {CMD_LOCK_LABEL_DATA_STORE_DATA, sizeof(CMD_LOCK_LABEL_DATA_STORE_DATA)};
+static const Command CMD_INACTIVATE_KILL_TAG = {CMD_INACTIVATE_KILL_TAG_DATA, sizeof(CMD_INACTIVATE_KILL_TAG_DATA)};
+static const Command CMD_SET_COMMUNICATION_BAUD_RATE = {CMD_SET_COMMUNICATION_BAUD_RATE_DATA, sizeof(CMD_SET_COMMUNICATION_BAUD_RATE_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_WORK_AREA = {CMD_SET_WORK_AREA_DATA, sizeof(CMD_SET_WORK_AREA_DATA)};

+ 57 - 0
non_catalog_apps/uhf_rfid/uhf_tag.c

@@ -0,0 +1,57 @@
+#include "uhf_tag.h"
+#include <stdlib.h>
+#include <string.h>
+
+UHFTagWrapper* uhf_tag_wrapper_alloc() {
+    UHFTagWrapper* uhf_tag_wrapper = (UHFTagWrapper*)malloc(sizeof(UHFTagWrapper));
+    uhf_tag_wrapper->uhf_tag = NULL;
+    return uhf_tag_wrapper;
+}
+
+void uhf_tag_wrapper_set_tag(UHFTagWrapper* uhf_tag_wrapper, UHFTag* uhf_tag) {
+    uhf_tag_wrapper->uhf_tag = uhf_tag;
+}
+
+void uhf_tag_wrapper_free(UHFTagWrapper* uhf_tag_wrapper) {
+    uhf_tag_free(uhf_tag_wrapper->uhf_tag);
+    free(uhf_tag_wrapper);
+}
+
+UHFTag* uhf_tag_alloc() {
+    UHFTag* uhf_tag = (UHFTag*)malloc(sizeof(UHFTag));
+    uhf_tag->reserved = (ReservedMemoryBank*)malloc(sizeof(ReservedMemoryBank));
+    uhf_tag->epc = (EPCMemoryBank*)malloc(sizeof(EPCMemoryBank));
+    uhf_tag->tid = (TIDMemoryBank*)malloc(sizeof(TIDMemoryBank));
+    uhf_tag->user = (UserMemoryBank*)malloc(sizeof(UserMemoryBank));
+    return uhf_tag;
+}
+
+void uhf_tag_reset(UHFTag* uhf_tag) {
+    uhf_tag->epc->crc = 0;
+    uhf_tag->epc->pc = 0;
+    uhf_tag->epc->size = 0;
+    uhf_tag->tid->size = 0;
+    uhf_tag->user->size = 0;
+}
+
+void uhf_tag_free(UHFTag* uhf_tag) {
+    if(uhf_tag == NULL) return;
+    free(uhf_tag->reserved);
+    free(uhf_tag->epc);
+    free(uhf_tag->tid);
+    free(uhf_tag->user);
+    free(uhf_tag);
+}
+
+void uhf_tag_set_epc_pc(UHFTag* uhf_tag, uint16_t pc) {
+    uhf_tag->epc->pc = pc;
+}
+
+void uhf_tag_set_epc_crc(UHFTag* uhf_tag, uint16_t crc) {
+    uhf_tag->epc->crc = crc;
+}
+
+void uhf_tag_set_epc(UHFTag* uhf_tag, uint8_t* data_in, size_t size) {
+    memcpy(uhf_tag->epc->data, data_in, size);
+    uhf_tag->epc->size = size;
+}

+ 74 - 0
non_catalog_apps/uhf_rfid/uhf_tag.h

@@ -0,0 +1,74 @@
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+// storage enum
+typedef enum { ReservedBank, EPCBank, TIDBank, UserBank } BankType;
+
+// Reserved Memory Bank
+typedef struct {
+    uint8_t kill_password[2]; // 2 bytes (16 bits) for kill password
+    uint8_t access_password[2]; // 2 bytes (16 bits) for access password
+} ReservedMemoryBank;
+
+// EPC Memory Bank
+typedef struct {
+    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
+    uint16_t pc;
+    uint16_t crc;
+} EPCMemoryBank;
+
+// TID Memory Bank
+typedef struct {
+    size_t size; // Size of TID memory data
+    uint8_t data[16]; // 4 bytes for Class ID and max 12 bytes for TID data
+} TIDMemoryBank;
+
+// User Memory Bank
+typedef struct {
+    size_t size; // Size of user memory data
+    uint8_t data[64]; // Assuming max 512 bits (64 bytes) for User Memory
+} UserMemoryBank;
+
+// EPC Gen 2 Tag containing all memory banks
+typedef struct {
+    ReservedMemoryBank* reserved;
+    EPCMemoryBank* epc;
+    TIDMemoryBank* tid;
+    UserMemoryBank* user;
+} UHFTag;
+
+typedef struct UHFTagWrapper {
+    UHFTag* uhf_tag;
+} UHFTagWrapper;
+
+UHFTagWrapper* uhf_tag_wrapper_alloc();
+void uhf_tag_wrapper_set_tag(UHFTagWrapper* uhf_tag_wrapper, UHFTag* uhf_tag);
+void uhf_tag_wrapper_free(UHFTagWrapper* uhf_tag_wrapper);
+
+UHFTag* uhf_tag_alloc();
+void uhf_tag_reset(UHFTag* uhf_tag);
+void uhf_tag_free(UHFTag* uhf_tag);
+
+void uhf_tag_set_kill_pwd(UHFTag* uhf_tag, uint8_t* data_in);
+void uhf_tag_set_access_pwd(UHFTag* uhf_tag, uint8_t* data_in);
+void uhf_tag_set_epc_pc(UHFTag* uhf_tag, uint16_t pc);
+void uhf_tag_set_epc_crc(UHFTag* uhf_tag, uint16_t crc);
+void uhf_tag_set_epc(UHFTag* uhf_tag, uint8_t* data_in, size_t size);
+void uhf_tag_set_tid(UHFTag* uhf_tag, uint8_t* data_in, size_t size);
+void uhf_tag_set_user(UHFTag* uhf_tag, uint8_t* data_in, size_t size);
+
+uint8_t* uhf_tag_get_kill_pwd(UHFTag* uhf_tag);
+uint8_t* uhf_tag_get_access_pwd(UHFTag* uhf_tag);
+uint8_t* uhf_tag_get_epc(UHFTag* uhf_tag);
+size_t uhf_tag_get_epc_size(UHFTag* uhf_tag);
+uint8_t* uhf_tag_get_tid(UHFTag* uhf_tag);
+size_t uhf_tag_get_tid_size(UHFTag* uhf_tag);
+uint8_t* uhf_tag_get_user(UHFTag* uhf_tag);
+size_t uhf_tag_get_user_size(UHFTag* uhf_tag);
+
+// debug
+char* uhf_tag_get_cstr(UHFTag* uhf_tag);

+ 173 - 180
non_catalog_apps/uhf_rfid/uhf_worker.c

@@ -1,223 +1,216 @@
 #include "uhf_worker.h"
 #include "uhf_worker.h"
-#include "uhf_cmd.h"
-
-#define CB_DELAY 50
-
-// uart callback functions
-void module_rx_callback(UartIrqEvent event, uint8_t data, void* ctx) {
-    UNUSED(event);
-    UHFData* uhf_data = ctx;
-    uhf_data_append(uhf_data, data);
-}
+#include "uhf_tag.h"
 
 
 // yrm100 module commands
 // yrm100 module commands
 UHFWorkerEvent verify_module_connected(UHFWorker* uhf_worker) {
 UHFWorkerEvent verify_module_connected(UHFWorker* uhf_worker) {
-    UHFResponseData* uhf_response_data = uhf_worker->response_data;
-    uhf_response_data_reset(uhf_response_data);
-    // FURI_LOG_E("log", "freeing done");
-    UHFData* hardware_version = uhf_response_data->head;
-    UHFData* software_version = uhf_response_data_add_new_uhf_data(uhf_response_data);
-    UHFData* manufacturer = uhf_response_data_add_new_uhf_data(uhf_response_data);
-    // FURI_LOG_E("log", "alloc done");
-    furi_hal_uart_set_br(FuriHalUartIdUSART1, DEFAULT_BAUD_RATE);
-    // read hardware version
-    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, hardware_version);
-    furi_hal_uart_tx(FuriHalUartIdUSART1, CMD_HARDWARE_VERSION.cmd, CMD_HARDWARE_VERSION.length);
-    furi_delay_ms(CB_DELAY);
-    // read software version
-    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, software_version);
-    furi_hal_uart_tx(FuriHalUartIdUSART1, CMD_SOFTWARE_VERSION.cmd, CMD_SOFTWARE_VERSION.length);
-    furi_delay_ms(CB_DELAY);
-    // read manufacturer
-    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, manufacturer);
-    furi_hal_uart_tx(FuriHalUartIdUSART1, CMD_MANUFACTURERS.cmd, CMD_MANUFACTURERS.length);
-    furi_delay_ms(CB_DELAY);
-    // verify that we received all data
-    if(!hardware_version->end || !software_version->end || !manufacturer->end) {
-        return UHFWorkerEventFail;
-    }
-    // verify all data was received correctly
-    if(!uhf_data_verfiy_checksum(hardware_version) ||
-       !uhf_data_verfiy_checksum(software_version) || !uhf_data_verfiy_checksum(manufacturer))
-        return UHFWorkerEventFail;
-
+    char* hw_version = m100_get_hardware_version(uhf_worker->module);
+    char* sw_version = m100_get_software_version(uhf_worker->module);
+    char* manufacturer = m100_get_manufacturers(uhf_worker->module);
+    // verify all data exists
+    if(hw_version == NULL || sw_version == NULL || manufacturer == NULL) return UHFWorkerEventFail;
     return UHFWorkerEventSuccess;
     return UHFWorkerEventSuccess;
 }
 }
 
 
-static uint8_t get_epc_length_in_bits(uint8_t pc) {
+uint8_t get_epc_length_in_bits(uint8_t pc) {
     uint8_t epc_length = pc;
     uint8_t epc_length = pc;
     epc_length >>= 3;
     epc_length >>= 3;
     return (uint8_t)epc_length * 16; // x-words * 16 bits
     return (uint8_t)epc_length * 16; // x-words * 16 bits
 }
 }
 
 
-static bool send_set_select_command(UHFData* selected_tag, UHFBank bank) {
-    bool success = false;
-    // Set select
-    UHFData* select_cmd = uhf_data_alloc();
-    select_cmd->start = true;
-    select_cmd->length = CMD_SET_SELECT_PARAMETER.length;
-    memcpy((void*)&select_cmd->data, (void*)&CMD_SET_SELECT_PARAMETER.cmd[0], select_cmd->length);
-    // set select param
-    size_t mask_length_bits = (size_t)get_epc_length_in_bits(selected_tag->data[6]);
-    size_t mask_length_bytes = (size_t)mask_length_bits / 8;
-    select_cmd->data[5] = bank; // 0x00=rfu, 0x01=epc, 0x10=tid, 0x11=user
-    // set ptr
-    select_cmd->data[9] = 0x20; // epc data begins after 0x20
-    // set mask length
-    select_cmd->data[10] = mask_length_bits;
-    // set mask starting position
-    select_cmd->length = 12;
-    // set mask
-    for(size_t i = 0; i < mask_length_bytes; i++) {
-        uhf_data_append(select_cmd, selected_tag->data[8 + i]);
-    }
-    uhf_data_append(select_cmd, 0x00); // add checksum section
-    uhf_data_append(select_cmd, FRAME_END); // command end
-    // add checksum
-    select_cmd->data[select_cmd->length - 2] = uhf_data_calculate_checksum(select_cmd);
-    UHFData* select_response = uhf_data_alloc();
-    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, select_response);
-    furi_hal_uart_tx(FuriHalUartIdUSART1, select_cmd->data, select_cmd->length);
-    furi_delay_ms(CB_DELAY);
-
-    success = select_response->data[5] == 0x00;
-
-    uhf_data_free(select_cmd);
-    uhf_data_free(select_response);
-
-    return success;
-}
-
-static bool read_bank(UHFData* read_bank_cmd, UHFData* response_bank, UHFBank bank) {
-    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, response_bank);
-    read_bank_cmd->data[9] = bank;
-    read_bank_cmd->data[read_bank_cmd->length - 2] = uhf_data_calculate_checksum(read_bank_cmd);
-    uhf_data_reset(response_bank);
-    furi_hal_uart_tx(FuriHalUartIdUSART1, read_bank_cmd->data, read_bank_cmd->length);
-    furi_delay_ms(CB_DELAY);
-    return response_bank->data[2] == read_bank_cmd->data[2];
-}
-
-UHFWorkerEvent read_single_card(UHFWorker* uhf_worker) {
-    // debug
-    // FuriString* temp_str;
-    // temp_str = furi_string_alloc();
-    // e-debug
-    UHFResponseData* uhf_response_data = uhf_worker->response_data;
-    uhf_response_data_reset(uhf_response_data);
-    UHFData* raw_read_data = uhf_response_data_get_uhf_data(uhf_response_data, 0);
-    furi_hal_uart_set_br(FuriHalUartIdUSART1, DEFAULT_BAUD_RATE);
-    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, raw_read_data);
-    uhf_data_reset(raw_read_data);
+// bool read_bank(UHFData* read_bank_cmd, UHFData* response_bank, UHFBank bank) {
+//     furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, response_bank);
+//     read_bank_cmd->data[9] = bank;
+//     read_bank_cmd->data[read_bank_cmd->length - 2] = uhf_data_calculate_checksum(read_bank_cmd);
+//     uhf_data_reset(response_bank);
+//     furi_hal_uart_tx(FuriHalUartIdUSART1, read_bank_cmd->data, read_bank_cmd->length);
+//     furi_delay_ms(CB_DELAY);
+//     return response_bank->data[2] == read_bank_cmd->data[2];
+// }
+
+// bool write_bank(UHFData* write_bank_cmd, UHFBank bank, uint8_t* bank_data, size_t bank_len) {
+//     UHFData* rp_data = uhf_data_alloc();
+//     write_bank_cmd->end = false;
+//     for(size_t i = 0; i < write_bank_cmd->length; i++) {
+//         continue;
+//     }
+//     furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, module_rx_callback, rp_data);
+//     for(int i = 5; i < 9; i++) { // no access password for now
+//         write_bank_cmd->data[i] = 0;
+//     }
+//     write_bank_cmd->data[9] = bank;
+//     size_t word_len = bank_len / 2;
+//     write_bank_cmd->data[13] = word_len;
+//     write_bank_cmd->length = 14;
+//     write_bank_cmd->start = true;
+//     for(size_t i = 0; i < bank_len; i++) {
+//         uhf_data_append(write_bank_cmd, bank_data[i]);
+//     }
+//     uhf_data_append(write_bank_cmd, 00);
+//     uhf_data_append(write_bank_cmd, FRAME_END);
+//     write_bank_cmd->data[4] = write_bank_cmd->length - 7;
+//     write_bank_cmd->data[write_bank_cmd->length - 2] = uhf_data_calculate_checksum(write_bank_cmd);
+//     furi_hal_uart_tx(FuriHalUartIdUSART1, write_bank_cmd->data, write_bank_cmd->length);
+//     furi_delay_ms(CB_DELAY);
+//     bool success = rp_data->data[2] == write_bank_cmd->data[2];
+//     uhf_data_free(rp_data);
+//     return success;
+// }
+
+UHFTag* send_polling_command(UHFWorker* uhf_worker) {
     // read epc bank
     // read epc bank
+    UHFTag* uhf_tag;
     while(true) {
     while(true) {
-        furi_hal_uart_tx(FuriHalUartIdUSART1, CMD_SINGLE_POLLING.cmd, CMD_SINGLE_POLLING.length);
+        uhf_tag = m100_send_single_poll(uhf_worker->module);
         furi_delay_ms(100);
         furi_delay_ms(100);
         if(uhf_worker->state == UHFWorkerStateStop) {
         if(uhf_worker->state == UHFWorkerStateStop) {
-            return UHFWorkerEventAborted;
-        }
-        if(raw_read_data->end) {
-            if(raw_read_data->data[1] == 0x01 && raw_read_data->data[5] == 0x15) {
-                uhf_data_reset(raw_read_data);
-                continue;
-            } else if(raw_read_data->data[1] == 0x02)
-                break; // read success
+            return NULL;
         }
         }
+        if(uhf_tag != NULL) break;
+        FURI_LOG_E("WKR", "null still");
     }
     }
+    return uhf_tag;
+}
 
 
-    // todo : rfu ?
-    UHFTag* uhf_tag = uhf_worker->uhf_tag;
-    uhf_tag_reset(uhf_tag);
-
+UHFWorkerEvent read_single_card(UHFWorker* uhf_worker) {
+    UHFTag* uhf_tag = send_polling_command(uhf_worker);
+    if(uhf_tag == NULL) return UHFWorkerEventAborted;
+    uhf_tag_wrapper_set_tag(uhf_worker->uhf_tag_wrapper, uhf_tag);
+    // Todo : set select here
+    bool select_success = m100_set_select(uhf_worker->module, uhf_tag);
+    FURI_LOG_E("TAG", "select success = %d", select_success);
+
+    // Todo : read rfu
+    m100_read_label_data_storage(uhf_worker->module, uhf_tag, ReservedBank, 0);
+    // Todo : read epc
+    m100_read_label_data_storage(uhf_worker->module, uhf_tag, EPCBank, 0);
+    // Todo : read tid
+    m100_read_label_data_storage(uhf_worker->module, uhf_tag, TIDBank, 0);
+    // Todo : read user
+    m100_read_label_data_storage(uhf_worker->module, uhf_tag, UserBank, 0);
     // add to tag object
     // add to tag object
-    UHFData* raw_bank_data = uhf_data_alloc();
-    size_t epc_length = (size_t)get_epc_length_in_bits(raw_read_data->data[6]) / 8;
-    size_t offset = (size_t)(8 + epc_length);
-
-    UHFData* read_bank_cmd = uhf_data_alloc();
-    read_bank_cmd->length = CMD_READ_LABEL_DATA_STORAGE.length;
-    memcpy(
-        (void*)&read_bank_cmd->data[0],
-        (void*)&CMD_READ_LABEL_DATA_STORAGE.cmd[0],
-        read_bank_cmd->length);
-
-    if(!send_set_select_command(raw_read_data, EPC_BANK)) return UHFWorkerEventFail;
-
-    int retry = 3;
-    do {
-        if(read_bank(read_bank_cmd, raw_bank_data, EPC_BANK)) {
-            uhf_tag_set_epc(uhf_tag, raw_bank_data->data + offset, epc_length + 2);
-            FURI_LOG_E("TAG", "epc read");
-            break;
-        }
-
-    } while(retry--);
-    // // debug
-    // furi_string_reset(temp_str);
-    // for(size_t i = 0; i < raw_bank_data->length; i++) {
-    //     furi_string_cat_printf(temp_str, "%02x ", raw_bank_data->data[i]);
+    // UHFData* raw_bank_data = uhf_data_alloc();
+    // size_t epc_length = (size_t)get_epc_length_in_bits(raw_read_data->data[6]) / 8;
+    // size_t offset = (size_t)(8 + epc_length);
+
+    // UHFData* read_bank_cmd = uhf_data_alloc();
+    // read_bank_cmd->length = CMD_READ_LABEL_DATA_STORAGE.length;
+    // memcpy(
+    //     (void*)&read_bank_cmd->data[0],
+    //     (void*)&CMD_READ_LABEL_DATA_STORAGE.cmd[0],
+    //     read_bank_cmd->length);
+
+    // if(!send_set_select_command(raw_read_data, EPC_BANK)) return UHFWorkerEventFail;
+
+    // int retry = 3;
+    // do {
+    //     if(read_bank(read_bank_cmd, raw_bank_data, EPC_BANK)) {
+    //         uhf_tag_set_epc(uhf_tag, raw_bank_data->data + offset, epc_length + 2);
+    //         break;
+    //     }
+
+    // } while(retry--);
+    // // // debug
+    // // furi_string_reset(temp_str);
+    // // for(size_t i = 0; i < raw_bank_data->length; i++) {
+    // //     furi_string_cat_printf(temp_str, "%02x ", raw_bank_data->data[i]);
+    // // }
+    // // FURI_LOG_E("TAG", "data = %s", furi_string_get_cstr(temp_str));
+    // // // e-debug
+    // uhf_data_reset(raw_bank_data);
+    // retry = 3;
+    // do {
+    //     if(read_bank(read_bank_cmd, raw_bank_data, TID_BANK)) {
+    //         uhf_tag_set_tid(uhf_tag, raw_bank_data->data + offset, 16);
+    //         break;
+    //     }
+    // } while(retry--);
+    // // // debug
+    // // furi_string_reset(temp_str);
+    // // for(size_t i = 0; i < raw_bank_data->length; i++) {
+    // //     furi_string_cat_printf(temp_str, "%02x ", raw_bank_data->data[i]);
+    // // }
+    // // FURI_LOG_E("TAG", "data = %s", furi_string_get_cstr(temp_str));
+    // // // e-debug
+    // uhf_data_reset(raw_bank_data);
+    // retry = 3;
+    // if(raw_read_data->data[6] & 0x04) {
+    //     do {
+    //         if(read_bank(read_bank_cmd, raw_bank_data, USER_BANK)) {
+    //             uhf_tag_set_user(uhf_tag, raw_bank_data->data + offset, 16);
+    //             break;
+    //         }
+    //     } while(retry--);
     // }
     // }
-    // FURI_LOG_E("TAG", "data = %s", furi_string_get_cstr(temp_str));
-    // // e-debug
-    uhf_data_reset(raw_bank_data);
-    retry = 3;
-    do {
-        if(read_bank(read_bank_cmd, raw_bank_data, TID_BANK)) {
-            uhf_tag_set_tid(uhf_tag, raw_bank_data->data + offset, 16);
-            break;
-        }
-    } while(retry--);
+    // // // debug
+    // // furi_string_reset(temp_str);
+    // // for(size_t i = 0; i < raw_bank_data->length; i++) {
+    // //     furi_string_cat_printf(temp_str, "%02x ", raw_bank_data->data[i]);
+    // // }
+    // // FURI_LOG_E("TAG", "data = %s", furi_string_get_cstr(temp_str));
+    // // // e-debug
+    // uhf_data_reset(raw_bank_data);
+    // uhf_data_free(raw_bank_data);
+    // uhf_data_free(read_bank_cmd);
     // // debug
     // // debug
-    // furi_string_reset(temp_str);
-    // for(size_t i = 0; i < raw_bank_data->length; i++) {
-    //     furi_string_cat_printf(temp_str, "%02x ", raw_bank_data->data[i]);
-    // }
-    // FURI_LOG_E("TAG", "data = %s", furi_string_get_cstr(temp_str));
-    // // e-debug
-    uhf_data_reset(raw_bank_data);
-    retry = 3;
-    if(raw_read_data->data[6] & 0x04) {
-        do {
-            if(read_bank(read_bank_cmd, raw_bank_data, USER_BANK)) {
-                uhf_tag_set_user(uhf_tag, raw_bank_data->data + offset, 16);
-                break;
-            }
-        } while(retry--);
-    }
-    // // debug
-    // furi_string_reset(temp_str);
-    // for(size_t i = 0; i < raw_bank_data->length; i++) {
-    //     furi_string_cat_printf(temp_str, "%02x ", raw_bank_data->data[i]);
-    // }
-    // FURI_LOG_E("TAG", "data = %s", furi_string_get_cstr(temp_str));
+    // // furi_string_free(temp_str);
     // // e-debug
     // // e-debug
-    uhf_data_reset(raw_bank_data);
-    uhf_data_free(raw_bank_data);
-    uhf_data_free(read_bank_cmd);
-    // debug
-    // furi_string_free(temp_str);
-    // e-debug
 
 
     return UHFWorkerEventSuccess;
     return UHFWorkerEventSuccess;
 }
 }
 
 
+// UHFWorkerEvent write_single_card(UHFWorker* uhf_worker) {
+//     UHFResponseData* uhf_response_data = uhf_worker->response_data;
+//     uhf_response_data_reset(uhf_response_data);
+//     UHFData* raw_read_data = uhf_response_data_get_uhf_data(uhf_response_data, 0);
+//     furi_hal_uart_set_br(FuriHalUartIdUSART1, DEFAULT_BAUD_RATE);
+
+//     send_polling_command(uhf_worker, raw_read_data);
+//     // todo : rfu ?
+//     UHFTag* uhf_tag = uhf_worker->uhf_tag;
+
+//     UHFData* write_bank_cmd = uhf_data_alloc();
+//     write_bank_cmd->length = CMD_WRITE_LABEL_DATA_STORAGE.length;
+
+//     memcpy(
+//         (void*)&write_bank_cmd->data[0],
+//         (void*)&CMD_WRITE_LABEL_DATA_STORAGE.cmd[0],
+//         write_bank_cmd->length);
+//     if(!send_set_select_command(raw_read_data, EPC_BANK)) return UHFWorkerEventFail;
+
+//     if(raw_read_data->data[6] & 0x04) {
+//         if(!write_bank(write_bank_cmd, USER_BANK, uhf_tag->user, uhf_tag->user_length))
+//             return UHFWorkerEventFail;
+//     }
+//     uint8_t write_data[uhf_tag->epc_length + 2];
+//     memcpy(&write_data, &raw_read_data->data[raw_read_data->length - 4], 2);
+//     memcpy(&write_data[2], &uhf_tag->epc, uhf_tag->epc_length);
+//     write_data[10] = 0xF1;
+//     if(!write_bank(write_bank_cmd, EPC_BANK, write_data, uhf_tag->epc_length + 2)) {
+//         return UHFWorkerEventFail;
+//     }
+//     return UHFWorkerEventSuccess;
+// }
+
 int32_t uhf_worker_task(void* ctx) {
 int32_t uhf_worker_task(void* ctx) {
     UHFWorker* uhf_worker = ctx;
     UHFWorker* uhf_worker = ctx;
     if(uhf_worker->state == UHFWorkerStateVerify) {
     if(uhf_worker->state == UHFWorkerStateVerify) {
         UHFWorkerEvent event = verify_module_connected(uhf_worker);
         UHFWorkerEvent event = verify_module_connected(uhf_worker);
         uhf_worker->callback(event, uhf_worker->ctx);
         uhf_worker->callback(event, uhf_worker->ctx);
-    }
-    if(uhf_worker->state == UHFWorkerStateDetectSingle) {
+    } else if(uhf_worker->state == UHFWorkerStateDetectSingle) {
         UHFWorkerEvent event = read_single_card(uhf_worker);
         UHFWorkerEvent event = read_single_card(uhf_worker);
         uhf_worker->callback(event, uhf_worker->ctx);
         uhf_worker->callback(event, uhf_worker->ctx);
     }
     }
+    // else if(uhf_worker->state == UHFWorkerStateWriteSingle) {
+    //     UHFWorkerEvent event = write_single_card(uhf_worker);
+    //     uhf_worker->callback(event, uhf_worker->ctx);
+    // }
     return 0;
     return 0;
 }
 }
 
 
 UHFWorker* uhf_worker_alloc() {
 UHFWorker* uhf_worker_alloc() {
     UHFWorker* uhf_worker = (UHFWorker*)malloc(sizeof(UHFWorker));
     UHFWorker* uhf_worker = (UHFWorker*)malloc(sizeof(UHFWorker));
     uhf_worker->thread = furi_thread_alloc_ex("UHFWorker", 8 * 1024, uhf_worker_task, uhf_worker);
     uhf_worker->thread = furi_thread_alloc_ex("UHFWorker", 8 * 1024, uhf_worker_task, uhf_worker);
-    uhf_worker->response_data = uhf_response_data_alloc();
+    uhf_worker->module = m100_module_alloc();
     uhf_worker->callback = NULL;
     uhf_worker->callback = NULL;
     uhf_worker->ctx = NULL;
     uhf_worker->ctx = NULL;
     return uhf_worker;
     return uhf_worker;
@@ -251,6 +244,6 @@ void uhf_worker_stop(UHFWorker* uhf_worker) {
 void uhf_worker_free(UHFWorker* uhf_worker) {
 void uhf_worker_free(UHFWorker* uhf_worker) {
     furi_assert(uhf_worker);
     furi_assert(uhf_worker);
     furi_thread_free(uhf_worker->thread);
     furi_thread_free(uhf_worker->thread);
-    uhf_response_data_free(uhf_worker->response_data);
+    m100_module_free(uhf_worker->module);
     free(uhf_worker);
     free(uhf_worker);
 }
 }

+ 3 - 3
non_catalog_apps/uhf_rfid/uhf_worker.h

@@ -2,7 +2,7 @@
 
 
 #include <furi.h>
 #include <furi.h>
 #include <furi_hal.h>
 #include <furi_hal.h>
-#include "uhf_data.h"
+#include "uhf_module.h"
 
 
 typedef enum {
 typedef enum {
     // Init states
     // Init states
@@ -30,10 +30,10 @@ typedef void (*UHFWorkerCallback)(UHFWorkerEvent event, void* ctx);
 
 
 typedef struct UHFWorker {
 typedef struct UHFWorker {
     FuriThread* thread;
     FuriThread* thread;
-    UHFResponseData* response_data;
-    UHFTag* uhf_tag;
+    M100Module* module;
     UHFWorkerCallback callback;
     UHFWorkerCallback callback;
     UHFWorkerState state;
     UHFWorkerState state;
+    UHFTagWrapper* uhf_tag_wrapper;
     void* ctx;
     void* ctx;
 } UHFWorker;
 } UHFWorker;