diff --git a/applications/external/esp8266_deauth/FlipperZeroWiFiDeauthModuleDefines.h b/applications/external/esp8266_deauth/FlipperZeroWiFiDeauthModuleDefines.h deleted file mode 100644 index a8e0e8d61..000000000 --- a/applications/external/esp8266_deauth/FlipperZeroWiFiDeauthModuleDefines.h +++ /dev/null @@ -1,7 +0,0 @@ -#define WIFI_MODULE_INIT_VERSION "WFDM_0.1" - -#define MODULE_CONTEXT_INITIALIZATION WIFI_MODULE_INIT_VERSION - -#define FLIPPERZERO_SERIAL_BAUD 230400 - -#define NA 0 diff --git a/applications/external/esp8266_deauth/application.fam b/applications/external/esp8266_deauth/application.fam deleted file mode 100644 index f36d85d18..000000000 --- a/applications/external/esp8266_deauth/application.fam +++ /dev/null @@ -1,13 +0,0 @@ -App( - appid="esp8266_deauther", - name="[ESP8266] Deauther", - apptype=FlipperAppType.EXTERNAL, - entry_point="esp8266_deauth_app", - requires=["gui"], - stack_size=2 * 1024, - fap_icon="wifi_10px.png", - fap_category="WiFi", - fap_author="@SequoiaSan & @xMasterX", - fap_version="1.0", - fap_description="DSTIKE Deauther module interface, based on ESP8266", -) diff --git a/applications/external/esp8266_deauth/esp8266_deauth.c b/applications/external/esp8266_deauth/esp8266_deauth.c deleted file mode 100644 index 29d33b7df..000000000 --- a/applications/external/esp8266_deauth/esp8266_deauth.c +++ /dev/null @@ -1,560 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -//#include -//#include -//#include -//#include -#include - -#include "FlipperZeroWiFiDeauthModuleDefines.h" - -#define UART_CH \ - (xtreme_settings.uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) - -#define DEAUTH_APP_DEBUG 0 - -#if DEAUTH_APP_DEBUG -#define APP_NAME_TAG "WiFi_Deauther" -#define DEAUTH_APP_LOG_I(format, ...) FURI_LOG_I(APP_NAME_TAG, format, ##__VA_ARGS__) -#define DEAUTH_APP_LOG_D(format, ...) FURI_LOG_D(APP_NAME_TAG, format, ##__VA_ARGS__) -#define DEAUTH_APP_LOG_E(format, ...) FURI_LOG_E(APP_NAME_TAG, format, ##__VA_ARGS__) -#else -#define DEAUTH_APP_LOG_I(format, ...) -#define DEAUTH_APP_LOG_D(format, ...) -#define DEAUTH_APP_LOG_E(format, ...) -#endif // WIFI_APP_DEBUG - -#define DISABLE_CONSOLE !DEAUTH_APP_DEBUG -#define ENABLE_MODULE_POWER 1 -#define ENABLE_MODULE_DETECTION 1 - -typedef enum EEventType // app internally defined event types -{ EventTypeKey // flipper input.h type -} EEventType; - -typedef struct SPluginEvent { - EEventType m_type; - InputEvent m_input; -} SPluginEvent; - -typedef enum EAppContext { - Undefined, - WaitingForModule, - Initializing, - ModuleActive, -} EAppContext; - -typedef enum EWorkerEventFlags { - WorkerEventReserved = (1 << 0), // Reserved for StreamBuffer internal event - WorkerEventStop = (1 << 1), - WorkerEventRx = (1 << 2), -} EWorkerEventFlags; - -typedef struct SGpioButtons { - GpioPin const* pinButtonUp; - GpioPin const* pinButtonDown; - GpioPin const* pinButtonOK; - GpioPin const* pinButtonBack; -} SGpioButtons; - -typedef struct SWiFiDeauthApp { - FuriMutex* mutex; - Gui* m_gui; - FuriThread* m_worker_thread; - //NotificationApp* m_notification; - FuriStreamBuffer* m_rx_stream; - SGpioButtons m_GpioButtons; - - bool m_wifiDeauthModuleInitialized; - bool m_wifiDeauthModuleAttached; - - EAppContext m_context; - - uint8_t m_backBuffer[128 * 8 * 8]; - //uint8_t m_renderBuffer[128 * 8 * 8]; - - uint8_t* m_backBufferPtr; - //uint8_t* m_m_renderBufferPtr; - - //uint8_t* m_originalBuffer; - //uint8_t** m_originalBufferLocation; - size_t m_canvasSize; - - bool m_needUpdateGUI; -} SWiFiDeauthApp; - -/////// INIT STATE /////// -static void esp8266_deauth_app_init(SWiFiDeauthApp* const app) { - app->m_context = Undefined; - - app->m_canvasSize = 128 * 8 * 8; - memset(app->m_backBuffer, DEAUTH_APP_DEBUG ? 0xFF : 0x00, app->m_canvasSize); - //memset(app->m_renderBuffer, DEAUTH_APP_DEBUG ? 0xFF : 0x00, app->m_canvasSize); - - //app->m_originalBuffer = NULL; - //app->m_originalBufferLocation = NULL; - - //app->m_m_renderBufferPtr = app->m_renderBuffer; - app->m_backBufferPtr = app->m_backBuffer; - - app->m_GpioButtons.pinButtonUp = &gpio_ext_pc3; - app->m_GpioButtons.pinButtonDown = &gpio_ext_pb2; - app->m_GpioButtons.pinButtonOK = &gpio_ext_pb3; - app->m_GpioButtons.pinButtonBack = &gpio_ext_pa4; - - app->m_needUpdateGUI = false; - -#if ENABLE_MODULE_POWER - app->m_wifiDeauthModuleInitialized = false; -#else - app->m_wifiDeauthModuleInitialized = true; -#endif // ENABLE_MODULE_POWER - -#if ENABLE_MODULE_DETECTION - app->m_wifiDeauthModuleAttached = false; -#else - app->m_wifiDeauthModuleAttached = true; -#endif -} - -static void esp8266_deauth_module_render_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - SWiFiDeauthApp* app = ctx; - furi_mutex_acquire(app->mutex, FuriWaitForever); - - //if(app->m_needUpdateGUI) - //{ - // app->m_needUpdateGUI = false; - - // //app->m_canvasSize = canvas_get_buffer_size(canvas); - // //app->m_originalBuffer = canvas_get_buffer(canvas); - // //app->m_originalBufferLocation = &u8g2_GetBufferPtr(&canvas->fb); - // //u8g2_GetBufferPtr(&canvas->fb) = app->m_m_renderBufferPtr; - //} - - //uint8_t* exchangeBuffers = app->m_m_renderBufferPtr; - //app->m_m_renderBufferPtr = app->m_backBufferPtr; - //app->m_backBufferPtr = exchangeBuffers; - - //if(app->m_needUpdateGUI) - //{ - // //memcpy(app->m_renderBuffer, app->m_backBuffer, app->m_canvasSize); - // app->m_needUpdateGUI = false; - //} - - switch(app->m_context) { - case Undefined: { - canvas_clear(canvas); - canvas_set_font(canvas, FontPrimary); - - const char* strInitializing = "Something wrong"; - canvas_draw_str( - canvas, - (128 / 2) - (canvas_string_width(canvas, strInitializing) / 2), - (64 / 2) /* - (canvas_current_font_height(canvas) / 2)*/, - strInitializing); - } break; - case WaitingForModule: -#if ENABLE_MODULE_DETECTION - furi_assert(!app->m_wifiDeauthModuleAttached); - if(!app->m_wifiDeauthModuleAttached) { - canvas_clear(canvas); - canvas_set_font(canvas, FontSecondary); - - const char* strInitializing = "Attach WiFi Deauther module"; - canvas_draw_str( - canvas, - (128 / 2) - (canvas_string_width(canvas, strInitializing) / 2), - (64 / 2) /* - (canvas_current_font_height(canvas) / 2)*/, - strInitializing); - } -#endif - break; - case Initializing: -#if ENABLE_MODULE_POWER - { - furi_assert(!app->m_wifiDeauthModuleInitialized); - if(!app->m_wifiDeauthModuleInitialized) { - canvas_set_font(canvas, FontPrimary); - - const char* strInitializing = "Initializing..."; - canvas_draw_str( - canvas, - (128 / 2) - (canvas_string_width(canvas, strInitializing) / 2), - (64 / 2) - (canvas_current_font_height(canvas) / 2), - strInitializing); - } - } -#endif // ENABLE_MODULE_POWER - break; - case ModuleActive: { - uint8_t* buffer = canvas->fb.tile_buf_ptr; - app->m_canvasSize = gui_get_framebuffer_size(app->m_gui); - memcpy(buffer, app->m_backBuffer, app->m_canvasSize); - } break; - default: - break; - } - - furi_mutex_release(app->mutex); -} - -static void - esp8266_deauth_module_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - SPluginEvent event = {.m_type = EventTypeKey, .m_input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { - furi_assert(context); - - SWiFiDeauthApp* app = context; - - DEAUTH_APP_LOG_I("uart_echo_on_irq_cb"); - - if(ev == UartIrqEventRXNE) { - DEAUTH_APP_LOG_I("ev == UartIrqEventRXNE"); - furi_stream_buffer_send(app->m_rx_stream, &data, 1, 0); - furi_thread_flags_set(furi_thread_get_id(app->m_worker_thread), WorkerEventRx); - } -} - -static int32_t uart_worker(void* context) { - furi_assert(context); - DEAUTH_APP_LOG_I("[UART] Worker thread init"); - - SWiFiDeauthApp* app = context; - furi_mutex_acquire(app->mutex, FuriWaitForever); - if(app == NULL) { - return 1; - } - - FuriStreamBuffer* rx_stream = app->m_rx_stream; - - furi_mutex_release(app->mutex); - -#if ENABLE_MODULE_POWER - bool initialized = false; - - FuriString* receivedString; - receivedString = furi_string_alloc(); -#endif // ENABLE_MODULE_POWER - - while(true) { - uint32_t events = furi_thread_flags_wait( - WorkerEventStop | WorkerEventRx, FuriFlagWaitAny, FuriWaitForever); - furi_check((events & FuriFlagError) == 0); - - if(events & WorkerEventStop) break; - if(events & WorkerEventRx) { - DEAUTH_APP_LOG_I("[UART] Received data"); - SWiFiDeauthApp* app = context; - furi_mutex_acquire(app->mutex, FuriWaitForever); - if(app == NULL) { - return 1; - } - - size_t dataReceivedLength = 0; - int index = 0; - do { - const uint8_t dataBufferSize = 64; - uint8_t dataBuffer[dataBufferSize]; - dataReceivedLength = - furi_stream_buffer_receive(rx_stream, dataBuffer, dataBufferSize, 25); - if(dataReceivedLength > 0) { -#if ENABLE_MODULE_POWER - if(!initialized) { - if(!(dataReceivedLength > strlen(MODULE_CONTEXT_INITIALIZATION))) { - DEAUTH_APP_LOG_I("[UART] Found possible init candidate"); - for(uint16_t i = 0; i < dataReceivedLength; i++) { - furi_string_push_back(receivedString, dataBuffer[i]); - } - } - } else -#endif // ENABLE_MODULE_POWER - { - DEAUTH_APP_LOG_I("[UART] Data copied to backbuffer"); - memcpy(app->m_backBuffer + index, dataBuffer, dataReceivedLength); - index += dataReceivedLength; - app->m_needUpdateGUI = true; - } - } - - } while(dataReceivedLength > 0); - -#if ENABLE_MODULE_POWER - if(!app->m_wifiDeauthModuleInitialized) { - if(furi_string_cmp_str(receivedString, MODULE_CONTEXT_INITIALIZATION) == 0) { - DEAUTH_APP_LOG_I("[UART] Initialized"); - initialized = true; - app->m_wifiDeauthModuleInitialized = true; - app->m_context = ModuleActive; - furi_string_free(receivedString); - } else { - DEAUTH_APP_LOG_I("[UART] Not an initialization command"); - furi_string_reset(receivedString); - } - } -#endif // ENABLE_MODULE_POWER - - furi_mutex_release(app->mutex); - } - } - - return 0; -} - -int32_t esp8266_deauth_app(void* p) { - UNUSED(p); - - DEAUTH_APP_LOG_I("Init"); - - // FuriTimer* timer = furi_timer_alloc(blink_test_update, FuriTimerTypePeriodic, event_queue); - // furi_timer_start(timer, furi_kernel_get_tick_frequency()); - - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(SPluginEvent)); - - SWiFiDeauthApp* app = malloc(sizeof(SWiFiDeauthApp)); - - esp8266_deauth_app_init(app); - - furi_hal_gpio_init_simple(app->m_GpioButtons.pinButtonUp, GpioModeOutputPushPull); - furi_hal_gpio_init_simple(app->m_GpioButtons.pinButtonDown, GpioModeOutputPushPull); - furi_hal_gpio_init_simple(app->m_GpioButtons.pinButtonOK, GpioModeOutputPushPull); - furi_hal_gpio_init_simple(app->m_GpioButtons.pinButtonBack, GpioModeOutputPushPull); - - furi_hal_gpio_write(app->m_GpioButtons.pinButtonUp, true); - furi_hal_gpio_write(app->m_GpioButtons.pinButtonDown, true); - furi_hal_gpio_write(app->m_GpioButtons.pinButtonOK, true); - furi_hal_gpio_write( - app->m_GpioButtons.pinButtonBack, false); // GPIO15 - Boot fails if pulled HIGH - -#if ENABLE_MODULE_DETECTION - furi_hal_gpio_init( - &gpio_ext_pc0, - GpioModeInput, - GpioPullUp, - GpioSpeedLow); // Connect to the Flipper's ground just to be sure - //furi_hal_gpio_add_int_callback(pinD0, input_isr_d0, this); - app->m_context = WaitingForModule; -#else -#if ENABLE_MODULE_POWER - app->m_context = Initializing; - uint8_t attempts = 0; - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - furi_delay_ms(10); - } - furi_delay_ms(200); -#else - app->m_context = ModuleActive; -#endif -#endif // ENABLE_MODULE_DETECTION - - app->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!app->mutex) { - DEAUTH_APP_LOG_E("cannot create mutex\r\n"); - free(app); - return 255; - } - - DEAUTH_APP_LOG_I("Mutex created"); - - //app->m_notification = furi_record_open(RECORD_NOTIFICATION); - - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, esp8266_deauth_module_render_callback, app); - view_port_input_callback_set(view_port, esp8266_deauth_module_input_callback, event_queue); - - // Open GUI and register view_port - app->m_gui = furi_record_open(RECORD_GUI); - gui_add_view_port(app->m_gui, view_port, GuiLayerFullscreen); - - //notification_message(app->notification, &sequence_set_only_blue_255); - - app->m_rx_stream = furi_stream_buffer_alloc(1 * 1024, 1); - - app->m_worker_thread = furi_thread_alloc(); - furi_thread_set_name(app->m_worker_thread, "WiFiDeauthModuleUARTWorker"); - furi_thread_set_stack_size(app->m_worker_thread, 1 * 1024); - furi_thread_set_context(app->m_worker_thread, app); - furi_thread_set_callback(app->m_worker_thread, uart_worker); - furi_thread_start(app->m_worker_thread); - DEAUTH_APP_LOG_I("UART thread allocated"); - - // Enable uart listener -#if DISABLE_CONSOLE - furi_hal_console_disable(); -#endif - - if(UART_CH == FuriHalUartIdUSART1) { - furi_hal_console_disable(); - } else if(UART_CH == FuriHalUartIdLPUART1) { - furi_hal_uart_init(UART_CH, FLIPPERZERO_SERIAL_BAUD); - } - - furi_hal_uart_set_br(FuriHalUartIdUSART1, FLIPPERZERO_SERIAL_BAUD); - furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, uart_on_irq_cb, app); - DEAUTH_APP_LOG_I("UART Listener created"); - - SPluginEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - furi_mutex_acquire(app->mutex, FuriWaitForever); - -#if ENABLE_MODULE_DETECTION - if(!app->m_wifiDeauthModuleAttached) { - if(furi_hal_gpio_read(&gpio_ext_pc0) == false) { - DEAUTH_APP_LOG_I("Module Attached"); - app->m_wifiDeauthModuleAttached = true; -#if ENABLE_MODULE_POWER - app->m_context = Initializing; - uint8_t attempts2 = 0; - while(!furi_hal_power_is_otg_enabled() && attempts2++ < 3) { - furi_hal_power_enable_otg(); - furi_delay_ms(10); - } -#else - app->m_context = ModuleActive; -#endif - } - } -#endif // ENABLE_MODULE_DETECTION - - if(event_status == FuriStatusOk) { - if(event.m_type == EventTypeKey) { - if(app->m_wifiDeauthModuleInitialized) { - if(app->m_context == ModuleActive) { - switch(event.m_input.key) { - case InputKeyUp: - if(event.m_input.type == InputTypePress) { - DEAUTH_APP_LOG_I("Up Press"); - furi_hal_gpio_write(app->m_GpioButtons.pinButtonUp, false); - } else if(event.m_input.type == InputTypeRelease) { - DEAUTH_APP_LOG_I("Up Release"); - furi_hal_gpio_write(app->m_GpioButtons.pinButtonUp, true); - } - break; - case InputKeyDown: - if(event.m_input.type == InputTypePress) { - DEAUTH_APP_LOG_I("Down Press"); - furi_hal_gpio_write(app->m_GpioButtons.pinButtonDown, false); - } else if(event.m_input.type == InputTypeRelease) { - DEAUTH_APP_LOG_I("Down Release"); - furi_hal_gpio_write(app->m_GpioButtons.pinButtonDown, true); - } - break; - case InputKeyOk: - if(event.m_input.type == InputTypePress) { - DEAUTH_APP_LOG_I("OK Press"); - furi_hal_gpio_write(app->m_GpioButtons.pinButtonOK, false); - } else if(event.m_input.type == InputTypeRelease) { - DEAUTH_APP_LOG_I("OK Release"); - furi_hal_gpio_write(app->m_GpioButtons.pinButtonOK, true); - } - break; - case InputKeyBack: - if(event.m_input.type == InputTypePress) { - DEAUTH_APP_LOG_I("Back Press"); - furi_hal_gpio_write(app->m_GpioButtons.pinButtonBack, false); - } else if(event.m_input.type == InputTypeRelease) { - DEAUTH_APP_LOG_I("Back Release"); - furi_hal_gpio_write(app->m_GpioButtons.pinButtonBack, true); - } else if(event.m_input.type == InputTypeLong) { - DEAUTH_APP_LOG_I("Back Long"); - processing = false; - } - break; - default: - break; - } - } - } else { - if(event.m_input.key == InputKeyBack) { - if(event.m_input.type == InputTypeShort || - event.m_input.type == InputTypeLong) { - processing = false; - } - } - } - } - } - -#if ENABLE_MODULE_DETECTION - if(app->m_wifiDeauthModuleAttached && furi_hal_gpio_read(&gpio_ext_pc0) == true) { - DEAUTH_APP_LOG_D("Module Disconnected - Exit"); - processing = false; - app->m_wifiDeauthModuleAttached = false; - app->m_wifiDeauthModuleInitialized = false; - } -#endif - - view_port_update(view_port); - furi_mutex_release(app->mutex); - } - - DEAUTH_APP_LOG_I("Start exit app"); - - furi_thread_flags_set(furi_thread_get_id(app->m_worker_thread), WorkerEventStop); - furi_thread_join(app->m_worker_thread); - furi_thread_free(app->m_worker_thread); - - DEAUTH_APP_LOG_I("Thread Deleted"); - - // Reset GPIO pins to default state - furi_hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(&gpio_ext_pc3, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(&gpio_ext_pb2, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(&gpio_ext_pb3, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(&gpio_ext_pa4, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - -#if DISABLE_CONSOLE - furi_hal_console_enable(); -#endif - - if(UART_CH == FuriHalUartIdLPUART1) { - furi_hal_uart_deinit(UART_CH); - } else { - furi_hal_console_enable(); - } - - //*app->m_originalBufferLocation = app->m_originalBuffer; - - view_port_enabled_set(view_port, false); - - gui_remove_view_port(app->m_gui, view_port); - - // Close gui record - furi_record_close(RECORD_GUI); - //furi_record_close(RECORD_NOTIFICATION); - app->m_gui = NULL; - - view_port_free(view_port); - - furi_message_queue_free(event_queue); - - furi_stream_buffer_free(app->m_rx_stream); - - furi_mutex_free(app->mutex); - - // Free rest - free(app); - - DEAUTH_APP_LOG_I("App freed"); - -#if ENABLE_MODULE_POWER - if(furi_hal_power_is_otg_enabled()) { - furi_hal_power_disable_otg(); - } -#endif - - return 0; -} diff --git a/applications/external/esp8266_deauth/wifi_10px.png b/applications/external/esp8266_deauth/wifi_10px.png deleted file mode 100644 index c13534660..000000000 Binary files a/applications/external/esp8266_deauth/wifi_10px.png and /dev/null differ diff --git a/applications/external/ifttt/application.fam b/applications/external/ifttt/application.fam deleted file mode 100644 index 6828447e9..000000000 --- a/applications/external/ifttt/application.fam +++ /dev/null @@ -1,13 +0,0 @@ -App( - appid="esp8266_ifttt_virtual_button", - name="[ESP8266] IFTTT Btn", - apptype=FlipperAppType.EXTERNAL, - entry_point="ifttt_virtual_button_app", - cdefines=["APP_IFTTT_VIRTUAL_BUTTON"], - requires=[ - "gui", - ], - stack_size=2 * 1024, - fap_icon="icon.png", - fap_category="WiFi", -) diff --git a/applications/external/ifttt/icon.png b/applications/external/ifttt/icon.png deleted file mode 100644 index f6d586b38..000000000 Binary files a/applications/external/ifttt/icon.png and /dev/null differ diff --git a/applications/external/ifttt/ifttt_virtual_button.c b/applications/external/ifttt/ifttt_virtual_button.c deleted file mode 100644 index ba1684daf..000000000 --- a/applications/external/ifttt/ifttt_virtual_button.c +++ /dev/null @@ -1,236 +0,0 @@ -#include "ifttt_virtual_button.h" - -#define IFTTT_FOLDER "/ext/apps_data/ifttt" -#define IFTTT_CONFIG_FOLDER "/ext/apps_data/ifttt/config" -const char* CONFIG_FILE_PATH = "/ext/apps_data/ifttt/config/config.settings"; - -#define FLIPPERZERO_SERIAL_BAUD 115200 -typedef enum ESerialCommand { ESerialCommand_Config } ESerialCommand; - -Settings save_settings(Settings settings) { - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* file = flipper_format_file_alloc(storage); - if(flipper_format_file_open_existing(file, CONFIG_FILE_PATH)) { - flipper_format_update_string_cstr(file, CONF_SSID, settings.save_ssid); - flipper_format_update_string_cstr(file, CONF_PASSWORD, settings.save_password); - flipper_format_update_string_cstr(file, CONF_KEY, settings.save_key); - flipper_format_update_string_cstr(file, CONF_EVENT, settings.save_event); - } else { - } - flipper_format_file_close(file); - flipper_format_free(file); - furi_record_close(RECORD_STORAGE); - return settings; -} - -void save_settings_file(FlipperFormat* file, Settings* settings) { - flipper_format_write_header_cstr(file, CONFIG_FILE_HEADER, CONFIG_FILE_VERSION); - flipper_format_write_comment_cstr(file, "Enter here the SSID of the wifi network"); - flipper_format_write_string_cstr(file, CONF_SSID, settings->save_ssid); - flipper_format_write_comment_cstr(file, "Enter here the PASSWORD of the wifi network"); - flipper_format_write_string_cstr(file, CONF_PASSWORD, settings->save_password); - flipper_format_write_comment_cstr(file, "Enter here the WEBHOOKS of your IFTTT account"); - flipper_format_write_string_cstr(file, CONF_KEY, settings->save_key); - flipper_format_write_comment_cstr(file, "Enter here the EVENT name of your trigger"); - flipper_format_write_string_cstr(file, CONF_EVENT, settings->save_event); -} - -Settings* load_settings() { - Settings* settings = malloc(sizeof(Settings)); - - settings->save_ssid = ""; - settings->save_password = ""; - settings->save_key = ""; - settings->save_event = ""; - - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* file = flipper_format_file_alloc(storage); - - FuriString* string_value = furi_string_alloc(); - FuriString* text_ssid_value = furi_string_alloc(); - FuriString* text_password_value = furi_string_alloc(); - FuriString* text_key_value = furi_string_alloc(); - FuriString* text_event_value = furi_string_alloc(); - - if(storage_common_stat(storage, CONFIG_FILE_PATH, NULL) != FSE_OK) { - if(flipper_format_file_open_new(file, CONFIG_FILE_PATH)) { - save_settings_file(file, settings); - } - flipper_format_file_close(file); - } else { - if(flipper_format_file_open_existing(file, CONFIG_FILE_PATH)) { - uint32_t value; - if(flipper_format_read_header(file, string_value, &value)) { - if(flipper_format_read_string(file, CONF_SSID, text_ssid_value)) { - settings->save_ssid = malloc(furi_string_size(text_ssid_value) + 1); - strcpy(settings->save_ssid, furi_string_get_cstr(text_ssid_value)); - } - if(flipper_format_read_string(file, CONF_PASSWORD, text_password_value)) { - settings->save_password = malloc(furi_string_size(text_password_value) + 1); - strcpy(settings->save_password, furi_string_get_cstr(text_password_value)); - } - if(flipper_format_read_string(file, CONF_KEY, text_key_value)) { - settings->save_key = malloc(furi_string_size(text_key_value) + 1); - strcpy(settings->save_key, furi_string_get_cstr(text_key_value)); - } - if(flipper_format_read_string(file, CONF_EVENT, text_event_value)) { - settings->save_event = malloc(furi_string_size(text_event_value) + 1); - strcpy(settings->save_event, furi_string_get_cstr(text_event_value)); - } - } - } - flipper_format_file_close(file); - } - - furi_string_free(text_ssid_value); - furi_string_free(text_password_value); - furi_string_free(text_key_value); - furi_string_free(text_event_value); - flipper_format_free(file); - furi_record_close(RECORD_STORAGE); - return settings; -} - -void send_serial_command_config(ESerialCommand command, Settings* settings) { - uint8_t data[1] = {0}; - - char config_tmp[100]; - strcpy(config_tmp, "config,"); - strcat(config_tmp, settings->save_key); - char config_tmp2[5]; - strcpy(config_tmp2, config_tmp); - strcat(config_tmp2, ","); - char config_tmp3[100]; - strcpy(config_tmp3, config_tmp2); - strcat(config_tmp3, settings->save_ssid); - char config_tmp4[5]; - strcpy(config_tmp4, config_tmp3); - strcat(config_tmp4, ","); - char config_tmp5[100]; - strcpy(config_tmp5, config_tmp4); - strcat(config_tmp5, settings->save_password); - char config_tmp6[5]; - strcpy(config_tmp6, config_tmp5); - strcat(config_tmp6, ","); - char config[350]; - strcpy(config, config_tmp6); - strcat(config, settings->save_event); - - int length = strlen(config); - for(int i = 0; i < length; i++) { - switch(command) { - case ESerialCommand_Config: - data[0] = config[i]; - break; - default: - return; - } - - furi_hal_uart_tx(FuriHalUartIdUSART1, data, 1); - } -} - -static bool ifttt_virtual_button_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - VirtualButtonApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool ifttt_virtual_button_back_event_callback(void* context) { - furi_assert(context); - VirtualButtonApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void ifttt_virtual_button_tick_event_callback(void* context) { - furi_assert(context); - VirtualButtonApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -VirtualButtonApp* ifttt_virtual_button_app_alloc(uint32_t first_scene) { - VirtualButtonApp* app = malloc(sizeof(VirtualButtonApp)); - - // Records - app->gui = furi_record_open(RECORD_GUI); - app->power = furi_record_open(RECORD_POWER); - - // View dispatcher - app->view_dispatcher = view_dispatcher_alloc(); - app->scene_manager = scene_manager_alloc(&virtual_button_scene_handlers, app); - view_dispatcher_enable_queue(app->view_dispatcher); - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, ifttt_virtual_button_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, ifttt_virtual_button_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, ifttt_virtual_button_tick_event_callback, 2000); - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - // Views - app->sen_view = send_view_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, VirtualButtonAppViewSendView, send_view_get_view(app->sen_view)); - - app->abou_view = about_view_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, VirtualButtonAppViewAboutView, about_view_get_view(app->abou_view)); - - app->submenu = submenu_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, VirtualButtonAppViewSubmenu, submenu_get_view(app->submenu)); - app->dialog = dialog_ex_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, VirtualButtonAppViewDialog, dialog_ex_get_view(app->dialog)); - - // Set first scene - scene_manager_next_scene(app->scene_manager, first_scene); - return app; -} - -void ifttt_virtual_button_app_free(VirtualButtonApp* app) { - furi_assert(app); - - free(app->settings.save_ssid); - free(app->settings.save_password); - free(app->settings.save_key); - - // Views - view_dispatcher_remove_view(app->view_dispatcher, VirtualButtonAppViewSendView); - send_view_free(app->sen_view); - view_dispatcher_remove_view(app->view_dispatcher, VirtualButtonAppViewAboutView); - about_view_free(app->abou_view); - view_dispatcher_remove_view(app->view_dispatcher, VirtualButtonAppViewSubmenu); - submenu_free(app->submenu); - view_dispatcher_remove_view(app->view_dispatcher, VirtualButtonAppViewDialog); - dialog_ex_free(app->dialog); - // View dispatcher - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - // Records - furi_record_close(RECORD_POWER); - furi_record_close(RECORD_GUI); - - free(app); -} - -int32_t ifttt_virtual_button_app(void* p) { - UNUSED(p); - - Storage* storage = furi_record_open(RECORD_STORAGE); - if(!storage_simply_mkdir(storage, IFTTT_FOLDER)) { - } - if(!storage_simply_mkdir(storage, IFTTT_CONFIG_FOLDER)) { - } - furi_record_close(RECORD_STORAGE); - - uint32_t first_scene = VirtualButtonAppSceneStart; - VirtualButtonApp* app = ifttt_virtual_button_app_alloc(first_scene); - memcpy(&app->settings, load_settings(), sizeof(Settings)); - send_serial_command_config(ESerialCommand_Config, &(app->settings)); - - view_dispatcher_run(app->view_dispatcher); - ifttt_virtual_button_app_free(app); - return 0; -} diff --git a/applications/external/ifttt/ifttt_virtual_button.h b/applications/external/ifttt/ifttt_virtual_button.h deleted file mode 100644 index 563f5cd95..000000000 --- a/applications/external/ifttt/ifttt_virtual_button.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include "views/send_view.h" -#include "views/about_view.h" -#include -#include -#include -#include -#include -#include -#include "scenes/virtual_button_scene.h" - -#define APP_NAME "[ESP8266] IFTTT Virtual Button" - -#define CONF_SSID "wifi_ssid" -#define CONF_PASSWORD "wifi_password" -#define CONF_KEY "webhooks_key" -#define CONF_EVENT "event" -#define CONFIG_FILE_HEADER "IFTTT Virtual Button Config File" -#define CONFIG_FILE_VERSION 1 - -typedef struct { - char* save_ssid; - char* save_password; - char* save_key; - char* save_event; -} Settings; - -typedef struct { - Power* power; - Gui* gui; - SceneManager* scene_manager; - ViewDispatcher* view_dispatcher; - SendView* sen_view; - AboutView* abou_view; - Submenu* submenu; - DialogEx* dialog; - PowerInfo info; - Settings settings; -} VirtualButtonApp; - -typedef enum { - VirtualButtonAppViewSendView, - VirtualButtonAppViewAboutView, - VirtualButtonAppViewSubmenu, - VirtualButtonAppViewDialog, -} VirtualButtonAppView; - -Settings save_settings(Settings settings); -Settings* load_settings(); \ No newline at end of file diff --git a/applications/external/ifttt/scenes/virtual_button_scene.c b/applications/external/ifttt/scenes/virtual_button_scene.c deleted file mode 100644 index a75d822fc..000000000 --- a/applications/external/ifttt/scenes/virtual_button_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "virtual_button_scene.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const virtual_button_on_enter_handlers[])(void*) = { -#include "virtual_button_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_event handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, -bool (*const virtual_button_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "virtual_button_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_exit handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, -void (*const virtual_button_on_exit_handlers[])(void* context) = { -#include "virtual_button_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers virtual_button_scene_handlers = { - .on_enter_handlers = virtual_button_on_enter_handlers, - .on_event_handlers = virtual_button_on_event_handlers, - .on_exit_handlers = virtual_button_on_exit_handlers, - .scene_num = VirtualButtonAppSceneNum, -}; diff --git a/applications/external/ifttt/scenes/virtual_button_scene.h b/applications/external/ifttt/scenes/virtual_button_scene.h deleted file mode 100644 index 870807dee..000000000 --- a/applications/external/ifttt/scenes/virtual_button_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) VirtualButtonAppScene##id, -typedef enum { -#include "virtual_button_scene_config.h" - VirtualButtonAppSceneNum, -} VirtualButtonAppScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers virtual_button_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "virtual_button_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_event handlers declaration -#define ADD_SCENE(prefix, name, id) \ - bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); -#include "virtual_button_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_exit handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); -#include "virtual_button_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/ifttt/scenes/virtual_button_scene_about.c b/applications/external/ifttt/scenes/virtual_button_scene_about.c deleted file mode 100644 index 86fe1a9d0..000000000 --- a/applications/external/ifttt/scenes/virtual_button_scene_about.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "../ifttt_virtual_button.h" - -static void virtual_button_scene_about_view_update_model(VirtualButtonApp* app) { - power_get_info(app->power, &app->info); -} - -void virtual_button_scene_about_view_on_enter(void* context) { - VirtualButtonApp* app = context; - virtual_button_scene_about_view_update_model(app); - view_dispatcher_switch_to_view(app->view_dispatcher, VirtualButtonAppViewAboutView); -} - -bool virtual_button_scene_about_view_on_event(void* context, SceneManagerEvent event) { - VirtualButtonApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeTick) { - virtual_button_scene_about_view_update_model(app); - consumed = true; - } - return consumed; -} - -void virtual_button_scene_about_view_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/ifttt/scenes/virtual_button_scene_config.h b/applications/external/ifttt/scenes/virtual_button_scene_config.h deleted file mode 100644 index 70af5ccf7..000000000 --- a/applications/external/ifttt/scenes/virtual_button_scene_config.h +++ /dev/null @@ -1,3 +0,0 @@ -ADD_SCENE(virtual_button, start, Start) -ADD_SCENE(virtual_button, send_view, SendView) -ADD_SCENE(virtual_button, about_view, AboutView) diff --git a/applications/external/ifttt/scenes/virtual_button_scene_send.c b/applications/external/ifttt/scenes/virtual_button_scene_send.c deleted file mode 100644 index caa23fadf..000000000 --- a/applications/external/ifttt/scenes/virtual_button_scene_send.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "../ifttt_virtual_button.h" - -static void virtual_button_scene_send_view_update_model(VirtualButtonApp* app) { - power_get_info(app->power, &app->info); -} - -void virtual_button_scene_send_view_on_enter(void* context) { - VirtualButtonApp* app = context; - virtual_button_scene_send_view_update_model(app); - view_dispatcher_switch_to_view(app->view_dispatcher, VirtualButtonAppViewSendView); -} - -bool virtual_button_scene_send_view_on_event(void* context, SceneManagerEvent event) { - VirtualButtonApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeTick) { - virtual_button_scene_send_view_update_model(app); - consumed = true; - } - return consumed; -} - -void virtual_button_scene_send_view_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/ifttt/scenes/virtual_button_scene_start.c b/applications/external/ifttt/scenes/virtual_button_scene_start.c deleted file mode 100644 index 6b03a35f0..000000000 --- a/applications/external/ifttt/scenes/virtual_button_scene_start.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "../ifttt_virtual_button.h" - -enum VirtualButtonSubmenuIndex { - VirtualButtonSubmenuIndexSendView, - VirtualButtonSubmenuIndexAboutView, -}; - -static void virtual_button_scene_start_submenu_callback(void* context, uint32_t index) { - furi_assert(context); - VirtualButtonApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void virtual_button_scene_start_on_enter(void* context) { - VirtualButtonApp* app = context; - Submenu* submenu = app->submenu; - - submenu_add_item( - submenu, - "Send IFTTT command", - VirtualButtonSubmenuIndexSendView, - virtual_button_scene_start_submenu_callback, - app); - submenu_add_item( - submenu, - "About", - VirtualButtonSubmenuIndexAboutView, - virtual_button_scene_start_submenu_callback, - app); - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(app->scene_manager, VirtualButtonAppSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, VirtualButtonAppViewSubmenu); -} - -bool virtual_button_scene_start_on_event(void* context, SceneManagerEvent event) { - VirtualButtonApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == VirtualButtonSubmenuIndexSendView) { - scene_manager_next_scene(app->scene_manager, VirtualButtonAppSceneSendView); - } else if(event.event == VirtualButtonSubmenuIndexAboutView) { - scene_manager_next_scene(app->scene_manager, VirtualButtonAppSceneAboutView); - } - scene_manager_set_scene_state(app->scene_manager, VirtualButtonAppSceneStart, event.event); - consumed = true; - } - return consumed; -} - -void virtual_button_scene_start_on_exit(void* context) { - VirtualButtonApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/external/ifttt/views/about_view.c b/applications/external/ifttt/views/about_view.c deleted file mode 100644 index 80c00883a..000000000 --- a/applications/external/ifttt/views/about_view.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "about_view.h" -#include -#include -#include -#include - -struct AboutView { - View* view; -}; - -typedef struct { - bool connected; -} AboutViewModel; - -static void about_view_draw_callback(Canvas* canvas, void* context) { - furi_assert(context); - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - canvas_draw_str_aligned(canvas, 0, 0, AlignLeft, AlignTop, "IFTTT Virtual button"); - canvas_draw_str_aligned(canvas, 0, 15, AlignLeft, AlignTop, "Version 0.2"); - canvas_draw_str_aligned(canvas, 0, 50, AlignLeft, AlignTop, "press back"); -} - -AboutView* about_view_alloc() { - AboutView* about_view = malloc(sizeof(AboutView)); - about_view->view = view_alloc(); - view_set_context(about_view->view, about_view); - view_allocate_model(about_view->view, ViewModelTypeLocking, sizeof(AboutViewModel)); - view_set_draw_callback(about_view->view, about_view_draw_callback); - return about_view; -} - -void about_view_free(AboutView* about_view) { - furi_assert(about_view); - view_free(about_view->view); - free(about_view); -} - -View* about_view_get_view(AboutView* about_view) { - furi_assert(about_view); - return about_view->view; -} - -void about_view_set_data(AboutView* about_view, bool connected) { - furi_assert(about_view); - with_view_model( - about_view->view, AboutViewModel * model, { model->connected = connected; }, true); -} \ No newline at end of file diff --git a/applications/external/ifttt/views/about_view.h b/applications/external/ifttt/views/about_view.h deleted file mode 100644 index d1ac287e3..000000000 --- a/applications/external/ifttt/views/about_view.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -typedef struct AboutView AboutView; - -AboutView* about_view_alloc(); - -void about_view_free(AboutView* about_view); - -View* about_view_get_view(AboutView* about_view); \ No newline at end of file diff --git a/applications/external/ifttt/views/send_view.c b/applications/external/ifttt/views/send_view.c deleted file mode 100644 index 6046c39e3..000000000 --- a/applications/external/ifttt/views/send_view.c +++ /dev/null @@ -1,137 +0,0 @@ -#include "send_view.h" -#include -#include -#include -#include -#include -#include -#include - -#define FLIPPERZERO_SERIAL_BAUD 115200 - -typedef enum ESerialCommand { ESerialCommand_Send } ESerialCommand; - -struct SendView { - View* view; -}; - -typedef struct { - bool right_pressed; - bool connected; -} SendViewModel; - -static void Shake(void) { - NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - notification_message(notification, &sequence_single_vibro); - furi_record_close(RECORD_NOTIFICATION); -} - -void send_serial_command_send(ESerialCommand command) { - uint8_t data[1] = {0}; - - char name[10] = "send"; - int length = strlen(name); - for(int i = 0; i < length; i++) { - switch(command) { - case ESerialCommand_Send: - data[0] = name[i]; - break; - default: - return; - }; - - furi_hal_uart_tx(FuriHalUartIdUSART1, data, 1); - } -} - -static void send_view_draw_callback(Canvas* canvas, void* context) { - furi_assert(context); - SendViewModel* model = context; - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - canvas_draw_str_aligned(canvas, 64, 0, AlignCenter, AlignTop, "SEND MODULE"); - canvas_draw_line(canvas, 0, 10, 128, 10); - canvas_draw_str_aligned(canvas, 64, 15, AlignCenter, AlignTop, "Press right to send IFTTT"); - canvas_draw_str_aligned(canvas, 64, 25, AlignCenter, AlignTop, "command or press and hold"); - canvas_draw_str_aligned(canvas, 64, 35, AlignCenter, AlignTop, "back to return to the menu"); - - // Right - if(model->right_pressed) { - } -} - -static void send_view_process(SendView* send_view, InputEvent* event) { - with_view_model( - send_view->view, - SendViewModel * model, - { - if(event->type == InputTypePress) { - if(event->key == InputKeyUp) { - } else if(event->key == InputKeyDown) { - } else if(event->key == InputKeyLeft) { - } else if(event->key == InputKeyRight) { - model->right_pressed = true; - Shake(); - send_serial_command_send(ESerialCommand_Send); - } else if(event->key == InputKeyOk) { - } else if(event->key == InputKeyBack) { - } - } else if(event->type == InputTypeRelease) { - if(event->key == InputKeyUp) { - } else if(event->key == InputKeyDown) { - } else if(event->key == InputKeyLeft) { - } else if(event->key == InputKeyRight) { - model->right_pressed = false; - } else if(event->key == InputKeyOk) { - } else if(event->key == InputKeyBack) { - } - } else if(event->type == InputTypeShort) { - if(event->key == InputKeyBack) { - } - } - }, - true); -} - -static bool send_view_input_callback(InputEvent* event, void* context) { - furi_assert(context); - SendView* send_view = context; - bool consumed = false; - - if(event->type == InputTypeLong && event->key == InputKeyBack) { - } else { - send_view_process(send_view, event); - consumed = true; - } - - return consumed; -} - -SendView* send_view_alloc() { - SendView* send_view = malloc(sizeof(SendView)); - send_view->view = view_alloc(); - view_set_context(send_view->view, send_view); - view_allocate_model(send_view->view, ViewModelTypeLocking, sizeof(SendViewModel)); - view_set_draw_callback(send_view->view, send_view_draw_callback); - view_set_input_callback(send_view->view, send_view_input_callback); - furi_hal_uart_set_br(FuriHalUartIdUSART1, FLIPPERZERO_SERIAL_BAUD); - - return send_view; -} - -void send_view_free(SendView* send_view) { - furi_assert(send_view); - view_free(send_view->view); - free(send_view); -} - -View* send_view_get_view(SendView* send_view) { - furi_assert(send_view); - return send_view->view; -} - -void send_view_set_data(SendView* send_view, bool connected) { - furi_assert(send_view); - with_view_model( - send_view->view, SendViewModel * model, { model->connected = connected; }, true); -} \ No newline at end of file diff --git a/applications/external/ifttt/views/send_view.h b/applications/external/ifttt/views/send_view.h deleted file mode 100644 index 4b1944dd4..000000000 --- a/applications/external/ifttt/views/send_view.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -typedef struct SendView SendView; - -SendView* send_view_alloc(); - -void send_view_free(SendView* send_view); - -View* send_view_get_view(SendView* send_view); \ No newline at end of file diff --git a/applications/external/morse_code/application.fam b/applications/external/morse_code/application.fam deleted file mode 100644 index d39f4738c..000000000 --- a/applications/external/morse_code/application.fam +++ /dev/null @@ -1,15 +0,0 @@ -App( - appid="morse_code", - name="Morse Code", - apptype=FlipperAppType.EXTERNAL, - entry_point="morse_code_app", - requires=[ - "gui", - ], - stack_size=1 * 1024, - fap_icon="morse_code_10px.png", - fap_category="Media", - fap_author="@wh00hw & @xMasterX", - fap_version="1.0", - fap_description="Simple Morse Code parser", -) diff --git a/applications/external/morse_code/morse_code.c b/applications/external/morse_code/morse_code.c deleted file mode 100644 index 3f96969e7..000000000 --- a/applications/external/morse_code/morse_code.c +++ /dev/null @@ -1,166 +0,0 @@ -#include "morse_code_worker.h" -#include -#include -#include -#include -#include -#include -#include - -static const float MORSE_CODE_VOLUMES[] = {0, .25, .5, .75, 1}; - -typedef struct { - FuriString* words; - uint8_t volume; - uint32_t dit_delta; -} MorseCodeModel; - -typedef struct { - MorseCodeModel* model; - FuriMutex** model_mutex; - - FuriMessageQueue* input_queue; - - ViewPort* view_port; - Gui* gui; - - MorseCodeWorker* worker; -} MorseCode; - -static void render_callback(Canvas* const canvas, void* ctx) { - MorseCode* morse_code = ctx; - furi_check(furi_mutex_acquire(morse_code->model_mutex, FuriWaitForever) == FuriStatusOk); - // border around the edge of the screen - canvas_set_font(canvas, FontPrimary); - - //write words - elements_multiline_text_aligned( - canvas, 64, 30, AlignCenter, AlignCenter, furi_string_get_cstr(morse_code->model->words)); - - // volume view_port - uint8_t vol_bar_x_pos = 124; - uint8_t vol_bar_y_pos = 0; - const uint8_t volume_h = (64 / (COUNT_OF(MORSE_CODE_VOLUMES) - 1)) * morse_code->model->volume; - canvas_draw_frame(canvas, vol_bar_x_pos, vol_bar_y_pos, 4, 64); - canvas_draw_box(canvas, vol_bar_x_pos, vol_bar_y_pos + (64 - volume_h), 4, volume_h); - - //dit bpms - FuriString* ditbpm = furi_string_alloc_printf("Dit: %ld ms", morse_code->model->dit_delta); - canvas_draw_str_aligned(canvas, 0, 10, AlignLeft, AlignCenter, furi_string_get_cstr(ditbpm)); - furi_string_free(ditbpm); - - //button info - elements_button_center(canvas, "Press/Hold"); - furi_mutex_release(morse_code->model_mutex); -} - -static void input_callback(InputEvent* input_event, void* ctx) { - MorseCode* morse_code = ctx; - furi_message_queue_put(morse_code->input_queue, input_event, FuriWaitForever); -} - -static void morse_code_worker_callback(FuriString* words, void* context) { - MorseCode* morse_code = context; - furi_check(furi_mutex_acquire(morse_code->model_mutex, FuriWaitForever) == FuriStatusOk); - furi_string_set(morse_code->model->words, words); - furi_mutex_release(morse_code->model_mutex); - view_port_update(morse_code->view_port); -} - -MorseCode* morse_code_alloc() { - MorseCode* instance = malloc(sizeof(MorseCode)); - - instance->model = malloc(sizeof(MorseCodeModel)); - instance->model->words = furi_string_alloc_set_str(""); - instance->model->volume = 3; - instance->model->dit_delta = 150; - instance->model_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - - instance->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); - - instance->worker = morse_code_worker_alloc(); - - morse_code_worker_set_callback(instance->worker, morse_code_worker_callback, instance); - - instance->view_port = view_port_alloc(); - view_port_draw_callback_set(instance->view_port, render_callback, instance); - view_port_input_callback_set(instance->view_port, input_callback, instance); - - // Open GUI and register view_port - instance->gui = furi_record_open(RECORD_GUI); - gui_add_view_port(instance->gui, instance->view_port, GuiLayerFullscreen); - - return instance; -} - -void morse_code_free(MorseCode* instance) { - gui_remove_view_port(instance->gui, instance->view_port); - furi_record_close(RECORD_GUI); - view_port_free(instance->view_port); - - morse_code_worker_free(instance->worker); - - furi_message_queue_free(instance->input_queue); - - furi_mutex_free(instance->model_mutex); - - furi_string_free(instance->model->words); - free(instance->model); - free(instance); -} - -int32_t morse_code_app() { - MorseCode* morse_code = morse_code_alloc(); - InputEvent input; - - morse_code_worker_start(morse_code->worker); - morse_code_worker_set_volume( - morse_code->worker, MORSE_CODE_VOLUMES[morse_code->model->volume]); - morse_code_worker_set_dit_delta(morse_code->worker, morse_code->model->dit_delta); - - while(furi_message_queue_get(morse_code->input_queue, &input, FuriWaitForever) == - FuriStatusOk) { - furi_check(furi_mutex_acquire(morse_code->model_mutex, FuriWaitForever) == FuriStatusOk); - if(input.key == InputKeyBack && input.type == InputTypeLong) { - furi_mutex_release(morse_code->model_mutex); - break; - } else if(input.key == InputKeyBack && input.type == InputTypeShort) { - morse_code_worker_reset_text(morse_code->worker); - furi_string_reset(morse_code->model->words); - } else if(input.key == InputKeyOk) { - if(input.type == InputTypePress) - morse_code_worker_play(morse_code->worker, true); - else if(input.type == InputTypeRelease) - morse_code_worker_play(morse_code->worker, false); - } else if(input.key == InputKeyUp && input.type == InputTypePress) { - if(morse_code->model->volume < COUNT_OF(MORSE_CODE_VOLUMES) - 1) - morse_code->model->volume++; - morse_code_worker_set_volume( - morse_code->worker, MORSE_CODE_VOLUMES[morse_code->model->volume]); - } else if(input.key == InputKeyDown && input.type == InputTypePress) { - if(morse_code->model->volume > 0) morse_code->model->volume--; - morse_code_worker_set_volume( - morse_code->worker, MORSE_CODE_VOLUMES[morse_code->model->volume]); - } else if(input.key == InputKeyLeft && input.type == InputTypePress) { - if(morse_code->model->dit_delta > 10) morse_code->model->dit_delta -= 10; - morse_code_worker_set_dit_delta(morse_code->worker, morse_code->model->dit_delta); - } else if(input.key == InputKeyRight && input.type == InputTypePress) { - if(morse_code->model->dit_delta >= 10) morse_code->model->dit_delta += 10; - morse_code_worker_set_dit_delta(morse_code->worker, morse_code->model->dit_delta); - } - - FURI_LOG_D( - "Input", - "%s %s %ld", - input_get_key_name(input.key), - input_get_type_name(input.type), - input.sequence); - - furi_mutex_release(morse_code->model_mutex); - view_port_update(morse_code->view_port); - } - - morse_code_worker_stop(morse_code->worker); - morse_code_free(morse_code); - return 0; -} \ No newline at end of file diff --git a/applications/external/morse_code/morse_code_10px.png b/applications/external/morse_code/morse_code_10px.png deleted file mode 100644 index 087c5b239..000000000 Binary files a/applications/external/morse_code/morse_code_10px.png and /dev/null differ diff --git a/applications/external/morse_code/morse_code_worker.c b/applications/external/morse_code/morse_code_worker.c deleted file mode 100644 index 47896b91a..000000000 --- a/applications/external/morse_code/morse_code_worker.c +++ /dev/null @@ -1,183 +0,0 @@ -#include "morse_code_worker.h" -#include -#include - -#define TAG "MorseCodeWorker" - -#define MORSE_CODE_VERSION 0 - -//A-Z0-1 -const char morse_array[36][6] = {".-", "-...", "-.-.", "-..", ".", "..-.", - "--.", "....", "..", ".---", "-.-", ".-..", - "--", "-.", "---", ".--.", "--.-", ".-.", - "...", "-", "..-", "...-", ".--", "-..-", - "-.--", "--..", ".----", "..---", "...--", "....-", - ".....", "-....", "--...", "---..", "----.", "-----"}; -const char symbol_array[36] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; - -struct MorseCodeWorker { - FuriThread* thread; - MorseCodeWorkerCallback callback; - void* callback_context; - bool is_running; - bool play; - float volume; - uint32_t dit_delta; - FuriString* buffer; - FuriString* words; -}; - -void morse_code_worker_fill_buffer(MorseCodeWorker* instance, uint32_t duration) { - FURI_LOG_D("MorseCode: Duration", "%ld", duration); - if(duration <= instance->dit_delta) - furi_string_push_back(instance->buffer, *DOT); - else if(duration <= (instance->dit_delta * 3)) - furi_string_push_back(instance->buffer, *LINE); - else - furi_string_reset(instance->buffer); - if(furi_string_size(instance->buffer) > 5) furi_string_reset(instance->buffer); - FURI_LOG_D("MorseCode: Buffer", "%s", furi_string_get_cstr(instance->buffer)); -} - -void morse_code_worker_fill_letter(MorseCodeWorker* instance) { - if(furi_string_size(instance->words) > 63) furi_string_reset(instance->words); - for(size_t i = 0; i < sizeof(morse_array); i++) { - if(furi_string_cmp_str(instance->buffer, morse_array[i]) == 0) { - furi_string_push_back(instance->words, symbol_array[i]); - break; - } - } - furi_string_reset(instance->buffer); - FURI_LOG_D("MorseCode: Words", "%s", furi_string_get_cstr(instance->words)); -} - -static int32_t morse_code_worker_thread_callback(void* context) { - furi_assert(context); - MorseCodeWorker* instance = context; - bool was_playing = false; - uint32_t start_tick = 0; - uint32_t end_tick = 0; - bool pushed = true; - bool spaced = true; - while(instance->is_running) { - furi_delay_ms(SLEEP); - - if(instance->play) { - if(!was_playing) { - start_tick = furi_get_tick(); - if(furi_hal_speaker_acquire(1000)) { - furi_hal_speaker_start(FREQUENCY, instance->volume); - } - was_playing = true; - } - } else { - if(was_playing) { - pushed = false; - spaced = false; - if(furi_hal_speaker_is_mine()) { - furi_hal_speaker_stop(); - furi_hal_speaker_release(); - } - end_tick = furi_get_tick(); - was_playing = false; - morse_code_worker_fill_buffer(instance, end_tick - start_tick); - start_tick = 0; - } - } - if(!pushed) { - if(end_tick + (instance->dit_delta * 3) < furi_get_tick()) { - //NEW LETTER - if(!furi_string_empty(instance->buffer)) { - morse_code_worker_fill_letter(instance); - if(instance->callback) - instance->callback(instance->words, instance->callback_context); - } else { - spaced = true; - } - pushed = true; - } - } - if(!spaced) { - if(end_tick + (instance->dit_delta * 7) < furi_get_tick()) { - //NEW WORD - furi_string_push_back(instance->words, *SPACE); - if(instance->callback) - instance->callback(instance->words, instance->callback_context); - spaced = true; - } - } - } - return 0; -} - -MorseCodeWorker* morse_code_worker_alloc() { - MorseCodeWorker* instance = malloc(sizeof(MorseCodeWorker)); - instance->thread = furi_thread_alloc(); - furi_thread_set_name(instance->thread, "MorseCodeWorker"); - furi_thread_set_stack_size(instance->thread, 1024); - furi_thread_set_context(instance->thread, instance); - furi_thread_set_callback(instance->thread, morse_code_worker_thread_callback); - instance->play = false; - instance->volume = 1.0f; - instance->dit_delta = 150; - instance->buffer = furi_string_alloc_set_str(""); - instance->words = furi_string_alloc_set_str(""); - return instance; -} - -void morse_code_worker_free(MorseCodeWorker* instance) { - furi_assert(instance); - furi_string_free(instance->buffer); - furi_string_free(instance->words); - furi_thread_free(instance->thread); - free(instance); -} - -void morse_code_worker_set_callback( - MorseCodeWorker* instance, - MorseCodeWorkerCallback callback, - void* context) { - furi_assert(instance); - instance->callback = callback; - instance->callback_context = context; -} - -void morse_code_worker_play(MorseCodeWorker* instance, bool play) { - furi_assert(instance); - instance->play = play; -} - -void morse_code_worker_set_volume(MorseCodeWorker* instance, float level) { - furi_assert(instance); - instance->volume = level; -} - -void morse_code_worker_set_dit_delta(MorseCodeWorker* instance, uint32_t delta) { - furi_assert(instance); - instance->dit_delta = delta; -} - -void morse_code_worker_reset_text(MorseCodeWorker* instance) { - furi_assert(instance); - furi_string_reset(instance->buffer); - furi_string_reset(instance->words); -} - -void morse_code_worker_start(MorseCodeWorker* instance) { - furi_assert(instance); - furi_assert(instance->is_running == false); - instance->is_running = true; - furi_thread_start(instance->thread); - FURI_LOG_D("MorseCode: Start", "is Running"); -} - -void morse_code_worker_stop(MorseCodeWorker* instance) { - furi_assert(instance); - furi_assert(instance->is_running == true); - instance->play = false; - instance->is_running = false; - furi_thread_join(instance->thread); - FURI_LOG_D("MorseCode: Stop", "Stop"); -} diff --git a/applications/external/morse_code/morse_code_worker.h b/applications/external/morse_code/morse_code_worker.h deleted file mode 100644 index e880c9579..000000000 --- a/applications/external/morse_code/morse_code_worker.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include -#include - -#define FREQUENCY 261.63f -#define SLEEP 10 -#define DOT "." -#define LINE "-" -#define SPACE " " - -typedef void (*MorseCodeWorkerCallback)(FuriString* buffer, void* context); - -typedef struct MorseCodeWorker MorseCodeWorker; - -MorseCodeWorker* morse_code_worker_alloc(); - -void morse_code_worker_free(MorseCodeWorker* instance); - -void morse_code_worker_set_callback( - MorseCodeWorker* instance, - MorseCodeWorkerCallback callback, - void* context); - -void morse_code_worker_start(MorseCodeWorker* instance); - -void morse_code_worker_stop(MorseCodeWorker* instance); - -void morse_code_worker_play(MorseCodeWorker* instance, bool play); - -void morse_code_worker_reset_text(MorseCodeWorker* instance); - -void morse_code_worker_set_volume(MorseCodeWorker* instance, float level); - -void morse_code_worker_set_dit_delta(MorseCodeWorker* instance, uint32_t delta); diff --git a/applications/external/multi_converter/application.fam b/applications/external/multi_converter/application.fam deleted file mode 100644 index 51d1c0798..000000000 --- a/applications/external/multi_converter/application.fam +++ /dev/null @@ -1,13 +0,0 @@ -App( - appid="multi_converter", - name="Multi Converter", - apptype=FlipperAppType.EXTERNAL, - entry_point="multi_converter_app", - requires=["gui"], - stack_size=1 * 1024, - fap_icon="converter_10px.png", - fap_category="Tools", - fap_author="@theisolinearchip", - fap_version="1.0", - fap_description="A multi-unit converter written with an easy and expandable system for adding new units and conversion methods", -) diff --git a/applications/external/multi_converter/converter_10px.png b/applications/external/multi_converter/converter_10px.png deleted file mode 100644 index 820b10639..000000000 Binary files a/applications/external/multi_converter/converter_10px.png and /dev/null differ diff --git a/applications/external/multi_converter/multi_converter.c b/applications/external/multi_converter/multi_converter.c deleted file mode 100644 index bd2b62587..000000000 --- a/applications/external/multi_converter/multi_converter.c +++ /dev/null @@ -1,164 +0,0 @@ -#include -#include -#include -#include - -#include "multi_converter_definitions.h" -#include "multi_converter_mode_display.h" -#include "multi_converter_mode_select.h" - -static void multi_converter_render_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - const MultiConverterState* multi_converter_state = ctx; - furi_mutex_acquire(multi_converter_state->mutex, FuriWaitForever); - - if(multi_converter_state->mode == ModeDisplay) { - multi_converter_mode_display_draw(canvas, multi_converter_state); - } else { - multi_converter_mode_select_draw(canvas, multi_converter_state); - } - - furi_mutex_release(multi_converter_state->mutex); -} - -static void - multi_converter_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - MultiConverterEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void multi_converter_init(MultiConverterState* const multi_converter_state) { - // initial default values - - multi_converter_state->buffer_orig[MULTI_CONVERTER_NUMBER_DIGITS] = '\0'; - multi_converter_state->buffer_dest[MULTI_CONVERTER_NUMBER_DIGITS] = '\0'; // null terminators - - multi_converter_state->unit_type_orig = UnitTypeDec; - multi_converter_state->unit_type_dest = UnitTypeHex; - - multi_converter_state->keyboard_lock = 0; - - // init the display view - multi_converter_mode_display_reset(multi_converter_state); - - // init the select view - multi_converter_mode_select_reset(multi_converter_state); - - // set ModeDisplay as the current mode - multi_converter_state->mode = ModeDisplay; -} - -// main entry point -int32_t multi_converter_app(void* p) { - UNUSED(p); - - // get event queue - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(MultiConverterEvent)); - - // allocate state - MultiConverterState* multi_converter_state = malloc(sizeof(MultiConverterState)); - - // set mutex for plugin state (different threads can access it) - multi_converter_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!multi_converter_state->mutex) { - FURI_LOG_E("MultiConverter", "cannot create mutex\r\n"); - furi_message_queue_free(event_queue); - free(multi_converter_state); - return 255; - } - - // register callbacks for drawing and input processing - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, multi_converter_render_callback, multi_converter_state); - view_port_input_callback_set(view_port, multi_converter_input_callback, event_queue); - - // open GUI and register view_port - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - multi_converter_init(multi_converter_state); - - // main loop - MultiConverterEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - furi_mutex_acquire(multi_converter_state->mutex, FuriWaitForever); - - if(event_status == FuriStatusOk) { - // press events - if(event.type == EventTypeKey && !multi_converter_state->keyboard_lock) { - if(multi_converter_state->mode == ModeDisplay) { - if(event.input.key == InputKeyBack) { - if(event.input.type == InputTypePress) processing = false; - } else if(event.input.key == InputKeyOk) { // the "ok" press can be short or long - MultiConverterModeTrigger t = None; - - if(event.input.type == InputTypeLong) - t = multi_converter_mode_display_ok(1, multi_converter_state); - else if(event.input.type == InputTypeShort) - t = multi_converter_mode_display_ok(0, multi_converter_state); - - if(t == Reset) { - multi_converter_mode_select_reset(multi_converter_state); - multi_converter_state->mode = ModeSelector; - } - } else { - if(event.input.type == InputTypePress) - multi_converter_mode_display_navigation( - event.input.key, multi_converter_state); - } - - } else { // ModeSelect - if(event.input.type == InputTypePress) { - switch(event.input.key) { - default: - break; - case InputKeyBack: - case InputKeyOk: { - MultiConverterModeTrigger t = multi_converter_mode_select_exit( - event.input.key == InputKeyOk ? 1 : 0, multi_converter_state); - - if(t == Reset) { - multi_converter_mode_display_reset(multi_converter_state); - } else if(t == Convert) { - multi_converter_mode_display_convert(multi_converter_state); - } - - multi_converter_state->keyboard_lock = 1; - multi_converter_state->mode = ModeDisplay; - break; - } - case InputKeyLeft: - case InputKeyRight: - multi_converter_mode_select_switch(multi_converter_state); - break; - case InputKeyUp: - multi_converter_mode_select_change_unit(-1, multi_converter_state); - break; - case InputKeyDown: - multi_converter_mode_select_change_unit(1, multi_converter_state); - break; - } - } - } - } else if(multi_converter_state->keyboard_lock) { - multi_converter_state->keyboard_lock = 0; - } - } - - view_port_update(view_port); - furi_mutex_release(multi_converter_state->mutex); - } - - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close(RECORD_GUI); - view_port_free(view_port); - furi_message_queue_free(event_queue); - furi_mutex_free(multi_converter_state->mutex); - free(multi_converter_state); - - return 0; -} \ No newline at end of file diff --git a/applications/external/multi_converter/multi_converter_definitions.h b/applications/external/multi_converter/multi_converter_definitions.h deleted file mode 100644 index 2f79bc7d9..000000000 --- a/applications/external/multi_converter/multi_converter_definitions.h +++ /dev/null @@ -1,83 +0,0 @@ -#pragma once - -#define MULTI_CONVERTER_NUMBER_DIGITS 9 - -typedef enum { - EventTypeKey, -} EventType; - -typedef struct { - InputEvent input; - EventType type; -} MultiConverterEvent; - -typedef enum { - ModeDisplay, - ModeSelector, -} MultiConverterMode; - -typedef enum { - None, - Reset, - Convert, -} MultiConverterModeTrigger; - -// new units goes here, used as index to the main multi_converter_available_units array (multi_converter_units.h) -typedef enum { - UnitTypeDec, - UnitTypeHex, - UnitTypeBin, - - UnitTypeCelsius, - UnitTypeFahernheit, - UnitTypeKelvin, - - UnitTypeKilometers, - UnitTypeMeters, - UnitTypeCentimeters, - UnitTypeMiles, - UnitTypeFeet, - UnitTypeInches, - - UnitTypeDegree, - UnitTypeRadian, -} MultiConverterUnitType; - -typedef struct { - MultiConverterUnitType selected_unit_type_orig; - MultiConverterUnitType selected_unit_type_dest; - uint8_t select_orig; -} MultiConverterModeSelect; - -typedef struct { - uint8_t cursor; // cursor position when typing - int8_t key; // hover key - uint8_t comma; // comma already added? (only one comma allowed) - uint8_t negative; // is negative? -} MultiConverterModeDisplay; - -typedef struct MultiConverterUnit MultiConverterUnit; -typedef struct MultiConverterState MultiConverterState; - -struct MultiConverterUnit { - uint8_t allow_comma; - uint8_t allow_negative; - uint8_t max_number_keys; - char mini_name[4]; - char name[12]; - void (*convert_function)(MultiConverterState* const); - uint8_t (*allowed_function)(MultiConverterUnitType); -}; - -struct MultiConverterState { - FuriMutex* mutex; - char buffer_orig[MULTI_CONVERTER_NUMBER_DIGITS + 1]; - char buffer_dest[MULTI_CONVERTER_NUMBER_DIGITS + 1]; - MultiConverterUnitType unit_type_orig; - MultiConverterUnitType unit_type_dest; - MultiConverterMode mode; - MultiConverterModeDisplay display; - MultiConverterModeSelect select; - uint8_t keyboard_lock; // used to create a small lock when switching from SELECT to DISPLAY modes - // (debouncing, basically; otherwise it switch modes twice 'cause it's too fast!) -}; diff --git a/applications/external/multi_converter/multi_converter_mode_display.c b/applications/external/multi_converter/multi_converter_mode_display.c deleted file mode 100644 index c72a954f7..000000000 --- a/applications/external/multi_converter/multi_converter_mode_display.c +++ /dev/null @@ -1,326 +0,0 @@ -#include "multi_converter_mode_display.h" - -#define MULTI_CONVERTER_DISPLAY_KEYS 18 // [0] to [F] + [BACK] + [SELECT] - -#define MULTI_CONVERTER_DISPLAY_KEY_NEGATIVE 0 // long press -#define MULTI_CONVERTER_DISPLAY_KEY_COMMA 1 // long press -#define MULTI_CONVERTER_DISPLAY_KEY_DEL 16 -#define MULTI_CONVERTER_DISPLAY_KEY_SELECT 17 - -#define MULTI_CONVERTER_DISPLAY_CHAR_COMMA '.' -#define MULTI_CONVERTER_DISPLAY_CHAR_NEGATIVE '-' -#define MULTI_CONVERTER_DISPLAY_CHAR_DEL '<' -#define MULTI_CONVERTER_DISPLAY_CHAR_SELECT '#' -#define MULTI_CONVERTER_DISPLAY_CHAR_BLANK ' ' - -#define MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN 3 -#define MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT 8 - -void multi_converter_mode_display_convert(MultiConverterState* const multi_converter_state) { - // 1.- if origin == destination (in theory user won't be allowed to choose the same options, but it's kinda "valid"...) - // just copy buffer_orig to buffer_dest and that's it - - if(multi_converter_state->unit_type_orig == multi_converter_state->unit_type_dest) { - memcpy( - multi_converter_state->buffer_dest, - multi_converter_state->buffer_orig, - MULTI_CONVERTER_NUMBER_DIGITS); - return; - } - - // 2.- origin_buffer has not null functions - if(multi_converter_get_unit(multi_converter_state->unit_type_orig).convert_function == NULL || - multi_converter_get_unit(multi_converter_state->unit_type_orig).allowed_function == NULL) - return; - - // 3.- valid destination type (using allowed_destinations function) - if(!multi_converter_get_unit(multi_converter_state->unit_type_orig) - .allowed_function(multi_converter_state->unit_type_dest)) - return; - - multi_converter_get_unit(multi_converter_state->unit_type_orig) - .convert_function(multi_converter_state); -} - -void multi_converter_mode_display_draw( - Canvas* const canvas, - const MultiConverterState* multi_converter_state) { - canvas_set_color(canvas, ColorBlack); - - // ORIGIN - canvas_set_font(canvas, FontPrimary); - canvas_draw_str( - canvas, 2, 10, multi_converter_get_unit(multi_converter_state->unit_type_orig).mini_name); - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 2 + 30, 10, multi_converter_state->buffer_orig); - - // DESTINATION - canvas_set_font(canvas, FontPrimary); - canvas_draw_str( - canvas, - 2, - 10 + 12, - multi_converter_get_unit(multi_converter_state->unit_type_dest).mini_name); - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 2 + 30, 10 + 12, multi_converter_state->buffer_dest); - - // SEPARATOR_LINE - canvas_draw_line(canvas, 2, 25, 128 - 3, 25); - - // KEYBOARD - uint8_t _x = 5; - uint8_t _y = 25 + 15; // line + 10 - - for(int i = 0; i < MULTI_CONVERTER_DISPLAY_KEYS; i++) { - char g; - if(i < 10) - g = (i + '0'); - else if(i < 16) - g = ((i - 10) + 'A'); - else if(i == MULTI_CONVERTER_DISPLAY_KEY_DEL) - g = MULTI_CONVERTER_DISPLAY_CHAR_DEL; - else - g = MULTI_CONVERTER_DISPLAY_CHAR_SELECT; - - uint8_t g_w = canvas_glyph_width(canvas, g); - - if(i < 16 && - i > multi_converter_get_unit(multi_converter_state->unit_type_orig).max_number_keys - - 1) { - // some units won't use the full [0] - [F] keyboard, in those situations just hide the char - // (won't be selectable anyway, so no worries here; this is just about drawing stuff) - g = MULTI_CONVERTER_DISPLAY_CHAR_BLANK; - } - - // currently hover key is highlighted - if((multi_converter_state->display).key == i) { - canvas_draw_box( - canvas, - _x - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN, - _y - (MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT + - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN), - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN + g_w + - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN, - MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT + - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2); - canvas_set_color(canvas, ColorWhite); - } else { - canvas_draw_frame( - canvas, - _x - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN, - _y - (MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT + - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN), - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN + g_w + - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN, - MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT + - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2); - } - - // draw key - canvas_draw_glyph(canvas, _x, _y, g); - - // certain keys have long_press features, draw whatever they're using there too - if(i == MULTI_CONVERTER_DISPLAY_KEY_NEGATIVE) { - canvas_draw_box( - canvas, - _x + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN + g_w - 4, - _y + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN - 2, - 4, - 2); - } else if(i == MULTI_CONVERTER_DISPLAY_KEY_COMMA) { - canvas_draw_box( - canvas, - _x + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN + g_w - 2, - _y + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN - 2, - 2, - 2); - } - - // back to black - canvas_set_color(canvas, ColorBlack); - - if(i < 8) { - _x += g_w + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2 + 2; - } else if(i == 8) { - _y += (MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT + - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2) + - 3; - _x = 8; // some padding at the beginning on second line - } else { - _x += g_w + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2 + 1; - } - } -} - -void multi_converter_mode_display_navigation( - InputKey key, - MultiConverterState* const multi_converter_state) { - // first move to keyboard position, then check if the ORIGIN allows that specific key, if not jump to the "closest one" - switch(key) { - default: - break; - - case InputKeyUp: - case InputKeyDown: - if((multi_converter_state->display).key >= 9) - (multi_converter_state->display).key -= 9; - else - (multi_converter_state->display).key += 9; - break; - - case InputKeyLeft: - case InputKeyRight: - - (multi_converter_state->display).key += (key == InputKeyLeft ? -1 : 1); - - if((multi_converter_state->display).key > MULTI_CONVERTER_DISPLAY_KEYS - 1) - (multi_converter_state->display).key = 0; - else if((multi_converter_state->display).key < 0) - (multi_converter_state->display).key = MULTI_CONVERTER_DISPLAY_KEYS - 1; - break; - } - - // if destination key is disabled by max_number_keys, move to the closest one - // (this could be improved with more accurate keys movements, probably...) - if(multi_converter_get_unit(multi_converter_state->unit_type_orig).max_number_keys >= 16) - return; // weird, since this means "do not show any number on the keyboard, but just in case..." - - int8_t i = -1; - if(key == InputKeyRight || key == InputKeyDown) i = 1; - - while((multi_converter_state->display).key < 16 && - (multi_converter_state->display).key > - multi_converter_get_unit(multi_converter_state->unit_type_orig).max_number_keys - - 1) { - (multi_converter_state->display).key += i; - if((multi_converter_state->display).key > MULTI_CONVERTER_DISPLAY_KEYS - 1) - (multi_converter_state->display).key = 0; - else if((multi_converter_state->display).key < 0) - (multi_converter_state->display).key = MULTI_CONVERTER_DISPLAY_KEYS - 1; - } -} - -void multi_converter_mode_display_reset(MultiConverterState* const multi_converter_state) { - // clean the buffers - for(int i = 0; i < MULTI_CONVERTER_NUMBER_DIGITS; i++) { - multi_converter_state->buffer_orig[i] = MULTI_CONVERTER_DISPLAY_CHAR_BLANK; - multi_converter_state->buffer_dest[i] = MULTI_CONVERTER_DISPLAY_CHAR_BLANK; - } - - // reset the display flags and index - multi_converter_state->display.cursor = 0; - multi_converter_state->display.key = 0; - multi_converter_state->display.comma = 0; - multi_converter_state->display.negative = 0; -} - -void multi_converter_mode_display_toggle_negative( - MultiConverterState* const multi_converter_state) { - if(multi_converter_get_unit(multi_converter_state->unit_type_orig).allow_negative) { - if(!(multi_converter_state->display).negative) { - // shift origin buffer one to right + add the "-" sign (last digit will be lost) - for(int i = MULTI_CONVERTER_NUMBER_DIGITS - 1; i > 0; i--) { - // we could avoid the blanks, but nevermind - multi_converter_state->buffer_orig[i] = multi_converter_state->buffer_orig[i - 1]; - } - multi_converter_state->buffer_orig[0] = MULTI_CONVERTER_DISPLAY_CHAR_NEGATIVE; - - // only increment cursor if we're not out of bound - if((multi_converter_state->display).cursor < MULTI_CONVERTER_NUMBER_DIGITS) - (multi_converter_state->display).cursor++; - } else { - // shift origin buffer one to left, append ' ' on the end - for(int i = 0; i < MULTI_CONVERTER_NUMBER_DIGITS - 1; i++) { - if(multi_converter_state->buffer_orig[i] == MULTI_CONVERTER_DISPLAY_CHAR_BLANK) - break; - - multi_converter_state->buffer_orig[i] = multi_converter_state->buffer_orig[i + 1]; - } - multi_converter_state->buffer_orig[MULTI_CONVERTER_NUMBER_DIGITS - 1] = - MULTI_CONVERTER_DISPLAY_CHAR_BLANK; - - (multi_converter_state->display).cursor--; - } - - // toggle flag - (multi_converter_state->display).negative ^= 1; - } -} - -void multi_converter_mode_display_add_comma(MultiConverterState* const multi_converter_state) { - if(!multi_converter_get_unit(multi_converter_state->unit_type_orig).allow_comma || - (multi_converter_state->display).comma || !(multi_converter_state->display).cursor || - ((multi_converter_state->display).cursor == (MULTI_CONVERTER_NUMBER_DIGITS - 1))) - return; // maybe not allowerd; or one comma already in place; also cannot add commas as first or last chars - - // set flag to one - (multi_converter_state->display).comma = 1; - - multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] = - MULTI_CONVERTER_DISPLAY_CHAR_COMMA; - (multi_converter_state->display).cursor++; -} - -void multi_converter_mode_display_add_number(MultiConverterState* const multi_converter_state) { - if((multi_converter_state->display).key > - multi_converter_get_unit(multi_converter_state->unit_type_orig).max_number_keys - 1) - return; - - if((multi_converter_state->display).key < 10) { - multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] = - (multi_converter_state->display).key + '0'; - } else { - multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] = - ((multi_converter_state->display).key - 10) + 'A'; - } - - (multi_converter_state->display).cursor++; -} - -MultiConverterModeTrigger multi_converter_mode_display_ok( - uint8_t long_press, - MultiConverterState* const multi_converter_state) { - if((multi_converter_state->display).key < MULTI_CONVERTER_DISPLAY_KEY_DEL) { - if((multi_converter_state->display).cursor >= MULTI_CONVERTER_NUMBER_DIGITS) - return None; // limit reached, ignore - - // long press on 0 toggle NEGATIVE if allowed, on 1 adds COMMA if allowed - if(long_press) { - if((multi_converter_state->display).key == MULTI_CONVERTER_DISPLAY_KEY_NEGATIVE) { - // toggle negative - multi_converter_mode_display_toggle_negative(multi_converter_state); - } else if((multi_converter_state->display).key == MULTI_CONVERTER_DISPLAY_KEY_COMMA) { - // add comma - multi_converter_mode_display_add_comma(multi_converter_state); - } - - } else { - // regular keys - multi_converter_mode_display_add_number(multi_converter_state); - } - - multi_converter_mode_display_convert(multi_converter_state); - - } else if((multi_converter_state->display).key == MULTI_CONVERTER_DISPLAY_KEY_DEL) { - if((multi_converter_state->display).cursor > 0) (multi_converter_state->display).cursor--; - - if(multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] == - MULTI_CONVERTER_DISPLAY_CHAR_COMMA) - (multi_converter_state->display).comma = 0; - if(multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] == - MULTI_CONVERTER_DISPLAY_CHAR_NEGATIVE) - (multi_converter_state->display).negative = 0; - - multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] = - MULTI_CONVERTER_DISPLAY_CHAR_BLANK; - - multi_converter_mode_display_convert(multi_converter_state); - - } else { // MULTI_CONVERTER_DISPLAY_KEY_SELECT - return Reset; - } - - return None; -} \ No newline at end of file diff --git a/applications/external/multi_converter/multi_converter_mode_display.h b/applications/external/multi_converter/multi_converter_mode_display.h deleted file mode 100644 index cae929d35..000000000 --- a/applications/external/multi_converter/multi_converter_mode_display.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include -#include - -#include "multi_converter_definitions.h" -#include "multi_converter_units.h" - -// -// performs a unit conversion from origin to source buffers, if there's any error, overflow or -// non-compatible format (which shouldn't happen, but just in case) abort conversion and outputs -// some "?" strings on the buffer or something similar -// -void multi_converter_mode_display_convert(MultiConverterState* const multi_converter_state); - -// -// draw the main DISPLAY view with the current multi_converter_state values -// -void multi_converter_mode_display_draw( - Canvas* const canvas, - const MultiConverterState* multi_converter_state); - -// -// keyboard navigation on DISPLAY mode (NAVIGATION only, no BACK nor OK - InputKey guaranteed to be left/right/up/down) -// -void multi_converter_mode_display_navigation( - InputKey key, - MultiConverterState* const multi_converter_state); - -// -// reset the DISPLAY mode with the current units, cleaning the buffers and different flags; -// call this when exiting the SELECT mode / changing the units -// -void multi_converter_mode_display_reset(MultiConverterState* const multi_converter_state); - -// -// toggle the negative flag on current selected buffer ONLY if the unit allows negative numbers -// (adding negative number may crop the last char on the buffer; it cannot be recovered) -// -void multi_converter_mode_display_toggle_negative(MultiConverterState* const multi_converter_state); - -// -// add a comma/dot/decimal separator/whatever on current selected buffer ONLY if the unit allows it -// (only ONE comma allowed, not in the beginning nor end) -// -void multi_converter_mode_display_add_comma(MultiConverterState* const multi_converter_state); - -// -// add a regular number to the buffer if it's <= the max_number_keys from the unit (not necessary -// since the draw and navigation functions won't allow a trigger for an invalid number, but still -// to keep the "checks" policy on each "add key" function...) -// -void multi_converter_mode_display_add_number(MultiConverterState* const multi_converter_state); - -// -// handle the OK action when selecting a specific key on the keyboard (add a number, a symbol, change mode...) -// returns a ModeTrigger enum value: may or may not let to a mode change on the main loop (WON'T change the mode here) -// -MultiConverterModeTrigger multi_converter_mode_display_ok( - uint8_t long_press, - MultiConverterState* const multi_converter_state); \ No newline at end of file diff --git a/applications/external/multi_converter/multi_converter_mode_select.c b/applications/external/multi_converter/multi_converter_mode_select.c deleted file mode 100644 index a56ccd58c..000000000 --- a/applications/external/multi_converter/multi_converter_mode_select.c +++ /dev/null @@ -1,210 +0,0 @@ -#include "multi_converter_mode_select.h" - -#define MULTI_CONVERTER_LIST_ENTRIES_COUNT 3 - -#define MULTI_CONVERTER_INFO_STRING_FROM "FROM:" -#define MULTI_CONVERTER_INFO_STRING_TO "TO:" -#define MULTI_CONVERTER_INFO_STRING_OK "OK: Change" -#define MULTI_CONVERTER_INFO_STRING_BACK "BACK: Cancel" - -void multi_converter_mode_select_draw_destination_offset( - uint8_t x, - uint8_t y, - int8_t d, - Canvas* const canvas, - const MultiConverterState* multi_converter_state) { - int i = 1; - while( - i < - MULTI_CONVERTER_AVAILABLE_UNITS) { // in case there's no match, to avoid an endless loop (in theory shouldn't happen, but...) - int ut = multi_converter_get_unit_type_offset( - (multi_converter_state->select).selected_unit_type_dest, i * d); - if(multi_converter_available_units[(multi_converter_state->select).selected_unit_type_orig] - .allowed_function(ut) && - (multi_converter_state->select).selected_unit_type_orig != ut) { - canvas_draw_str(canvas, x, y, multi_converter_available_units[ut].name); - break; - } - i++; - } -} - -void multi_converter_mode_select_draw_selected_unit( - uint8_t x, - uint8_t y, - MultiConverterUnitType unit_type, - Canvas* const canvas) { - canvas_draw_box( - canvas, - x - 2, - y - 10, - canvas_string_width(canvas, multi_converter_available_units[unit_type].name) + 4, - 13); - canvas_set_color(canvas, ColorWhite); - canvas_draw_str(canvas, x, y, multi_converter_available_units[unit_type].name); - canvas_set_color(canvas, ColorBlack); -} - -void multi_converter_mode_select_draw( - Canvas* const canvas, - const MultiConverterState* multi_converter_state) { - int y = 10; - int x = 10; - - canvas_set_color(canvas, ColorBlack); - - // FROM - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, x, y, MULTI_CONVERTER_INFO_STRING_FROM); - - canvas_set_font(canvas, FontSecondary); - - // offset -1 - y += 12; - - canvas_draw_str( - canvas, - x, - y, - multi_converter_available_units[multi_converter_get_unit_type_offset( - (multi_converter_state->select).selected_unit_type_orig, - -1)] - .name); - - // current selected element - y += 12; - - multi_converter_mode_select_draw_selected_unit( - x, y, (multi_converter_state->select).selected_unit_type_orig, canvas); - - if((multi_converter_state->select).select_orig) canvas_draw_str(canvas, x - 6, y, ">"); - - // offset +1 - y += 12; - - canvas_draw_str( - canvas, - x, - y, - multi_converter_available_units[multi_converter_get_unit_type_offset( - (multi_converter_state->select).selected_unit_type_orig, - 1)] - .name); - - // TO - y = 10; - x = 70; - - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, x, y, MULTI_CONVERTER_INFO_STRING_TO); - - canvas_set_font(canvas, FontSecondary); - - // offset -1: go back from current selected destination and find the first one valid (even if it's itself) - y += 12; - - multi_converter_mode_select_draw_destination_offset(x, y, -1, canvas, multi_converter_state); - - // current selected element - y += 12; - - multi_converter_mode_select_draw_selected_unit( - x, y, (multi_converter_state->select).selected_unit_type_dest, canvas); - - if(!(multi_converter_state->select).select_orig) canvas_draw_str(canvas, x - 6, y, ">"); - - // offset +1: same but on the opposite direction - y += 12; - - multi_converter_mode_select_draw_destination_offset(x, y, 1, canvas, multi_converter_state); - - // OK / CANCEL - - canvas_set_color(canvas, ColorBlack); - canvas_draw_box( - canvas, 0, 64 - 12, canvas_string_width(canvas, MULTI_CONVERTER_INFO_STRING_OK) + 4, 12); - canvas_draw_box( - canvas, - 128 - 4 - canvas_string_width(canvas, MULTI_CONVERTER_INFO_STRING_BACK), - 64 - 12, - canvas_string_width(canvas, "BACK: Cancel") + 4, - 12); - - canvas_set_color(canvas, ColorWhite); - canvas_draw_str(canvas, 2, 64 - 3, MULTI_CONVERTER_INFO_STRING_OK); - canvas_draw_str( - canvas, - 128 - 2 - canvas_string_width(canvas, MULTI_CONVERTER_INFO_STRING_BACK), - 64 - 3, - MULTI_CONVERTER_INFO_STRING_BACK); -} - -void multi_converter_mode_select_reset(MultiConverterState* const multi_converter_state) { - // initial pre-selected values are equal to the current selected values - (multi_converter_state->select).selected_unit_type_orig = - multi_converter_state->unit_type_orig; - (multi_converter_state->select).selected_unit_type_dest = - multi_converter_state->unit_type_dest; - - (multi_converter_state->select).select_orig = 1; -} - -MultiConverterModeTrigger multi_converter_mode_select_exit( - uint8_t save_changes, - MultiConverterState* const multi_converter_state) { - if(save_changes) { - multi_converter_state->unit_type_dest = - (multi_converter_state->select).selected_unit_type_dest; - - if(multi_converter_state->unit_type_orig == - (multi_converter_state->select).selected_unit_type_orig) { - // if the ORIGIN unit didn't changed, just trigger the convert - - return Convert; - } else { - multi_converter_state->unit_type_orig = - (multi_converter_state->select).selected_unit_type_orig; - multi_converter_state->unit_type_dest = - (multi_converter_state->select).selected_unit_type_dest; - - return Reset; - } - } - - return None; -} - -void multi_converter_mode_select_switch(MultiConverterState* const multi_converter_state) { - (multi_converter_state->select).select_orig ^= 1; -} - -void multi_converter_mode_select_change_unit( - int8_t direction, - MultiConverterState* const multi_converter_state) { - MultiConverterUnitType d; - if((multi_converter_state->select).select_orig) { - (multi_converter_state->select).selected_unit_type_orig = - multi_converter_get_unit_type_offset( - (multi_converter_state->select).selected_unit_type_orig, direction); - d = (multi_converter_state->select).selected_unit_type_dest; - } else { - d = ((multi_converter_state->select).selected_unit_type_dest + direction) % - MULTI_CONVERTER_AVAILABLE_UNITS; - } - - // check each unit with the ORIGIN allowed_function() to make sure we're selecting a valid DESTINATION - // (when changing the ORIGIN unit the DIRECTION in which we'll switch the DESTINATION will be the SAME); - // also notice that ORIGIN must be DIFFERENT than DESTINATION - int i = 0; - while(i < MULTI_CONVERTER_AVAILABLE_UNITS) { - if(multi_converter_available_units[(multi_converter_state->select).selected_unit_type_orig] - .allowed_function(d) && - (multi_converter_state->select).selected_unit_type_orig != d) { - (multi_converter_state->select).selected_unit_type_dest = d; - break; - } - - d = multi_converter_get_unit_type_offset(d, direction); - i++; - } -} diff --git a/applications/external/multi_converter/multi_converter_mode_select.h b/applications/external/multi_converter/multi_converter_mode_select.h deleted file mode 100644 index c10ab8e01..000000000 --- a/applications/external/multi_converter/multi_converter_mode_select.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "multi_converter_definitions.h" -#include "multi_converter_units.h" - -// -// aux draw function for units offsets and draw stuff -// -void multi_converter_mode_select_draw_destination_offset( - uint8_t x, - uint8_t y, - int8_t d, - Canvas* const canvas, - const MultiConverterState* multi_converter_state); - -void multi_converter_mode_select_draw_selected_unit( - uint8_t x, - uint8_t y, - MultiConverterUnitType unit_type, - Canvas* const canvas); - -// -// draw the main SELECT view with the current multi_converter_state values -// -void multi_converter_mode_select_draw( - Canvas* const canvas, - const MultiConverterState* multi_converter_state); - -// -// reset the SELECT mode view, showing as "pre-selected" the current working units -// -void multi_converter_mode_select_reset(MultiConverterState* const multi_converter_state); - -// -// exit from SELECT mode and go back to display view, if save_changes == 1 use the current SELECT view info -// to modify the current selected units and reset the views properly (usually if the ORIGIN unit has been -// changed, reset everything; otherwise just trigger the convert function with a new DESTINATION) -// -// currently this function DON'T CHECK invalid unit relations (the navigation and display functions will -// prevent weird behaviours, so for now we're trusting the selected_unit_orig/dest_type values) -// -// returns an enum code MultiConverterDisplayTrigger based on doing nothing (cancel), triggering the display -// convert method or reseting the whole display mode (when fully changing the units) -// -// notice the MODE CHANGE itself is not done here but in the main loop (outside the call) via the ModeTrigger enum element -// -MultiConverterModeTrigger multi_converter_mode_select_exit( - uint8_t save_changes, - MultiConverterState* const multi_converter_state); - -// -// switch between selecting the ORIGIN or the DESTINATION unit on DISPLAY mode (since there're only -// two options, both left/right arrow keys acts as toggles, no "direction" required) -// -void multi_converter_mode_select_switch(MultiConverterState* const multi_converter_state); - -// -// change the selected unit on SELECTED mode, using the select_orig flag to check if we're switching the -// ORIGIN or the DESTINATION unit; the DIRECTION (up or down to travel the array) is set as a param -// -// when switching the ORIGIN one, reset the DESTINATION to the first valid unit (if the current one is not -// valid anymore); when switching the DESTINATION one, an allowed_function() check is performed in order to -// properly set a valid destination unit. -// -// (notice the draw step also perform which units are valid to display, so no worries about that here) -// -void multi_converter_mode_select_change_unit( - int8_t direction, - MultiConverterState* const multi_converter_state); diff --git a/applications/external/multi_converter/multi_converter_units.c b/applications/external/multi_converter/multi_converter_units.c deleted file mode 100644 index 4381f0e6e..000000000 --- a/applications/external/multi_converter/multi_converter_units.c +++ /dev/null @@ -1,261 +0,0 @@ -#include "multi_converter_units.h" - -#define MULTI_CONVERTER_CHAR_OVERFLOW '#' -#define MULTI_CONVERTER_MAX_SUPORTED_INT 999999999 - -#define multi_converter_unit_set_overflow(b) \ - for(int _i = 0; _i < MULTI_CONVERTER_NUMBER_DIGITS; _i++) \ - b[_i] = MULTI_CONVERTER_CHAR_OVERFLOW; - -// -// DEC / HEX / BIN conversion -// -void multi_converter_unit_dec_hex_bin_convert(MultiConverterState* const multi_converter_state) { - char dest[MULTI_CONVERTER_NUMBER_DIGITS]; - - int i = 0; - uint8_t overflow = 0; - - int a = 0; - int r = 0; - uint8_t f = 1; - - switch(multi_converter_state->unit_type_orig) { - default: - break; - case UnitTypeDec: { - a = atoi(multi_converter_state->buffer_orig); - f = (multi_converter_state->unit_type_dest == UnitTypeHex ? 16 : 2); - - break; - } - case UnitTypeHex: - a = strtol(multi_converter_state->buffer_orig, NULL, 16); - f = (multi_converter_state->unit_type_dest == UnitTypeDec ? 10 : 2); - - break; - case UnitTypeBin: - a = strtol(multi_converter_state->buffer_orig, NULL, 2); - f = (multi_converter_state->unit_type_dest == UnitTypeDec ? 10 : 16); - - break; - } - - while(a > 0) { - r = a % f; - dest[i] = r + (r < 10 ? '0' : ('A' - 10)); - a /= f; - if(i++ >= MULTI_CONVERTER_NUMBER_DIGITS) { - overflow = 1; - break; - } - } - - if(overflow) { - multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); - } else { - // copy DEST (reversed) to destination and append empty chars at the end - for(int j = 0; j < MULTI_CONVERTER_NUMBER_DIGITS; j++) { - if(i >= 1) - multi_converter_state->buffer_dest[j] = dest[--i]; - else - multi_converter_state->buffer_dest[j] = ' '; - } - } -} - -uint8_t multi_converter_unit_dec_hex_bin_allowed(MultiConverterUnitType unit_type) { - return (unit_type == UnitTypeDec || unit_type == UnitTypeHex || unit_type == UnitTypeBin); -} - -// -// CEL / FAR / KEL -// -void multi_converter_unit_temperature_convert(MultiConverterState* const multi_converter_state) { - double a = strtof(multi_converter_state->buffer_orig, NULL); - uint8_t overflow = 0; - - switch(multi_converter_state->unit_type_orig) { - default: - break; - case UnitTypeCelsius: - if(multi_converter_state->unit_type_dest == UnitTypeFahernheit) { - // celsius to fahrenheit - a = (a * ((double)1.8)) + 32; - } else { // UnitTypeKelvin - a += ((double)273.15); - } - - break; - case UnitTypeFahernheit: - // fahrenheit to celsius, always - a = (a - 32) / ((double)1.8); - if(multi_converter_state->unit_type_dest == UnitTypeKelvin) { - // if kelvin, add - a += ((double)273.15); - } - - break; - case UnitTypeKelvin: - // kelvin to celsius, always - a -= ((double)273.15); - if(multi_converter_state->unit_type_dest == UnitTypeFahernheit) { - // if fahernheit, convert - a = (a * ((double)1.8)) + 32; - } - - break; - } - - if(overflow) { - multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); - } else { - int ret = snprintf( - multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%.3lf", a); - - if(ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); - } -} - -uint8_t multi_converter_unit_temperature_allowed(MultiConverterUnitType unit_type) { - return ( - unit_type == UnitTypeCelsius || unit_type == UnitTypeFahernheit || - unit_type == UnitTypeKelvin); -} - -// -// KM / M / CM / MILES / FEET / INCHES -// - -void multi_converter_unit_distance_convert(MultiConverterState* const multi_converter_state) { - double a = strtof(multi_converter_state->buffer_orig, NULL); - uint8_t overflow = 0; - - switch(multi_converter_state->unit_type_orig) { - default: - break; - case UnitTypeKilometers: - if(multi_converter_state->unit_type_dest == UnitTypeMeters) - a *= ((double)1000); - else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters) - a *= ((double)100000); - else if(multi_converter_state->unit_type_dest == UnitTypeMiles) - a *= ((double)0.6213711); - else if(multi_converter_state->unit_type_dest == UnitTypeFeet) - a *= ((double)3280.839895013); - else if(multi_converter_state->unit_type_dest == UnitTypeInches) - a *= ((double)39370.078740157); - break; - case UnitTypeMeters: - if(multi_converter_state->unit_type_dest == UnitTypeKilometers) - a /= ((double)1000); - else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters) - a *= ((double)100); - else if(multi_converter_state->unit_type_dest == UnitTypeMiles) - a *= ((double)0.0006213711); - else if(multi_converter_state->unit_type_dest == UnitTypeFeet) - a *= ((double)3.280839895013); - else if(multi_converter_state->unit_type_dest == UnitTypeInches) - a *= ((double)39.370078740157); - break; - case UnitTypeCentimeters: - if(multi_converter_state->unit_type_dest == UnitTypeKilometers) - a /= ((double)100000); - else if(multi_converter_state->unit_type_dest == UnitTypeMeters) - a /= ((double)100); - else if(multi_converter_state->unit_type_dest == UnitTypeMiles) - a *= ((double)0.000006213711); - else if(multi_converter_state->unit_type_dest == UnitTypeFeet) - a *= ((double)0.03280839895013); - else if(multi_converter_state->unit_type_dest == UnitTypeInches) - a *= ((double)0.39370078740157); - break; - - case UnitTypeMiles: - if(multi_converter_state->unit_type_dest == UnitTypeKilometers) - a *= ((double)1.609344); - else if(multi_converter_state->unit_type_dest == UnitTypeMeters) - a *= ((double)1609.344); - else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters) - a *= ((double)160934.4); - else if(multi_converter_state->unit_type_dest == UnitTypeFeet) - a *= ((double)5280); - else if(multi_converter_state->unit_type_dest == UnitTypeInches) - a *= ((double)63360); - break; - case UnitTypeFeet: - if(multi_converter_state->unit_type_dest == UnitTypeKilometers) - a *= ((double)0.0003048); - else if(multi_converter_state->unit_type_dest == UnitTypeMeters) - a *= ((double)0.3048); - else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters) - a *= ((double)30.48); - else if(multi_converter_state->unit_type_dest == UnitTypeMiles) - a *= ((double)0.000189393939394); - else if(multi_converter_state->unit_type_dest == UnitTypeInches) - a *= ((double)12); - break; - case UnitTypeInches: - if(multi_converter_state->unit_type_dest == UnitTypeKilometers) - a *= ((double)0.0000254); - else if(multi_converter_state->unit_type_dest == UnitTypeMeters) - a *= ((double)0.0254); - else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters) - a *= ((double)2.54); - else if(multi_converter_state->unit_type_dest == UnitTypeMiles) - a *= ((double)0.0000157828282828); - else if(multi_converter_state->unit_type_dest == UnitTypeFeet) - a *= ((double)0.0833333333333); - break; - } - - if(overflow) { - multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); - } else { - int ret = snprintf( - multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%lf", a); - - if(ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); - } -} - -uint8_t multi_converter_unit_distance_allowed(MultiConverterUnitType unit_type) { - return ( - unit_type == UnitTypeKilometers || unit_type == UnitTypeMeters || - unit_type == UnitTypeCentimeters || unit_type == UnitTypeMiles || - unit_type == UnitTypeFeet || unit_type == UnitTypeInches); -} - -// -// DEG / RAD -// - -void multi_converter_unit_angle_convert(MultiConverterState* const multi_converter_state) { - double a = strtof(multi_converter_state->buffer_orig, NULL); - uint8_t overflow = 0; - - switch(multi_converter_state->unit_type_orig) { - default: - break; - case UnitTypeDegree: - if(multi_converter_state->unit_type_dest == UnitTypeRadian) a *= ((double)0.0174532925199); - break; - - case UnitTypeRadian: - if(multi_converter_state->unit_type_dest == UnitTypeDegree) a *= ((double)57.2957795131); - break; - } - - if(overflow) { - multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); - } else { - int ret = snprintf( - multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%lf", a); - - if(ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); - } -} - -uint8_t multi_converter_unit_angle_allowed(MultiConverterUnitType unit_type) { - return (unit_type == UnitTypeDegree || unit_type == UnitTypeRadian); -} \ No newline at end of file diff --git a/applications/external/multi_converter/multi_converter_units.h b/applications/external/multi_converter/multi_converter_units.h deleted file mode 100644 index 6d3b477bb..000000000 --- a/applications/external/multi_converter/multi_converter_units.h +++ /dev/null @@ -1,171 +0,0 @@ -#pragma once - -#include -#include - -#include "multi_converter_definitions.h" - -#define MULTI_CONVERTER_AVAILABLE_UNITS 14 - -#define multi_converter_get_unit(unit_type) multi_converter_available_units[unit_type] -#define multi_converter_get_unit_type_offset(unit_type, offset) \ - (((unit_type + offset) % MULTI_CONVERTER_AVAILABLE_UNITS + MULTI_CONVERTER_AVAILABLE_UNITS) % \ - MULTI_CONVERTER_AVAILABLE_UNITS) -// the modulo operation will fail with extremely large values on the units array - -// DEC / HEX / BIN -void multi_converter_unit_dec_hex_bin_convert(MultiConverterState* const multi_converter_state); -uint8_t multi_converter_unit_dec_hex_bin_allowed(MultiConverterUnitType); - -// CEL / FAR / KEL -void multi_converter_unit_temperature_convert(MultiConverterState* const multi_converter_state); -uint8_t multi_converter_unit_temperature_allowed(MultiConverterUnitType); - -// KM / M / CM / MILES / FEET / INCHES -void multi_converter_unit_distance_convert(MultiConverterState* const multi_converter_state); -uint8_t multi_converter_unit_distance_allowed(MultiConverterUnitType); - -// DEG / RAD -void multi_converter_unit_angle_convert(MultiConverterState* const multi_converter_state); -uint8_t multi_converter_unit_angle_allowed(MultiConverterUnitType unit_type); - -// -// each unit is made of comma? + negative? + keyboard_length + mini_name + name + convert function + allowed function -// (setting functions as NULL will cause convert / select options to be ignored) -// -static const MultiConverterUnit multi_converter_unit_dec = { - 0, - 0, - 10, - "DEC\0", - "Decimal\0", - multi_converter_unit_dec_hex_bin_convert, - multi_converter_unit_dec_hex_bin_allowed}; -static const MultiConverterUnit multi_converter_unit_hex = { - 0, - 0, - 16, - "HEX\0", - "Hexadecimal\0", - multi_converter_unit_dec_hex_bin_convert, - multi_converter_unit_dec_hex_bin_allowed}; -static const MultiConverterUnit multi_converter_unit_bin = { - 0, - 0, - 2, - "BIN\0", - "Binary\0", - multi_converter_unit_dec_hex_bin_convert, - multi_converter_unit_dec_hex_bin_allowed}; - -static const MultiConverterUnit multi_converter_unit_cel = { - 1, - 1, - 10, - "CEL\0", - "Celsius\0", - multi_converter_unit_temperature_convert, - multi_converter_unit_temperature_allowed}; -static const MultiConverterUnit multi_converter_unit_far = { - 1, - 1, - 10, - "FAR\0", - "Fahernheit\0", - multi_converter_unit_temperature_convert, - multi_converter_unit_temperature_allowed}; -static const MultiConverterUnit multi_converter_unit_kel = { - 1, - 1, - 10, - "KEL\0", - "Kelvin\0", - multi_converter_unit_temperature_convert, - multi_converter_unit_temperature_allowed}; - -static const MultiConverterUnit multi_converter_unit_km = { - 1, - 0, - 10, - "KM\0", - "Kilometers\0", - multi_converter_unit_distance_convert, - multi_converter_unit_distance_allowed}; -static const MultiConverterUnit multi_converter_unit_m = { - 1, - 0, - 10, - "M\0", - "Meters\0", - multi_converter_unit_distance_convert, - multi_converter_unit_distance_allowed}; -static const MultiConverterUnit multi_converter_unit_cm = { - 1, - 0, - 10, - "CM\0", - "Centimeters\0", - multi_converter_unit_distance_convert, - multi_converter_unit_distance_allowed}; -static const MultiConverterUnit multi_converter_unit_mi = { - 1, - 0, - 10, - "MI\0", - "Miles\0", - multi_converter_unit_distance_convert, - multi_converter_unit_distance_allowed}; -static const MultiConverterUnit multi_converter_unit_ft = { - 1, - 0, - 10, - "FT\0", - "Feet\0", - multi_converter_unit_distance_convert, - multi_converter_unit_distance_allowed}; -static const MultiConverterUnit multi_converter_unit_in = { - 1, - 0, - 10, - " \"\0", - "Inches\0", - multi_converter_unit_distance_convert, - multi_converter_unit_distance_allowed}; - -static const MultiConverterUnit multi_converter_unit_deg = { - 1, - 0, - 10, - "DEG\0", - "Degree\0", - multi_converter_unit_angle_convert, - multi_converter_unit_angle_allowed}; -static const MultiConverterUnit multi_converter_unit_rad = { - 1, - 0, - 10, - "RAD\0", - "Radian\0", - multi_converter_unit_angle_convert, - multi_converter_unit_angle_allowed}; - -// index order set by the MultiConverterUnitType enum element (multi_converter_definitions.h) -static const MultiConverterUnit multi_converter_available_units[MULTI_CONVERTER_AVAILABLE_UNITS] = { - [UnitTypeDec] = multi_converter_unit_dec, - [UnitTypeHex] = multi_converter_unit_hex, - [UnitTypeBin] = multi_converter_unit_bin, - - [UnitTypeCelsius] = multi_converter_unit_cel, - [UnitTypeFahernheit] = multi_converter_unit_far, - [UnitTypeKelvin] = multi_converter_unit_kel, - - [UnitTypeKilometers] = multi_converter_unit_km, - [UnitTypeMeters] = multi_converter_unit_m, - [UnitTypeCentimeters] = multi_converter_unit_cm, - [UnitTypeMiles] = multi_converter_unit_mi, - [UnitTypeFeet] = multi_converter_unit_ft, - [UnitTypeInches] = multi_converter_unit_in, - - [UnitTypeDegree] = multi_converter_unit_deg, - [UnitTypeRadian] = multi_converter_unit_rad, -}; \ No newline at end of file diff --git a/applications/external/multi_dice/application.fam b/applications/external/multi_dice/application.fam deleted file mode 100644 index 6bca3167a..000000000 --- a/applications/external/multi_dice/application.fam +++ /dev/null @@ -1,11 +0,0 @@ -App( - appid="multi_dice", - name="Multi-Dice", - apptype=FlipperAppType.EXTERNAL, - entry_point="dice_app", - cdefines=["APP_DICE"], - requires=["gui"], - stack_size=2 * 1024, - fap_icon="dice.png", - fap_category="Games", -) diff --git a/applications/external/multi_dice/dice.c b/applications/external/multi_dice/dice.c deleted file mode 100644 index 2de407cf0..000000000 --- a/applications/external/multi_dice/dice.c +++ /dev/null @@ -1,558 +0,0 @@ -#include -#include -#include "furi_hal_random.h" -#include -#include -#include - -#define TAG "Dice Roller" - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} PluginEvent; - -typedef struct { - FuriMutex* mutex; - FuriMessageQueue* event_queue; - FuriHalRtcDateTime datetime; - uint8_t diceSelect; - uint8_t diceQty; - uint8_t diceRoll; - uint8_t playerOneScore; - uint8_t playerTwoScore; - char rollTime[1][15]; - char diceType[1][11]; - char strings[5][45]; - char theScores[1][45]; - bool letsRoll; -} DiceState; - -static void dice_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void dice_render_callback(Canvas* const canvas, void* ctx) { - DiceState* state = ctx; - if(furi_mutex_acquire(state->mutex, 200) != FuriStatusOk) { - // Can't obtain mutex, requeue render - PluginEvent event = {.type = EventTypeTick}; - furi_message_queue_put(state->event_queue, &event, 0); - return; - } - - canvas_set_font(canvas, FontSecondary); - if(state->diceSelect < 220) { - if(state->diceQty == 1) { - elements_button_left(canvas, "x1"); - } else if(state->diceQty == 2) { - elements_button_left(canvas, "x2"); - } else if(state->diceQty == 3) { - elements_button_left(canvas, "x3"); - } else if(state->diceQty == 4) { - elements_button_left(canvas, "x4"); - } else if(state->diceQty == 5) { - elements_button_left(canvas, "x5"); - } else if(state->diceQty == 6) { - elements_button_left(canvas, "x6"); - } - } - if(state->letsRoll) { - furi_hal_rtc_get_datetime(&state->datetime); - uint8_t hour = state->datetime.hour; - char strAMPM[3]; - snprintf(strAMPM, sizeof(strAMPM), "%s", "AM"); - if(hour > 12) { - hour -= 12; - snprintf(strAMPM, sizeof(strAMPM), "%s", "PM"); - } - snprintf( - state->rollTime[0], - sizeof(state->rollTime[0]), - "%.2d:%.2d:%.2d %s", - hour, - state->datetime.minute, - state->datetime.second, - strAMPM); - if(state->diceSelect == 229) { - const char* eightBall[] = { - "It is certain", - "Without a doubt", - "You may rely on it", - "Yes definitely", - "It is decidedly so", - "As I see it, yes", - "Most likely", - "Yes", - "Outlook good", - "Signs point to yes", - "Reply hazy try again", - "Better not tell you now", - "Ask again later", - "Cannot predict now", - "Concentrate and ask again", - "Don't count on it", - "Outlook not so good", - "My sources say no", - "Very doubtful", - "My reply is no"}; - state->diceRoll = - ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG - snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "8BALL"); - snprintf( - state->strings[0], - sizeof(state->strings[0]), - "%s at %s", - state->diceType[0], - state->rollTime[0]); - uint8_t d1_i = rand() % COUNT_OF(eightBall); - snprintf(state->strings[1], sizeof(state->strings[1]), "%s", eightBall[d1_i]); - } else if(state->diceSelect == 228) { - const char* eightBall[] = { - "I'd do it.", - "Hell, yeah!", - "You bet your life!", - "What are you waiting for?", - "You could do worse things.", - "Sure, I won't tell.", - "Yeah, you got this. Would I lie to you?", - "Looks like fun to me. ", - "Yeah, sure, why not?", - "DO IT!!!", - "Who's it gonna hurt?", - "Can you blame someone else?", - "Ask me again later.", - "Maybe, maybe not, I can't tell right now. ", - "Are you the betting type? ", - "Don't blame me if you get caught.", - "What have you got to lose?", - "I wouldn't if I were you.", - "My money's on the snowball.", - "Oh Hell no!"}; - state->diceRoll = - ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG - snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "Devil Ball"); - snprintf( - state->strings[0], - sizeof(state->strings[0]), - "%s at %s", - state->diceType[0], - state->rollTime[0]); - uint8_t d1_i = rand() % COUNT_OF(eightBall); - snprintf(state->strings[1], sizeof(state->strings[1]), "%s", eightBall[d1_i]); - } else if(state->diceSelect == 230) { - const char* diceOne[] = { - "Nibble", - "Massage", - "Touch", - "Caress", - "Pet", - "Fondle", - "Suck", - "Lick", - "Blow", - "Kiss", - "???"}; - const char* diceTwo[] = { - "Navel", - "Ears", - "Lips", - "Neck", - "Hand", - "Thigh", - "Nipple", - "Breasts", - "???", - "Genitals"}; - state->diceRoll = - ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG - snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "SEX?"); - snprintf( - state->strings[0], - sizeof(state->strings[0]), - "%s at %s", - state->diceType[0], - state->rollTime[0]); - uint8_t d1_i = rand() % COUNT_OF(diceOne); - uint8_t d2_i = rand() % COUNT_OF(diceTwo); - snprintf( - state->strings[1], - sizeof(state->strings[1]), - "%s %s", - diceOne[d1_i], - diceTwo[d2_i]); - } else if(state->diceSelect == 231) { - const char* deckOne[] = {"2H", "2C", "2D", "2S", "3H", "3C", "3D", "3S", "4H", - "4C", "4D", "4S", "5H", "5C", "5D", "5S", "6H", "6C", - "6D", "6S", "7H", "7C", "7D", "7S", "8H", "8C", "8D", - "8S", "9H", "9C", "9D", "9S", "10H", "10C", "10D", "10S", - "JH", "JC", "JD", "JS", "QH", "QC", "QD", "QS", "KH", - "KC", "KD", "KS", "AH", "AC", "AD", "AS"}; - char* deckTwo[] = {"2H", "2C", "2D", "2S", "3H", "3C", "3D", "3S", "4H", - "4C", "4D", "4S", "5H", "5C", "5D", "5S", "6H", "6C", - "6D", "6S", "7H", "7C", "7D", "7S", "8H", "8C", "8D", - "8S", "9H", "9C", "9D", "9S", "10H", "10C", "10D", "10S", - "JH", "JC", "JD", "JS", "QH", "QC", "QD", "QS", "KH", - "KC", "KD", "KS", "AH", "AC", "AD"}; // ONE LESS SINCE ONE WILL BE REMOVED - state->diceRoll = - ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG - snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "WAR!"); - snprintf( - state->strings[0], - sizeof(state->strings[0]), - "%s at %s", - state->diceType[0], - state->rollTime[0]); - uint8_t d1_i = rand() % COUNT_OF(deckOne); - // INITIALIZE WITH PLACEHOLDERS TO AVOID MAYBE UNINITIALIZED ERROR - for(uint8_t i = 0; i < COUNT_OF(deckOne); i++) { - if(i < d1_i) { - snprintf(deckTwo[i], 8, "%s", deckOne[i]); - } else if(i > d1_i) { - snprintf(deckTwo[i - 1], 8, "%s", deckOne[i]); - } - } - uint8_t d2_i = rand() % COUNT_OF(deckTwo); - if(d1_i > d2_i) { - state->playerOneScore++; - snprintf( - state->strings[1], - sizeof(state->strings[1]), - "%s > %s", - deckOne[d1_i], - deckTwo[d2_i]); - } else { - state->playerTwoScore++; - snprintf( - state->strings[1], - sizeof(state->strings[1]), - "%s < %s", - deckOne[d1_i], - deckTwo[d2_i]); - } - } else if(state->diceSelect == 232) { - const char* diceOne[] = { - "You", "You choose", "Nobody", "Everyone", "Nose goes", "Player to your right"}; - const char* diceTwo[] = { - "take a tiny toke", - "just chill", - "take 2 tokes", - "take a huge hit", - "bogart it", - "take a puff"}; - const char* diceThree[] = { - "while humming a tune", - "with your eyes closed", - "on your knees", - "while holding your nose", - "while spinning in a circle", - "in slow motion"}; - const char* diceFour[] = { - "twice", - "then tell a joke", - "then laugh as hard as you can", - "with the player to your left", - "then sing a song", - "then do a dance"}; - state->diceRoll = - ((rand() % state->diceSelect) + 1); // JUST TO GET IT GOING? AND FIX BUG - snprintf(state->diceType[0], sizeof(state->diceType[0]), "%s", "WEED!"); - snprintf( - state->strings[0], - sizeof(state->strings[0]), - "%s at %s", - state->diceType[0], - state->rollTime[0]); - uint8_t d1_i = rand() % COUNT_OF(diceOne); - uint8_t d2_i = rand() % COUNT_OF(diceTwo); - uint8_t d3_i = rand() % COUNT_OF(diceThree); - uint8_t d4_i = rand() % COUNT_OF(diceFour); - snprintf(state->strings[1], sizeof(state->strings[1]), "%s", diceOne[d1_i]); - snprintf(state->strings[2], sizeof(state->strings[2]), "%s", diceTwo[d2_i]); - snprintf(state->strings[3], sizeof(state->strings[3]), "%s", diceThree[d3_i]); - snprintf(state->strings[4], sizeof(state->strings[4]), "%s", diceFour[d4_i]); - } else { - state->diceRoll = ((rand() % state->diceSelect) + 1); - snprintf( - state->diceType[0], sizeof(state->diceType[0]), "%s%d", "d", state->diceSelect); - snprintf( - state->strings[0], - sizeof(state->strings[0]), - "%d%s at %s", - state->diceQty, - state->diceType[0], - state->rollTime[0]); - if(state->diceQty == 1) { - snprintf(state->strings[1], sizeof(state->strings[1]), "%d", state->diceRoll); - } else if(state->diceQty == 2) { - snprintf( - state->strings[1], - sizeof(state->strings[1]), - "%d %d", - state->diceRoll, - ((rand() % state->diceSelect) + 1)); - } else if(state->diceQty == 3) { - snprintf( - state->strings[1], - sizeof(state->strings[1]), - "%d %d %d", - state->diceRoll, - ((rand() % state->diceSelect) + 1), - ((rand() % state->diceSelect) + 1)); - } else if(state->diceQty == 4) { - snprintf( - state->strings[1], - sizeof(state->strings[1]), - "%d %d %d %d", - state->diceRoll, - ((rand() % state->diceSelect) + 1), - ((rand() % state->diceSelect) + 1), - ((rand() % state->diceSelect) + 1)); - } else if(state->diceQty == 5) { - snprintf( - state->strings[1], - sizeof(state->strings[1]), - "%d %d %d %d %d", - state->diceRoll, - ((rand() % state->diceSelect) + 1), - ((rand() % state->diceSelect) + 1), - ((rand() % state->diceSelect) + 1), - ((rand() % state->diceSelect) + 1)); - } else if(state->diceQty == 6) { - snprintf( - state->strings[1], - sizeof(state->strings[1]), - "%d %d %d %d %d %d", - state->diceRoll, - ((rand() % state->diceSelect) + 1), - ((rand() % state->diceSelect) + 1), - ((rand() % state->diceSelect) + 1), - ((rand() % state->diceSelect) + 1), - ((rand() % state->diceSelect) + 1)); - } - } - state->letsRoll = false; - } - furi_mutex_release(state->mutex); - if(state->diceRoll != 0) { - if(state->diceSelect == 232) { - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 64, 8, AlignCenter, AlignCenter, state->strings[0]); - canvas_draw_str_aligned(canvas, 64, 18, AlignCenter, AlignCenter, state->strings[1]); - canvas_draw_str_aligned(canvas, 64, 26, AlignCenter, AlignCenter, state->strings[2]); - canvas_draw_str_aligned(canvas, 64, 34, AlignCenter, AlignCenter, state->strings[3]); - canvas_draw_str_aligned(canvas, 64, 42, AlignCenter, AlignCenter, state->strings[4]); - } else if(state->diceSelect == 228 || state->diceSelect == 229) { - canvas_set_font(canvas, FontBatteryPercent); - canvas_draw_str_aligned(canvas, 64, 20, AlignCenter, AlignCenter, state->strings[1]); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 64, 8, AlignCenter, AlignCenter, state->strings[0]); - } else { - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 64, 20, AlignCenter, AlignCenter, state->strings[1]); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str_aligned(canvas, 64, 8, AlignCenter, AlignCenter, state->strings[0]); - } - if(state->diceSelect == 231 && - !(state->playerOneScore == 0 && state->playerTwoScore == 0)) { - canvas_set_font(canvas, FontSecondary); - snprintf( - state->theScores[0], - sizeof(state->theScores[0]), - "%d %d", - state->playerOneScore, - state->playerTwoScore); - canvas_draw_str_aligned(canvas, 64, 34, AlignCenter, AlignCenter, state->theScores[0]); - } - } - if(state->diceSelect == 229 || state->diceSelect == 228) { - elements_button_center(canvas, "Shake"); - } else if(state->diceSelect == 231) { - elements_button_center(canvas, "Draw"); - } else { - elements_button_center(canvas, "Roll"); - } - if(state->diceSelect == 2) { - elements_button_right(canvas, "d2"); - } else if(state->diceSelect == 3) { - elements_button_right(canvas, "d3"); - } else if(state->diceSelect == 4) { - elements_button_right(canvas, "d4"); - } else if(state->diceSelect == 6) { - elements_button_right(canvas, "d6"); - } else if(state->diceSelect == 8) { - elements_button_right(canvas, "d8"); - } else if(state->diceSelect == 10) { - elements_button_right(canvas, "d10"); - } else if(state->diceSelect == 12) { - elements_button_right(canvas, "d12"); - } else if(state->diceSelect == 20) { - elements_button_right(canvas, "d20"); - } else if(state->diceSelect == 59) { - elements_button_right(canvas, "d59"); - } else if(state->diceSelect == 69) { - elements_button_right(canvas, "d69"); - } else if(state->diceSelect == 100) { - elements_button_right(canvas, "d100"); - } else if(state->diceSelect == 229) { - elements_button_right(canvas, "8BALL"); - } else if(state->diceSelect == 228) { - elements_button_right(canvas, "DBALL"); - } else if(state->diceSelect == 230) { - elements_button_right(canvas, "SEX"); - } else if(state->diceSelect == 231) { - elements_button_right(canvas, "WAR"); - } else if(state->diceSelect == 232) { - elements_button_right(canvas, "WEED"); - } -} - -static void dice_state_init(DiceState* const state) { - memset(state, 0, sizeof(DiceState)); - furi_hal_rtc_get_datetime(&state->datetime); - state->diceSelect = 20; - state->diceQty = 1; - state->diceRoll = 0; - state->playerOneScore = 0; - state->playerTwoScore = 0; - state->letsRoll = false; -} - -static void dice_tick(void* ctx) { - furi_assert(ctx); - FuriMessageQueue* event_queue = ctx; - PluginEvent event = {.type = EventTypeTick}; - // It's OK to lose this event if system overloaded - furi_message_queue_put(event_queue, &event, 0); -} - -int32_t dice_app(void* p) { - UNUSED(p); - DiceState* plugin_state = malloc(sizeof(DiceState)); - dice_state_init(plugin_state); - plugin_state->event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - if(plugin_state->event_queue == NULL) { - FURI_LOG_E(TAG, "cannot create event queue\n"); - free(plugin_state); - return 255; - } - - plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(plugin_state->mutex == NULL) { - FURI_LOG_E(TAG, "cannot create mutex\n"); - furi_message_queue_free(plugin_state->event_queue); - free(plugin_state); - return 255; - } - - FuriTimer* timer = - furi_timer_alloc(dice_tick, FuriTimerTypePeriodic, plugin_state->event_queue); - if(timer == NULL) { - FURI_LOG_E(TAG, "cannot create timer\n"); - furi_mutex_free(plugin_state->mutex); - furi_message_queue_free(plugin_state->event_queue); - free(plugin_state); - return 255; - } - - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, dice_render_callback, plugin_state); - view_port_input_callback_set(view_port, dice_input_callback, plugin_state->event_queue); - - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - furi_timer_start(timer, furi_kernel_get_tick_frequency()); - - // Main loop - PluginEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(plugin_state->event_queue, &event, 100); - if(event_status == FuriStatusOk) { - if(event.type == EventTypeKey) { - if(event.input.type == InputTypeShort || event.input.type == InputTypeRepeat) { - switch(event.input.key) { - case InputKeyUp: - break; - case InputKeyDown: - break; - case InputKeyRight: - if(plugin_state->diceSelect == 2) { - plugin_state->diceSelect = 3; - } else if(plugin_state->diceSelect == 3) { - plugin_state->diceSelect = 4; - } else if(plugin_state->diceSelect == 4) { - plugin_state->diceSelect = 6; - } else if(plugin_state->diceSelect == 6) { - plugin_state->diceSelect = 8; - } else if(plugin_state->diceSelect == 8) { - plugin_state->diceSelect = 10; - } else if(plugin_state->diceSelect == 10) { - plugin_state->diceSelect = 12; - } else if(plugin_state->diceSelect == 12) { - plugin_state->diceSelect = 20; - } else if(plugin_state->diceSelect == 20) { - plugin_state->diceSelect = 100; - } else if(plugin_state->diceSelect == 100) { - plugin_state->diceSelect = 230; - } else if(plugin_state->diceSelect == 230) { - plugin_state->playerOneScore = 0; - plugin_state->playerTwoScore = 0; - plugin_state->diceSelect = 231; - } else if(plugin_state->diceSelect == 231) { - plugin_state->diceSelect = 229; - } else if(plugin_state->diceSelect == 229) { - plugin_state->diceSelect = 228; - } else if(plugin_state->diceSelect == 228) { - plugin_state->diceSelect = 232; - } else if(plugin_state->diceSelect == 232) { - plugin_state->diceSelect = 59; - } else if(plugin_state->diceSelect == 59) { - plugin_state->diceSelect = 69; - } else { - plugin_state->diceSelect = 2; - } - break; - case InputKeyLeft: - if(plugin_state->diceQty <= 5) { - plugin_state->diceQty = plugin_state->diceQty + 1; - } else { - plugin_state->diceQty = 1; - } - break; - case InputKeyOk: - plugin_state->letsRoll = true; - break; - case InputKeyBack: - processing = false; - break; - default: - break; - } - } - } else if(event.type == EventTypeTick) { - // furi_hal_rtc_get_datetime(&plugin_state->datetime); - } - view_port_update(view_port); - furi_mutex_release(plugin_state->mutex); - } else { - // FURI_LOG_D(TAG, "osMessageQueue: event timeout"); - } - } - // Cleanup - furi_timer_free(timer); - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close(RECORD_GUI); - view_port_free(view_port); - furi_message_queue_free(plugin_state->event_queue); - furi_mutex_free(plugin_state->mutex); - free(plugin_state); - return 0; -} diff --git a/applications/external/multi_dice/dice.png b/applications/external/multi_dice/dice.png deleted file mode 100644 index 64928b1de..000000000 Binary files a/applications/external/multi_dice/dice.png and /dev/null differ diff --git a/applications/external/music_beeper/application.fam b/applications/external/music_beeper/application.fam deleted file mode 100644 index 24a592c4a..000000000 --- a/applications/external/music_beeper/application.fam +++ /dev/null @@ -1,14 +0,0 @@ -App( - appid="music_beeper", - name="Music Beeper", - apptype=FlipperAppType.EXTERNAL, - entry_point="music_beeper_app", - requires=[ - "gui", - "dialogs", - ], - stack_size=2 * 1024, - fap_icon="music_10px.png", - fap_icon_assets="icons", - fap_category="Media", -) diff --git a/applications/external/music_beeper/music_10px.png b/applications/external/music_beeper/music_10px.png deleted file mode 100644 index d41eb0db8..000000000 Binary files a/applications/external/music_beeper/music_10px.png and /dev/null differ diff --git a/applications/external/music_beeper/music_beeper.c b/applications/external/music_beeper/music_beeper.c deleted file mode 100644 index e3ddbe68f..000000000 --- a/applications/external/music_beeper/music_beeper.c +++ /dev/null @@ -1,368 +0,0 @@ -#include "music_beeper_worker.h" - -#include -#include - -#include "music_beeper_icons.h" -#include -#include -#include -#include - -#define TAG "MusicBeeper" - -#define MUSIC_BEEPER_APP_PATH_FOLDER EXT_PATH("music_player") -#define MUSIC_BEEPER_APP_EXTENSION "*" - -#define MUSIC_BEEPER_SEMITONE_HISTORY_SIZE 4 - -typedef struct { - uint8_t semitone_history[MUSIC_BEEPER_SEMITONE_HISTORY_SIZE]; - uint8_t duration_history[MUSIC_BEEPER_SEMITONE_HISTORY_SIZE]; - - uint8_t volume; - uint8_t semitone; - uint8_t dots; - uint8_t duration; - float position; -} MusicBeeperModel; - -typedef struct { - MusicBeeperModel* model; - FuriMutex** model_mutex; - - FuriMessageQueue* input_queue; - - ViewPort* view_port; - Gui* gui; - - MusicBeeperWorker* worker; -} MusicBeeper; - -static const float MUSIC_BEEPER_VOLUMES[] = {0, .25, .5, .75, 1}; - -static const char* semitone_to_note(int8_t semitone) { - switch(semitone) { - case 0: - return "C"; - case 1: - return "C#"; - case 2: - return "D"; - case 3: - return "D#"; - case 4: - return "E"; - case 5: - return "F"; - case 6: - return "F#"; - case 7: - return "G"; - case 8: - return "G#"; - case 9: - return "A"; - case 10: - return "A#"; - case 11: - return "B"; - default: - return "--"; - } -} - -static bool is_white_note(uint8_t semitone, uint8_t id) { - switch(semitone) { - case 0: - if(id == 0) return true; - break; - case 2: - if(id == 1) return true; - break; - case 4: - if(id == 2) return true; - break; - case 5: - if(id == 3) return true; - break; - case 7: - if(id == 4) return true; - break; - case 9: - if(id == 5) return true; - break; - case 11: - if(id == 6) return true; - break; - default: - break; - } - - return false; -} - -static bool is_black_note(uint8_t semitone, uint8_t id) { - switch(semitone) { - case 1: - if(id == 0) return true; - break; - case 3: - if(id == 1) return true; - break; - case 6: - if(id == 3) return true; - break; - case 8: - if(id == 4) return true; - break; - case 10: - if(id == 5) return true; - break; - default: - break; - } - - return false; -} - -static void render_callback(Canvas* canvas, void* ctx) { - MusicBeeper* music_beeper = ctx; - furi_check(furi_mutex_acquire(music_beeper->model_mutex, FuriWaitForever) == FuriStatusOk); - - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 0, 12, "MusicBeeper"); - - uint8_t x_pos = 0; - uint8_t y_pos = 24; - const uint8_t white_w = 10; - const uint8_t white_h = 40; - - const int8_t black_x = 6; - const int8_t black_y = -5; - const uint8_t black_w = 8; - const uint8_t black_h = 32; - - // white keys - for(size_t i = 0; i < 7; i++) { - if(is_white_note(music_beeper->model->semitone, i)) { - canvas_draw_box(canvas, x_pos + white_w * i, y_pos, white_w + 1, white_h); - } else { - canvas_draw_frame(canvas, x_pos + white_w * i, y_pos, white_w + 1, white_h); - } - } - - // black keys - for(size_t i = 0; i < 7; i++) { - if(i != 2 && i != 6) { - canvas_set_color(canvas, ColorWhite); - canvas_draw_box( - canvas, x_pos + white_w * i + black_x, y_pos + black_y, black_w + 1, black_h); - canvas_set_color(canvas, ColorBlack); - if(is_black_note(music_beeper->model->semitone, i)) { - canvas_draw_box( - canvas, x_pos + white_w * i + black_x, y_pos + black_y, black_w + 1, black_h); - } else { - canvas_draw_frame( - canvas, x_pos + white_w * i + black_x, y_pos + black_y, black_w + 1, black_h); - } - } - } - - // volume view_port - x_pos = 124; - y_pos = 0; - const uint8_t volume_h = - (64 / (COUNT_OF(MUSIC_BEEPER_VOLUMES) - 1)) * music_beeper->model->volume; - canvas_draw_frame(canvas, x_pos, y_pos, 4, 64); - canvas_draw_box(canvas, x_pos, y_pos + (64 - volume_h), 4, volume_h); - - // note stack view_port - x_pos = 73; - y_pos = 0; - canvas_set_color(canvas, ColorBlack); - canvas_set_font(canvas, FontPrimary); - canvas_draw_frame(canvas, x_pos, y_pos, 49, 64); - canvas_draw_line(canvas, x_pos + 28, 0, x_pos + 28, 64); - - char duration_text[16]; - for(uint8_t i = 0; i < MUSIC_BEEPER_SEMITONE_HISTORY_SIZE; i++) { - if(music_beeper->model->duration_history[i] == 0xFF) { - snprintf(duration_text, 15, "--"); - } else { - snprintf(duration_text, 15, "%d", music_beeper->model->duration_history[i]); - } - - if(i == 0) { - canvas_draw_box(canvas, x_pos, y_pos + 48, 49, 16); - canvas_set_color(canvas, ColorWhite); - } else { - canvas_set_color(canvas, ColorBlack); - } - canvas_draw_str( - canvas, - x_pos + 4, - 64 - 16 * i - 3, - semitone_to_note(music_beeper->model->semitone_history[i])); - canvas_draw_str(canvas, x_pos + 31, 64 - 16 * i - 3, duration_text); - canvas_draw_line(canvas, x_pos, 64 - 16 * i, x_pos + 48, 64 - 16 * i); - } - - furi_mutex_release(music_beeper->model_mutex); -} - -static void input_callback(InputEvent* input_event, void* ctx) { - MusicBeeper* music_beeper = ctx; - if(input_event->type == InputTypeShort) { - furi_message_queue_put(music_beeper->input_queue, input_event, 0); - } -} - -static void music_beeper_worker_callback( - uint8_t semitone, - uint8_t dots, - uint8_t duration, - float position, - void* context) { - MusicBeeper* music_beeper = context; - furi_check(furi_mutex_acquire(music_beeper->model_mutex, FuriWaitForever) == FuriStatusOk); - - for(size_t i = 0; i < MUSIC_BEEPER_SEMITONE_HISTORY_SIZE - 1; i++) { - size_t r = MUSIC_BEEPER_SEMITONE_HISTORY_SIZE - 1 - i; - music_beeper->model->duration_history[r] = music_beeper->model->duration_history[r - 1]; - music_beeper->model->semitone_history[r] = music_beeper->model->semitone_history[r - 1]; - } - - semitone = (semitone == 0xFF) ? 0xFF : semitone % 12; - - music_beeper->model->semitone = semitone; - music_beeper->model->dots = dots; - music_beeper->model->duration = duration; - music_beeper->model->position = position; - - music_beeper->model->semitone_history[0] = semitone; - music_beeper->model->duration_history[0] = duration; - - furi_mutex_release(music_beeper->model_mutex); - view_port_update(music_beeper->view_port); -} - -void music_beeper_clear(MusicBeeper* instance) { - memset(instance->model->duration_history, 0xff, MUSIC_BEEPER_SEMITONE_HISTORY_SIZE); - memset(instance->model->semitone_history, 0xff, MUSIC_BEEPER_SEMITONE_HISTORY_SIZE); - music_beeper_worker_clear(instance->worker); -} - -MusicBeeper* music_beeper_alloc() { - MusicBeeper* instance = malloc(sizeof(MusicBeeper)); - - instance->model = malloc(sizeof(MusicBeeperModel)); - instance->model->volume = 4; - - instance->model_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - - instance->input_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); - - instance->worker = music_beeper_worker_alloc(); - music_beeper_worker_set_volume( - instance->worker, MUSIC_BEEPER_VOLUMES[instance->model->volume]); - music_beeper_worker_set_callback(instance->worker, music_beeper_worker_callback, instance); - - music_beeper_clear(instance); - - instance->view_port = view_port_alloc(); - view_port_draw_callback_set(instance->view_port, render_callback, instance); - view_port_input_callback_set(instance->view_port, input_callback, instance); - - // Open GUI and register view_port - instance->gui = furi_record_open(RECORD_GUI); - gui_add_view_port(instance->gui, instance->view_port, GuiLayerFullscreen); - - return instance; -} - -void music_beeper_free(MusicBeeper* instance) { - gui_remove_view_port(instance->gui, instance->view_port); - furi_record_close(RECORD_GUI); - view_port_free(instance->view_port); - - music_beeper_worker_free(instance->worker); - - furi_message_queue_free(instance->input_queue); - - furi_mutex_free(instance->model_mutex); - - free(instance->model); - free(instance); -} - -int32_t music_beeper_app(void* p) { - MusicBeeper* music_beeper = music_beeper_alloc(); - - FuriString* file_path; - file_path = furi_string_alloc(); - - do { - if(p && strlen(p)) { - furi_string_set(file_path, (const char*)p); - } else { - furi_string_set(file_path, MUSIC_BEEPER_APP_PATH_FOLDER); - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options( - &browser_options, MUSIC_BEEPER_APP_EXTENSION, &I_music_10px); - browser_options.base_path = MUSIC_BEEPER_APP_PATH_FOLDER; - - DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); - bool res = dialog_file_browser_show(dialogs, file_path, file_path, &browser_options); - - furi_record_close(RECORD_DIALOGS); - if(!res) { - FURI_LOG_E(TAG, "No file selected"); - break; - } - } - - if(!music_beeper_worker_load(music_beeper->worker, furi_string_get_cstr(file_path))) { - FURI_LOG_E(TAG, "Unable to load file"); - break; - } - - music_beeper_worker_start(music_beeper->worker); - - InputEvent input; - while(furi_message_queue_get(music_beeper->input_queue, &input, FuriWaitForever) == - FuriStatusOk) { - furi_check( - furi_mutex_acquire(music_beeper->model_mutex, FuriWaitForever) == FuriStatusOk); - - if(input.key == InputKeyBack) { - furi_mutex_release(music_beeper->model_mutex); - break; - } else if(input.key == InputKeyUp) { - if(music_beeper->model->volume < COUNT_OF(MUSIC_BEEPER_VOLUMES) - 1) - music_beeper->model->volume++; - music_beeper_worker_set_volume( - music_beeper->worker, MUSIC_BEEPER_VOLUMES[music_beeper->model->volume]); - } else if(input.key == InputKeyDown) { - if(music_beeper->model->volume > 0) music_beeper->model->volume--; - music_beeper_worker_set_volume( - music_beeper->worker, MUSIC_BEEPER_VOLUMES[music_beeper->model->volume]); - } - - furi_mutex_release(music_beeper->model_mutex); - view_port_update(music_beeper->view_port); - } - - music_beeper_worker_stop(music_beeper->worker); - if(p && strlen(p)) break; // Exit instead of going to browser if launched with arg - music_beeper_clear(music_beeper); - } while(1); - - furi_string_free(file_path); - music_beeper_free(music_beeper); - - return 0; -} diff --git a/applications/external/music_beeper/music_beeper_cli.c b/applications/external/music_beeper/music_beeper_cli.c deleted file mode 100644 index 26299fa64..000000000 --- a/applications/external/music_beeper/music_beeper_cli.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include "music_beeper_worker.h" - -static void music_beeper_cli(Cli* cli, FuriString* args, void* context) { - UNUSED(context); - MusicBeeperWorker* music_beeper_worker = music_beeper_worker_alloc(); - Storage* storage = furi_record_open(RECORD_STORAGE); - - do { - if(storage_common_stat(storage, furi_string_get_cstr(args), NULL) == FSE_OK) { - if(!music_beeper_worker_load(music_beeper_worker, furi_string_get_cstr(args))) { - printf("Failed to open file %s\r\n", furi_string_get_cstr(args)); - break; - } - } else { - if(!music_beeper_worker_load_rtttl_from_string( - music_beeper_worker, furi_string_get_cstr(args))) { - printf("Argument is not a file or RTTTL\r\n"); - break; - } - } - - printf("Press CTRL+C to stop\r\n"); - music_beeper_worker_set_volume(music_beeper_worker, 1.0f); - music_beeper_worker_start(music_beeper_worker); - while(!cli_cmd_interrupt_received(cli)) { - furi_delay_ms(50); - } - music_beeper_worker_stop(music_beeper_worker); - } while(0); - - furi_record_close(RECORD_STORAGE); - music_beeper_worker_free(music_beeper_worker); -} - -void music_beeper_on_system_start() { -#ifdef SRV_CLI - Cli* cli = furi_record_open(RECORD_CLI); - - cli_add_command(cli, "music_beeper", CliCommandFlagDefault, music_beeper_cli, NULL); - - furi_record_close(RECORD_CLI); -#else - UNUSED(music_beeper_cli); -#endif -} diff --git a/applications/external/music_beeper/music_beeper_worker.c b/applications/external/music_beeper/music_beeper_worker.c deleted file mode 100644 index e06e77447..000000000 --- a/applications/external/music_beeper/music_beeper_worker.c +++ /dev/null @@ -1,510 +0,0 @@ -#include "music_beeper_worker.h" - -#include -#include - -#include -#include - -#include - -#define TAG "MusicBeeperWorker" - -#define MUSIC_BEEPER_FILETYPE "Flipper Music Format" -#define MUSIC_BEEPER_VERSION 0 - -#define SEMITONE_PAUSE 0xFF - -#define NOTE_C4 261.63f -#define NOTE_C4_SEMITONE (4.0f * 12.0f) -#define TWO_POW_TWELTH_ROOT 1.059463094359f - -typedef struct { - uint8_t semitone; - uint8_t duration; - uint8_t dots; -} NoteBlock; - -ARRAY_DEF(NoteBlockArray, NoteBlock, M_POD_OPLIST); - -struct MusicBeeperWorker { - FuriThread* thread; - bool should_work; - - MusicBeeperWorkerCallback callback; - void* callback_context; - - float volume; - uint32_t bpm; - uint32_t duration; - uint32_t octave; - NoteBlockArray_t notes; -}; - -static int32_t music_beeper_worker_thread_callback(void* context) { - furi_assert(context); - MusicBeeperWorker* instance = context; - - NoteBlockArray_it_t it; - NoteBlockArray_it(it, instance->notes); - if(furi_hal_speaker_acquire(1000)) { - while(instance->should_work) { - if(NoteBlockArray_end_p(it)) { - NoteBlockArray_it(it, instance->notes); - furi_delay_ms(10); - } else { - NoteBlock* note_block = NoteBlockArray_ref(it); - - float note_from_a4 = (float)note_block->semitone - NOTE_C4_SEMITONE; - float frequency = NOTE_C4 * powf(TWO_POW_TWELTH_ROOT, note_from_a4); - float duration = 60.0 * furi_kernel_get_tick_frequency() * 4 / instance->bpm / - note_block->duration; - uint32_t dots = note_block->dots; - while(dots > 0) { - duration += duration / 2; - dots--; - } - uint32_t next_tick = furi_get_tick() + duration; - float volume = instance->volume; - - if(instance->callback) { - instance->callback( - note_block->semitone, - note_block->dots, - note_block->duration, - 0.0, - instance->callback_context); - } - - furi_hal_speaker_stop(); - furi_hal_speaker_start(frequency, volume); - while(instance->should_work && furi_get_tick() < next_tick) { - volume *= 1; - furi_hal_speaker_set_volume(volume); - furi_delay_ms(2); - } - NoteBlockArray_next(it); - } - } - - furi_hal_speaker_stop(); - furi_hal_speaker_release(); - } else { - FURI_LOG_E(TAG, "Speaker system is busy with another process."); - } - - return 0; -} - -MusicBeeperWorker* music_beeper_worker_alloc() { - MusicBeeperWorker* instance = malloc(sizeof(MusicBeeperWorker)); - - NoteBlockArray_init(instance->notes); - - instance->thread = furi_thread_alloc(); - furi_thread_set_name(instance->thread, "MusicBeeperWorker"); - furi_thread_set_stack_size(instance->thread, 1024); - furi_thread_set_context(instance->thread, instance); - furi_thread_set_callback(instance->thread, music_beeper_worker_thread_callback); - - instance->volume = 1.0f; - - return instance; -} - -void music_beeper_worker_clear(MusicBeeperWorker* instance) { - NoteBlockArray_reset(instance->notes); -} - -void music_beeper_worker_free(MusicBeeperWorker* instance) { - furi_assert(instance); - furi_thread_free(instance->thread); - NoteBlockArray_clear(instance->notes); - free(instance); -} - -static bool is_digit(const char c) { - return isdigit(c) != 0; -} - -static bool is_letter(const char c) { - return islower(c) != 0 || isupper(c) != 0; -} - -static bool is_space(const char c) { - return c == ' ' || c == '\t'; -} - -static size_t extract_number(const char* string, uint32_t* number) { - size_t ret = 0; - *number = 0; - while(is_digit(*string)) { - *number *= 10; - *number += (*string - '0'); - string++; - ret++; - } - return ret; -} - -static size_t extract_dots(const char* string, uint32_t* number) { - size_t ret = 0; - *number = 0; - while(*string == '.') { - *number += 1; - string++; - ret++; - } - return ret; -} - -static size_t extract_char(const char* string, char* symbol) { - if(is_letter(*string)) { - *symbol = *string; - return 1; - } else { - return 0; - } -} - -static size_t extract_sharp(const char* string, char* symbol) { - if(*string == '#' || *string == '_') { - *symbol = '#'; - return 1; - } else { - return 0; - } -} - -static size_t skip_till(const char* string, const char symbol) { - size_t ret = 0; - while(*string != '\0' && *string != symbol) { - string++; - ret++; - } - if(*string != symbol) { - ret = 0; - } - return ret; -} - -static bool music_beeper_worker_add_note( - MusicBeeperWorker* instance, - uint8_t semitone, - uint8_t duration, - uint8_t dots) { - NoteBlock note_block; - - note_block.semitone = semitone; - note_block.duration = duration; - note_block.dots = dots; - - NoteBlockArray_push_back(instance->notes, note_block); - - return true; -} - -static int8_t note_to_semitone(const char note) { - switch(note) { - case 'C': - return 0; - // C# - case 'D': - return 2; - // D# - case 'E': - return 4; - case 'F': - return 5; - // F# - case 'G': - return 7; - // G# - case 'A': - return 9; - // A# - case 'B': - return 11; - default: - return 0; - } -} - -static bool music_beeper_worker_parse_notes(MusicBeeperWorker* instance, const char* string) { - const char* cursor = string; - bool result = true; - - while(*cursor != '\0') { - if(!is_space(*cursor)) { - uint32_t duration = 0; - char note_char = '\0'; - char sharp_char = '\0'; - uint32_t octave = 0; - uint32_t dots = 0; - - // Parsing - cursor += extract_number(cursor, &duration); - cursor += extract_char(cursor, ¬e_char); - cursor += extract_sharp(cursor, &sharp_char); - cursor += extract_number(cursor, &octave); - cursor += extract_dots(cursor, &dots); - - // Post processing - note_char = toupper(note_char); - if(!duration) { - duration = instance->duration; - } - if(!octave) { - octave = instance->octave; - } - - // Validation - bool is_valid = true; - is_valid &= (duration >= 1 && duration <= 128); - is_valid &= ((note_char >= 'A' && note_char <= 'G') || note_char == 'P'); - is_valid &= (sharp_char == '#' || sharp_char == '\0'); - is_valid &= (octave <= 16); - is_valid &= (dots <= 16); - if(!is_valid) { - FURI_LOG_E( - TAG, - "Invalid note: %lu%c%c%lu.%lu", - duration, - note_char == '\0' ? '_' : note_char, - sharp_char == '\0' ? '_' : sharp_char, - octave, - dots); - result = false; - break; - } - - // Note to semitones - uint8_t semitone = 0; - if(note_char == 'P') { - semitone = SEMITONE_PAUSE; - } else { - semitone += octave * 12; - semitone += note_to_semitone(note_char); - semitone += sharp_char == '#' ? 1 : 0; - } - - if(music_beeper_worker_add_note(instance, semitone, duration, dots)) { - FURI_LOG_D( - TAG, - "Added note: %c%c%lu.%lu = %u %lu", - note_char == '\0' ? '_' : note_char, - sharp_char == '\0' ? '_' : sharp_char, - octave, - dots, - semitone, - duration); - } else { - FURI_LOG_E( - TAG, - "Invalid note: %c%c%lu.%lu = %u %lu", - note_char == '\0' ? '_' : note_char, - sharp_char == '\0' ? '_' : sharp_char, - octave, - dots, - semitone, - duration); - } - cursor += skip_till(cursor, ','); - } - - if(*cursor != '\0') cursor++; - } - - return result; -} - -bool music_beeper_worker_load(MusicBeeperWorker* instance, const char* file_path) { - furi_assert(instance); - furi_assert(file_path); - - bool ret = false; - if(strcasestr(file_path, ".fmf")) { - ret = music_beeper_worker_load_fmf_from_file(instance, file_path); - } else { - ret = music_beeper_worker_load_rtttl_from_file(instance, file_path); - } - return ret; -} - -bool music_beeper_worker_load_fmf_from_file(MusicBeeperWorker* instance, const char* file_path) { - furi_assert(instance); - furi_assert(file_path); - - bool result = false; - FuriString* temp_str; - temp_str = furi_string_alloc(); - - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* file = flipper_format_file_alloc(storage); - - do { - if(!flipper_format_file_open_existing(file, file_path)) break; - - uint32_t version = 0; - if(!flipper_format_read_header(file, temp_str, &version)) break; - if(furi_string_cmp_str(temp_str, MUSIC_BEEPER_FILETYPE) || - (version != MUSIC_BEEPER_VERSION)) { - FURI_LOG_E(TAG, "Incorrect file format or version"); - break; - } - - if(!flipper_format_read_uint32(file, "BPM", &instance->bpm, 1)) { - FURI_LOG_E(TAG, "BPM is missing"); - break; - } - if(!flipper_format_read_uint32(file, "Duration", &instance->duration, 1)) { - FURI_LOG_E(TAG, "Duration is missing"); - break; - } - if(!flipper_format_read_uint32(file, "Octave", &instance->octave, 1)) { - FURI_LOG_E(TAG, "Octave is missing"); - break; - } - - if(!flipper_format_read_string(file, "Notes", temp_str)) { - FURI_LOG_E(TAG, "Notes is missing"); - break; - } - - if(!music_beeper_worker_parse_notes(instance, furi_string_get_cstr(temp_str))) { - break; - } - - result = true; - } while(false); - - furi_record_close(RECORD_STORAGE); - flipper_format_free(file); - furi_string_free(temp_str); - - return result; -} - -bool music_beeper_worker_load_rtttl_from_file(MusicBeeperWorker* instance, const char* file_path) { - furi_assert(instance); - furi_assert(file_path); - - bool result = false; - FuriString* content; - content = furi_string_alloc(); - Storage* storage = furi_record_open(RECORD_STORAGE); - File* file = storage_file_alloc(storage); - - do { - if(!storage_file_open(file, file_path, FSAM_READ, FSOM_OPEN_EXISTING)) { - FURI_LOG_E(TAG, "Unable to open file"); - break; - }; - - uint16_t ret = 0; - do { - uint8_t buffer[65] = {0}; - ret = storage_file_read(file, buffer, sizeof(buffer) - 1); - for(size_t i = 0; i < ret; i++) { - furi_string_push_back(content, buffer[i]); - } - } while(ret > 0); - - furi_string_trim(content); - if(!furi_string_size(content)) { - FURI_LOG_E(TAG, "Empty file"); - break; - } - - if(!music_beeper_worker_load_rtttl_from_string(instance, furi_string_get_cstr(content))) { - FURI_LOG_E(TAG, "Invalid file content"); - break; - } - - result = true; - } while(0); - - storage_file_free(file); - furi_record_close(RECORD_STORAGE); - furi_string_free(content); - - return result; -} - -bool music_beeper_worker_load_rtttl_from_string(MusicBeeperWorker* instance, const char* string) { - furi_assert(instance); - - const char* cursor = string; - - // Skip name - cursor += skip_till(cursor, ':'); - if(*cursor != ':') { - return false; - } - - // Duration - cursor += skip_till(cursor, '='); - if(*cursor != '=') { - return false; - } - cursor++; - cursor += extract_number(cursor, &instance->duration); - - // Octave - cursor += skip_till(cursor, '='); - if(*cursor != '=') { - return false; - } - cursor++; - cursor += extract_number(cursor, &instance->octave); - - // BPM - cursor += skip_till(cursor, '='); - if(*cursor != '=') { - return false; - } - cursor++; - cursor += extract_number(cursor, &instance->bpm); - - // Notes - cursor += skip_till(cursor, ':'); - if(*cursor != ':') { - return false; - } - cursor++; - if(!music_beeper_worker_parse_notes(instance, cursor)) { - return false; - } - - return true; -} - -void music_beeper_worker_set_callback( - MusicBeeperWorker* instance, - MusicBeeperWorkerCallback callback, - void* context) { - furi_assert(instance); - instance->callback = callback; - instance->callback_context = context; -} - -void music_beeper_worker_set_volume(MusicBeeperWorker* instance, float volume) { - furi_assert(instance); - instance->volume = volume; -} - -void music_beeper_worker_start(MusicBeeperWorker* instance) { - furi_assert(instance); - furi_assert(instance->should_work == false); - - instance->should_work = true; - furi_thread_start(instance->thread); -} - -void music_beeper_worker_stop(MusicBeeperWorker* instance) { - furi_assert(instance); - furi_assert(instance->should_work == true); - - instance->should_work = false; - furi_thread_join(instance->thread); -} diff --git a/applications/external/music_beeper/music_beeper_worker.h b/applications/external/music_beeper/music_beeper_worker.h deleted file mode 100644 index bc30abf81..000000000 --- a/applications/external/music_beeper/music_beeper_worker.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*MusicBeeperWorkerCallback)( - uint8_t semitone, - uint8_t dots, - uint8_t duration, - float position, - void* context); - -typedef struct MusicBeeperWorker MusicBeeperWorker; - -MusicBeeperWorker* music_beeper_worker_alloc(); - -void music_beeper_worker_clear(MusicBeeperWorker* instance); - -void music_beeper_worker_free(MusicBeeperWorker* instance); - -bool music_beeper_worker_load(MusicBeeperWorker* instance, const char* file_path); - -bool music_beeper_worker_load_fmf_from_file(MusicBeeperWorker* instance, const char* file_path); - -bool music_beeper_worker_load_rtttl_from_file(MusicBeeperWorker* instance, const char* file_path); - -bool music_beeper_worker_load_rtttl_from_string(MusicBeeperWorker* instance, const char* string); - -void music_beeper_worker_set_callback( - MusicBeeperWorker* instance, - MusicBeeperWorkerCallback callback, - void* context); - -void music_beeper_worker_set_volume(MusicBeeperWorker* instance, float volume); - -void music_beeper_worker_start(MusicBeeperWorker* instance); - -void music_beeper_worker_stop(MusicBeeperWorker* instance); - -#ifdef __cplusplus -} -#endif diff --git a/applications/external/nrf24mousejacker/application.fam b/applications/external/nrf24mousejacker/application.fam deleted file mode 100644 index 30de60b5d..000000000 --- a/applications/external/nrf24mousejacker/application.fam +++ /dev/null @@ -1,25 +0,0 @@ -App( - appid="nrf24mousejacker", - name="[NRF24] Mouse Jacker", - apptype=FlipperAppType.EXTERNAL, - entry_point="mousejacker_app", - requires=[ - "gui", - "dialogs", - ], - stack_size=2 * 1024, - fap_icon="mouse_10px.png", - fap_category="GPIO", - fap_author="@mothball187 & @xMasterX", - fap_version="1.0", - fap_description="App works with NRF24 Sniffer app to perform mousejack attacks", - fap_icon_assets="images", - fap_private_libs=[ - Lib( - name="nrf24", - sources=[ - "nrf24.c", - ], - ), - ], -) diff --git a/applications/external/nrf24mousejacker/lib/nrf24/nrf24.c b/applications/external/nrf24mousejacker/lib/nrf24/nrf24.c deleted file mode 100644 index fe62d5db3..000000000 --- a/applications/external/nrf24mousejacker/lib/nrf24/nrf24.c +++ /dev/null @@ -1,546 +0,0 @@ -#include "nrf24.h" -#include -#include -#include -#include -#include - -void nrf24_init() { - // this is needed if multiple SPI devices are connected to the same bus but with different CS pins - if(xtreme_settings.spi_nrf24_handle == SpiDefault) { - furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull); - furi_hal_gpio_write(&gpio_ext_pc3, true); - } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { - furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); - furi_hal_gpio_write(&gpio_ext_pa4, true); - } - - furi_hal_spi_bus_handle_init(nrf24_HANDLE); - furi_hal_spi_acquire(nrf24_HANDLE); - furi_hal_gpio_init(nrf24_CE_PIN, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); - furi_hal_gpio_write(nrf24_CE_PIN, false); -} - -void nrf24_deinit() { - furi_hal_spi_release(nrf24_HANDLE); - furi_hal_spi_bus_handle_deinit(nrf24_HANDLE); - furi_hal_gpio_write(nrf24_CE_PIN, false); - furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - - // resetting the CS pins to floating - if(xtreme_settings.spi_nrf24_handle == SpiDefault) { - furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog); - } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { - furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog); - } -} - -void nrf24_spi_trx( - FuriHalSpiBusHandle* handle, - uint8_t* tx, - uint8_t* rx, - uint8_t size, - uint32_t timeout) { - UNUSED(timeout); - furi_hal_gpio_write(handle->cs, false); - furi_hal_spi_bus_trx(handle, tx, rx, size, nrf24_TIMEOUT); - furi_hal_gpio_write(handle->cs, true); -} - -uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data) { - uint8_t tx[2] = {W_REGISTER | (REGISTER_MASK & reg), data}; - uint8_t rx[2] = {0}; - nrf24_spi_trx(handle, tx, rx, 2, nrf24_TIMEOUT); - return rx[0]; -} - -uint8_t - nrf24_write_buf_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) { - uint8_t tx[size + 1]; - uint8_t rx[size + 1]; - memset(rx, 0, size + 1); - tx[0] = W_REGISTER | (REGISTER_MASK & reg); - memcpy(&tx[1], data, size); - nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT); - return rx[0]; -} - -uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) { - uint8_t tx[size + 1]; - uint8_t rx[size + 1]; - memset(rx, 0, size + 1); - tx[0] = R_REGISTER | (REGISTER_MASK & reg); - memset(&tx[1], 0, size); - nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT); - memcpy(data, &rx[1], size); - return rx[0]; -} - -uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle) { - uint8_t tx[] = {FLUSH_RX}; - uint8_t rx[] = {0}; - nrf24_spi_trx(handle, tx, rx, 1, nrf24_TIMEOUT); - return rx[0]; -} - -uint8_t nrf24_flush_tx(FuriHalSpiBusHandle* handle) { - uint8_t tx[] = {FLUSH_TX}; - uint8_t rx[] = {0}; - nrf24_spi_trx(handle, tx, rx, 1, nrf24_TIMEOUT); - return rx[0]; -} - -uint8_t nrf24_get_maclen(FuriHalSpiBusHandle* handle) { - uint8_t maclen; - nrf24_read_reg(handle, REG_SETUP_AW, &maclen, 1); - maclen &= 3; - return maclen + 2; -} - -uint8_t nrf24_set_maclen(FuriHalSpiBusHandle* handle, uint8_t maclen) { - assert(maclen > 1 && maclen < 6); - uint8_t status = 0; - status = nrf24_write_reg(handle, REG_SETUP_AW, maclen - 2); - return status; -} - -uint8_t nrf24_status(FuriHalSpiBusHandle* handle) { - uint8_t status; - uint8_t tx[] = {R_REGISTER | (REGISTER_MASK & REG_STATUS)}; - nrf24_spi_trx(handle, tx, &status, 1, nrf24_TIMEOUT); - return status; -} - -uint32_t nrf24_get_rate(FuriHalSpiBusHandle* handle) { - uint8_t setup = 0; - uint32_t rate = 0; - nrf24_read_reg(handle, REG_RF_SETUP, &setup, 1); - setup &= 0x28; - if(setup == 0x20) - rate = 250000; // 250kbps - else if(setup == 0x08) - rate = 2000000; // 2Mbps - else if(setup == 0x00) - rate = 1000000; // 1Mbps - - return rate; -} - -uint8_t nrf24_set_rate(FuriHalSpiBusHandle* handle, uint32_t rate) { - uint8_t r6 = 0; - uint8_t status = 0; - if(!rate) rate = 2000000; - - nrf24_read_reg(handle, REG_RF_SETUP, &r6, 1); // RF_SETUP register - r6 = r6 & (~0x28); // Clear rate fields. - if(rate == 2000000) - r6 = r6 | 0x08; - else if(rate == 1000000) - r6 = r6; - else if(rate == 250000) - r6 = r6 | 0x20; - - status = nrf24_write_reg(handle, REG_RF_SETUP, r6); // Write new rate. - return status; -} - -uint8_t nrf24_get_chan(FuriHalSpiBusHandle* handle) { - uint8_t channel = 0; - nrf24_read_reg(handle, REG_RF_CH, &channel, 1); - return channel; -} - -uint8_t nrf24_set_chan(FuriHalSpiBusHandle* handle, uint8_t chan) { - uint8_t status; - status = nrf24_write_reg(handle, REG_RF_CH, chan); - return status; -} - -uint8_t nrf24_get_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac) { - uint8_t size = 0; - uint8_t status = 0; - size = nrf24_get_maclen(handle); - status = nrf24_read_reg(handle, REG_RX_ADDR_P0, mac, size); - return status; -} - -uint8_t nrf24_set_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size) { - uint8_t status = 0; - uint8_t clearmac[] = {0, 0, 0, 0, 0}; - nrf24_set_maclen(handle, size); - nrf24_write_buf_reg(handle, REG_RX_ADDR_P0, clearmac, 5); - status = nrf24_write_buf_reg(handle, REG_RX_ADDR_P0, mac, size); - return status; -} - -uint8_t nrf24_get_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac) { - uint8_t size = 0; - uint8_t status = 0; - size = nrf24_get_maclen(handle); - status = nrf24_read_reg(handle, REG_TX_ADDR, mac, size); - return status; -} - -uint8_t nrf24_set_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size) { - uint8_t status = 0; - uint8_t clearmac[] = {0, 0, 0, 0, 0}; - nrf24_set_maclen(handle, size); - nrf24_write_buf_reg(handle, REG_TX_ADDR, clearmac, 5); - status = nrf24_write_buf_reg(handle, REG_TX_ADDR, mac, size); - return status; -} - -uint8_t nrf24_get_packetlen(FuriHalSpiBusHandle* handle) { - uint8_t len = 0; - nrf24_read_reg(handle, RX_PW_P0, &len, 1); - return len; -} - -uint8_t nrf24_set_packetlen(FuriHalSpiBusHandle* handle, uint8_t len) { - uint8_t status = 0; - status = nrf24_write_reg(handle, RX_PW_P0, len); - return status; -} - -uint8_t - nrf24_rxpacket(FuriHalSpiBusHandle* handle, uint8_t* packet, uint8_t* packetsize, bool full) { - uint8_t status = 0; - uint8_t size = 0; - uint8_t tx_pl_wid[] = {R_RX_PL_WID, 0}; - uint8_t rx_pl_wid[] = {0, 0}; - uint8_t tx_cmd[33] = {0}; // 32 max payload size + 1 for command - uint8_t tmp_packet[33] = {0}; - - status = nrf24_status(handle); - - if(status & 0x40) { - if(full) - size = nrf24_get_packetlen(handle); - else { - nrf24_spi_trx(handle, tx_pl_wid, rx_pl_wid, 2, nrf24_TIMEOUT); - size = rx_pl_wid[1]; - } - - tx_cmd[0] = R_RX_PAYLOAD; - nrf24_spi_trx(handle, tx_cmd, tmp_packet, size + 1, nrf24_TIMEOUT); - nrf24_write_reg(handle, REG_STATUS, 0x40); // clear bit. - memcpy(packet, &tmp_packet[1], size); - } else if(status == 0) { - nrf24_flush_rx(handle); - nrf24_write_reg(handle, REG_STATUS, 0x40); // clear bit. - } - - *packetsize = size; - return status; -} - -uint8_t nrf24_txpacket(FuriHalSpiBusHandle* handle, uint8_t* payload, uint8_t size, bool ack) { - uint8_t status = 0; - uint8_t tx[size + 1]; - uint8_t rx[size + 1]; - memset(tx, 0, size + 1); - memset(rx, 0, size + 1); - - if(!ack) - tx[0] = W_TX_PAYLOAD_NOACK; - else - tx[0] = W_TX_PAYLOAD; - - memcpy(&tx[1], payload, size); - nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT); - nrf24_set_tx_mode(handle); - - while(!(status & (TX_DS | MAX_RT))) status = nrf24_status(handle); - - if(status & MAX_RT) nrf24_flush_tx(handle); - - nrf24_set_idle(handle); - nrf24_write_reg(handle, REG_STATUS, TX_DS | MAX_RT); - return status & TX_DS; -} - -uint8_t nrf24_power_up(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg = cfg | 2; - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - furi_delay_ms(5000); - return status; -} - -uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg &= 0xfc; // clear bottom two bits to power down the radio - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - //nr204_write_reg(handle, REG_EN_RXADDR, 0x0); - furi_hal_gpio_write(nrf24_CE_PIN, false); - return status; -} - -uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - //status = nrf24_write_reg(handle, REG_CONFIG, 0x0F); // enable 2-byte CRC, PWR_UP, and PRIM_RX - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg |= 0x03; // PWR_UP, and PRIM_RX - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - //nr204_write_reg(REG_EN_RXADDR, 0x03) // Set RX Pipe 0 and 1 - furi_hal_gpio_write(nrf24_CE_PIN, true); - furi_delay_ms(2000); - return status; -} - -uint8_t nrf24_set_tx_mode(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - furi_hal_gpio_write(nrf24_CE_PIN, false); - nrf24_write_reg(handle, REG_STATUS, 0x30); - //status = nrf24_write_reg(handle, REG_CONFIG, 0x0E); // enable 2-byte CRC, PWR_UP - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg &= 0xfe; // disable PRIM_RX - cfg |= 0x02; // PWR_UP - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - furi_hal_gpio_write(nrf24_CE_PIN, true); - furi_delay_ms(2); - return status; -} - -void nrf24_configure( - FuriHalSpiBusHandle* handle, - uint8_t rate, - uint8_t* srcmac, - uint8_t* dstmac, - uint8_t maclen, - uint8_t channel, - bool noack, - bool disable_aa) { - assert(channel <= 125); - assert(rate == 1 || rate == 2); - if(rate == 2) - rate = 8; // 2Mbps - else - rate = 0; // 1Mbps - - nrf24_write_reg(handle, REG_CONFIG, 0x00); // Stop nRF - nrf24_set_idle(handle); - nrf24_write_reg(handle, REG_STATUS, 0x1c); // clear interrupts - if(disable_aa) - nrf24_write_reg(handle, REG_EN_AA, 0x00); // Disable Shockburst - else - nrf24_write_reg(handle, REG_EN_AA, 0x1F); // Enable Shockburst - - nrf24_write_reg(handle, REG_DYNPD, 0x3F); // enable dynamic payload length on all pipes - if(noack) - nrf24_write_reg(handle, REG_FEATURE, 0x05); // disable payload-with-ack, enable noack - else { - nrf24_write_reg(handle, REG_CONFIG, 0x0C); // 2 byte CRC - nrf24_write_reg(handle, REG_FEATURE, 0x07); // enable dyn payload and ack - nrf24_write_reg( - handle, REG_SETUP_RETR, 0x1f); // 15 retries for AA, 500us auto retransmit delay - } - - nrf24_set_idle(handle); - nrf24_flush_rx(handle); - nrf24_flush_tx(handle); - - if(maclen) nrf24_set_maclen(handle, maclen); - if(srcmac) nrf24_set_src_mac(handle, srcmac, maclen); - if(dstmac) nrf24_set_dst_mac(handle, dstmac, maclen); - - nrf24_write_reg(handle, REG_RF_CH, channel); - nrf24_write_reg(handle, REG_RF_SETUP, rate); - furi_delay_ms(200); -} - -void nrf24_init_promisc_mode(FuriHalSpiBusHandle* handle, uint8_t channel, uint8_t rate) { - //uint8_t preamble[] = {0x55, 0x00}; // little endian - uint8_t preamble[] = {0xAA, 0x00}; // little endian - //uint8_t preamble[] = {0x00, 0x55}; // little endian - //uint8_t preamble[] = {0x00, 0xAA}; // little endian - nrf24_write_reg(handle, REG_CONFIG, 0x00); // Stop nRF - nrf24_write_reg(handle, REG_STATUS, 0x1c); // clear interrupts - nrf24_write_reg(handle, REG_DYNPD, 0x0); // disable shockburst - nrf24_write_reg(handle, REG_EN_AA, 0x00); // Disable Shockburst - nrf24_write_reg(handle, REG_FEATURE, 0x05); // disable payload-with-ack, enable noack - nrf24_set_maclen(handle, 2); // shortest address - nrf24_set_src_mac(handle, preamble, 2); // set src mac to preamble bits to catch everything - nrf24_set_packetlen(handle, 32); // set max packet length - nrf24_set_idle(handle); - nrf24_flush_rx(handle); - nrf24_flush_tx(handle); - nrf24_write_reg(handle, REG_RF_CH, channel); - nrf24_write_reg(handle, REG_RF_SETUP, rate); - - // prime for RX, no checksum - nrf24_write_reg(handle, REG_CONFIG, 0x03); // PWR_UP and PRIM_RX, disable AA and CRC - furi_hal_gpio_write(nrf24_CE_PIN, true); - furi_delay_ms(100); -} - -void hexlify(uint8_t* in, uint8_t size, char* out) { - memset(out, 0, size * 2); - for(int i = 0; i < size; i++) - snprintf(out + strlen(out), sizeof(out + strlen(out)), "%02X", in[i]); -} - -uint64_t bytes_to_int64(uint8_t* bytes, uint8_t size, bool bigendian) { - uint64_t ret = 0; - for(int i = 0; i < size; i++) - if(bigendian) - ret |= bytes[i] << ((size - 1 - i) * 8); - else - ret |= bytes[i] << (i * 8); - - return ret; -} - -void int64_to_bytes(uint64_t val, uint8_t* out, bool bigendian) { - for(int i = 0; i < 8; i++) { - if(bigendian) - out[i] = (val >> ((7 - i) * 8)) & 0xff; - else - out[i] = (val >> (i * 8)) & 0xff; - } -} - -uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian) { - uint32_t ret = 0; - for(int i = 0; i < 4; i++) - if(bigendian) - ret |= bytes[i] << ((3 - i) * 8); - else - ret |= bytes[i] << (i * 8); - - return ret; -} - -void int32_to_bytes(uint32_t val, uint8_t* out, bool bigendian) { - for(int i = 0; i < 4; i++) { - if(bigendian) - out[i] = (val >> ((3 - i) * 8)) & 0xff; - else - out[i] = (val >> (i * 8)) & 0xff; - } -} - -uint64_t bytes_to_int16(uint8_t* bytes, bool bigendian) { - uint16_t ret = 0; - for(int i = 0; i < 2; i++) - if(bigendian) - ret |= bytes[i] << ((1 - i) * 8); - else - ret |= bytes[i] << (i * 8); - - return ret; -} - -void int16_to_bytes(uint16_t val, uint8_t* out, bool bigendian) { - for(int i = 0; i < 2; i++) { - if(bigendian) - out[i] = (val >> ((1 - i) * 8)) & 0xff; - else - out[i] = (val >> (i * 8)) & 0xff; - } -} - -// handle iffyness with preamble processing sometimes being a bit (literally) off -void alt_address_old(uint8_t* packet, uint8_t* altaddr) { - uint8_t macmess_hi_b[4]; - uint8_t macmess_lo_b[2]; - uint32_t macmess_hi; - uint16_t macmess_lo; - uint8_t preserved; - - // get first 6 bytes into 32-bit and 16-bit variables - memcpy(macmess_hi_b, packet, 4); - memcpy(macmess_lo_b, packet + 4, 2); - - macmess_hi = bytes_to_int32(macmess_hi_b, true); - - //preserve least 7 bits from hi that will be shifted down to lo - preserved = macmess_hi & 0x7f; - macmess_hi >>= 7; - - macmess_lo = bytes_to_int16(macmess_lo_b, true); - macmess_lo >>= 7; - macmess_lo = (preserved << 9) | macmess_lo; - int32_to_bytes(macmess_hi, macmess_hi_b, true); - int16_to_bytes(macmess_lo, macmess_lo_b, true); - memcpy(altaddr, &macmess_hi_b[1], 3); - memcpy(altaddr + 3, macmess_lo_b, 2); -} - -bool validate_address(uint8_t* addr) { - uint8_t bad[][3] = {{0x55, 0x55}, {0xAA, 0xAA}, {0x00, 0x00}, {0xFF, 0xFF}}; - for(int i = 0; i < 4; i++) - for(int j = 0; j < 2; j++) - if(!memcmp(addr + j * 2, bad[i], 2)) return false; - - return true; -} - -bool nrf24_sniff_address(FuriHalSpiBusHandle* handle, uint8_t maclen, uint8_t* address) { - bool found = false; - uint8_t packet[32] = {0}; - uint8_t packetsize; - //char printit[65]; - uint8_t status = 0; - status = nrf24_rxpacket(handle, packet, &packetsize, true); - if(status & 0x40) { - if(validate_address(packet)) { - for(int i = 0; i < maclen; i++) address[i] = packet[maclen - 1 - i]; - - /* - alt_address(packet, packet); - - for(i = 0; i < maclen; i++) - address[i + 5] = packet[maclen - 1 - i]; - */ - - //memcpy(address, packet, maclen); - //hexlify(packet, packetsize, printit); - found = true; - } - } - - return found; -} - -uint8_t nrf24_find_channel( - FuriHalSpiBusHandle* handle, - uint8_t* srcmac, - uint8_t* dstmac, - uint8_t maclen, - uint8_t rate, - uint8_t min_channel, - uint8_t max_channel, - bool autoinit) { - uint8_t ping_packet[] = {0x0f, 0x0f, 0x0f, 0x0f}; // this can be anything, we just need an ack - uint8_t ch = max_channel + 1; // means fail - nrf24_configure(handle, rate, srcmac, dstmac, maclen, 2, false, false); - for(ch = min_channel; ch <= max_channel + 1; ch++) { - nrf24_write_reg(handle, REG_RF_CH, ch); - if(nrf24_txpacket(handle, ping_packet, 4, true)) break; - } - - if(autoinit) { - FURI_LOG_D("nrf24", "initializing radio for channel %d", ch); - nrf24_configure(handle, rate, srcmac, dstmac, maclen, ch, false, false); - return ch; - } - - return ch; -} - -bool nrf24_check_connected(FuriHalSpiBusHandle* handle) { - uint8_t status = nrf24_status(handle); - - if(status != 0x00) { - return true; - } else { - return false; - } -} diff --git a/applications/external/nrf24mousejacker/lib/nrf24/nrf24.h b/applications/external/nrf24mousejacker/lib/nrf24/nrf24.h deleted file mode 100644 index de9212af2..000000000 --- a/applications/external/nrf24mousejacker/lib/nrf24/nrf24.h +++ /dev/null @@ -1,376 +0,0 @@ -#pragma once -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define R_REGISTER 0x00 -#define W_REGISTER 0x20 -#define REGISTER_MASK 0x1F -#define ACTIVATE 0x50 -#define R_RX_PL_WID 0x60 -#define R_RX_PAYLOAD 0x61 -#define W_TX_PAYLOAD 0xA0 -#define W_TX_PAYLOAD_NOACK 0xB0 -#define W_ACK_PAYLOAD 0xA8 -#define FLUSH_TX 0xE1 -#define FLUSH_RX 0xE2 -#define REUSE_TX_PL 0xE3 -#define RF24_NOP 0xFF - -#define REG_CONFIG 0x00 -#define REG_EN_AA 0x01 -#define REG_EN_RXADDR 0x02 -#define REG_SETUP_AW 0x03 -#define REG_SETUP_RETR 0x04 -#define REG_DYNPD 0x1C -#define REG_FEATURE 0x1D -#define REG_RF_SETUP 0x06 -#define REG_STATUS 0x07 -#define REG_RX_ADDR_P0 0x0A -#define REG_RF_CH 0x05 -#define REG_TX_ADDR 0x10 - -#define RX_PW_P0 0x11 -#define TX_DS 0x20 -#define MAX_RT 0x10 - -#define nrf24_TIMEOUT 500 -#define nrf24_CE_PIN &gpio_ext_pb2 -#define nrf24_HANDLE \ - (xtreme_settings.spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ - &furi_hal_spi_bus_handle_external_extra) - -/* Low level API */ - -/** Write device register - * - * @param handle - pointer to FuriHalSpiHandle - * @param reg - register - * @param data - data to write - * - * @return device status - */ -uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data); - -/** Write buffer to device register - * - * @param handle - pointer to FuriHalSpiHandle - * @param reg - register - * @param data - data to write - * @param size - size of data to write - * - * @return device status - */ -uint8_t nrf24_write_buf_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size); - -/** Read device register - * - * @param handle - pointer to FuriHalSpiHandle - * @param reg - register - * @param[out] data - pointer to data - * - * @return device status - */ -uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size); - -/** Power up the radio for operation - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_power_up(FuriHalSpiBusHandle* handle); - -/** Power down the radio - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle); - -/** Sets the radio to RX mode - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle); - -/** Sets the radio to TX mode - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_set_tx_mode(FuriHalSpiBusHandle* handle); - -/*=============================================================================================================*/ - -/* High level API */ - -/** Must call this before using any other nrf24 API - * - */ -void nrf24_init(); - -/** Must call this when we end using nrf24 device - * - */ -void nrf24_deinit(); - -/** Send flush rx command - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle); - -/** Send flush tx command - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_flush_tx(FuriHalSpiBusHandle* handle); - -/** Gets the RX packet length in data pipe 0 - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return packet length in data pipe 0 - */ -uint8_t nrf24_get_packetlen(FuriHalSpiBusHandle* handle); - -/** Sets the RX packet length in data pipe 0 - * - * @param handle - pointer to FuriHalSpiHandle - * @param len - length to set - * - * @return device status - */ -uint8_t nrf24_set_packetlen(FuriHalSpiBusHandle* handle, uint8_t len); - -/** Gets configured length of MAC address - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return MAC address length - */ -uint8_t nrf24_get_maclen(FuriHalSpiBusHandle* handle); - -/** Sets configured length of MAC address - * - * @param handle - pointer to FuriHalSpiHandle - * @param maclen - length to set MAC address to, must be greater than 1 and less than 6 - * - * @return MAC address length - */ -uint8_t nrf24_set_maclen(FuriHalSpiBusHandle* handle, uint8_t maclen); - -/** Gets the current status flags from the STATUS register - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return status flags - */ -uint8_t nrf24_status(FuriHalSpiBusHandle* handle); - -/** Gets the current transfer rate - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return transfer rate in bps - */ -uint32_t nrf24_get_rate(FuriHalSpiBusHandle* handle); - -/** Sets the transfer rate - * - * @param handle - pointer to FuriHalSpiHandle - * @param rate - the transfer rate in bps - * - * @return device status - */ -uint8_t nrf24_set_rate(FuriHalSpiBusHandle* handle, uint32_t rate); - -/** Gets the current channel - * In nrf24, the channel number is multiplied times 1MHz and added to 2400MHz to get the frequency - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return channel - */ -uint8_t nrf24_get_chan(FuriHalSpiBusHandle* handle); - -/** Sets the channel - * - * @param handle - pointer to FuriHalSpiHandle - * @param frequency - the frequency in hertz - * - * @return device status - */ -uint8_t nrf24_set_chan(FuriHalSpiBusHandle* handle, uint8_t chan); - -/** Gets the source mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param[out] mac - the source mac address - * - * @return device status - */ -uint8_t nrf24_get_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac); - -/** Sets the source mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param mac - the mac address to set - * @param size - the size of the mac address (2 to 5) - * - * @return device status - */ -uint8_t nrf24_set_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size); - -/** Gets the dest mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param[out] mac - the source mac address - * - * @return device status - */ -uint8_t nrf24_get_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac); - -/** Sets the dest mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param mac - the mac address to set - * @param size - the size of the mac address (2 to 5) - * - * @return device status - */ -uint8_t nrf24_set_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size); - -/** Reads RX packet - * - * @param handle - pointer to FuriHalSpiHandle - * @param[out] packet - the packet contents - * @param[out] packetsize - size of the received packet - * @param full - boolean set to true, packet length is determined by RX_PW_P0 register, false it is determined by dynamic payload length command - * - * @return device status - */ -uint8_t - nrf24_rxpacket(FuriHalSpiBusHandle* handle, uint8_t* packet, uint8_t* packetsize, bool full); - -/** Sends TX packet - * - * @param handle - pointer to FuriHalSpiHandle - * @param packet - the packet contents - * @param size - packet size - * @param ack - boolean to determine whether an ACK is required for the packet or not - * - * @return device status - */ -uint8_t nrf24_txpacket(FuriHalSpiBusHandle* handle, uint8_t* payload, uint8_t size, bool ack); - -/** Configure the radio - * This is not comprehensive, but covers a lot of the common configuration options that may be changed - * @param handle - pointer to FuriHalSpiHandle - * @param rate - transfer rate in Mbps (1 or 2) - * @param srcmac - source mac address - * @param dstmac - destination mac address - * @param maclen - length of mac address - * @param channel - channel to tune to - * @param noack - if true, disable auto-acknowledge - * @param disable_aa - if true, disable ShockBurst - * - */ -void nrf24_configure( - FuriHalSpiBusHandle* handle, - uint8_t rate, - uint8_t* srcmac, - uint8_t* dstmac, - uint8_t maclen, - uint8_t channel, - bool noack, - bool disable_aa); - -/** Configures the radio for "promiscuous mode" and primes it for rx - * This is not an actual mode of the nrf24, but this function exploits a few bugs in the chip that allows it to act as if it were. - * See http://travisgoodspeed.blogspot.com/2011/02/promiscuity-is-nrf24l01s-duty.html for details. - * @param handle - pointer to FuriHalSpiHandle - * @param channel - channel to tune to - * @param rate - transfer rate in Mbps (1 or 2) - */ -void nrf24_init_promisc_mode(FuriHalSpiBusHandle* handle, uint8_t channel, uint8_t rate); - -/** Listens for a packet and returns first possible address sniffed - * Call this only after calling nrf24_init_promisc_mode - * @param handle - pointer to FuriHalSpiHandle - * @param maclen - length of target mac address - * @param[out] addresses - sniffed address - * - * @return success - */ -bool nrf24_sniff_address(FuriHalSpiBusHandle* handle, uint8_t maclen, uint8_t* address); - -/** Sends ping packet on each channel for designated tx mac looking for ack - * - * @param handle - pointer to FuriHalSpiHandle - * @param srcmac - source address - * @param dstmac - destination address - * @param maclen - length of address - * @param rate - transfer rate in Mbps (1 or 2) - * @param min_channel - channel to start with - * @param max_channel - channel to end at - * @param autoinit - if true, automatically configure radio for this channel - * - * @return channel that the address is listening on, if this value is above the max_channel param, it failed - */ -uint8_t nrf24_find_channel( - FuriHalSpiBusHandle* handle, - uint8_t* srcmac, - uint8_t* dstmac, - uint8_t maclen, - uint8_t rate, - uint8_t min_channel, - uint8_t max_channel, - bool autoinit); - -/** Converts 64 bit value into uint8_t array - * @param val - 64-bit integer - * @param[out] out - bytes out - * @param bigendian - if true, convert as big endian, otherwise little endian - */ -void int64_to_bytes(uint64_t val, uint8_t* out, bool bigendian); - -/** Converts 32 bit value into uint8_t array - * @param val - 32-bit integer - * @param[out] out - bytes out - * @param bigendian - if true, convert as big endian, otherwise little endian - */ -void int32_to_bytes(uint32_t val, uint8_t* out, bool bigendian); - -/** Converts uint8_t array into 32 bit value - * @param bytes - uint8_t array - * @param bigendian - if true, convert as big endian, otherwise little endian - * - * @return 32-bit value - */ -uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian); - -/** Check if the nrf24 is connected - * @param handle - pointer to FuriHalSpiHandle - * - * @return true if connected, otherwise false -*/ -bool nrf24_check_connected(FuriHalSpiBusHandle* handle); - -#ifdef __cplusplus -} -#endif diff --git a/applications/external/nrf24mousejacker/mouse_10px.png b/applications/external/nrf24mousejacker/mouse_10px.png deleted file mode 100644 index 94c3a7a14..000000000 Binary files a/applications/external/nrf24mousejacker/mouse_10px.png and /dev/null differ diff --git a/applications/external/nrf24mousejacker/mousejacker.c b/applications/external/nrf24mousejacker/mousejacker.c deleted file mode 100644 index 02d91f788..000000000 --- a/applications/external/nrf24mousejacker/mousejacker.c +++ /dev/null @@ -1,407 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "mousejacker_ducky.h" -#include "nrf24mousejacker_icons.h" -#include - -#define TAG "mousejacker" -#define LOGITECH_MAX_CHANNEL 85 -#define NRFSNIFF_APP_PATH_FOLDER_ADDRESSES EXT_PATH("apps_data/nrf24sniff/addresses.txt") -#define BADKB_FOLDER EXT_PATH("badkb") -#define MOUSEJACKER_APP_PATH_EXTENSION ".txt" -#define MAX_ADDRS 100 - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} PluginEvent; - -uint8_t addrs_count = 0; -int8_t addr_idx = 0; -uint8_t loaded_addrs[MAX_ADDRS][6]; // first byte is rate, the rest are the address - -char target_fmt_text[] = "Target addr: %s"; -char target_address_str[12] = "None"; -char target_text[30]; -char index_text[30]; - -static void render_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - const PluginState* plugin_state = ctx; - furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); - - // border around the edge of the screen - canvas_draw_frame(canvas, 0, 0, 128, 64); - - canvas_set_font(canvas, FontSecondary); - if(!plugin_state->addr_err && !plugin_state->ducky_err && !plugin_state->is_thread_running && - !plugin_state->is_ducky_running) { - snprintf(target_text, sizeof(target_text), target_fmt_text, target_address_str); - canvas_draw_str_aligned(canvas, 7, 10, AlignLeft, AlignBottom, target_text); - canvas_draw_str_aligned(canvas, 22, 20, AlignLeft, AlignBottom, "<- select address ->"); - snprintf( - index_text, sizeof(index_text), "Address index: %d/%d", addr_idx + 1, addrs_count); - canvas_draw_str_aligned(canvas, 10, 30, AlignLeft, AlignBottom, index_text); - canvas_draw_str_aligned(canvas, 10, 40, AlignLeft, AlignBottom, "Press Ok button to "); - canvas_draw_str_aligned(canvas, 10, 50, AlignLeft, AlignBottom, "browse for ducky script"); - if(!plugin_state->is_nrf24_connected) { - canvas_draw_str_aligned( - canvas, 10, 60, AlignLeft, AlignBottom, "Connect NRF24 to GPIO!"); - } - } else if(plugin_state->addr_err) { - canvas_draw_str_aligned( - canvas, 10, 10, AlignLeft, AlignBottom, "Error: No nrf24sniff folder"); - canvas_draw_str_aligned(canvas, 10, 20, AlignLeft, AlignBottom, "or addresses.txt file"); - canvas_draw_str_aligned( - canvas, 10, 30, AlignLeft, AlignBottom, "loading error / empty file"); - canvas_draw_str_aligned( - canvas, 7, 40, AlignLeft, AlignBottom, "Run (NRF24: Sniff) app first!"); - } else if(plugin_state->ducky_err) { - canvas_draw_str_aligned( - canvas, 3, 10, AlignLeft, AlignBottom, "Error: No mousejacker folder"); - canvas_draw_str_aligned(canvas, 3, 20, AlignLeft, AlignBottom, "or duckyscript file"); - canvas_draw_str_aligned(canvas, 3, 30, AlignLeft, AlignBottom, "loading error"); - } else if(plugin_state->is_thread_running && !plugin_state->is_ducky_running) { - canvas_draw_str_aligned(canvas, 3, 10, AlignLeft, AlignBottom, "Loading..."); - canvas_draw_str_aligned(canvas, 3, 20, AlignLeft, AlignBottom, "Please wait!"); - } else if(plugin_state->is_thread_running && plugin_state->is_ducky_running) { - canvas_draw_str_aligned(canvas, 3, 10, AlignLeft, AlignBottom, "Running duckyscript"); - canvas_draw_str_aligned(canvas, 3, 20, AlignLeft, AlignBottom, "Please wait!"); - canvas_draw_str_aligned( - canvas, 3, 30, AlignLeft, AlignBottom, "Press back to exit (if it stuck)"); - } else { - canvas_draw_str_aligned(canvas, 3, 10, AlignLeft, AlignBottom, "Unknown Error"); - canvas_draw_str_aligned(canvas, 3, 20, AlignLeft, AlignBottom, "press back"); - canvas_draw_str_aligned(canvas, 3, 30, AlignLeft, AlignBottom, "to exit"); - } - - furi_mutex_release(plugin_state->mutex); -} - -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void mousejacker_state_init(PluginState* const plugin_state) { - plugin_state->is_thread_running = false; - plugin_state->is_nrf24_connected = true; -} - -static void hexlify(uint8_t* in, uint8_t size, char* out) { - memset(out, 0, size * 2); - for(int i = 0; i < size; i++) - snprintf(out + strlen(out), sizeof(out + strlen(out)), "%02X", in[i]); -} - -static bool open_ducky_script(Stream* stream, PluginState* plugin_state) { - DialogsApp* dialogs = furi_record_open("dialogs"); - bool result = false; - FuriString* path; - path = furi_string_alloc(); - furi_string_set(path, BADKB_FOLDER); - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options( - &browser_options, MOUSEJACKER_APP_PATH_EXTENSION, &I_badkb_10px); - browser_options.hide_ext = false; - - bool ret = dialog_file_browser_show(dialogs, path, path, &browser_options); - - furi_record_close("dialogs"); - if(ret) { - if(!file_stream_open(stream, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { - FURI_LOG_D(TAG, "Cannot open file \"%s\"", furi_string_get_cstr(path)); - } else { - result = true; - } - } - furi_string_free(path); - - plugin_state->is_ducky_running = true; - - return result; -} - -static bool open_addrs_file(Stream* stream) { - bool result = false; - FuriString* path; - path = furi_string_alloc(); - furi_string_set(path, NRFSNIFF_APP_PATH_FOLDER_ADDRESSES); - - if(!file_stream_open(stream, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { - FURI_LOG_D(TAG, "Cannot open file \"%s\"", furi_string_get_cstr(path)); - } else { - result = true; - } - - furi_string_free(path); - return result; -} - -static bool process_ducky_file( - Stream* file_stream, - uint8_t* addr, - uint8_t addr_size, - uint8_t rate, - PluginState* plugin_state) { - size_t file_size = 0; - size_t bytes_read = 0; - uint8_t* file_buf; - bool loaded = false; - FURI_LOG_D(TAG, "opening ducky script"); - if(open_ducky_script(file_stream, plugin_state)) { - file_size = stream_size(file_stream); - if(file_size == (size_t)0) { - FURI_LOG_D(TAG, "load failed. file_size: %d", file_size); - plugin_state->is_ducky_running = false; - return loaded; - } - file_buf = malloc(file_size); - memset(file_buf, 0, file_size); - bytes_read = stream_read(file_stream, file_buf, file_size); - if(bytes_read == file_size) { - FURI_LOG_D(TAG, "executing ducky script"); - mj_process_ducky_script( - nrf24_HANDLE, addr, addr_size, rate, (char*)file_buf, plugin_state); - FURI_LOG_D(TAG, "finished execution"); - loaded = true; - } else { - FURI_LOG_D(TAG, "load failed. file size: %d", file_size); - } - free(file_buf); - } - plugin_state->is_ducky_running = false; - return loaded; -} - -static bool load_addrs_file(Stream* file_stream) { - size_t file_size = 0; - size_t bytes_read = 0; - uint8_t* file_buf; - char* line_ptr; - uint8_t rate; - uint8_t addrlen = 0; - uint32_t counter = 0; - uint8_t addr[5] = {0}; - uint32_t i_addr_lo = 0; - uint32_t i_addr_hi = 0; - bool loaded = false; - FURI_LOG_D(TAG, "opening addrs file"); - addrs_count = 0; - if(open_addrs_file(file_stream)) { - file_size = stream_size(file_stream); - if(file_size == (size_t)0) { - FURI_LOG_D(TAG, "load failed. file_size: %d", file_size); - return loaded; - } - file_buf = malloc(file_size); - memset(file_buf, 0, file_size); - bytes_read = stream_read(file_stream, file_buf, file_size); - if(bytes_read == file_size) { - FURI_LOG_D(TAG, "loading addrs file"); - char* line = strtok((char*)file_buf, "\n"); - - while(line != NULL) { - line_ptr = strstr((char*)line, ","); - *line_ptr = 0; - rate = atoi(line_ptr + 1); - addrlen = (uint8_t)(strlen(line) / 2); - i_addr_lo = strtoul(line + 2, NULL, 16); - line[2] = (char)0; - i_addr_hi = strtoul(line, NULL, 16); - int32_to_bytes(i_addr_lo, &addr[1], true); - addr[0] = (uint8_t)(i_addr_hi & 0xFF); - memset(loaded_addrs[counter], rate, 1); - memcpy(&loaded_addrs[counter++][1], addr, addrlen); - addrs_count++; - line = strtok(NULL, "\n"); - loaded = true; - } - } else { - FURI_LOG_D(TAG, "load failed. file size: %d", file_size); - } - free(file_buf); - } - return loaded; -} - -// entrypoint for worker -static int32_t mj_worker_thread(void* ctx) { - PluginState* plugin_state = ctx; - bool ducky_ok = false; - if(!plugin_state->addr_err) { - plugin_state->is_thread_running = true; - plugin_state->file_stream = file_stream_alloc(plugin_state->storage); - nrf24_find_channel( - nrf24_HANDLE, - loaded_addrs[addr_idx] + 1, - loaded_addrs[addr_idx] + 1, - 5, - loaded_addrs[addr_idx][0], - 2, - LOGITECH_MAX_CHANNEL, - true); - ducky_ok = process_ducky_file( - plugin_state->file_stream, - loaded_addrs[addr_idx] + 1, - 5, - loaded_addrs[addr_idx][0], - plugin_state); - if(!ducky_ok) { - plugin_state->ducky_err = true; - } else { - plugin_state->ducky_err = false; - } - stream_free(plugin_state->file_stream); - } - plugin_state->is_thread_running = false; - return 0; -} - -int32_t mousejacker_app(void* p) { - UNUSED(p); - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - - PluginState* plugin_state = malloc(sizeof(PluginState)); - mousejacker_state_init(plugin_state); - plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!plugin_state->mutex) { - FURI_LOG_E("mousejacker", "cannot create mutex\r\n"); - furi_message_queue_free(event_queue); - free(plugin_state); - return 255; - } - - uint8_t attempts = 0; - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - furi_delay_ms(10); - } - - NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - - // Set system callbacks - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, plugin_state); - view_port_input_callback_set(view_port, input_callback, event_queue); - - // Open GUI and register view_port - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - plugin_state->storage = furi_record_open(RECORD_STORAGE); - plugin_state->file_stream = file_stream_alloc(plugin_state->storage); - - plugin_state->mjthread = furi_thread_alloc(); - furi_thread_set_name(plugin_state->mjthread, "MJ Worker"); - furi_thread_set_stack_size(plugin_state->mjthread, 2048); - furi_thread_set_context(plugin_state->mjthread, plugin_state); - furi_thread_set_callback(plugin_state->mjthread, mj_worker_thread); - - // spawn load file dialog to choose sniffed addresses file - if(load_addrs_file(plugin_state->file_stream)) { - addr_idx = 0; - hexlify(&loaded_addrs[addr_idx][1], 5, target_address_str); - plugin_state->addr_err = false; - } else { - plugin_state->addr_err = true; - } - stream_free(plugin_state->file_stream); - nrf24_init(); - - PluginEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); - - if(event_status == FuriStatusOk) { - // press events - if(event.type == EventTypeKey) { - if(event.input.type == InputTypePress) { - switch(event.input.key) { - case InputKeyUp: - break; - case InputKeyDown: - break; - case InputKeyRight: - if(!plugin_state->addr_err) { - addr_idx++; - if(addr_idx >= addrs_count) addr_idx = 0; - hexlify(loaded_addrs[addr_idx] + 1, 5, target_address_str); - } - break; - case InputKeyLeft: - if(!plugin_state->addr_err) { - addr_idx--; - if(addr_idx < 0) addr_idx = addrs_count - 1; - hexlify(loaded_addrs[addr_idx] + 1, 5, target_address_str); - } - break; - case InputKeyOk: - if(!plugin_state->addr_err) { - if(!nrf24_check_connected(nrf24_HANDLE)) { - plugin_state->is_nrf24_connected = false; - view_port_update(view_port); - notification_message(notification, &sequence_error); - } else if(!plugin_state->is_thread_running) { - furi_thread_start(plugin_state->mjthread); - view_port_update(view_port); - } - } - break; - case InputKeyBack: - plugin_state->close_thread_please = true; - if(plugin_state->is_thread_running && plugin_state->mjthread) { - furi_thread_join( - plugin_state->mjthread); // wait until thread is finished - } - plugin_state->close_thread_please = false; - processing = false; - break; - default: - break; - } - } - } - } - - view_port_update(view_port); - furi_mutex_release(plugin_state->mutex); - } - - furi_thread_free(plugin_state->mjthread); - nrf24_deinit(); - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close(RECORD_NOTIFICATION); - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_STORAGE); - view_port_free(view_port); - furi_message_queue_free(event_queue); - furi_mutex_free(plugin_state->mutex); - free(plugin_state); - - if(furi_hal_power_is_otg_enabled()) { - furi_hal_power_disable_otg(); - } - - return 0; -} diff --git a/applications/external/nrf24mousejacker/mousejacker_ducky.c b/applications/external/nrf24mousejacker/mousejacker_ducky.c deleted file mode 100644 index 04b0bfaca..000000000 --- a/applications/external/nrf24mousejacker/mousejacker_ducky.c +++ /dev/null @@ -1,460 +0,0 @@ -#include "mousejacker_ducky.h" - -static const char ducky_cmd_comment[] = {"REM"}; -static const char ducky_cmd_delay[] = {"DELAY "}; -static const char ducky_cmd_string[] = {"STRING "}; -static const char ducky_cmd_altstring[] = {"ALTSTRING "}; -static const char ducky_cmd_repeat[] = {"REPEAT "}; - -static uint8_t LOGITECH_HID_TEMPLATE[] = - {0x00, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -static uint8_t LOGITECH_HELLO[] = {0x00, 0x4F, 0x00, 0x04, 0xB0, 0x10, 0x00, 0x00, 0x00, 0xED}; -static uint8_t LOGITECH_KEEPALIVE[] = {0x00, 0x40, 0x00, 0x55, 0x6B}; - -uint8_t prev_hid = 0; -static bool holding_ctrl = false; -static bool holding_shift = false; -static bool holding_alt = false; -static bool holding_gui = false; - -#define RT_THRESHOLD 50 -#define LOGITECH_MIN_CHANNEL 2 -#define LOGITECH_MAX_CHANNEL 83 -#define LOGITECH_KEEPALIVE_SIZE 5 -#define LOGITECH_HID_TEMPLATE_SIZE 10 -#define LOGITECH_HELLO_SIZE 10 -#define TAG "mousejacker_ducky" - -MJDuckyKey mj_ducky_keys[] = {{" ", 44, 0}, {"!", 30, 2}, {"\"", 52, 2}, - {"#", 32, 2}, {"$", 33, 2}, {"%", 34, 2}, - {"&", 36, 2}, {"'", 52, 0}, {"(", 38, 2}, - {")", 39, 2}, {"*", 37, 2}, {"+", 46, 2}, - {",", 54, 0}, {"-", 45, 0}, {".", 55, 0}, - {"/", 56, 0}, {"0", 39, 0}, {"1", 30, 0}, - {"2", 31, 0}, {"3", 32, 0}, {"4", 33, 0}, - {"5", 34, 0}, {"6", 35, 0}, {"7", 36, 0}, - {"8", 37, 0}, {"9", 38, 0}, {":", 51, 2}, - {";", 51, 0}, {"<", 54, 2}, {"=", 46, 0}, - {">", 55, 2}, {"?", 56, 2}, {"@", 31, 2}, - {"A", 4, 2}, {"B", 5, 2}, {"C", 6, 2}, - {"D", 7, 2}, {"E", 8, 2}, {"F", 9, 2}, - {"G", 10, 2}, {"H", 11, 2}, {"I", 12, 2}, - {"J", 13, 2}, {"K", 14, 2}, {"L", 15, 2}, - {"M", 16, 2}, {"N", 17, 2}, {"O", 18, 2}, - {"P", 19, 2}, {"Q", 20, 2}, {"R", 21, 2}, - {"S", 22, 2}, {"T", 23, 2}, {"U", 24, 2}, - {"V", 25, 2}, {"W", 26, 2}, {"X", 27, 2}, - {"Y", 28, 2}, {"Z", 29, 2}, {"[", 47, 0}, - {"\\", 49, 0}, {"]", 48, 0}, {"^", 35, 2}, - {"_", 45, 2}, {"`", 53, 0}, {"a", 4, 0}, - {"b", 5, 0}, {"c", 6, 0}, {"d", 7, 0}, - {"e", 8, 0}, {"f", 9, 0}, {"g", 10, 0}, - {"h", 11, 0}, {"i", 12, 0}, {"j", 13, 0}, - {"k", 14, 0}, {"l", 15, 0}, {"m", 16, 0}, - {"n", 17, 0}, {"o", 18, 0}, {"p", 19, 0}, - {"q", 20, 0}, {"r", 21, 0}, {"s", 22, 0}, - {"t", 23, 0}, {"u", 24, 0}, {"v", 25, 0}, - {"w", 26, 0}, {"x", 27, 0}, {"y", 28, 0}, - {"z", 29, 0}, {"{", 47, 2}, {"|", 49, 2}, - {"}", 48, 2}, {"~", 53, 2}, {"BACKSPACE", 42, 0}, - {"", 0, 0}, {"ALT", 0, 4}, {"SHIFT", 0, 2}, - {"CTRL", 0, 1}, {"GUI", 0, 8}, {"SCROLLLOCK", 71, 0}, - {"ENTER", 40, 0}, {"F12", 69, 0}, {"HOME", 74, 0}, - {"F10", 67, 0}, {"F9", 66, 0}, {"ESCAPE", 41, 0}, - {"PAGEUP", 75, 0}, {"TAB", 43, 0}, {"PRINTSCREEN", 70, 0}, - {"F2", 59, 0}, {"CAPSLOCK", 57, 0}, {"F1", 58, 0}, - {"F4", 61, 0}, {"F6", 63, 0}, {"F8", 65, 0}, - {"DOWNARROW", 81, 0}, {"DELETE", 42, 0}, {"RIGHT", 79, 0}, - {"F3", 60, 0}, {"DOWN", 81, 0}, {"DEL", 76, 0}, - {"END", 77, 0}, {"INSERT", 73, 0}, {"F5", 62, 0}, - {"LEFTARROW", 80, 0}, {"RIGHTARROW", 79, 0}, {"PAGEDOWN", 78, 0}, - {"PAUSE", 72, 0}, {"SPACE", 44, 0}, {"UPARROW", 82, 0}, - {"F11", 68, 0}, {"F7", 64, 0}, {"UP", 82, 0}, - {"LEFT", 80, 0}, {"NUM 1", 89, 0}, {"NUM 2", 90, 0}, - {"NUM 3", 91, 0}, {"NUM 4", 92, 0}, {"NUM 5", 93, 0}, - {"NUM 6", 94, 0}, {"NUM 7", 95, 0}, {"NUM 8", 96, 0}, - {"NUM 9", 97, 0}, {"NUM 0", 98, 0}}; - -/* -static bool mj_ducky_get_number(const char* param, uint32_t* val) { - uint32_t value = 0; - if(sscanf(param, "%lu", &value) == 1) { - *val = value; - return true; - } - return false; -} -*/ - -static uint32_t mj_ducky_get_command_len(const char* line) { - uint32_t len = strlen(line); - for(uint32_t i = 0; i < len; i++) { - if(line[i] == ' ') return i; - } - return 0; -} - -static bool mj_get_ducky_key(char* key, size_t keylen, MJDuckyKey* dk) { - //FURI_LOG_D(TAG, "looking up key %s with length %d", key, keylen); - for(uint i = 0; i < sizeof(mj_ducky_keys) / sizeof(MJDuckyKey); i++) { - if(strlen(mj_ducky_keys[i].name) == keylen && - !strncmp(mj_ducky_keys[i].name, key, keylen)) { - memcpy(dk, &mj_ducky_keys[i], sizeof(MJDuckyKey)); - return true; - } - } - - return false; -} - -static void checksum(uint8_t* payload, uint len) { - // This is also from the KeyKeriki paper - // Thanks Thorsten and Max! - uint8_t cksum = 0xff; - for(uint n = 0; n < len - 2; n++) cksum = (cksum - payload[n]) & 0xff; - cksum = (cksum + 1) & 0xff; - payload[len - 1] = cksum; -} - -static void inject_packet( - FuriHalSpiBusHandle* handle, - uint8_t* addr, - uint8_t addr_size, - uint8_t rate, - uint8_t* payload, - size_t payload_size, - PluginState* plugin_state) { - uint8_t rt_count = 0; - while(1) { - if(!plugin_state->is_thread_running || plugin_state->close_thread_please) { - return; - } - if(nrf24_txpacket(handle, payload, payload_size, true)) { - break; - } - - rt_count++; - // retransmit threshold exceeded, scan for new channel - if(rt_count > RT_THRESHOLD) { - if(nrf24_find_channel( - handle, - addr, - addr, - addr_size, - rate, - LOGITECH_MIN_CHANNEL, - LOGITECH_MAX_CHANNEL, - true) > LOGITECH_MAX_CHANNEL) { - return; // fail - } - //FURI_LOG_D("mj", "find channel passed, %d", tessst); - - rt_count = 0; - } - } -} - -static void build_hid_packet(uint8_t mod, uint8_t hid, uint8_t* payload) { - memcpy(payload, LOGITECH_HID_TEMPLATE, LOGITECH_HID_TEMPLATE_SIZE); - payload[2] = mod; - payload[3] = hid; - checksum(payload, LOGITECH_HID_TEMPLATE_SIZE); -} - -static void release_key( - FuriHalSpiBusHandle* handle, - uint8_t* addr, - uint8_t addr_size, - uint8_t rate, - PluginState* plugin_state) { - // This function release keys currently pressed, but keep pressing special keys - // if holding mod keys variable are set to true - - uint8_t hid_payload[LOGITECH_HID_TEMPLATE_SIZE] = {0}; - build_hid_packet( - 0 | holding_ctrl | holding_shift << 1 | holding_alt << 2 | holding_gui << 3, - 0, - hid_payload); - inject_packet( - handle, - addr, - addr_size, - rate, - hid_payload, - LOGITECH_HID_TEMPLATE_SIZE, - plugin_state); // empty hid packet -} - -static void send_hid_packet( - FuriHalSpiBusHandle* handle, - uint8_t* addr, - uint8_t addr_size, - uint8_t rate, - uint8_t mod, - uint8_t hid, - PluginState* plugin_state) { - uint8_t hid_payload[LOGITECH_HID_TEMPLATE_SIZE] = {0}; - if(hid == prev_hid) release_key(handle, addr, addr_size, rate, plugin_state); - - prev_hid = hid; - build_hid_packet( - mod | holding_ctrl | holding_shift << 1 | holding_alt << 2 | holding_gui << 3, - hid, - hid_payload); - inject_packet( - handle, addr, addr_size, rate, hid_payload, LOGITECH_HID_TEMPLATE_SIZE, plugin_state); - furi_delay_ms(12); -} - -static bool ducky_end_line(const char chr) { - return ((chr == ' ') || (chr == '\0') || (chr == '\r') || (chr == '\n')); -} - -// returns false if there was an error processing script line -static bool mj_process_ducky_line( - FuriHalSpiBusHandle* handle, - uint8_t* addr, - uint8_t addr_size, - uint8_t rate, - char* line, - char* prev_line, - PluginState* plugin_state) { - MJDuckyKey dk; - uint8_t hid_payload[LOGITECH_HID_TEMPLATE_SIZE] = {0}; - char* line_tmp = line; - uint32_t line_len = strlen(line); - if(!plugin_state->is_thread_running || plugin_state->close_thread_please) { - return true; - } - for(uint32_t i = 0; i < line_len; i++) { - if((line_tmp[i] != ' ') && (line_tmp[i] != '\t') && (line_tmp[i] != '\n')) { - line_tmp = &line_tmp[i]; - break; // Skip spaces and tabs - } - if(i == line_len - 1) return true; // Skip empty lines - } - - FURI_LOG_D(TAG, "line: %s", line_tmp); - - // General commands - if(strncmp(line_tmp, ducky_cmd_comment, strlen(ducky_cmd_comment)) == 0) { - // REM - comment line - return true; - } else if(strncmp(line_tmp, ducky_cmd_delay, strlen(ducky_cmd_delay)) == 0) { - // DELAY - line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1]; - uint32_t delay_val = 0; - delay_val = atoi(line_tmp); - if(delay_val > 0) { - uint32_t delay_count = delay_val / 10; - build_hid_packet(0, 0, hid_payload); - inject_packet( - handle, - addr, - addr_size, - rate, - hid_payload, - LOGITECH_HID_TEMPLATE_SIZE, - plugin_state); // empty hid packet - for(uint32_t i = 0; i < delay_count; i++) { - if(!plugin_state->is_thread_running || plugin_state->close_thread_please) { - return true; - } - inject_packet( - handle, - addr, - addr_size, - rate, - LOGITECH_KEEPALIVE, - LOGITECH_KEEPALIVE_SIZE, - plugin_state); - furi_delay_ms(10); - } - return true; - } - return false; - } else if(strncmp(line_tmp, ducky_cmd_string, strlen(ducky_cmd_string)) == 0) { - // STRING - line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1]; - for(size_t i = 0; i < strlen(line_tmp); i++) { - if(!mj_get_ducky_key(&line_tmp[i], 1, &dk)) return false; - - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - } - - return true; - } else if(strncmp(line_tmp, ducky_cmd_altstring, strlen(ducky_cmd_altstring)) == 0) { - // ALTSTRING - line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1]; - for(size_t i = 0; i < strlen(line_tmp); i++) { - if((line_tmp[i] < ' ') || (line_tmp[i] > '~')) { - continue; // Skip non-printable chars - } - - char alt_code[4]; - // Getting altcode of the char - snprintf(alt_code, 4, "%u", line_tmp[i]); - - uint8_t j = 0; - while(!ducky_end_line(alt_code[j])) { - char pad_num[5] = {'N', 'U', 'M', ' ', alt_code[j]}; - if(!mj_get_ducky_key(pad_num, 5, &dk)) return false; - holding_alt = true; - FURI_LOG_D(TAG, "Sending %s", pad_num); - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - j++; - } - holding_alt = false; - release_key(handle, addr, addr_size, rate, plugin_state); - } - - return true; - } else if(strncmp(line_tmp, ducky_cmd_repeat, strlen(ducky_cmd_repeat)) == 0) { - // REPEAT - uint32_t repeat_cnt = 0; - if(prev_line == NULL) return false; - - line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1]; - repeat_cnt = atoi(line_tmp); - if(repeat_cnt < 2) return false; - - FURI_LOG_D(TAG, "repeating %s %ld times", prev_line, repeat_cnt); - for(uint32_t i = 0; i < repeat_cnt; i++) - mj_process_ducky_line(handle, addr, addr_size, rate, prev_line, NULL, plugin_state); - - return true; - } else if(strncmp(line_tmp, "ALT", strlen("ALT")) == 0) { - line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1]; - if(!mj_get_ducky_key(line_tmp, strlen(line_tmp), &dk)) return false; - holding_alt = true; - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - holding_alt = false; - return true; - } else if( - strncmp(line_tmp, "GUI", strlen("GUI")) == 0 || - strncmp(line_tmp, "WINDOWS", strlen("WINDOWS")) == 0 || - strncmp(line_tmp, "COMMAND", strlen("COMMAND")) == 0) { - line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1]; - if(!mj_get_ducky_key(line_tmp, strlen(line_tmp), &dk)) return false; - holding_gui = true; - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - holding_gui = false; - return true; - } else if( - strncmp(line_tmp, "CTRL-ALT", strlen("CTRL-ALT")) == 0 || - strncmp(line_tmp, "CONTROL-ALT", strlen("CONTROL-ALT")) == 0) { - line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1]; - if(!mj_get_ducky_key(line_tmp, strlen(line_tmp), &dk)) return false; - holding_ctrl = true; - holding_alt = true; - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - holding_ctrl = false; - holding_alt = false; - return true; - } else if( - strncmp(line_tmp, "CTRL-SHIFT", strlen("CTRL-SHIFT")) == 0 || - strncmp(line_tmp, "CONTROL-SHIFT", strlen("CONTROL-SHIFT")) == 0) { - line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1]; - if(!mj_get_ducky_key(line_tmp, strlen(line_tmp), &dk)) return false; - holding_ctrl = true; - holding_shift = true; - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - holding_ctrl = false; - holding_shift = false; - return true; - } else if( - strncmp(line_tmp, "CTRL", strlen("CTRL")) == 0 || - strncmp(line_tmp, "CONTROL", strlen("CONTROL")) == 0) { - line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1]; - if(!mj_get_ducky_key(line_tmp, strlen(line_tmp), &dk)) return false; - holding_ctrl = true; - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - holding_ctrl = false; - return true; - } else if(strncmp(line_tmp, "SHIFT", strlen("SHIFT")) == 0) { - line_tmp = &line_tmp[mj_ducky_get_command_len(line_tmp) + 1]; - if(!mj_get_ducky_key(line_tmp, strlen(line_tmp), &dk)) return false; - holding_shift = true; - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - holding_shift = false; - return true; - } else if( - strncmp(line_tmp, "ESC", strlen("ESC")) == 0 || - strncmp(line_tmp, "APP", strlen("APP")) == 0 || - strncmp(line_tmp, "ESCAPE", strlen("ESCAPE")) == 0) { - if(!mj_get_ducky_key("ESCAPE", 6, &dk)) return false; - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - return true; - } else if(strncmp(line_tmp, "ENTER", strlen("ENTER")) == 0) { - if(!mj_get_ducky_key("ENTER", 5, &dk)) return false; - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - return true; - } else if( - strncmp(line_tmp, "UP", strlen("UP")) == 0 || - strncmp(line_tmp, "UPARROW", strlen("UPARROW")) == 0) { - if(!mj_get_ducky_key("UP", 2, &dk)) return false; - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - return true; - } else if( - strncmp(line_tmp, "DOWN", strlen("DOWN")) == 0 || - strncmp(line_tmp, "DOWNARROW", strlen("DOWNARROW")) == 0) { - if(!mj_get_ducky_key("DOWN", 4, &dk)) return false; - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - return true; - } else if( - strncmp(line_tmp, "LEFT", strlen("LEFT")) == 0 || - strncmp(line_tmp, "LEFTARROW", strlen("LEFTARROW")) == 0) { - if(!mj_get_ducky_key("LEFT", 4, &dk)) return false; - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - return true; - } else if( - strncmp(line_tmp, "RIGHT", strlen("RIGHT")) == 0 || - strncmp(line_tmp, "RIGHTARROW", strlen("RIGHTARROW")) == 0) { - if(!mj_get_ducky_key("RIGHT", 5, &dk)) return false; - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - return true; - } else if(strncmp(line_tmp, "SPACE", strlen("SPACE")) == 0) { - if(!mj_get_ducky_key("SPACE", 5, &dk)) return false; - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - return true; - } else if(strncmp(line_tmp, "TAB", strlen("TAB")) == 0) { - if(!mj_get_ducky_key("TAB", 3, &dk)) return false; - send_hid_packet(handle, addr, addr_size, rate, dk.mod, dk.hid, plugin_state); - return true; - } - - return false; -} - -void mj_process_ducky_script( - FuriHalSpiBusHandle* handle, - uint8_t* addr, - uint8_t addr_size, - uint8_t rate, - char* script, - PluginState* plugin_state) { - uint8_t hid_payload[LOGITECH_HID_TEMPLATE_SIZE] = {0}; - char* prev_line = NULL; - - inject_packet( - handle, addr, addr_size, rate, LOGITECH_HELLO, LOGITECH_HELLO_SIZE, plugin_state); - char* line = strtok(script, "\n"); - while(line != NULL) { - if(strcmp(&line[strlen(line) - 1], "\r") == 0) line[strlen(line) - 1] = (char)0; - - if(!mj_process_ducky_line(handle, addr, addr_size, rate, line, prev_line, plugin_state)) - FURI_LOG_D(TAG, "unable to process ducky script line: %s", line); - - prev_line = line; - line = strtok(NULL, "\n"); - } - build_hid_packet(0, 0, hid_payload); - inject_packet( - handle, - addr, - addr_size, - rate, - hid_payload, - LOGITECH_HID_TEMPLATE_SIZE, - plugin_state); // empty hid packet at end -} \ No newline at end of file diff --git a/applications/external/nrf24mousejacker/mousejacker_ducky.h b/applications/external/nrf24mousejacker/mousejacker_ducky.h deleted file mode 100644 index 01dc32c30..000000000 --- a/applications/external/nrf24mousejacker/mousejacker_ducky.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - char* name; - uint8_t hid; - uint8_t mod; -} MJDuckyKey; - -typedef struct { - FuriMutex* mutex; - bool ducky_err; - bool addr_err; - bool is_thread_running; - bool is_ducky_running; - bool is_nrf24_connected; - bool close_thread_please; - Storage* storage; - FuriThread* mjthread; - Stream* file_stream; -} PluginState; - -void mj_process_ducky_script( - FuriHalSpiBusHandle* handle, - uint8_t* addr, - uint8_t addr_size, - uint8_t rate, - char* script, - PluginState* plugin_state); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/applications/external/nrf24sniff/application.fam b/applications/external/nrf24sniff/application.fam deleted file mode 100644 index 98be7d06e..000000000 --- a/applications/external/nrf24sniff/application.fam +++ /dev/null @@ -1,21 +0,0 @@ -App( - appid="nrf24sniff", - name="[NRF24] Sniffer", - apptype=FlipperAppType.EXTERNAL, - entry_point="nrfsniff_app", - requires=["gui"], - stack_size=2 * 1024, - fap_icon="nrfsniff_10px.png", - fap_category="GPIO", - fap_author="@mothball187 & @xMasterX", - fap_version="1.0", - fap_description="App captures addresses to use with NRF24 Mouse Jacker app to perform mousejack attacks", - fap_private_libs=[ - Lib( - name="nrf24", - sources=[ - "nrf24.c", - ], - ), - ], -) diff --git a/applications/external/nrf24sniff/lib/nrf24/nrf24.c b/applications/external/nrf24sniff/lib/nrf24/nrf24.c deleted file mode 100644 index fe62d5db3..000000000 --- a/applications/external/nrf24sniff/lib/nrf24/nrf24.c +++ /dev/null @@ -1,546 +0,0 @@ -#include "nrf24.h" -#include -#include -#include -#include -#include - -void nrf24_init() { - // this is needed if multiple SPI devices are connected to the same bus but with different CS pins - if(xtreme_settings.spi_nrf24_handle == SpiDefault) { - furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull); - furi_hal_gpio_write(&gpio_ext_pc3, true); - } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { - furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); - furi_hal_gpio_write(&gpio_ext_pa4, true); - } - - furi_hal_spi_bus_handle_init(nrf24_HANDLE); - furi_hal_spi_acquire(nrf24_HANDLE); - furi_hal_gpio_init(nrf24_CE_PIN, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); - furi_hal_gpio_write(nrf24_CE_PIN, false); -} - -void nrf24_deinit() { - furi_hal_spi_release(nrf24_HANDLE); - furi_hal_spi_bus_handle_deinit(nrf24_HANDLE); - furi_hal_gpio_write(nrf24_CE_PIN, false); - furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - - // resetting the CS pins to floating - if(xtreme_settings.spi_nrf24_handle == SpiDefault) { - furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeAnalog); - } else if(xtreme_settings.spi_nrf24_handle == SpiExtra) { - furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog); - } -} - -void nrf24_spi_trx( - FuriHalSpiBusHandle* handle, - uint8_t* tx, - uint8_t* rx, - uint8_t size, - uint32_t timeout) { - UNUSED(timeout); - furi_hal_gpio_write(handle->cs, false); - furi_hal_spi_bus_trx(handle, tx, rx, size, nrf24_TIMEOUT); - furi_hal_gpio_write(handle->cs, true); -} - -uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data) { - uint8_t tx[2] = {W_REGISTER | (REGISTER_MASK & reg), data}; - uint8_t rx[2] = {0}; - nrf24_spi_trx(handle, tx, rx, 2, nrf24_TIMEOUT); - return rx[0]; -} - -uint8_t - nrf24_write_buf_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) { - uint8_t tx[size + 1]; - uint8_t rx[size + 1]; - memset(rx, 0, size + 1); - tx[0] = W_REGISTER | (REGISTER_MASK & reg); - memcpy(&tx[1], data, size); - nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT); - return rx[0]; -} - -uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size) { - uint8_t tx[size + 1]; - uint8_t rx[size + 1]; - memset(rx, 0, size + 1); - tx[0] = R_REGISTER | (REGISTER_MASK & reg); - memset(&tx[1], 0, size); - nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT); - memcpy(data, &rx[1], size); - return rx[0]; -} - -uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle) { - uint8_t tx[] = {FLUSH_RX}; - uint8_t rx[] = {0}; - nrf24_spi_trx(handle, tx, rx, 1, nrf24_TIMEOUT); - return rx[0]; -} - -uint8_t nrf24_flush_tx(FuriHalSpiBusHandle* handle) { - uint8_t tx[] = {FLUSH_TX}; - uint8_t rx[] = {0}; - nrf24_spi_trx(handle, tx, rx, 1, nrf24_TIMEOUT); - return rx[0]; -} - -uint8_t nrf24_get_maclen(FuriHalSpiBusHandle* handle) { - uint8_t maclen; - nrf24_read_reg(handle, REG_SETUP_AW, &maclen, 1); - maclen &= 3; - return maclen + 2; -} - -uint8_t nrf24_set_maclen(FuriHalSpiBusHandle* handle, uint8_t maclen) { - assert(maclen > 1 && maclen < 6); - uint8_t status = 0; - status = nrf24_write_reg(handle, REG_SETUP_AW, maclen - 2); - return status; -} - -uint8_t nrf24_status(FuriHalSpiBusHandle* handle) { - uint8_t status; - uint8_t tx[] = {R_REGISTER | (REGISTER_MASK & REG_STATUS)}; - nrf24_spi_trx(handle, tx, &status, 1, nrf24_TIMEOUT); - return status; -} - -uint32_t nrf24_get_rate(FuriHalSpiBusHandle* handle) { - uint8_t setup = 0; - uint32_t rate = 0; - nrf24_read_reg(handle, REG_RF_SETUP, &setup, 1); - setup &= 0x28; - if(setup == 0x20) - rate = 250000; // 250kbps - else if(setup == 0x08) - rate = 2000000; // 2Mbps - else if(setup == 0x00) - rate = 1000000; // 1Mbps - - return rate; -} - -uint8_t nrf24_set_rate(FuriHalSpiBusHandle* handle, uint32_t rate) { - uint8_t r6 = 0; - uint8_t status = 0; - if(!rate) rate = 2000000; - - nrf24_read_reg(handle, REG_RF_SETUP, &r6, 1); // RF_SETUP register - r6 = r6 & (~0x28); // Clear rate fields. - if(rate == 2000000) - r6 = r6 | 0x08; - else if(rate == 1000000) - r6 = r6; - else if(rate == 250000) - r6 = r6 | 0x20; - - status = nrf24_write_reg(handle, REG_RF_SETUP, r6); // Write new rate. - return status; -} - -uint8_t nrf24_get_chan(FuriHalSpiBusHandle* handle) { - uint8_t channel = 0; - nrf24_read_reg(handle, REG_RF_CH, &channel, 1); - return channel; -} - -uint8_t nrf24_set_chan(FuriHalSpiBusHandle* handle, uint8_t chan) { - uint8_t status; - status = nrf24_write_reg(handle, REG_RF_CH, chan); - return status; -} - -uint8_t nrf24_get_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac) { - uint8_t size = 0; - uint8_t status = 0; - size = nrf24_get_maclen(handle); - status = nrf24_read_reg(handle, REG_RX_ADDR_P0, mac, size); - return status; -} - -uint8_t nrf24_set_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size) { - uint8_t status = 0; - uint8_t clearmac[] = {0, 0, 0, 0, 0}; - nrf24_set_maclen(handle, size); - nrf24_write_buf_reg(handle, REG_RX_ADDR_P0, clearmac, 5); - status = nrf24_write_buf_reg(handle, REG_RX_ADDR_P0, mac, size); - return status; -} - -uint8_t nrf24_get_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac) { - uint8_t size = 0; - uint8_t status = 0; - size = nrf24_get_maclen(handle); - status = nrf24_read_reg(handle, REG_TX_ADDR, mac, size); - return status; -} - -uint8_t nrf24_set_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size) { - uint8_t status = 0; - uint8_t clearmac[] = {0, 0, 0, 0, 0}; - nrf24_set_maclen(handle, size); - nrf24_write_buf_reg(handle, REG_TX_ADDR, clearmac, 5); - status = nrf24_write_buf_reg(handle, REG_TX_ADDR, mac, size); - return status; -} - -uint8_t nrf24_get_packetlen(FuriHalSpiBusHandle* handle) { - uint8_t len = 0; - nrf24_read_reg(handle, RX_PW_P0, &len, 1); - return len; -} - -uint8_t nrf24_set_packetlen(FuriHalSpiBusHandle* handle, uint8_t len) { - uint8_t status = 0; - status = nrf24_write_reg(handle, RX_PW_P0, len); - return status; -} - -uint8_t - nrf24_rxpacket(FuriHalSpiBusHandle* handle, uint8_t* packet, uint8_t* packetsize, bool full) { - uint8_t status = 0; - uint8_t size = 0; - uint8_t tx_pl_wid[] = {R_RX_PL_WID, 0}; - uint8_t rx_pl_wid[] = {0, 0}; - uint8_t tx_cmd[33] = {0}; // 32 max payload size + 1 for command - uint8_t tmp_packet[33] = {0}; - - status = nrf24_status(handle); - - if(status & 0x40) { - if(full) - size = nrf24_get_packetlen(handle); - else { - nrf24_spi_trx(handle, tx_pl_wid, rx_pl_wid, 2, nrf24_TIMEOUT); - size = rx_pl_wid[1]; - } - - tx_cmd[0] = R_RX_PAYLOAD; - nrf24_spi_trx(handle, tx_cmd, tmp_packet, size + 1, nrf24_TIMEOUT); - nrf24_write_reg(handle, REG_STATUS, 0x40); // clear bit. - memcpy(packet, &tmp_packet[1], size); - } else if(status == 0) { - nrf24_flush_rx(handle); - nrf24_write_reg(handle, REG_STATUS, 0x40); // clear bit. - } - - *packetsize = size; - return status; -} - -uint8_t nrf24_txpacket(FuriHalSpiBusHandle* handle, uint8_t* payload, uint8_t size, bool ack) { - uint8_t status = 0; - uint8_t tx[size + 1]; - uint8_t rx[size + 1]; - memset(tx, 0, size + 1); - memset(rx, 0, size + 1); - - if(!ack) - tx[0] = W_TX_PAYLOAD_NOACK; - else - tx[0] = W_TX_PAYLOAD; - - memcpy(&tx[1], payload, size); - nrf24_spi_trx(handle, tx, rx, size + 1, nrf24_TIMEOUT); - nrf24_set_tx_mode(handle); - - while(!(status & (TX_DS | MAX_RT))) status = nrf24_status(handle); - - if(status & MAX_RT) nrf24_flush_tx(handle); - - nrf24_set_idle(handle); - nrf24_write_reg(handle, REG_STATUS, TX_DS | MAX_RT); - return status & TX_DS; -} - -uint8_t nrf24_power_up(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg = cfg | 2; - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - furi_delay_ms(5000); - return status; -} - -uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg &= 0xfc; // clear bottom two bits to power down the radio - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - //nr204_write_reg(handle, REG_EN_RXADDR, 0x0); - furi_hal_gpio_write(nrf24_CE_PIN, false); - return status; -} - -uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - //status = nrf24_write_reg(handle, REG_CONFIG, 0x0F); // enable 2-byte CRC, PWR_UP, and PRIM_RX - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg |= 0x03; // PWR_UP, and PRIM_RX - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - //nr204_write_reg(REG_EN_RXADDR, 0x03) // Set RX Pipe 0 and 1 - furi_hal_gpio_write(nrf24_CE_PIN, true); - furi_delay_ms(2000); - return status; -} - -uint8_t nrf24_set_tx_mode(FuriHalSpiBusHandle* handle) { - uint8_t status = 0; - uint8_t cfg = 0; - furi_hal_gpio_write(nrf24_CE_PIN, false); - nrf24_write_reg(handle, REG_STATUS, 0x30); - //status = nrf24_write_reg(handle, REG_CONFIG, 0x0E); // enable 2-byte CRC, PWR_UP - nrf24_read_reg(handle, REG_CONFIG, &cfg, 1); - cfg &= 0xfe; // disable PRIM_RX - cfg |= 0x02; // PWR_UP - status = nrf24_write_reg(handle, REG_CONFIG, cfg); - furi_hal_gpio_write(nrf24_CE_PIN, true); - furi_delay_ms(2); - return status; -} - -void nrf24_configure( - FuriHalSpiBusHandle* handle, - uint8_t rate, - uint8_t* srcmac, - uint8_t* dstmac, - uint8_t maclen, - uint8_t channel, - bool noack, - bool disable_aa) { - assert(channel <= 125); - assert(rate == 1 || rate == 2); - if(rate == 2) - rate = 8; // 2Mbps - else - rate = 0; // 1Mbps - - nrf24_write_reg(handle, REG_CONFIG, 0x00); // Stop nRF - nrf24_set_idle(handle); - nrf24_write_reg(handle, REG_STATUS, 0x1c); // clear interrupts - if(disable_aa) - nrf24_write_reg(handle, REG_EN_AA, 0x00); // Disable Shockburst - else - nrf24_write_reg(handle, REG_EN_AA, 0x1F); // Enable Shockburst - - nrf24_write_reg(handle, REG_DYNPD, 0x3F); // enable dynamic payload length on all pipes - if(noack) - nrf24_write_reg(handle, REG_FEATURE, 0x05); // disable payload-with-ack, enable noack - else { - nrf24_write_reg(handle, REG_CONFIG, 0x0C); // 2 byte CRC - nrf24_write_reg(handle, REG_FEATURE, 0x07); // enable dyn payload and ack - nrf24_write_reg( - handle, REG_SETUP_RETR, 0x1f); // 15 retries for AA, 500us auto retransmit delay - } - - nrf24_set_idle(handle); - nrf24_flush_rx(handle); - nrf24_flush_tx(handle); - - if(maclen) nrf24_set_maclen(handle, maclen); - if(srcmac) nrf24_set_src_mac(handle, srcmac, maclen); - if(dstmac) nrf24_set_dst_mac(handle, dstmac, maclen); - - nrf24_write_reg(handle, REG_RF_CH, channel); - nrf24_write_reg(handle, REG_RF_SETUP, rate); - furi_delay_ms(200); -} - -void nrf24_init_promisc_mode(FuriHalSpiBusHandle* handle, uint8_t channel, uint8_t rate) { - //uint8_t preamble[] = {0x55, 0x00}; // little endian - uint8_t preamble[] = {0xAA, 0x00}; // little endian - //uint8_t preamble[] = {0x00, 0x55}; // little endian - //uint8_t preamble[] = {0x00, 0xAA}; // little endian - nrf24_write_reg(handle, REG_CONFIG, 0x00); // Stop nRF - nrf24_write_reg(handle, REG_STATUS, 0x1c); // clear interrupts - nrf24_write_reg(handle, REG_DYNPD, 0x0); // disable shockburst - nrf24_write_reg(handle, REG_EN_AA, 0x00); // Disable Shockburst - nrf24_write_reg(handle, REG_FEATURE, 0x05); // disable payload-with-ack, enable noack - nrf24_set_maclen(handle, 2); // shortest address - nrf24_set_src_mac(handle, preamble, 2); // set src mac to preamble bits to catch everything - nrf24_set_packetlen(handle, 32); // set max packet length - nrf24_set_idle(handle); - nrf24_flush_rx(handle); - nrf24_flush_tx(handle); - nrf24_write_reg(handle, REG_RF_CH, channel); - nrf24_write_reg(handle, REG_RF_SETUP, rate); - - // prime for RX, no checksum - nrf24_write_reg(handle, REG_CONFIG, 0x03); // PWR_UP and PRIM_RX, disable AA and CRC - furi_hal_gpio_write(nrf24_CE_PIN, true); - furi_delay_ms(100); -} - -void hexlify(uint8_t* in, uint8_t size, char* out) { - memset(out, 0, size * 2); - for(int i = 0; i < size; i++) - snprintf(out + strlen(out), sizeof(out + strlen(out)), "%02X", in[i]); -} - -uint64_t bytes_to_int64(uint8_t* bytes, uint8_t size, bool bigendian) { - uint64_t ret = 0; - for(int i = 0; i < size; i++) - if(bigendian) - ret |= bytes[i] << ((size - 1 - i) * 8); - else - ret |= bytes[i] << (i * 8); - - return ret; -} - -void int64_to_bytes(uint64_t val, uint8_t* out, bool bigendian) { - for(int i = 0; i < 8; i++) { - if(bigendian) - out[i] = (val >> ((7 - i) * 8)) & 0xff; - else - out[i] = (val >> (i * 8)) & 0xff; - } -} - -uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian) { - uint32_t ret = 0; - for(int i = 0; i < 4; i++) - if(bigendian) - ret |= bytes[i] << ((3 - i) * 8); - else - ret |= bytes[i] << (i * 8); - - return ret; -} - -void int32_to_bytes(uint32_t val, uint8_t* out, bool bigendian) { - for(int i = 0; i < 4; i++) { - if(bigendian) - out[i] = (val >> ((3 - i) * 8)) & 0xff; - else - out[i] = (val >> (i * 8)) & 0xff; - } -} - -uint64_t bytes_to_int16(uint8_t* bytes, bool bigendian) { - uint16_t ret = 0; - for(int i = 0; i < 2; i++) - if(bigendian) - ret |= bytes[i] << ((1 - i) * 8); - else - ret |= bytes[i] << (i * 8); - - return ret; -} - -void int16_to_bytes(uint16_t val, uint8_t* out, bool bigendian) { - for(int i = 0; i < 2; i++) { - if(bigendian) - out[i] = (val >> ((1 - i) * 8)) & 0xff; - else - out[i] = (val >> (i * 8)) & 0xff; - } -} - -// handle iffyness with preamble processing sometimes being a bit (literally) off -void alt_address_old(uint8_t* packet, uint8_t* altaddr) { - uint8_t macmess_hi_b[4]; - uint8_t macmess_lo_b[2]; - uint32_t macmess_hi; - uint16_t macmess_lo; - uint8_t preserved; - - // get first 6 bytes into 32-bit and 16-bit variables - memcpy(macmess_hi_b, packet, 4); - memcpy(macmess_lo_b, packet + 4, 2); - - macmess_hi = bytes_to_int32(macmess_hi_b, true); - - //preserve least 7 bits from hi that will be shifted down to lo - preserved = macmess_hi & 0x7f; - macmess_hi >>= 7; - - macmess_lo = bytes_to_int16(macmess_lo_b, true); - macmess_lo >>= 7; - macmess_lo = (preserved << 9) | macmess_lo; - int32_to_bytes(macmess_hi, macmess_hi_b, true); - int16_to_bytes(macmess_lo, macmess_lo_b, true); - memcpy(altaddr, &macmess_hi_b[1], 3); - memcpy(altaddr + 3, macmess_lo_b, 2); -} - -bool validate_address(uint8_t* addr) { - uint8_t bad[][3] = {{0x55, 0x55}, {0xAA, 0xAA}, {0x00, 0x00}, {0xFF, 0xFF}}; - for(int i = 0; i < 4; i++) - for(int j = 0; j < 2; j++) - if(!memcmp(addr + j * 2, bad[i], 2)) return false; - - return true; -} - -bool nrf24_sniff_address(FuriHalSpiBusHandle* handle, uint8_t maclen, uint8_t* address) { - bool found = false; - uint8_t packet[32] = {0}; - uint8_t packetsize; - //char printit[65]; - uint8_t status = 0; - status = nrf24_rxpacket(handle, packet, &packetsize, true); - if(status & 0x40) { - if(validate_address(packet)) { - for(int i = 0; i < maclen; i++) address[i] = packet[maclen - 1 - i]; - - /* - alt_address(packet, packet); - - for(i = 0; i < maclen; i++) - address[i + 5] = packet[maclen - 1 - i]; - */ - - //memcpy(address, packet, maclen); - //hexlify(packet, packetsize, printit); - found = true; - } - } - - return found; -} - -uint8_t nrf24_find_channel( - FuriHalSpiBusHandle* handle, - uint8_t* srcmac, - uint8_t* dstmac, - uint8_t maclen, - uint8_t rate, - uint8_t min_channel, - uint8_t max_channel, - bool autoinit) { - uint8_t ping_packet[] = {0x0f, 0x0f, 0x0f, 0x0f}; // this can be anything, we just need an ack - uint8_t ch = max_channel + 1; // means fail - nrf24_configure(handle, rate, srcmac, dstmac, maclen, 2, false, false); - for(ch = min_channel; ch <= max_channel + 1; ch++) { - nrf24_write_reg(handle, REG_RF_CH, ch); - if(nrf24_txpacket(handle, ping_packet, 4, true)) break; - } - - if(autoinit) { - FURI_LOG_D("nrf24", "initializing radio for channel %d", ch); - nrf24_configure(handle, rate, srcmac, dstmac, maclen, ch, false, false); - return ch; - } - - return ch; -} - -bool nrf24_check_connected(FuriHalSpiBusHandle* handle) { - uint8_t status = nrf24_status(handle); - - if(status != 0x00) { - return true; - } else { - return false; - } -} diff --git a/applications/external/nrf24sniff/lib/nrf24/nrf24.h b/applications/external/nrf24sniff/lib/nrf24/nrf24.h deleted file mode 100644 index de9212af2..000000000 --- a/applications/external/nrf24sniff/lib/nrf24/nrf24.h +++ /dev/null @@ -1,376 +0,0 @@ -#pragma once -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define R_REGISTER 0x00 -#define W_REGISTER 0x20 -#define REGISTER_MASK 0x1F -#define ACTIVATE 0x50 -#define R_RX_PL_WID 0x60 -#define R_RX_PAYLOAD 0x61 -#define W_TX_PAYLOAD 0xA0 -#define W_TX_PAYLOAD_NOACK 0xB0 -#define W_ACK_PAYLOAD 0xA8 -#define FLUSH_TX 0xE1 -#define FLUSH_RX 0xE2 -#define REUSE_TX_PL 0xE3 -#define RF24_NOP 0xFF - -#define REG_CONFIG 0x00 -#define REG_EN_AA 0x01 -#define REG_EN_RXADDR 0x02 -#define REG_SETUP_AW 0x03 -#define REG_SETUP_RETR 0x04 -#define REG_DYNPD 0x1C -#define REG_FEATURE 0x1D -#define REG_RF_SETUP 0x06 -#define REG_STATUS 0x07 -#define REG_RX_ADDR_P0 0x0A -#define REG_RF_CH 0x05 -#define REG_TX_ADDR 0x10 - -#define RX_PW_P0 0x11 -#define TX_DS 0x20 -#define MAX_RT 0x10 - -#define nrf24_TIMEOUT 500 -#define nrf24_CE_PIN &gpio_ext_pb2 -#define nrf24_HANDLE \ - (xtreme_settings.spi_nrf24_handle == SpiDefault ? &furi_hal_spi_bus_handle_external : \ - &furi_hal_spi_bus_handle_external_extra) - -/* Low level API */ - -/** Write device register - * - * @param handle - pointer to FuriHalSpiHandle - * @param reg - register - * @param data - data to write - * - * @return device status - */ -uint8_t nrf24_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data); - -/** Write buffer to device register - * - * @param handle - pointer to FuriHalSpiHandle - * @param reg - register - * @param data - data to write - * @param size - size of data to write - * - * @return device status - */ -uint8_t nrf24_write_buf_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size); - -/** Read device register - * - * @param handle - pointer to FuriHalSpiHandle - * @param reg - register - * @param[out] data - pointer to data - * - * @return device status - */ -uint8_t nrf24_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data, uint8_t size); - -/** Power up the radio for operation - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_power_up(FuriHalSpiBusHandle* handle); - -/** Power down the radio - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_set_idle(FuriHalSpiBusHandle* handle); - -/** Sets the radio to RX mode - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_set_rx_mode(FuriHalSpiBusHandle* handle); - -/** Sets the radio to TX mode - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_set_tx_mode(FuriHalSpiBusHandle* handle); - -/*=============================================================================================================*/ - -/* High level API */ - -/** Must call this before using any other nrf24 API - * - */ -void nrf24_init(); - -/** Must call this when we end using nrf24 device - * - */ -void nrf24_deinit(); - -/** Send flush rx command - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_flush_rx(FuriHalSpiBusHandle* handle); - -/** Send flush tx command - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return device status - */ -uint8_t nrf24_flush_tx(FuriHalSpiBusHandle* handle); - -/** Gets the RX packet length in data pipe 0 - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return packet length in data pipe 0 - */ -uint8_t nrf24_get_packetlen(FuriHalSpiBusHandle* handle); - -/** Sets the RX packet length in data pipe 0 - * - * @param handle - pointer to FuriHalSpiHandle - * @param len - length to set - * - * @return device status - */ -uint8_t nrf24_set_packetlen(FuriHalSpiBusHandle* handle, uint8_t len); - -/** Gets configured length of MAC address - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return MAC address length - */ -uint8_t nrf24_get_maclen(FuriHalSpiBusHandle* handle); - -/** Sets configured length of MAC address - * - * @param handle - pointer to FuriHalSpiHandle - * @param maclen - length to set MAC address to, must be greater than 1 and less than 6 - * - * @return MAC address length - */ -uint8_t nrf24_set_maclen(FuriHalSpiBusHandle* handle, uint8_t maclen); - -/** Gets the current status flags from the STATUS register - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return status flags - */ -uint8_t nrf24_status(FuriHalSpiBusHandle* handle); - -/** Gets the current transfer rate - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return transfer rate in bps - */ -uint32_t nrf24_get_rate(FuriHalSpiBusHandle* handle); - -/** Sets the transfer rate - * - * @param handle - pointer to FuriHalSpiHandle - * @param rate - the transfer rate in bps - * - * @return device status - */ -uint8_t nrf24_set_rate(FuriHalSpiBusHandle* handle, uint32_t rate); - -/** Gets the current channel - * In nrf24, the channel number is multiplied times 1MHz and added to 2400MHz to get the frequency - * - * @param handle - pointer to FuriHalSpiHandle - * - * @return channel - */ -uint8_t nrf24_get_chan(FuriHalSpiBusHandle* handle); - -/** Sets the channel - * - * @param handle - pointer to FuriHalSpiHandle - * @param frequency - the frequency in hertz - * - * @return device status - */ -uint8_t nrf24_set_chan(FuriHalSpiBusHandle* handle, uint8_t chan); - -/** Gets the source mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param[out] mac - the source mac address - * - * @return device status - */ -uint8_t nrf24_get_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac); - -/** Sets the source mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param mac - the mac address to set - * @param size - the size of the mac address (2 to 5) - * - * @return device status - */ -uint8_t nrf24_set_src_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size); - -/** Gets the dest mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param[out] mac - the source mac address - * - * @return device status - */ -uint8_t nrf24_get_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac); - -/** Sets the dest mac address - * - * @param handle - pointer to FuriHalSpiHandle - * @param mac - the mac address to set - * @param size - the size of the mac address (2 to 5) - * - * @return device status - */ -uint8_t nrf24_set_dst_mac(FuriHalSpiBusHandle* handle, uint8_t* mac, uint8_t size); - -/** Reads RX packet - * - * @param handle - pointer to FuriHalSpiHandle - * @param[out] packet - the packet contents - * @param[out] packetsize - size of the received packet - * @param full - boolean set to true, packet length is determined by RX_PW_P0 register, false it is determined by dynamic payload length command - * - * @return device status - */ -uint8_t - nrf24_rxpacket(FuriHalSpiBusHandle* handle, uint8_t* packet, uint8_t* packetsize, bool full); - -/** Sends TX packet - * - * @param handle - pointer to FuriHalSpiHandle - * @param packet - the packet contents - * @param size - packet size - * @param ack - boolean to determine whether an ACK is required for the packet or not - * - * @return device status - */ -uint8_t nrf24_txpacket(FuriHalSpiBusHandle* handle, uint8_t* payload, uint8_t size, bool ack); - -/** Configure the radio - * This is not comprehensive, but covers a lot of the common configuration options that may be changed - * @param handle - pointer to FuriHalSpiHandle - * @param rate - transfer rate in Mbps (1 or 2) - * @param srcmac - source mac address - * @param dstmac - destination mac address - * @param maclen - length of mac address - * @param channel - channel to tune to - * @param noack - if true, disable auto-acknowledge - * @param disable_aa - if true, disable ShockBurst - * - */ -void nrf24_configure( - FuriHalSpiBusHandle* handle, - uint8_t rate, - uint8_t* srcmac, - uint8_t* dstmac, - uint8_t maclen, - uint8_t channel, - bool noack, - bool disable_aa); - -/** Configures the radio for "promiscuous mode" and primes it for rx - * This is not an actual mode of the nrf24, but this function exploits a few bugs in the chip that allows it to act as if it were. - * See http://travisgoodspeed.blogspot.com/2011/02/promiscuity-is-nrf24l01s-duty.html for details. - * @param handle - pointer to FuriHalSpiHandle - * @param channel - channel to tune to - * @param rate - transfer rate in Mbps (1 or 2) - */ -void nrf24_init_promisc_mode(FuriHalSpiBusHandle* handle, uint8_t channel, uint8_t rate); - -/** Listens for a packet and returns first possible address sniffed - * Call this only after calling nrf24_init_promisc_mode - * @param handle - pointer to FuriHalSpiHandle - * @param maclen - length of target mac address - * @param[out] addresses - sniffed address - * - * @return success - */ -bool nrf24_sniff_address(FuriHalSpiBusHandle* handle, uint8_t maclen, uint8_t* address); - -/** Sends ping packet on each channel for designated tx mac looking for ack - * - * @param handle - pointer to FuriHalSpiHandle - * @param srcmac - source address - * @param dstmac - destination address - * @param maclen - length of address - * @param rate - transfer rate in Mbps (1 or 2) - * @param min_channel - channel to start with - * @param max_channel - channel to end at - * @param autoinit - if true, automatically configure radio for this channel - * - * @return channel that the address is listening on, if this value is above the max_channel param, it failed - */ -uint8_t nrf24_find_channel( - FuriHalSpiBusHandle* handle, - uint8_t* srcmac, - uint8_t* dstmac, - uint8_t maclen, - uint8_t rate, - uint8_t min_channel, - uint8_t max_channel, - bool autoinit); - -/** Converts 64 bit value into uint8_t array - * @param val - 64-bit integer - * @param[out] out - bytes out - * @param bigendian - if true, convert as big endian, otherwise little endian - */ -void int64_to_bytes(uint64_t val, uint8_t* out, bool bigendian); - -/** Converts 32 bit value into uint8_t array - * @param val - 32-bit integer - * @param[out] out - bytes out - * @param bigendian - if true, convert as big endian, otherwise little endian - */ -void int32_to_bytes(uint32_t val, uint8_t* out, bool bigendian); - -/** Converts uint8_t array into 32 bit value - * @param bytes - uint8_t array - * @param bigendian - if true, convert as big endian, otherwise little endian - * - * @return 32-bit value - */ -uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian); - -/** Check if the nrf24 is connected - * @param handle - pointer to FuriHalSpiHandle - * - * @return true if connected, otherwise false -*/ -bool nrf24_check_connected(FuriHalSpiBusHandle* handle); - -#ifdef __cplusplus -} -#endif diff --git a/applications/external/nrf24sniff/nrfsniff.c b/applications/external/nrf24sniff/nrfsniff.c deleted file mode 100644 index fca394180..000000000 --- a/applications/external/nrf24sniff/nrfsniff.c +++ /dev/null @@ -1,473 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include - -#define LOGITECH_MAX_CHANNEL 85 -#define COUNT_THRESHOLD 2 -#define DEFAULT_SAMPLE_TIME 4000 -#define MAX_ADDRS 100 -#define MAX_CONFIRMED 32 - -#define NRFSNIFF_APP_PATH_FOLDER STORAGE_APP_DATA_PATH_PREFIX -#define NRFSNIFF_APP_FILENAME "addresses.txt" -#define TAG "nrfsniff" - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} PluginEvent; - -typedef struct { - FuriMutex* mutex; -} PluginState; - -char rate_text_fmt[] = "Transfer rate: %dMbps"; -char sample_text_fmt[] = "Sample Time: %d ms"; -char channel_text_fmt[] = "Channel: %d Sniffing: %s"; -char preamble_text_fmt[] = "Preamble: %02X"; -char sniff_text_fmt[] = "Found: %d Unique: %u"; -char addresses_header_text[] = "Address,rate"; -char sniffed_address_fmt[] = "%s,%d"; -char rate_text[46]; -char channel_text[38]; -char sample_text[32]; -char preamble_text[14]; -char sniff_text[38]; -char sniffed_address[14]; - -uint8_t target_channel = 0; -uint32_t found_count = 0; -uint32_t unique_saved_count = 0; -uint32_t sample_time = DEFAULT_SAMPLE_TIME; -uint8_t target_rate = 8; // rate can be either 8 (2Mbps) or 0 (1Mbps) -uint8_t target_preamble[] = {0xAA, 0x00}; -uint8_t sniffing_state = false; -char top_address[12]; - -uint8_t candidates[MAX_ADDRS][5] = {0}; // last 100 sniffed addresses -uint32_t counts[MAX_ADDRS]; -uint8_t confirmed[MAX_CONFIRMED][5] = {0}; // first 32 confirmed addresses -uint8_t confirmed_idx = 0; -uint32_t total_candidates = 0; -uint32_t candidate_idx = 0; - -static int get_addr_index(uint8_t* addr, uint8_t addr_size) { - for(uint32_t i = 0; i < total_candidates; i++) { - uint8_t* arr_item = candidates[i]; - if(!memcmp(arr_item, addr, addr_size)) return i; - } - - return -1; -} - -static int get_highest_idx() { - uint32_t highest = 0; - int highest_idx = 0; - for(uint32_t i = 0; i < total_candidates; i++) { - if(counts[i] > highest) { - highest = counts[i]; - highest_idx = i; - } - } - - return highest_idx; -} - -// if array is full, start over from beginning -static void insert_addr(uint8_t* addr, uint8_t addr_size) { - if(candidate_idx >= MAX_ADDRS) candidate_idx = 0; - - memcpy(candidates[candidate_idx], addr, addr_size); - counts[candidate_idx] = 1; - if(total_candidates < MAX_ADDRS) total_candidates++; - candidate_idx++; -} - -static void render_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - const PluginState* plugin_state = ctx; - furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); - - uint8_t rate = 2; - char sniffing[] = "Yes"; - - // border around the edge of the screen - canvas_draw_frame(canvas, 0, 0, 128, 64); - canvas_set_font(canvas, FontSecondary); - - if(target_rate == 0) rate = 1; - - if(!sniffing_state) strcpy(sniffing, "No"); - - snprintf(rate_text, sizeof(rate_text), rate_text_fmt, (int)rate); - snprintf(channel_text, sizeof(channel_text), channel_text_fmt, (int)target_channel, sniffing); - snprintf(sample_text, sizeof(sample_text), sample_text_fmt, (int)sample_time); - //snprintf(preamble_text, sizeof(preamble_text), preamble_text_fmt, target_preamble[0]); - snprintf(sniff_text, sizeof(sniff_text), sniff_text_fmt, found_count, unique_saved_count); - snprintf( - sniffed_address, sizeof(sniffed_address), sniffed_address_fmt, top_address, (int)rate); - canvas_draw_str_aligned(canvas, 10, 10, AlignLeft, AlignBottom, rate_text); - canvas_draw_str_aligned(canvas, 10, 20, AlignLeft, AlignBottom, sample_text); - canvas_draw_str_aligned(canvas, 10, 30, AlignLeft, AlignBottom, channel_text); - //canvas_draw_str_aligned(canvas, 10, 30, AlignLeft, AlignBottom, preamble_text); - canvas_draw_str_aligned(canvas, 10, 40, AlignLeft, AlignBottom, sniff_text); - canvas_draw_str_aligned(canvas, 30, 50, AlignLeft, AlignBottom, addresses_header_text); - canvas_draw_str_aligned(canvas, 30, 60, AlignLeft, AlignBottom, sniffed_address); - - furi_mutex_release(plugin_state->mutex); -} - -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void hexlify(uint8_t* in, uint8_t size, char* out) { - memset(out, 0, size * 2); - for(int i = 0; i < size; i++) - snprintf(out + strlen(out), sizeof(out + strlen(out)), "%02X", in[i]); -} - -static bool save_addr_to_file( - Storage* storage, - uint8_t* data, - uint8_t size, - NotificationApp* notification) { - size_t file_size = 0; - uint8_t linesize = 0; - char filepath[42] = {0}; - char addrline[14] = {0}; - char ending[4]; - uint8_t* file_contents; - uint8_t rate = 1; - Stream* stream = file_stream_alloc(storage); - - if(target_rate == 8) rate = 2; - snprintf(ending, sizeof(ending), ",%d\n", rate); - hexlify(data, size, addrline); - strcat(addrline, ending); - linesize = strlen(addrline); - strcpy(filepath, NRFSNIFF_APP_PATH_FOLDER); - strcat(filepath, "/"); - strcat(filepath, NRFSNIFF_APP_FILENAME); - stream_seek(stream, 0, StreamOffsetFromStart); - - // check if address already exists in file - if(file_stream_open(stream, filepath, FSAM_READ_WRITE, FSOM_OPEN_APPEND)) { - bool found = false; - file_size = stream_size(stream); - stream_seek(stream, 0, StreamOffsetFromStart); - if(file_size > 0) { - file_contents = malloc(file_size + 1); - memset(file_contents, 0, file_size + 1); - if(stream_read(stream, file_contents, file_size) > 0) { - char* line = strtok((char*)file_contents, "\n"); - - while(line != NULL) { - if(!memcmp(line, addrline, 12)) { - found = true; - break; - } - line = strtok(NULL, "\n"); - } - } - free(file_contents); - } - - if(found) { - FURI_LOG_I(TAG, "Address exists in file. Ending save process."); - stream_free(stream); - return false; - } else { - if(stream_write(stream, (uint8_t*)addrline, linesize) != linesize) { - FURI_LOG_I(TAG, "Failed to write bytes to file stream."); - stream_free(stream); - return false; - } else { - FURI_LOG_I(TAG, "Found a new address: %s", addrline); - FURI_LOG_I(TAG, "Save successful!"); - - notification_message(notification, &sequence_success); - - stream_free(stream); - unique_saved_count++; - return true; - } - } - } else { - FURI_LOG_I(TAG, "Cannot open file \"%s\"", filepath); - stream_free(stream); - return false; - } -} - -void alt_address(uint8_t* addr, uint8_t* altaddr) { - uint8_t macmess_hi_b[4]; - uint32_t macmess_hi; - uint8_t macmess_lo; - uint8_t preserved; - uint8_t tmpaddr[5]; - - // swap bytes - for(int i = 0; i < 5; i++) tmpaddr[i] = addr[4 - i]; - - // get address into 32-bit and 8-bit variables - memcpy(macmess_hi_b, tmpaddr, 4); - macmess_lo = tmpaddr[4]; - - macmess_hi = bytes_to_int32(macmess_hi_b, true); - - //preserve lowest bit from hi to shift to low - preserved = macmess_hi & 1; - macmess_hi >>= 1; - macmess_lo >>= 1; - macmess_lo = (preserved << 7) | macmess_lo; - int32_to_bytes(macmess_hi, macmess_hi_b, true); - memcpy(tmpaddr, macmess_hi_b, 4); - tmpaddr[4] = macmess_lo; - - // swap bytes back - for(int i = 0; i < 5; i++) altaddr[i] = tmpaddr[4 - i]; -} - -static bool previously_confirmed(uint8_t* addr) { - bool found = false; - for(int i = 0; i < MAX_CONFIRMED; i++) { - if(!memcmp(confirmed[i], addr, 5)) { - found = true; - break; - } - } - - return found; -} - -static void wrap_up(Storage* storage, NotificationApp* notification) { - uint8_t ch; - uint8_t addr[5]; - uint8_t altaddr[5]; - char trying[12]; - int idx; - uint8_t rate = 0; - if(target_rate == 8) rate = 2; - - nrf24_set_idle(nrf24_HANDLE); - - while(true) { - idx = get_highest_idx(); - if(counts[idx] < COUNT_THRESHOLD) break; - - counts[idx] = 0; - memcpy(addr, candidates[idx], 5); - hexlify(addr, 5, trying); - FURI_LOG_I(TAG, "trying address %s", trying); - ch = nrf24_find_channel(nrf24_HANDLE, addr, addr, 5, rate, 2, LOGITECH_MAX_CHANNEL, false); - FURI_LOG_I(TAG, "find_channel returned %d", (int)ch); - if(ch > LOGITECH_MAX_CHANNEL) { - alt_address(addr, altaddr); - hexlify(altaddr, 5, trying); - FURI_LOG_I(TAG, "trying alternate address %s", trying); - ch = nrf24_find_channel( - nrf24_HANDLE, altaddr, altaddr, 5, rate, 2, LOGITECH_MAX_CHANNEL, false); - FURI_LOG_I(TAG, "find_channel returned %d", (int)ch); - memcpy(addr, altaddr, 5); - } - - if(ch <= LOGITECH_MAX_CHANNEL) { - hexlify(addr, 5, top_address); - found_count++; - save_addr_to_file(storage, addr, 5, notification); - if(confirmed_idx < MAX_CONFIRMED) memcpy(confirmed[confirmed_idx++], addr, 5); - break; - } - } -} - -static void clear_cache() { - found_count = 0; - unique_saved_count = 0; - confirmed_idx = 0; - candidate_idx = 0; - target_channel = 2; - total_candidates = 0; - memset(candidates, 0, sizeof(candidates)); - memset(counts, 0, sizeof(counts)); - memset(confirmed, 0, sizeof(confirmed)); -} - -static void start_sniffing() { - nrf24_init_promisc_mode(nrf24_HANDLE, target_channel, target_rate); -} - -int32_t nrfsniff_app(void* p) { - UNUSED(p); - uint8_t address[5] = {0}; - uint32_t start = 0; - hexlify(address, 5, top_address); - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - PluginState* plugin_state = malloc(sizeof(PluginState)); - plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!plugin_state->mutex) { - furi_message_queue_free(event_queue); - FURI_LOG_E(TAG, "cannot create mutex\r\n"); - free(plugin_state); - return 255; - } - - uint8_t attempts = 0; - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - furi_delay_ms(10); - } - - nrf24_init(); - - // Set system callbacks - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, plugin_state); - view_port_input_callback_set(view_port, input_callback, event_queue); - - // Open GUI and register view_port - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - - Storage* storage = furi_record_open(RECORD_STORAGE); - storage_common_migrate(storage, EXT_PATH("nrfsniff"), NRFSNIFF_APP_PATH_FOLDER); - storage_common_mkdir(storage, NRFSNIFF_APP_PATH_FOLDER); - - PluginEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); - - if(event_status == FuriStatusOk) { - // press events - if(event.type == EventTypeKey) { - if(event.input.type == InputTypePress || - (event.input.type == InputTypeLong && event.input.key == InputKeyBack)) { - switch(event.input.key) { - case InputKeyUp: - // toggle rate 1/2Mbps - if(!sniffing_state) { - if(target_rate == 0) - target_rate = 8; - else - target_rate = 0; - } - break; - case InputKeyDown: - // toggle preamble - if(!sniffing_state) { - if(target_preamble[0] == 0x55) - target_preamble[0] = 0xAA; - else - target_preamble[0] = 0x55; - - nrf24_set_src_mac(nrf24_HANDLE, target_preamble, 2); - } - break; - case InputKeyRight: - // increment channel - //if(!sniffing_state && target_channel <= LOGITECH_MAX_CHANNEL) - // target_channel++; - sample_time += 500; - break; - case InputKeyLeft: - // decrement channel - //if(!sniffing_state && target_channel > 0) target_channel--; - if(sample_time > 500) sample_time -= 500; - break; - case InputKeyOk: - // toggle sniffing - if(nrf24_check_connected(nrf24_HANDLE)) { - sniffing_state = !sniffing_state; - if(sniffing_state) { - clear_cache(); - start_sniffing(); - start = furi_get_tick(); - } else { - wrap_up(storage, notification); - } - } else { - notification_message(notification, &sequence_error); - } - - break; - case InputKeyBack: - processing = false; - break; - default: - break; - } - } - } - } - - if(sniffing_state) { - if(nrf24_sniff_address(nrf24_HANDLE, 5, address)) { - int idx; - uint8_t* top_addr; - if(!previously_confirmed(address)) { - idx = get_addr_index(address, 5); - if(idx == -1) - insert_addr(address, 5); - else - counts[idx]++; - - top_addr = candidates[get_highest_idx()]; - hexlify(top_addr, 5, top_address); - } - } - - if(furi_get_tick() - start >= sample_time) { - target_channel++; - if(target_channel > LOGITECH_MAX_CHANNEL) target_channel = 2; - { - wrap_up(storage, notification); - start_sniffing(); - } - - start = furi_get_tick(); - } - } - - view_port_update(view_port); - furi_mutex_release(plugin_state->mutex); - } - - clear_cache(); - sample_time = DEFAULT_SAMPLE_TIME; - target_rate = 8; // rate can be either 8 (2Mbps) or 0 (1Mbps) - sniffing_state = false; - nrf24_deinit(); - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_NOTIFICATION); - furi_record_close(RECORD_STORAGE); - view_port_free(view_port); - furi_message_queue_free(event_queue); - furi_mutex_free(plugin_state->mutex); - free(plugin_state); - - if(furi_hal_power_is_otg_enabled()) { - furi_hal_power_disable_otg(); - } - - return 0; -} diff --git a/applications/external/nrf24sniff/nrfsniff_10px.png b/applications/external/nrf24sniff/nrfsniff_10px.png deleted file mode 100644 index 348b35eca..000000000 Binary files a/applications/external/nrf24sniff/nrfsniff_10px.png and /dev/null differ diff --git a/applications/external/ocarina/application.fam b/applications/external/ocarina/application.fam deleted file mode 100644 index 572aa1679..000000000 --- a/applications/external/ocarina/application.fam +++ /dev/null @@ -1,16 +0,0 @@ -App( - appid="ocarina", - name="Ocarina", - apptype=FlipperAppType.EXTERNAL, - entry_point="ocarina_app", - cdefines=["APP_OCARINA"], - requires=["gui"], - stack_size=1 * 1024, - fap_icon="music_10px.png", - fap_category="Media", - fap_icon_assets="icons", - fap_author="@invalidna-me", - fap_weburl="https://github.com/invalidna-me/flipperzero-ocarina", - fap_version="1.0", - fap_description="A basic Ocarina (of Time), Controls are the same as the N64 version of the Ocarina of Time", -) diff --git a/applications/external/ocarina/music_10px.png b/applications/external/ocarina/music_10px.png deleted file mode 100644 index d41eb0db8..000000000 Binary files a/applications/external/ocarina/music_10px.png and /dev/null differ diff --git a/applications/external/ocarina/ocarina.c b/applications/external/ocarina/ocarina.c deleted file mode 100644 index 7fdfce74c..000000000 --- a/applications/external/ocarina/ocarina.c +++ /dev/null @@ -1,134 +0,0 @@ -#include -#include -#include -#include -#include - -#define NOTE_UP 587.33f -#define NOTE_LEFT 493.88f -#define NOTE_RIGHT 440.00f -#define NOTE_DOWN 349.23 -#define NOTE_OK 293.66f - -typedef struct { - FuriMutex* model_mutex; - - FuriMessageQueue* event_queue; - - ViewPort* view_port; - Gui* gui; -} Ocarina; - -void draw_callback(Canvas* canvas, void* ctx) { - Ocarina* ocarina = ctx; - furi_check(furi_mutex_acquire(ocarina->model_mutex, FuriWaitForever) == FuriStatusOk); - - //canvas_draw_box(canvas, ocarina->model->x, ocarina->model->y, 4, 4); - canvas_draw_frame(canvas, 0, 0, 128, 64); - canvas_draw_str(canvas, 50, 10, "Ocarina"); - canvas_draw_str(canvas, 30, 20, "OK button for A"); - - furi_mutex_release(ocarina->model_mutex); -} - -void input_callback(InputEvent* input, void* ctx) { - Ocarina* ocarina = ctx; - // Puts input onto event queue with priority 0, and waits until completion. - furi_message_queue_put(ocarina->event_queue, input, FuriWaitForever); -} - -Ocarina* ocarina_alloc() { - Ocarina* instance = malloc(sizeof(Ocarina)); - - instance->model_mutex = furi_mutex_alloc(FuriMutexTypeNormal); - - instance->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); - - instance->view_port = view_port_alloc(); - view_port_draw_callback_set(instance->view_port, draw_callback, instance); - view_port_input_callback_set(instance->view_port, input_callback, instance); - - instance->gui = furi_record_open("gui"); - gui_add_view_port(instance->gui, instance->view_port, GuiLayerFullscreen); - - return instance; -} - -void ocarina_free(Ocarina* instance) { - view_port_enabled_set(instance->view_port, false); // Disabsles our ViewPort - gui_remove_view_port(instance->gui, instance->view_port); // Removes our ViewPort from the Gui - furi_record_close("gui"); // Closes the gui record - view_port_free(instance->view_port); // Frees memory allocated by view_port_alloc - furi_message_queue_free(instance->event_queue); - - furi_mutex_free(instance->model_mutex); - - if(furi_hal_speaker_is_mine()) { - furi_hal_speaker_stop(); - furi_hal_speaker_release(); - } - - free(instance); -} - -int32_t ocarina_app(void* p) { - UNUSED(p); - - Ocarina* ocarina = ocarina_alloc(); - - InputEvent event; - for(bool processing = true; processing;) { - // Pops a message off the queue and stores it in `event`. - // No message priority denoted by NULL, and 100 ticks of timeout. - FuriStatus status = furi_message_queue_get(ocarina->event_queue, &event, 100); - furi_check(furi_mutex_acquire(ocarina->model_mutex, FuriWaitForever) == FuriStatusOk); - - float volume = 1.0f; - if(status == FuriStatusOk) { - if(event.type == InputTypePress) { - switch(event.key) { - case InputKeyUp: - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { - furi_hal_speaker_start(NOTE_UP, volume); - } - break; - case InputKeyDown: - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { - furi_hal_speaker_start(NOTE_DOWN, volume); - } - break; - case InputKeyLeft: - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { - furi_hal_speaker_start(NOTE_LEFT, volume); - } - break; - case InputKeyRight: - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { - furi_hal_speaker_start(NOTE_RIGHT, volume); - } - break; - case InputKeyOk: - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { - furi_hal_speaker_start(NOTE_OK, volume); - } - break; - case InputKeyBack: - processing = false; - break; - default: - break; - } - } else if(event.type == InputTypeRelease) { - if(furi_hal_speaker_is_mine()) { - furi_hal_speaker_stop(); - furi_hal_speaker_release(); - } - } - } - - furi_mutex_release(ocarina->model_mutex); - view_port_update(ocarina->view_port); // signals our draw callback - } - ocarina_free(ocarina); - return 0; -} diff --git a/applications/external/orgasmotron/application.fam b/applications/external/orgasmotron/application.fam deleted file mode 100644 index f58a4a734..000000000 --- a/applications/external/orgasmotron/application.fam +++ /dev/null @@ -1,11 +0,0 @@ -App( - appid="orgasmotron", - name="Orgasmotron", - apptype=FlipperAppType.EXTERNAL, - entry_point="orgasmotron_app", - cdefines=["ORGASMOTRON"], - requires=["gui"], - stack_size=1 * 1024, - fap_icon="orgasmotron_10px.png", - fap_category="Tools", -) diff --git a/applications/external/orgasmotron/orgasmotron.c b/applications/external/orgasmotron/orgasmotron.c deleted file mode 100644 index fd66d7b04..000000000 --- a/applications/external/orgasmotron/orgasmotron.c +++ /dev/null @@ -1,163 +0,0 @@ -#include -#include - -#include -#include -#include - -typedef struct { - FuriMutex* mutex; - int mode; -} PluginState; - -void vibro_test_draw_callback(Canvas* canvas, void* ctx) { - UNUSED(ctx); - canvas_clear(canvas); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 2, 10, "Vibro Modes"); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 2, 22, "UP: Pulsed"); - canvas_draw_str(canvas, 2, 34, "LEFT: strong / RIGHT: Soft"); - canvas_draw_str(canvas, 2, 46, "DOWN: Pleasure combo"); - canvas_draw_str(canvas, 2, 58, "OK: Pause"); -} - -void vibro_test_input_callback(InputEvent* input_event, void* ctx) { - furi_assert(ctx); - FuriMessageQueue* event_queue = ctx; - furi_message_queue_put(event_queue, input_event, FuriWaitForever); -} - -void delay(int milliseconds) { - furi_thread_flags_wait(0, FuriFlagWaitAny, milliseconds); -} - -int32_t orgasmotron_app(void* p) { - UNUSED(p); - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); - - PluginState* plugin_state = malloc(sizeof(PluginState)); - plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!plugin_state->mutex) { - FURI_LOG_E("Orgasmatron", "cannot create mutex\r\n"); - free(plugin_state); - return 255; - } - - // Configure view port - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, vibro_test_draw_callback, NULL); - view_port_input_callback_set(view_port, vibro_test_input_callback, event_queue); - - // Register view port in GUI - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - - InputEvent event; - bool processing = true; - size_t i = 0; - while(processing) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 50); - furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); - if(event_status == FuriStatusOk) { - if(event.key == InputKeyBack && event.type == InputTypeShort) { - //Exit Application - plugin_state->mode = 0; - processing = false; - } - if(event.key == InputKeyOk && - (event.type == InputTypePress || event.type == InputTypeRelease)) { - plugin_state->mode = 0; - } - if(event.key == InputKeyLeft && - (event.type == InputTypePress || event.type == InputTypeRelease)) { - notification_message(notification, &sequence_set_green_255); - plugin_state->mode = 1; - } - if(event.key == InputKeyRight && - (event.type == InputTypePress || event.type == InputTypeRelease)) { - notification_message(notification, &sequence_set_green_255); - plugin_state->mode = 3; - } - if(event.key == InputKeyUp && - (event.type == InputTypePress || event.type == InputTypeRelease)) { - notification_message(notification, &sequence_set_green_255); - plugin_state->mode = 2; - } - if(event.key == InputKeyDown && - (event.type == InputTypePress || event.type == InputTypeRelease)) { - notification_message(notification, &sequence_set_green_255); - plugin_state->mode = 4; - } - i = 0; - } - - if(plugin_state->mode == 0) { - //Stop Vibration - if(i == 0) { - notification_message(notification, &sequence_reset_vibro); - notification_message(notification, &sequence_reset_green); - i++; - } - } else if(plugin_state->mode == 1) { - //Full power - if(i == 0) { - notification_message(notification, &sequence_set_vibro_on); - i++; - } - } else if(plugin_state->mode == 2) { - //Pulsed Vibration - i++; - if(i == 1) { - notification_message(notification, &sequence_set_vibro_on); - } - if(i == 3) { - notification_message(notification, &sequence_reset_vibro); - } - if(i == 4) { - i = 0; - } - } else if(plugin_state->mode == 3) { - //Soft power - i++; - if(i == 1) { - notification_message(notification, &sequence_set_vibro_on); - } - if(i == 2) { - notification_message(notification, &sequence_reset_vibro); - i = 0; - } - } else if(plugin_state->mode == 4) { - //Special Sequence - i++; - if(i < 23) { - if(i % 2) { - notification_message(notification, &sequence_set_vibro_on); - } else { - notification_message(notification, &sequence_reset_vibro); - } - } else if(i < 40) { - if(i == 24 || i == 33) { - notification_message(notification, &sequence_set_vibro_on); - } else if(i == 32) { - notification_message(notification, &sequence_reset_vibro); - } - } else if(i == 41) { - notification_message(notification, &sequence_reset_vibro); - i = 0; - } - } - furi_mutex_release(plugin_state->mutex); - } - gui_remove_view_port(gui, view_port); - view_port_free(view_port); - furi_mutex_free(plugin_state->mutex); - furi_message_queue_free(event_queue); - - furi_record_close(RECORD_NOTIFICATION); - furi_record_close(RECORD_GUI); - - return 0; -} diff --git a/applications/external/orgasmotron/orgasmotron_10px.png b/applications/external/orgasmotron/orgasmotron_10px.png deleted file mode 100644 index b6c93c9f9..000000000 Binary files a/applications/external/orgasmotron/orgasmotron_10px.png and /dev/null differ diff --git a/applications/external/pong/application.fam b/applications/external/pong/application.fam deleted file mode 100644 index 97292e6c5..000000000 --- a/applications/external/pong/application.fam +++ /dev/null @@ -1,17 +0,0 @@ -App( - appid="flipper_pong", - name="Pong", - apptype=FlipperAppType.EXTERNAL, - entry_point="flipper_pong_app", - cdefines=["APP_FLIPPER_PONG"], - requires=[ - "gui", - ], - stack_size=1 * 1024, - fap_icon="pong.png", - fap_category="Games", - fap_author="@nmrr & @SimplyMinimal", - fap_weburl="https://github.com/nmrr/flipperzero-pong", - fap_version="1.1", - fap_description="Simple pong game", -) diff --git a/applications/external/pong/flipper_pong.c b/applications/external/pong/flipper_pong.c deleted file mode 100644 index 55b371ad5..000000000 --- a/applications/external/pong/flipper_pong.c +++ /dev/null @@ -1,293 +0,0 @@ -// CC0 1.0 Universal (CC0 1.0) -// Public Domain Dedication -// https://github.com/nmrr - -#include -#include -#include -#include -#include -#include - -#define SCREEN_SIZE_X 128 -#define SCREEN_SIZE_Y 64 -#define FPS 20 - -#define PAD_SIZE_X 3 -#define PAD_SIZE_Y 8 -#define PLAYER1_PAD_SPEED 4 - -#define PLAYER2_PAD_SPEED 2 -#define BALL_SIZE 4 - -typedef enum { - EventTypeInput, - ClockEventTypeTick, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} EventApp; - -typedef struct Players { - FuriMutex* mutex; - uint8_t player1_X, player1_Y, player2_X, player2_Y; - uint16_t player1_score, player2_score; - uint8_t ball_X, ball_Y, ball_X_speed, ball_Y_speed, ball_X_direction, ball_Y_direction; -} Players; - -static void draw_callback(Canvas* canvas, void* ctx) { - furi_assert(ctx); - Players* playersMutex = ctx; - furi_mutex_acquire(playersMutex->mutex, FuriWaitForever); - - canvas_draw_frame(canvas, 0, 0, 128, 64); - canvas_draw_box( - canvas, playersMutex->player1_X, playersMutex->player1_Y, PAD_SIZE_X, PAD_SIZE_Y); - canvas_draw_box( - canvas, playersMutex->player2_X, playersMutex->player2_Y, PAD_SIZE_X, PAD_SIZE_Y); - canvas_draw_box(canvas, playersMutex->ball_X, playersMutex->ball_Y, BALL_SIZE, BALL_SIZE); - - canvas_set_font(canvas, FontPrimary); - canvas_set_font_direction(canvas, CanvasDirectionBottomToTop); - char buffer[16]; - snprintf( - buffer, - sizeof(buffer), - "%u - %u", - playersMutex->player1_score, - playersMutex->player2_score); - canvas_draw_str_aligned( - canvas, SCREEN_SIZE_X / 2 + 15, SCREEN_SIZE_Y / 2 + 2, AlignCenter, AlignTop, buffer); - - furi_mutex_release(playersMutex->mutex); -} - -static void input_callback(InputEvent* input_event, void* ctx) { - furi_assert(ctx); - FuriMessageQueue* event_queue = ctx; - EventApp event = {.type = EventTypeInput, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void clock_tick(void* ctx) { - furi_assert(ctx); - FuriMessageQueue* queue = ctx; - EventApp event = {.type = ClockEventTypeTick}; - furi_message_queue_put(queue, &event, 0); -} - -bool insidePad(uint8_t x, uint8_t y, uint8_t playerX, uint8_t playerY) { - if(x >= playerX && x <= playerX + PAD_SIZE_X && y >= playerY && y <= playerY + PAD_SIZE_Y) - return true; - return false; -} - -uint8_t changeSpeed() { - uint8_t randomuint8[1]; - while(1) { - furi_hal_random_fill_buf(randomuint8, 1); - randomuint8[0] &= 0b00000011; - if(randomuint8[0] >= 1) break; - } - return randomuint8[0]; -} - -uint8_t changeDirection() { - uint8_t randomuint8[1]; - furi_hal_random_fill_buf(randomuint8, 1); - randomuint8[0] &= 0b1; - return randomuint8[0]; -} - -int32_t flipper_pong_app(void* p) { - UNUSED(p); - EventApp event; - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(EventApp)); - - Players players; - players.player1_X = SCREEN_SIZE_X - PAD_SIZE_X - 1; - players.player1_Y = SCREEN_SIZE_Y / 2 - PAD_SIZE_Y / 2; - players.player1_score = 0; - - players.player2_X = 1; - players.player2_Y = SCREEN_SIZE_Y / 2 - PAD_SIZE_Y / 2; - players.player2_score = 0; - - players.ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2; - players.ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2; - players.ball_X_speed = 1; - players.ball_Y_speed = 1; - players.ball_X_direction = changeDirection(); - players.ball_Y_direction = changeDirection(); - - players.mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!players.mutex) { - furi_message_queue_free(event_queue); - return 255; - } - - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, draw_callback, &players); - view_port_input_callback_set(view_port, input_callback, event_queue); - - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - if(players.ball_X_direction == 0) - notification_message(notification, &sequence_set_only_red_255); - else - notification_message(notification, &sequence_set_only_blue_255); - - FuriTimer* timer = furi_timer_alloc(clock_tick, FuriTimerTypePeriodic, event_queue); - furi_timer_start(timer, 1000 / FPS); - - while(1) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, FuriWaitForever); - furi_mutex_acquire(players.mutex, FuriWaitForever); - - if(event_status == FuriStatusOk) { - if(event.type == EventTypeInput) { - if(event.input.key == InputKeyBack) { - furi_mutex_release(players.mutex); - notification_message(notification, &sequence_set_only_green_255); - break; - } else if(event.input.key == InputKeyUp) { - if(players.player1_Y >= 1 + PLAYER1_PAD_SPEED) - players.player1_Y -= PLAYER1_PAD_SPEED; - else - players.player1_Y = 1; - } else if(event.input.key == InputKeyDown) { - if(players.player1_Y <= SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER1_PAD_SPEED - 1) - players.player1_Y += PLAYER1_PAD_SPEED; - else - players.player1_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1; - } - } else if(event.type == ClockEventTypeTick) { - if(players.ball_X + BALL_SIZE / 2 <= SCREEN_SIZE_X * 0.35 && - players.ball_X_direction == 0) { - if(players.ball_Y + BALL_SIZE / 2 < players.player2_Y + PAD_SIZE_Y / 2) { - if(players.player2_Y >= 1 + PLAYER2_PAD_SPEED) - players.player2_Y -= PLAYER2_PAD_SPEED; - else - players.player2_Y = 1; - } else if(players.ball_Y + BALL_SIZE / 2 > players.player2_Y + PAD_SIZE_Y / 2) { - if(players.player2_Y <= SCREEN_SIZE_Y - PAD_SIZE_Y - PLAYER2_PAD_SPEED - 1) - players.player2_Y += PLAYER2_PAD_SPEED; - else - players.player2_Y = SCREEN_SIZE_Y - PAD_SIZE_Y - 1; - } - } - - uint8_t ball_corner_X[4] = { - players.ball_X, - players.ball_X + BALL_SIZE, - players.ball_X + BALL_SIZE, - players.ball_X}; - uint8_t ball_corner_Y[4] = { - players.ball_Y, - players.ball_Y, - players.ball_Y + BALL_SIZE, - players.ball_Y + BALL_SIZE}; - bool insidePlayer1 = false, insidePlayer2 = false; - - for(int i = 0; i < 4; i++) { - if(insidePad( - ball_corner_X[i], - ball_corner_Y[i], - players.player1_X, - players.player1_Y) == true) { - insidePlayer1 = true; - break; - } - - if(insidePad( - ball_corner_X[i], - ball_corner_Y[i], - players.player2_X, - players.player2_Y) == true) { - insidePlayer2 = true; - break; - } - } - - if(insidePlayer1 == true) { - players.ball_X_direction = 0; - players.ball_X -= players.ball_X_speed; - players.ball_X_speed = changeSpeed(); - players.ball_Y_speed = changeSpeed(); - notification_message(notification, &sequence_set_only_red_255); - } else if(insidePlayer2 == true) { - players.ball_X_direction = 1; - players.ball_X += players.ball_X_speed; - players.ball_X_speed = changeSpeed(); - players.ball_Y_speed = changeSpeed(); - notification_message(notification, &sequence_set_only_blue_255); - } else { - if(players.ball_X_direction == 1) { - if(players.ball_X <= - SCREEN_SIZE_X - BALL_SIZE - 1 - players.ball_X_speed) { - players.ball_X += players.ball_X_speed; - } else { - players.ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2; - players.ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2; - players.ball_X_speed = 1; - players.ball_Y_speed = 1; - players.ball_X_direction = 0; - players.player2_score++; - notification_message(notification, &sequence_set_only_red_255); - } - } else { - if(players.ball_X >= 1 + players.ball_X_speed) { - players.ball_X -= players.ball_X_speed; - } else { - players.ball_X = SCREEN_SIZE_X / 2 - BALL_SIZE / 2; - players.ball_Y = SCREEN_SIZE_Y / 2 - BALL_SIZE / 2; - players.ball_X_speed = 1; - players.ball_Y_speed = 1; - players.ball_X_direction = 1; - players.player1_score++; - notification_message(notification, &sequence_set_only_blue_255); - } - } - } - - if(players.ball_Y_direction == 1) { - if(players.ball_Y <= SCREEN_SIZE_Y - BALL_SIZE - 1 - players.ball_Y_speed) { - players.ball_Y += players.ball_Y_speed; - } else { - players.ball_Y = SCREEN_SIZE_Y - BALL_SIZE - 1; - players.ball_X_speed = changeSpeed(); - players.ball_Y_speed = changeSpeed(); - players.ball_Y_direction = 0; - } - } else { - if(players.ball_Y >= 1 + players.ball_Y_speed) { - players.ball_Y -= players.ball_Y_speed; - } else { - players.ball_Y = 1; - players.ball_X_speed = changeSpeed(); - players.ball_Y_speed = changeSpeed(); - players.ball_Y_direction = 1; - } - } - } - } - - furi_mutex_release(players.mutex); - view_port_update(view_port); - } - - notification_message(notification, &sequence_reset_rgb); - furi_message_queue_free(event_queue); - furi_mutex_free(players.mutex); - gui_remove_view_port(gui, view_port); - view_port_free(view_port); - furi_timer_free(timer); - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_NOTIFICATION); - - return 0; -} \ No newline at end of file diff --git a/applications/external/pong/pong.png b/applications/external/pong/pong.png deleted file mode 100644 index b86745f28..000000000 Binary files a/applications/external/pong/pong.png and /dev/null differ diff --git a/applications/external/sam/application.fam b/applications/external/sam/application.fam deleted file mode 100644 index e123f455b..000000000 --- a/applications/external/sam/application.fam +++ /dev/null @@ -1,52 +0,0 @@ -App( - appid="sam", - name="SAM AYBABTU", - apptype=FlipperAppType.EXTERNAL, - entry_point="sam_app", - requires=[ - "gui", - "dialogs", - ], - stack_size=4 * 1024, - fap_icon="music_10px.png", - fap_category="Media", -) -App( - appid="sam_yes", - name="SAM YES", - apptype=FlipperAppType.EXTERNAL, - entry_point="sam_app_yes", - requires=[ - "gui", - "dialogs", - ], - stack_size=4 * 1024, - fap_icon="music_10px.png", - fap_category="Media", -) -App( - appid="sam_no", - name="SAM NO", - apptype=FlipperAppType.EXTERNAL, - entry_point="sam_app_no", - requires=[ - "gui", - "dialogs", - ], - stack_size=4 * 1024, - fap_icon="music_10px.png", - fap_category="Media", -) -App( - appid="sam_wtf", - name="SAM WTF", - apptype=FlipperAppType.EXTERNAL, - entry_point="sam_app_wtf", - requires=[ - "gui", - "dialogs", - ], - stack_size=4 * 1024, - fap_icon="music_10px.png", - fap_category="Media", -) diff --git a/applications/external/sam/music_10px.png b/applications/external/sam/music_10px.png deleted file mode 100644 index d41eb0db8..000000000 Binary files a/applications/external/sam/music_10px.png and /dev/null differ diff --git a/applications/external/sam/sam_app.cpp b/applications/external/sam/sam_app.cpp deleted file mode 100644 index 81adf3093..000000000 --- a/applications/external/sam/sam_app.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include "stm32_sam.h" -// WOULD BE COOL IF SOMEONE MADE A TEXT ENTRY SCREEN TO HAVE IT READ WHAT IS ENTERED TO TEXT -STM32SAM voice; - -extern "C" int32_t sam_app(void* p) { - UNUSED(p); - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { - voice.begin(); - voice.say( - "All your base are belong to us. You have no chance to survive make your time. ha. ha. ha. GOOD BYE. "); - furi_hal_speaker_release(); - } - return 0; -} - -extern "C" int32_t sam_app_yes(void* p) { - UNUSED(p); - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { - voice.begin(); - voice.say("Yes"); - furi_hal_speaker_release(); - } - return 0; -} - -extern "C" int32_t sam_app_no(void* p) { - UNUSED(p); - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { - voice.begin(); - voice.say("No"); - furi_hal_speaker_release(); - } - return 0; -} - -extern "C" int32_t sam_app_wtf(void* p) { - UNUSED(p); - if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) { - voice.begin(); - voice.say("What The Fuck"); - furi_hal_speaker_release(); - } - return 0; -} diff --git a/applications/external/sam/stm32_sam.cpp b/applications/external/sam/stm32_sam.cpp deleted file mode 100644 index 1ab73a66d..000000000 --- a/applications/external/sam/stm32_sam.cpp +++ /dev/null @@ -1,5704 +0,0 @@ - -#include "stm32_sam.h" -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// All -// -//////////////////////////////////////////////////////////////////////////////////////////// - -char input[256 + 1] = {0}; //tab39445 -//standard sam sound - -unsigned char wait1 = 7; -unsigned char wait2 = 6; - -unsigned char A, X, Y; -unsigned char mem44; -unsigned char mem47; -unsigned char mem49; -unsigned char mem39; -unsigned char mem50; -unsigned char mem51; -unsigned char mem53; -unsigned char mem56; -unsigned char mem59 = 0; - -unsigned char phonemeIndexOutput[60]; //tab47296 -unsigned char stressOutput[60]; //tab47365 -unsigned char phonemeLengthOutput[60]; //tab47416 - -// contains the soundbuffer position -int bufferpos; - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// Sam Tabs -// -//////////////////////////////////////////////////////////////////////////////////////////// - -//tab40672 -const unsigned char stressInputTable[] = {'*', '1', '2', '3', '4', '5', '6', '7', '8'}; - -//tab40682 -const unsigned char signInputTable1[] = { - ' ', '.', '?', ',', '-', 'I', 'I', 'E', 'A', 'A', 'A', 'A', 'U', 'A', 'I', 'E', 'U', - 'O', 'R', 'L', 'W', 'Y', 'W', 'R', 'L', 'W', 'Y', 'M', 'N', 'N', 'D', 'Q', 'S', 'S', - 'F', 'T', '/', '/', 'Z', 'Z', 'V', 'D', 'C', '*', 'J', '*', '*', '*', 'E', 'A', 'O', - 'A', 'O', 'U', 'B', '*', '*', 'D', '*', '*', 'G', '*', '*', 'G', '*', '*', 'P', '*', - '*', 'T', '*', '*', 'K', '*', '*', 'K', '*', '*', 'U', 'U', 'U'}; - -//tab40763 -const unsigned char signInputTable2[] = { - '*', '*', '*', '*', '*', 'Y', 'H', 'H', 'E', 'A', 'H', 'O', 'H', 'X', 'X', 'R', 'X', - 'H', 'X', 'X', 'X', 'X', 'H', '*', '*', '*', '*', '*', '*', 'X', 'X', '*', '*', 'H', - '*', 'H', 'H', 'X', '*', 'H', '*', 'H', 'H', '*', '*', '*', '*', '*', 'Y', 'Y', 'Y', - 'W', 'W', 'W', '*', '*', '*', '*', '*', '*', '*', '*', '*', 'X', '*', '*', '*', '*', - '*', '*', '*', '*', '*', '*', '*', 'X', '*', '*', 'L', 'M', 'N'}; - -//loc_9F8C -const unsigned char flags[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0x84, 0x84, 0xA4, - 0xA4, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x44, 0x44, 0x44, 0x44, 0x44, 0x4C, - 0x4C, 0x4C, 0x48, 0x4C, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0x44, 0x44, 0x44, - 0x48, 0x40, 0x4C, 0x44, 0x00, 0x00, 0xB4, 0xB4, 0xB4, 0x94, 0x94, 0x94, 0x4E, 0x4E, - 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4B, 0x4B, 0x4B, 0x4B, - 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x80, 0xC1, 0xC1 - -}; - -//??? flags overlap flags2 -//loc_9FDA -const unsigned char flags2[] = { - 0x80, 0xC1, 0xC1, 0xC1, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0C, 0x08, 0x04, 0x40, - 0x24, 0x20, 0x20, 0x24, 0x00, 0x00, 0x24, 0x20, 0x20, 0x24, 0x20, 0x20, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - -//tab45616??? -const unsigned char phonemeStressedLengthTable[] = { - 0x00, 0x12, 0x12, 0x12, 8, 0xB, 9, 0xB, 0xE, 0xF, 0xB, 0x10, 0xC, 6, 6, 0xE, - 0xC, 0xE, 0xC, 0xB, 8, 8, 0xB, 0xA, 9, 8, 8, 8, 8, 8, 3, 5, - 2, 2, 2, 2, 2, 2, 6, 6, 8, 6, 6, 2, 9, 4, 2, 1, - 0xE, 0xF, 0xF, 0xF, 0xE, 0xE, 8, 2, 2, 7, 2, 1, 7, 2, 2, 7, - 2, 2, 8, 2, 2, 6, 2, 2, 7, 2, 4, 7, 1, 4, 5, 5}; - -//tab45536??? -const unsigned char phonemeLengthTable[] = { - 0, 0x12, 0x12, 0x12, 8, 8, 8, 8, 8, 0xB, 6, 0xC, 0xA, 5, 5, 0xB, 0xA, 0xA, 0xA, 9, - 8, 7, 9, 7, 6, 8, 6, 7, 7, 7, 2, 5, 2, 2, 2, 2, 2, 2, 6, 6, - 7, 6, 6, 2, 8, 3, 1, 0x1E, 0xD, 0xC, 0xC, 0xC, 0xE, 9, 6, 1, 2, 5, 1, 1, - 6, 1, 2, 6, 1, 2, 8, 2, 2, 4, 2, 2, 6, 1, 4, 6, 1, 4, 0xC7, 0xFF}; - -/* - - Ind | phoneme | flags | - -----|---------|----------| - 0 | * | 00000000 | - 1 | .* | 00000000 | - 2 | ?* | 00000000 | - 3 | ,* | 00000000 | - 4 | -* | 00000000 | - - VOWELS - 5 | IY | 10100100 | - 6 | IH | 10100100 | - 7 | EH | 10100100 | - 8 | AE | 10100100 | - 9 | AA | 10100100 | - 10 | AH | 10100100 | - 11 | AO | 10000100 | - 17 | OH | 10000100 | - 12 | UH | 10000100 | - 16 | UX | 10000100 | - 15 | ER | 10000100 | - 13 | AX | 10100100 | - 14 | IX | 10100100 | - - DIPHTONGS - 48 | EY | 10110100 | - 49 | AY | 10110100 | - 50 | OY | 10110100 | - 51 | AW | 10010100 | - 52 | OW | 10010100 | - 53 | UW | 10010100 | - - - 21 | YX | 10000100 | - 20 | WX | 10000100 | - 18 | RX | 10000100 | - 19 | LX | 10000100 | - 37 | /X | 01000000 | - 30 | DX | 01001000 | - - - 22 | WH | 01000100 | - - - VOICED CONSONANTS - 23 | R* | 01000100 | - 24 | L* | 01000100 | - 25 | W* | 01000100 | - 26 | Y* | 01000100 | - 27 | M* | 01001100 | - 28 | N* | 01001100 | - 29 | NX | 01001100 | - 54 | B* | 01001110 | - 57 | D* | 01001110 | - 60 | G* | 01001110 | - 44 | J* | 01001100 | - 38 | Z* | 01000100 | - 39 | ZH | 01000100 | - 40 | V* | 01000100 | - 41 | DH | 01000100 | - - unvoiced CONSONANTS - 32 | S* | 01000000 | - 33 | SH | 01000000 | - 34 | F* | 01000000 | - 35 | TH | 01000000 | - 66 | P* | 01001011 | - 69 | T* | 01001011 | - 72 | K* | 01001011 | - 42 | CH | 01001000 | - 36 | /H | 01000000 | - - 43 | ** | 01000000 | - 45 | ** | 01000100 | - 46 | ** | 00000000 | - 47 | ** | 00000000 | - - - 55 | ** | 01001110 | - 56 | ** | 01001110 | - 58 | ** | 01001110 | - 59 | ** | 01001110 | - 61 | ** | 01001110 | - 62 | ** | 01001110 | - 63 | GX | 01001110 | - 64 | ** | 01001110 | - 65 | ** | 01001110 | - 67 | ** | 01001011 | - 68 | ** | 01001011 | - 70 | ** | 01001011 | - 71 | ** | 01001011 | - 73 | ** | 01001011 | - 74 | ** | 01001011 | - 75 | KX | 01001011 | - 76 | ** | 01001011 | - 77 | ** | 01001011 | - - - SPECIAL - 78 | UL | 10000000 | - 79 | UM | 11000001 | - 80 | UN | 11000001 | - 31 | Q* | 01001100 | - -*/ - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// RenderTabs -// -//////////////////////////////////////////////////////////////////////////////////////////// - -const unsigned char tab48426[5] = {0x18, 0x1A, 0x17, 0x17, 0x17}; - -const unsigned char tab47492[] = {0, 0, 0xE0, 0xE6, 0xEC, 0xF3, 0xF9, 0, 6, 0xC, 6}; - -const unsigned char amplitudeRescale[] = { - 0, - 1, - 2, - 2, - 2, - 3, - 3, - 4, - 4, - 5, - 6, - 8, - 9, - 0xB, - 0xD, - 0xF, - 0 //17 elements? -}; - -// Used to decide which phoneme's blend lengths. The candidate with the lower score is selected. -// tab45856 -const unsigned char blendRank[] = {0, 0x1F, 0x1F, 0x1F, 0x1F, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 5, 5, 2, 0xA, 2, 8, - 5, 5, 0xB, 0xA, 9, 8, 8, 0xA0, 8, 8, - 0x17, 0x1F, 0x12, 0x12, 0x12, 0x12, 0x1E, 0x1E, 0x14, 0x14, - 0x14, 0x14, 0x17, 0x17, 0x1A, 0x1A, 0x1D, 0x1D, 2, 2, - 2, 2, 2, 2, 0x1A, 0x1D, 0x1B, 0x1A, 0x1D, 0x1B, - 0x1A, 0x1D, 0x1B, 0x1A, 0x1D, 0x1B, 0x17, 0x1D, 0x17, 0x17, - 0x1D, 0x17, 0x17, 0x1D, 0x17, 0x17, 0x1D, 0x17, 0x17, 0x17}; - -// Number of frames at the end of a phoneme devoted to interpolating to next phoneme's final value -//tab45696 -const unsigned char outBlendLength[] = {0, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 3, 2, 4, 4, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 0, 1, 0, 1, 0, 5, - 5, 5, 5, 5, 4, 4, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, - 0, 1, 2, 0, 2, 2, 0, 1, 3, 0, 2, 3, 0, 2, 0xA0, 0xA0}; - -// Number of frames at beginning of a phoneme devoted to interpolating to phoneme's final value -// tab45776 -const unsigned char inBlendLength[] = {0, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 3, 3, 4, 4, 3, 3, 3, 3, 3, 1, 2, 3, 2, 1, - 3, 3, 3, 3, 1, 1, 3, 3, 3, 2, 2, 3, 2, 3, 0, 0, - 5, 5, 5, 5, 4, 4, 2, 0, 2, 2, 0, 3, 2, 0, 4, 2, - 0, 3, 2, 0, 2, 2, 0, 2, 3, 0, 3, 3, 0, 3, 0xB0, 0xA0}; - -// Looks like it's used as bit flags -// High bits masked by 248 (11111000) -// -// 32: S* 241 11110001 -// 33: SH 226 11100010 -// 34: F* 211 11010011 -// 35: TH 187 10111011 -// 36: /H 124 01111100 -// 37: /X 149 10010101 -// 38: Z* 1 00000001 -// 39: ZH 2 00000010 -// 40: V* 3 00000011 -// 41: DH 3 00000011 -// 43: ** 114 01110010 -// 45: ** 2 00000010 -// 67: ** 27 00011011 -// 70: ** 25 00011001 -// tab45936 -const unsigned char sampledConsonantFlags[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xF1, 0xE2, 0xD3, 0xBB, 0x7C, 0x95, 1, 2, - 3, 3, 0, 0x72, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x1B, 0, 0, 0x19, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -//tab45056 -unsigned char freq1data[] = { - 0x00, 0x13, 0x13, 0x13, 0x13, 0xA, 0xE, 0x12, 0x18, 0x1A, 0x16, 0x14, 0x10, 0x14, 0xE, 0x12, - 0xE, 0x12, 0x12, 0x10, 0xC, 0xE, 0xA, 0x12, 0xE, 0xA, 8, 6, 6, 6, 6, 0x11, - 6, 6, 6, 6, 0xE, 0x10, 9, 0xA, 8, 0xA, 6, 6, 6, 5, 6, 0, - 0x12, 0x1A, 0x14, 0x1A, 0x12, 0xC, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 0xA, 0xA, 6, 6, 6, 0x2C, 0x13}; - -//tab451356 -unsigned char freq2data[] = {0x00, 0x43, 0x43, 0x43, 0x43, 0x54, 0x48, 0x42, 0x3E, 0x28, - 0x2C, 0x1E, 0x24, 0x2C, 0x48, 0x30, 0x24, 0x1E, 0x32, 0x24, - 0x1C, 0x44, 0x18, 0x32, 0x1E, 0x18, 0x52, 0x2E, 0x36, 0x56, - 0x36, 0x43, 0x49, 0x4F, 0x1A, 0x42, 0x49, 0x25, 0x33, 0x42, - 0x28, 0x2F, 0x4F, 0x4F, 0x42, 0x4F, 0x6E, 0x00, 0x48, 0x26, - 0x1E, 0x2A, 0x1E, 0x22, 0x1A, 0x1A, 0x1A, 0x42, 0x42, 0x42, - 0x6E, 0x6E, 0x6E, 0x54, 0x54, 0x54, 0x1A, 0x1A, 0x1A, 0x42, - 0x42, 0x42, 0x6D, 0x56, 0x6D, 0x54, 0x54, 0x54, 0x7F, 0x7F}; -//tab45216 -unsigned char freq3data[] = {0x00, 0x5B, 0x5B, 0x5B, 0x5B, 0x6E, 0x5D, 0x5B, 0x58, 0x59, - 0x57, 0x58, 0x52, 0x59, 0x5D, 0x3E, 0x52, 0x58, 0x3E, 0x6E, - 0x50, 0x5D, 0x5A, 0x3C, 0x6E, 0x5A, 0x6E, 0x51, 0x79, 0x65, - 0x79, 0x5B, 0x63, 0x6A, 0x51, 0x79, 0x5D, 0x52, 0x5D, 0x67, - 0x4C, 0x5D, 0x65, 0x65, 0x79, 0x65, 0x79, 0x00, 0x5A, 0x58, - 0x58, 0x58, 0x58, 0x52, 0x51, 0x51, 0x51, 0x79, 0x79, 0x79, - 0x70, 0x6E, 0x6E, 0x5E, 0x5E, 0x5E, 0x51, 0x51, 0x51, 0x79, - 0x79, 0x79, 0x65, 0x65, 0x70, 0x5E, 0x5E, 0x5E, 0x08, 0x01}; - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// Reciter -// -//////////////////////////////////////////////////////////////////////////////////////////// - -unsigned char inputtemp[256]; // secure copy of input tab36096 - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// Render -// -//////////////////////////////////////////////////////////////////////////////////////////// - -//timetable for more accurate c64 simulation -int timetable[5][5] = { - {162, 167, 167, 127, 128}, - {226, 60, 60, 0, 0}, - {225, 60, 59, 0, 0}, - {200, 0, 0, 54, 55}, - {199, 0, 0, 54, 54}}; - -unsigned oldtimetableindex; - -const unsigned char ampl1data[] = {0, 0, 0, 0, 0, 0xD, 0xD, 0xE, 0xF, 0xF, 0xF, 0xF, - 0xF, 0xC, 0xD, 0xC, 0xF, 0xF, 0xD, 0xD, 0xD, 0xE, 0xD, 0xC, - 0xD, 0xD, 0xD, 0xC, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0xB, 0xB, 0xB, 0xB, 0, 0, 1, 0xB, 0, 2, - 0xE, 0xF, 0xF, 0xF, 0xF, 0xD, 2, 4, 0, 2, 4, 0, - 1, 4, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, - 0, 0xC, 0, 0, 0, 0, 0xF, 0xF}; - -const unsigned char ampl2data[] = { - 0, 0, 0, 0, 0, 0xA, 0xB, 0xD, 0xE, 0xD, 0xC, 0xC, 0xB, 9, 0xB, 0xB, 0xC, 0xC, 0xC, 8, - 8, 0xC, 8, 0xA, 8, 8, 0xA, 3, 9, 6, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, - 3, 4, 0, 0, 0, 5, 0xA, 2, 0xE, 0xD, 0xC, 0xD, 0xC, 8, 0, 1, 0, 0, 1, 0, - 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0xA, 0, 0, 0xA, 0, 0, 0}; - -const unsigned char ampl3data[] = {0, 0, 0, 0, 0, 8, 7, 8, 8, 1, 1, 0, 1, 0, 7, 5, - 1, 0, 6, 1, 0, 7, 0, 5, 1, 0, 8, 0, 0, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0xE, 1, - 9, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 5, 0, 0x13, 0x10}; - -//tab42240 -const signed char sinus[256] = { - 0, 3, 6, 9, 12, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, - 49, 51, 54, 57, 60, 63, 65, 68, 71, 73, 76, 78, 81, 83, 85, 88, - 90, 92, 94, 96, 98, 100, 102, 104, 106, 107, 109, 111, 112, 113, 115, 116, - 117, 118, 120, 121, 122, 122, 123, 124, 125, 125, 126, 126, 126, 127, 127, 127, - 127, 127, 127, 127, 126, 126, 126, 125, 125, 124, 123, 122, 122, 121, 120, 118, - 117, 116, 115, 113, 112, 111, 109, 107, 106, 104, 102, 100, 98, 96, 94, 92, - 90, 88, 85, 83, 81, 78, 76, 73, 71, 68, 65, 63, 60, 57, 54, 51, - 49, 46, 43, 40, 37, 34, 31, 28, 25, 22, 19, 16, 12, 9, 6, 3, - 0, -3, -6, -9, -12, -16, -19, -22, -25, -28, -31, -34, -37, -40, -43, -46, - -49, -51, -54, -57, -60, -63, -65, -68, -71, -73, -76, -78, -81, -83, -85, -88, - -90, -92, -94, -96, -98, -100, -102, -104, -106, -107, -109, -111, -112, -113, -115, -116, - -117, -118, -120, -121, -122, -122, -123, -124, -125, -125, -126, -126, -126, -127, -127, -127, - -127, -127, -127, -127, -126, -126, -126, -125, -125, -124, -123, -122, -122, -121, -120, -118, - -117, -116, -115, -113, -112, -111, -109, -107, -106, -104, -102, -100, -98, -96, -94, -92, - -90, -88, -85, -83, -81, -78, -76, -73, -71, -68, -65, -63, -60, -57, -54, -51, - -49, -46, -43, -40, -37, -34, -31, -28, -25, -22, -19, -16, -12, -9, -6, -3}; - -//tab42496 -const unsigned char rectangle[] = { - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70}; - -//random data ? -const unsigned char sampleTable[0x500] = { - //00 - - 0x38, - 0x84, - 0x6B, - 0x19, - 0xC6, - 0x63, - 0x18, - 0x86, - 0x73, - 0x98, - 0xC6, - 0xB1, - 0x1C, - 0xCA, - 0x31, - 0x8C, - 0xC7, - 0x31, - 0x88, - 0xC2, - 0x30, - 0x98, - 0x46, - 0x31, - 0x18, - 0xC6, - 0x35, - 0xC, - 0xCA, - 0x31, - 0xC, - 0xC6 - //20 - , - 0x21, - 0x10, - 0x24, - 0x69, - 0x12, - 0xC2, - 0x31, - 0x14, - 0xC4, - 0x71, - 8, - 0x4A, - 0x22, - 0x49, - 0xAB, - 0x6A, - 0xA8, - 0xAC, - 0x49, - 0x51, - 0x32, - 0xD5, - 0x52, - 0x88, - 0x93, - 0x6C, - 0x94, - 0x22, - 0x15, - 0x54, - 0xD2, - 0x25 - //40 - , - 0x96, - 0xD4, - 0x50, - 0xA5, - 0x46, - 0x21, - 8, - 0x85, - 0x6B, - 0x18, - 0xC4, - 0x63, - 0x10, - 0xCE, - 0x6B, - 0x18, - 0x8C, - 0x71, - 0x19, - 0x8C, - 0x63, - 0x35, - 0xC, - 0xC6, - 0x33, - 0x99, - 0xCC, - 0x6C, - 0xB5, - 0x4E, - 0xA2, - 0x99 - //60 - , - 0x46, - 0x21, - 0x28, - 0x82, - 0x95, - 0x2E, - 0xE3, - 0x30, - 0x9C, - 0xC5, - 0x30, - 0x9C, - 0xA2, - 0xB1, - 0x9C, - 0x67, - 0x31, - 0x88, - 0x66, - 0x59, - 0x2C, - 0x53, - 0x18, - 0x84, - 0x67, - 0x50, - 0xCA, - 0xE3, - 0xA, - 0xAC, - 0xAB, - 0x30 - //80 - , - 0xAC, - 0x62, - 0x30, - 0x8C, - 0x63, - 0x10, - 0x94, - 0x62, - 0xB1, - 0x8C, - 0x82, - 0x28, - 0x96, - 0x33, - 0x98, - 0xD6, - 0xB5, - 0x4C, - 0x62, - 0x29, - 0xA5, - 0x4A, - 0xB5, - 0x9C, - 0xC6, - 0x31, - 0x14, - 0xD6, - 0x38, - 0x9C, - 0x4B, - 0xB4 - //A0 - , - 0x86, - 0x65, - 0x18, - 0xAE, - 0x67, - 0x1C, - 0xA6, - 0x63, - 0x19, - 0x96, - 0x23, - 0x19, - 0x84, - 0x13, - 8, - 0xA6, - 0x52, - 0xAC, - 0xCA, - 0x22, - 0x89, - 0x6E, - 0xAB, - 0x19, - 0x8C, - 0x62, - 0x34, - 0xC4, - 0x62, - 0x19, - 0x86, - 0x63 - //C0 - , - 0x18, - 0xC4, - 0x23, - 0x58, - 0xD6, - 0xA3, - 0x50, - 0x42, - 0x54, - 0x4A, - 0xAD, - 0x4A, - 0x25, - 0x11, - 0x6B, - 0x64, - 0x89, - 0x4A, - 0x63, - 0x39, - 0x8A, - 0x23, - 0x31, - 0x2A, - 0xEA, - 0xA2, - 0xA9, - 0x44, - 0xC5, - 0x12, - 0xCD, - 0x42 - //E0 - , - 0x34, - 0x8C, - 0x62, - 0x18, - 0x8C, - 0x63, - 0x11, - 0x48, - 0x66, - 0x31, - 0x9D, - 0x44, - 0x33, - 0x1D, - 0x46, - 0x31, - 0x9C, - 0xC6, - 0xB1, - 0xC, - 0xCD, - 0x32, - 0x88, - 0xC4, - 0x73, - 0x18, - 0x86, - 0x73, - 8, - 0xD6, - 0x63, - 0x58 - //100 - , - 7, - 0x81, - 0xE0, - 0xF0, - 0x3C, - 7, - 0x87, - 0x90, - 0x3C, - 0x7C, - 0xF, - 0xC7, - 0xC0, - 0xC0, - 0xF0, - 0x7C, - 0x1E, - 7, - 0x80, - 0x80, - 0, - 0x1C, - 0x78, - 0x70, - 0xF1, - 0xC7, - 0x1F, - 0xC0, - 0xC, - 0xFE, - 0x1C, - 0x1F - //120 - , - 0x1F, - 0xE, - 0xA, - 0x7A, - 0xC0, - 0x71, - 0xF2, - 0x83, - 0x8F, - 3, - 0xF, - 0xF, - 0xC, - 0, - 0x79, - 0xF8, - 0x61, - 0xE0, - 0x43, - 0xF, - 0x83, - 0xE7, - 0x18, - 0xF9, - 0xC1, - 0x13, - 0xDA, - 0xE9, - 0x63, - 0x8F, - 0xF, - 0x83 - //140 - , - 0x83, - 0x87, - 0xC3, - 0x1F, - 0x3C, - 0x70, - 0xF0, - 0xE1, - 0xE1, - 0xE3, - 0x87, - 0xB8, - 0x71, - 0xE, - 0x20, - 0xE3, - 0x8D, - 0x48, - 0x78, - 0x1C, - 0x93, - 0x87, - 0x30, - 0xE1, - 0xC1, - 0xC1, - 0xE4, - 0x78, - 0x21, - 0x83, - 0x83, - 0xC3 - //160 - , - 0x87, - 6, - 0x39, - 0xE5, - 0xC3, - 0x87, - 7, - 0xE, - 0x1C, - 0x1C, - 0x70, - 0xF4, - 0x71, - 0x9C, - 0x60, - 0x36, - 0x32, - 0xC3, - 0x1E, - 0x3C, - 0xF3, - 0x8F, - 0xE, - 0x3C, - 0x70, - 0xE3, - 0xC7, - 0x8F, - 0xF, - 0xF, - 0xE, - 0x3C - //180 - , - 0x78, - 0xF0, - 0xE3, - 0x87, - 6, - 0xF0, - 0xE3, - 7, - 0xC1, - 0x99, - 0x87, - 0xF, - 0x18, - 0x78, - 0x70, - 0x70, - 0xFC, - 0xF3, - 0x10, - 0xB1, - 0x8C, - 0x8C, - 0x31, - 0x7C, - 0x70, - 0xE1, - 0x86, - 0x3C, - 0x64, - 0x6C, - 0xB0, - 0xE1 - //1A0 - , - 0xE3, - 0xF, - 0x23, - 0x8F, - 0xF, - 0x1E, - 0x3E, - 0x38, - 0x3C, - 0x38, - 0x7B, - 0x8F, - 7, - 0xE, - 0x3C, - 0xF4, - 0x17, - 0x1E, - 0x3C, - 0x78, - 0xF2, - 0x9E, - 0x72, - 0x49, - 0xE3, - 0x25, - 0x36, - 0x38, - 0x58, - 0x39, - 0xE2, - 0xDE - //1C0 - , - 0x3C, - 0x78, - 0x78, - 0xE1, - 0xC7, - 0x61, - 0xE1, - 0xE1, - 0xB0, - 0xF0, - 0xF0, - 0xC3, - 0xC7, - 0xE, - 0x38, - 0xC0, - 0xF0, - 0xCE, - 0x73, - 0x73, - 0x18, - 0x34, - 0xB0, - 0xE1, - 0xC7, - 0x8E, - 0x1C, - 0x3C, - 0xF8, - 0x38, - 0xF0, - 0xE1 - //1E0 - , - 0xC1, - 0x8B, - 0x86, - 0x8F, - 0x1C, - 0x78, - 0x70, - 0xF0, - 0x78, - 0xAC, - 0xB1, - 0x8F, - 0x39, - 0x31, - 0xDB, - 0x38, - 0x61, - 0xC3, - 0xE, - 0xE, - 0x38, - 0x78, - 0x73, - 0x17, - 0x1E, - 0x39, - 0x1E, - 0x38, - 0x64, - 0xE1, - 0xF1, - 0xC1 - //200 - , - 0x4E, - 0xF, - 0x40, - 0xA2, - 2, - 0xC5, - 0x8F, - 0x81, - 0xA1, - 0xFC, - 0x12, - 8, - 0x64, - 0xE0, - 0x3C, - 0x22, - 0xE0, - 0x45, - 7, - 0x8E, - 0xC, - 0x32, - 0x90, - 0xF0, - 0x1F, - 0x20, - 0x49, - 0xE0, - 0xF8, - 0xC, - 0x60, - 0xF0 - //220 - , - 0x17, - 0x1A, - 0x41, - 0xAA, - 0xA4, - 0xD0, - 0x8D, - 0x12, - 0x82, - 0x1E, - 0x1E, - 3, - 0xF8, - 0x3E, - 3, - 0xC, - 0x73, - 0x80, - 0x70, - 0x44, - 0x26, - 3, - 0x24, - 0xE1, - 0x3E, - 4, - 0x4E, - 4, - 0x1C, - 0xC1, - 9, - 0xCC - //240 - , - 0x9E, - 0x90, - 0x21, - 7, - 0x90, - 0x43, - 0x64, - 0xC0, - 0xF, - 0xC6, - 0x90, - 0x9C, - 0xC1, - 0x5B, - 3, - 0xE2, - 0x1D, - 0x81, - 0xE0, - 0x5E, - 0x1D, - 3, - 0x84, - 0xB8, - 0x2C, - 0xF, - 0x80, - 0xB1, - 0x83, - 0xE0, - 0x30, - 0x41 - //260 - , - 0x1E, - 0x43, - 0x89, - 0x83, - 0x50, - 0xFC, - 0x24, - 0x2E, - 0x13, - 0x83, - 0xF1, - 0x7C, - 0x4C, - 0x2C, - 0xC9, - 0xD, - 0x83, - 0xB0, - 0xB5, - 0x82, - 0xE4, - 0xE8, - 6, - 0x9C, - 7, - 0xA0, - 0x99, - 0x1D, - 7, - 0x3E, - 0x82, - 0x8F - //280 - , - 0x70, - 0x30, - 0x74, - 0x40, - 0xCA, - 0x10, - 0xE4, - 0xE8, - 0xF, - 0x92, - 0x14, - 0x3F, - 6, - 0xF8, - 0x84, - 0x88, - 0x43, - 0x81, - 0xA, - 0x34, - 0x39, - 0x41, - 0xC6, - 0xE3, - 0x1C, - 0x47, - 3, - 0xB0, - 0xB8, - 0x13, - 0xA, - 0xC2 - //2A0 - , - 0x64, - 0xF8, - 0x18, - 0xF9, - 0x60, - 0xB3, - 0xC0, - 0x65, - 0x20, - 0x60, - 0xA6, - 0x8C, - 0xC3, - 0x81, - 0x20, - 0x30, - 0x26, - 0x1E, - 0x1C, - 0x38, - 0xD3, - 1, - 0xB0, - 0x26, - 0x40, - 0xF4, - 0xB, - 0xC3, - 0x42, - 0x1F, - 0x85, - 0x32 - //2C0 - , - 0x26, - 0x60, - 0x40, - 0xC9, - 0xCB, - 1, - 0xEC, - 0x11, - 0x28, - 0x40, - 0xFA, - 4, - 0x34, - 0xE0, - 0x70, - 0x4C, - 0x8C, - 0x1D, - 7, - 0x69, - 3, - 0x16, - 0xC8, - 4, - 0x23, - 0xE8, - 0xC6, - 0x9A, - 0xB, - 0x1A, - 3, - 0xE0 - //2E0 - , - 0x76, - 6, - 5, - 0xCF, - 0x1E, - 0xBC, - 0x58, - 0x31, - 0x71, - 0x66, - 0, - 0xF8, - 0x3F, - 4, - 0xFC, - 0xC, - 0x74, - 0x27, - 0x8A, - 0x80, - 0x71, - 0xC2, - 0x3A, - 0x26, - 6, - 0xC0, - 0x1F, - 5, - 0xF, - 0x98, - 0x40, - 0xAE - //300 - , - 1, - 0x7F, - 0xC0, - 7, - 0xFF, - 0, - 0xE, - 0xFE, - 0, - 3, - 0xDF, - 0x80, - 3, - 0xEF, - 0x80, - 0x1B, - 0xF1, - 0xC2, - 0, - 0xE7, - 0xE0, - 0x18, - 0xFC, - 0xE0, - 0x21, - 0xFC, - 0x80, - 0x3C, - 0xFC, - 0x40, - 0xE, - 0x7E - //320 - , - 0, - 0x3F, - 0x3E, - 0, - 0xF, - 0xFE, - 0, - 0x1F, - 0xFF, - 0, - 0x3E, - 0xF0, - 7, - 0xFC, - 0, - 0x7E, - 0x10, - 0x3F, - 0xFF, - 0, - 0x3F, - 0x38, - 0xE, - 0x7C, - 1, - 0x87, - 0xC, - 0xFC, - 0xC7, - 0, - 0x3E, - 4 - //340 - , - 0xF, - 0x3E, - 0x1F, - 0xF, - 0xF, - 0x1F, - 0xF, - 2, - 0x83, - 0x87, - 0xCF, - 3, - 0x87, - 0xF, - 0x3F, - 0xC0, - 7, - 0x9E, - 0x60, - 0x3F, - 0xC0, - 3, - 0xFE, - 0, - 0x3F, - 0xE0, - 0x77, - 0xE1, - 0xC0, - 0xFE, - 0xE0, - 0xC3 - //360 - , - 0xE0, - 1, - 0xDF, - 0xF8, - 3, - 7, - 0, - 0x7E, - 0x70, - 0, - 0x7C, - 0x38, - 0x18, - 0xFE, - 0xC, - 0x1E, - 0x78, - 0x1C, - 0x7C, - 0x3E, - 0xE, - 0x1F, - 0x1E, - 0x1E, - 0x3E, - 0, - 0x7F, - 0x83, - 7, - 0xDB, - 0x87, - 0x83 - //380 - , - 7, - 0xC7, - 7, - 0x10, - 0x71, - 0xFF, - 0, - 0x3F, - 0xE2, - 1, - 0xE0, - 0xC1, - 0xC3, - 0xE1, - 0, - 0x7F, - 0xC0, - 5, - 0xF0, - 0x20, - 0xF8, - 0xF0, - 0x70, - 0xFE, - 0x78, - 0x79, - 0xF8, - 2, - 0x3F, - 0xC, - 0x8F, - 3 - //3a0 - , - 0xF, - 0x9F, - 0xE0, - 0xC1, - 0xC7, - 0x87, - 3, - 0xC3, - 0xC3, - 0xB0, - 0xE1, - 0xE1, - 0xC1, - 0xE3, - 0xE0, - 0x71, - 0xF0, - 0, - 0xFC, - 0x70, - 0x7C, - 0xC, - 0x3E, - 0x38, - 0xE, - 0x1C, - 0x70, - 0xC3, - 0xC7, - 3, - 0x81, - 0xC1 - //3c0 - , - 0xC7, - 0xE7, - 0, - 0xF, - 0xC7, - 0x87, - 0x19, - 9, - 0xEF, - 0xC4, - 0x33, - 0xE0, - 0xC1, - 0xFC, - 0xF8, - 0x70, - 0xF0, - 0x78, - 0xF8, - 0xF0, - 0x61, - 0xC7, - 0, - 0x1F, - 0xF8, - 1, - 0x7C, - 0xF8, - 0xF0, - 0x78, - 0x70, - 0x3C - //3e0 - , - 0x7C, - 0xCE, - 0xE, - 0x21, - 0x83, - 0xCF, - 8, - 7, - 0x8F, - 8, - 0xC1, - 0x87, - 0x8F, - 0x80, - 0xC7, - 0xE3, - 0, - 7, - 0xF8, - 0xE0, - 0xEF, - 0, - 0x39, - 0xF7, - 0x80, - 0xE, - 0xF8, - 0xE1, - 0xE3, - 0xF8, - 0x21, - 0x9F - //400 - , - 0xC0, - 0xFF, - 3, - 0xF8, - 7, - 0xC0, - 0x1F, - 0xF8, - 0xC4, - 4, - 0xFC, - 0xC4, - 0xC1, - 0xBC, - 0x87, - 0xF0, - 0xF, - 0xC0, - 0x7F, - 5, - 0xE0, - 0x25, - 0xEC, - 0xC0, - 0x3E, - 0x84, - 0x47, - 0xF0, - 0x8E, - 3, - 0xF8, - 3 - //420 - , - 0xFB, - 0xC0, - 0x19, - 0xF8, - 7, - 0x9C, - 0xC, - 0x17, - 0xF8, - 7, - 0xE0, - 0x1F, - 0xA1, - 0xFC, - 0xF, - 0xFC, - 1, - 0xF0, - 0x3F, - 0, - 0xFE, - 3, - 0xF0, - 0x1F, - 0, - 0xFD, - 0, - 0xFF, - 0x88, - 0xD, - 0xF9, - 1 - //440 - , - 0xFF, - 0, - 0x70, - 7, - 0xC0, - 0x3E, - 0x42, - 0xF3, - 0xD, - 0xC4, - 0x7F, - 0x80, - 0xFC, - 7, - 0xF0, - 0x5E, - 0xC0, - 0x3F, - 0, - 0x78, - 0x3F, - 0x81, - 0xFF, - 1, - 0xF8, - 1, - 0xC3, - 0xE8, - 0xC, - 0xE4, - 0x64, - 0x8F - ////460 - , - 0xE4, - 0xF, - 0xF0, - 7, - 0xF0, - 0xC2, - 0x1F, - 0, - 0x7F, - 0xC0, - 0x6F, - 0x80, - 0x7E, - 3, - 0xF8, - 7, - 0xF0, - 0x3F, - 0xC0, - 0x78, - 0xF, - 0x82, - 7, - 0xFE, - 0x22, - 0x77, - 0x70, - 2, - 0x76, - 3, - 0xFE, - 0 - //480 - , - 0xFE, - 0x67, - 0, - 0x7C, - 0xC7, - 0xF1, - 0x8E, - 0xC6, - 0x3B, - 0xE0, - 0x3F, - 0x84, - 0xF3, - 0x19, - 0xD8, - 3, - 0x99, - 0xFC, - 9, - 0xB8, - 0xF, - 0xF8, - 0, - 0x9D, - 0x24, - 0x61, - 0xF9, - 0xD, - 0, - 0xFD, - 3, - 0xF0 - //4a0 - , - 0x1F, - 0x90, - 0x3F, - 1, - 0xF8, - 0x1F, - 0xD0, - 0xF, - 0xF8, - 0x37, - 1, - 0xF8, - 7, - 0xF0, - 0xF, - 0xC0, - 0x3F, - 0, - 0xFE, - 3, - 0xF8, - 0xF, - 0xC0, - 0x3F, - 0, - 0xFA, - 3, - 0xF0, - 0xF, - 0x80, - 0xFF, - 1 - //4c0 - , - 0xB8, - 7, - 0xF0, - 1, - 0xFC, - 1, - 0xBC, - 0x80, - 0x13, - 0x1E, - 0, - 0x7F, - 0xE1, - 0x40, - 0x7F, - 0xA0, - 0x7F, - 0xB0, - 0, - 0x3F, - 0xC0, - 0x1F, - 0xC0, - 0x38, - 0xF, - 0xF0, - 0x1F, - 0x80, - 0xFF, - 1, - 0xFC, - 3 - //4e0 - , - 0xF1, - 0x7E, - 1, - 0xFE, - 1, - 0xF0, - 0xFF, - 0, - 0x7F, - 0xC0, - 0x1D, - 7, - 0xF0, - 0xF, - 0xC0, - 0x7E, - 6, - 0xE0, - 7, - 0xE0, - 0xF, - 0xF8, - 6, - 0xC1, - 0xFE, - 1, - 0xFC, - 3, - 0xE0, - 0xF, - 0, - 0xFC}; - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// Render -// -//////////////////////////////////////////////////////////////////////////////////////////// - -unsigned char pitches[256]; // tab43008 - -unsigned char frequency1[256]; -unsigned char frequency2[256]; -unsigned char frequency3[256]; - -unsigned char amplitude1[256]; -unsigned char amplitude2[256]; -unsigned char amplitude3[256]; - -unsigned char sampledConsonantFlag[256]; // tab44800 - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// Sam -// -//////////////////////////////////////////////////////////////////////////////////////////// - -unsigned char stress[256]; //numbers from 0 to 8 -unsigned char phonemeLength[256]; //tab40160 -unsigned char phonemeindex[256]; - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// ReciterTabs -// -//////////////////////////////////////////////////////////////////////////////////////////// - -//some flags -const unsigned char tab36376[] = { - 0, 0, 0, 0, 0, 0, 0, 0, // 0-7 - 0, 0, 0, 0, 0, 0, 0, 0, // 8-15 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 130, // ' ', '!' - 0, 0, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 2, 2, 2, 2, 2, 192, 168, 176, 172, 192, 160, 184, // '@', 'A' - 160, 192, 188, 160, 172, 168, 172, 192, 160, 160, 172, 180, 164, 192, 168, 168, - 176, 192, 188, 0, 0, 0, 2, 0, // 'X', 'Y', 'Z', '[', - 32, 32, 155, 32, 192, 185, 32, 205, 163, 76, 138, 142}; - -const unsigned char rules[] = { - ']', 'A' | 0x80, ' ', '(', 'A', '.', ')', '=', - 'E', 'H', '4', 'Y', '.', ' ' | 0x80, '(', 'A', - ')', ' ', '=', 'A', 'H' | 0x80, ' ', '(', 'A', - 'R', 'E', ')', ' ', '=', 'A', 'A', 'R' | 0x80, - ' ', '(', 'A', 'R', ')', 'O', '=', 'A', - 'X', 'R' | 0x80, '(', 'A', 'R', ')', '#', '=', - 'E', 'H', '4', 'R' | 0x80, ' ', '^', '(', 'A', - 'S', ')', '#', '=', 'E', 'Y', '4', 'S' | 0x80, - '(', 'A', ')', 'W', 'A', '=', 'A', 'X' | 0x80, - '(', 'A', 'W', ')', '=', 'A', 'O', '5' | 0x80, - ' ', ':', '(', 'A', 'N', 'Y', ')', '=', - 'E', 'H', '4', 'N', 'I', 'Y' | 0x80, '(', 'A', - ')', '^', '+', '#', '=', 'E', 'Y', '5' | 0x80, - '#', ':', '(', 'A', 'L', 'L', 'Y', ')', - '=', 'U', 'L', 'I', 'Y' | 0x80, ' ', '(', 'A', - 'L', ')', '#', '=', 'U', 'L' | 0x80, '(', 'A', - 'G', 'A', 'I', 'N', ')', '=', 'A', 'X', - 'G', 'E', 'H', '4', 'N' | 0x80, '#', ':', '(', - 'A', 'G', ')', 'E', '=', 'I', 'H', 'J' | 0x80, - '(', 'A', ')', '^', '%', '=', 'E', 'Y' | 0x80, - '(', 'A', ')', '^', '+', ':', '#', '=', - 'A', 'E' | 0x80, ' ', ':', '(', 'A', ')', '^', - '+', ' ', '=', 'E', 'Y', '4' | 0x80, ' ', '(', - 'A', 'R', 'R', ')', '=', 'A', 'X', 'R' | 0x80, - '(', 'A', 'R', 'R', ')', '=', 'A', 'E', - '4', 'R' | 0x80, ' ', '^', '(', 'A', 'R', ')', - ' ', '=', 'A', 'A', '5', 'R' | 0x80, '(', 'A', - 'R', ')', '=', 'A', 'A', '5', 'R' | 0x80, '(', - 'A', 'I', 'R', ')', '=', 'E', 'H', '4', - 'R' | 0x80, '(', 'A', 'I', ')', '=', 'E', 'Y', - '4' | 0x80, '(', 'A', 'Y', ')', '=', 'E', 'Y', - '5' | 0x80, '(', 'A', 'U', ')', '=', 'A', 'O', - '4' | 0x80, '#', ':', '(', 'A', 'L', ')', ' ', - '=', 'U', 'L' | 0x80, '#', ':', '(', 'A', 'L', - 'S', ')', ' ', '=', 'U', 'L', 'Z' | 0x80, '(', - 'A', 'L', 'K', ')', '=', 'A', 'O', '4', - 'K' | 0x80, '(', 'A', 'L', ')', '^', '=', 'A', - 'O', 'L' | 0x80, ' ', ':', '(', 'A', 'B', 'L', - 'E', ')', '=', 'E', 'Y', '4', 'B', 'U', - 'L' | 0x80, '(', 'A', 'B', 'L', 'E', ')', '=', - 'A', 'X', 'B', 'U', 'L' | 0x80, '(', 'A', ')', - 'V', 'O', '=', 'E', 'Y', '4' | 0x80, '(', 'A', - 'N', 'G', ')', '+', '=', 'E', 'Y', '4', - 'N', 'J' | 0x80, '(', 'A', 'T', 'A', 'R', 'I', - ')', '=', 'A', 'H', 'T', 'A', 'A', '4', - 'R', 'I', 'Y' | 0x80, '(', 'A', ')', 'T', 'O', - 'M', '=', 'A', 'E' | 0x80, '(', 'A', ')', 'T', - 'T', 'I', '=', 'A', 'E' | 0x80, ' ', '(', 'A', - 'T', ')', ' ', '=', 'A', 'E', 'T' | 0x80, ' ', - '(', 'A', ')', 'T', '=', 'A', 'H' | 0x80, '(', - 'A', ')', '=', 'A', 'E' | 0x80, - - ']', 'B' | 0x80, ' ', '(', 'B', ')', ' ', '=', - 'B', 'I', 'Y', '4' | 0x80, ' ', '(', 'B', 'E', - ')', '^', '#', '=', 'B', 'I', 'H' | 0x80, '(', - 'B', 'E', 'I', 'N', 'G', ')', '=', 'B', - 'I', 'Y', '4', 'I', 'H', 'N', 'X' | 0x80, ' ', - '(', 'B', 'O', 'T', 'H', ')', ' ', '=', - 'B', 'O', 'W', '4', 'T', 'H' | 0x80, ' ', '(', - 'B', 'U', 'S', ')', '#', '=', 'B', 'I', - 'H', '4', 'Z' | 0x80, '(', 'B', 'R', 'E', 'A', - 'K', ')', '=', 'B', 'R', 'E', 'Y', '5', - 'K' | 0x80, '(', 'B', 'U', 'I', 'L', ')', '=', - 'B', 'I', 'H', '4', 'L' | 0x80, '(', 'B', ')', - '=', 'B' | 0x80, - - ']', 'C' | 0x80, ' ', '(', 'C', ')', ' ', '=', - 'S', 'I', 'Y', '4' | 0x80, ' ', '(', 'C', 'H', - ')', '^', '=', 'K' | 0x80, '^', 'E', '(', 'C', - 'H', ')', '=', 'K' | 0x80, '(', 'C', 'H', 'A', - ')', 'R', '#', '=', 'K', 'E', 'H', '5' | 0x80, - '(', 'C', 'H', ')', '=', 'C', 'H' | 0x80, ' ', - 'S', '(', 'C', 'I', ')', '#', '=', 'S', - 'A', 'Y', '4' | 0x80, '(', 'C', 'I', ')', 'A', - '=', 'S', 'H' | 0x80, '(', 'C', 'I', ')', 'O', - '=', 'S', 'H' | 0x80, '(', 'C', 'I', ')', 'E', - 'N', '=', 'S', 'H' | 0x80, '(', 'C', 'I', 'T', - 'Y', ')', '=', 'S', 'I', 'H', 'T', 'I', - 'Y' | 0x80, '(', 'C', ')', '+', '=', 'S' | 0x80, '(', - 'C', 'K', ')', '=', 'K' | 0x80, '(', 'C', 'O', - 'M', 'M', 'O', 'D', 'O', 'R', 'E', ')', - '=', 'K', 'A', 'A', '4', 'M', 'A', 'H', - 'D', 'O', 'H', 'R' | 0x80, '(', 'C', 'O', 'M', - ')', '=', 'K', 'A', 'H', 'M' | 0x80, '(', 'C', - 'U', 'I', 'T', ')', '=', 'K', 'I', 'H', - 'T' | 0x80, '(', 'C', 'R', 'E', 'A', ')', '=', - 'K', 'R', 'I', 'Y', 'E', 'Y' | 0x80, '(', 'C', - ')', '=', 'K' | 0x80, - - ']', 'D' | 0x80, ' ', '(', 'D', ')', ' ', '=', - 'D', 'I', 'Y', '4' | 0x80, ' ', '(', 'D', 'R', - '.', ')', ' ', '=', 'D', 'A', 'A', '4', - 'K', 'T', 'E', 'R' | 0x80, '#', ':', '(', 'D', - 'E', 'D', ')', ' ', '=', 'D', 'I', 'H', - 'D' | 0x80, '.', 'E', '(', 'D', ')', ' ', '=', - 'D' | 0x80, '#', ':', '^', 'E', '(', 'D', ')', - ' ', '=', 'T' | 0x80, ' ', '(', 'D', 'E', ')', - '^', '#', '=', 'D', 'I', 'H' | 0x80, ' ', '(', - 'D', 'O', ')', ' ', '=', 'D', 'U', 'W' | 0x80, - ' ', '(', 'D', 'O', 'E', 'S', ')', '=', - 'D', 'A', 'H', 'Z' | 0x80, '(', 'D', 'O', 'N', - 'E', ')', ' ', '=', 'D', 'A', 'H', '5', - 'N' | 0x80, '(', 'D', 'O', 'I', 'N', 'G', ')', - '=', 'D', 'U', 'W', '4', 'I', 'H', 'N', - 'X' | 0x80, ' ', '(', 'D', 'O', 'W', ')', '=', - 'D', 'A', 'W' | 0x80, '#', '(', 'D', 'U', ')', - 'A', '=', 'J', 'U', 'W' | 0x80, '#', '(', 'D', - 'U', ')', '^', '#', '=', 'J', 'A', 'X' | 0x80, - '(', 'D', ')', '=', 'D' | 0x80, - - ']', 'E' | 0x80, ' ', '(', 'E', ')', ' ', '=', - 'I', 'Y', 'I', 'Y', '4' | 0x80, '#', ':', '(', - 'E', ')', ' ', '=' | 0x80, '\'', ':', '^', '(', - 'E', ')', ' ', '=' | 0x80, ' ', ':', '(', 'E', - ')', ' ', '=', 'I', 'Y' | 0x80, '#', '(', 'E', - 'D', ')', ' ', '=', 'D' | 0x80, '#', ':', '(', - 'E', ')', 'D', ' ', '=' | 0x80, '(', 'E', 'V', - ')', 'E', 'R', '=', 'E', 'H', '4', 'V' | 0x80, - '(', 'E', ')', '^', '%', '=', 'I', 'Y', - '4' | 0x80, '(', 'E', 'R', 'I', ')', '#', '=', - 'I', 'Y', '4', 'R', 'I', 'Y' | 0x80, '(', 'E', - 'R', 'I', ')', '=', 'E', 'H', '4', 'R', - 'I', 'H' | 0x80, '#', ':', '(', 'E', 'R', ')', - '#', '=', 'E', 'R' | 0x80, '(', 'E', 'R', 'R', - 'O', 'R', ')', '=', 'E', 'H', '4', 'R', - 'O', 'H', 'R' | 0x80, '(', 'E', 'R', 'A', 'S', - 'E', ')', '=', 'I', 'H', 'R', 'E', 'Y', - '5', 'S' | 0x80, '(', 'E', 'R', ')', '#', '=', - 'E', 'H', 'R' | 0x80, '(', 'E', 'R', ')', '=', - 'E', 'R' | 0x80, ' ', '(', 'E', 'V', 'E', 'N', - ')', '=', 'I', 'Y', 'V', 'E', 'H', 'N' | 0x80, - '#', ':', '(', 'E', ')', 'W', '=' | 0x80, '@', - '(', 'E', 'W', ')', '=', 'U', 'W' | 0x80, '(', - 'E', 'W', ')', '=', 'Y', 'U', 'W' | 0x80, '(', - 'E', ')', 'O', '=', 'I', 'Y' | 0x80, '#', ':', - '&', '(', 'E', 'S', ')', ' ', '=', 'I', - 'H', 'Z' | 0x80, '#', ':', '(', 'E', ')', 'S', - ' ', '=' | 0x80, '#', ':', '(', 'E', 'L', 'Y', - ')', ' ', '=', 'L', 'I', 'Y' | 0x80, '#', ':', - '(', 'E', 'M', 'E', 'N', 'T', ')', '=', - 'M', 'E', 'H', 'N', 'T' | 0x80, '(', 'E', 'F', - 'U', 'L', ')', '=', 'F', 'U', 'H', 'L' | 0x80, - '(', 'E', 'E', ')', '=', 'I', 'Y', '4' | 0x80, - '(', 'E', 'A', 'R', 'N', ')', '=', 'E', - 'R', '5', 'N' | 0x80, ' ', '(', 'E', 'A', 'R', - ')', '^', '=', 'E', 'R', '5' | 0x80, '(', 'E', - 'A', 'D', ')', '=', 'E', 'H', 'D' | 0x80, '#', - ':', '(', 'E', 'A', ')', ' ', '=', 'I', - 'Y', 'A', 'X' | 0x80, '(', 'E', 'A', ')', 'S', - 'U', '=', 'E', 'H', '5' | 0x80, '(', 'E', 'A', - ')', '=', 'I', 'Y', '5' | 0x80, '(', 'E', 'I', - 'G', 'H', ')', '=', 'E', 'Y', '4' | 0x80, '(', - 'E', 'I', ')', '=', 'I', 'Y', '4' | 0x80, ' ', - '(', 'E', 'Y', 'E', ')', '=', 'A', 'Y', - '4' | 0x80, '(', 'E', 'Y', ')', '=', 'I', 'Y' | 0x80, - '(', 'E', 'U', ')', '=', 'Y', 'U', 'W', - '5' | 0x80, '(', 'E', 'Q', 'U', 'A', 'L', ')', - '=', 'I', 'Y', '4', 'K', 'W', 'U', 'L' | 0x80, - '(', 'E', ')', '=', 'E', 'H' | 0x80, - - ']', 'F' | 0x80, ' ', '(', 'F', ')', ' ', '=', - 'E', 'H', '4', 'F' | 0x80, '(', 'F', 'U', 'L', - ')', '=', 'F', 'U', 'H', 'L' | 0x80, '(', 'F', - 'R', 'I', 'E', 'N', 'D', ')', '=', 'F', - 'R', 'E', 'H', '5', 'N', 'D' | 0x80, '(', 'F', - 'A', 'T', 'H', 'E', 'R', ')', '=', 'F', - 'A', 'A', '4', 'D', 'H', 'E', 'R' | 0x80, '(', - 'F', ')', 'F', '=' | 0x80, '(', 'F', ')', '=', - 'F' | 0x80, - - ']', 'G' | 0x80, ' ', '(', 'G', ')', ' ', '=', - 'J', 'I', 'Y', '4' | 0x80, '(', 'G', 'I', 'V', - ')', '=', 'G', 'I', 'H', '5', 'V' | 0x80, ' ', - '(', 'G', ')', 'I', '^', '=', 'G' | 0x80, '(', - 'G', 'E', ')', 'T', '=', 'G', 'E', 'H', - '5' | 0x80, 'S', 'U', '(', 'G', 'G', 'E', 'S', - ')', '=', 'G', 'J', 'E', 'H', '4', 'S' | 0x80, - '(', 'G', 'G', ')', '=', 'G' | 0x80, ' ', 'B', - '#', '(', 'G', ')', '=', 'G' | 0x80, '(', 'G', - ')', '+', '=', 'J' | 0x80, '(', 'G', 'R', 'E', - 'A', 'T', ')', '=', 'G', 'R', 'E', 'Y', - '4', 'T' | 0x80, '(', 'G', 'O', 'N', ')', 'E', - '=', 'G', 'A', 'O', '5', 'N' | 0x80, '#', '(', - 'G', 'H', ')', '=' | 0x80, ' ', '(', 'G', 'N', - ')', '=', 'N' | 0x80, '(', 'G', ')', '=', 'G' | 0x80, - - ']', 'H' | 0x80, ' ', '(', 'H', ')', ' ', '=', - 'E', 'Y', '4', 'C', 'H' | 0x80, ' ', '(', 'H', - 'A', 'V', ')', '=', '/', 'H', 'A', 'E', - '6', 'V' | 0x80, ' ', '(', 'H', 'E', 'R', 'E', - ')', '=', '/', 'H', 'I', 'Y', 'R' | 0x80, ' ', - '(', 'H', 'O', 'U', 'R', ')', '=', 'A', - 'W', '5', 'E', 'R' | 0x80, '(', 'H', 'O', 'W', - ')', '=', '/', 'H', 'A', 'W' | 0x80, '(', 'H', - ')', '#', '=', '/', 'H' | 0x80, '(', 'H', ')', - '=' | 0x80, - - ']', 'I' | 0x80, ' ', '(', 'I', 'N', ')', '=', - 'I', 'H', 'N' | 0x80, ' ', '(', 'I', ')', ' ', - '=', 'A', 'Y', '4' | 0x80, '(', 'I', ')', ' ', - '=', 'A', 'Y' | 0x80, '(', 'I', 'N', ')', 'D', - '=', 'A', 'Y', '5', 'N' | 0x80, 'S', 'E', 'M', - '(', 'I', ')', '=', 'I', 'Y' | 0x80, ' ', 'A', - 'N', 'T', '(', 'I', ')', '=', 'A', 'Y' | 0x80, - '(', 'I', 'E', 'R', ')', '=', 'I', 'Y', - 'E', 'R' | 0x80, '#', ':', 'R', '(', 'I', 'E', - 'D', ')', ' ', '=', 'I', 'Y', 'D' | 0x80, '(', - 'I', 'E', 'D', ')', ' ', '=', 'A', 'Y', - '5', 'D' | 0x80, '(', 'I', 'E', 'N', ')', '=', - 'I', 'Y', 'E', 'H', 'N' | 0x80, '(', 'I', 'E', - ')', 'T', '=', 'A', 'Y', '4', 'E', 'H' | 0x80, - '(', 'I', '\'', ')', '=', 'A', 'Y', '5' | 0x80, - ' ', ':', '(', 'I', ')', '^', '%', '=', - 'A', 'Y', '5' | 0x80, ' ', ':', '(', 'I', 'E', - ')', ' ', '=', 'A', 'Y', '4' | 0x80, '(', 'I', - ')', '%', '=', 'I', 'Y' | 0x80, '(', 'I', 'E', - ')', '=', 'I', 'Y', '4' | 0x80, ' ', '(', 'I', - 'D', 'E', 'A', ')', '=', 'A', 'Y', 'D', - 'I', 'Y', '5', 'A', 'H' | 0x80, '(', 'I', ')', - '^', '+', ':', '#', '=', 'I', 'H' | 0x80, '(', - 'I', 'R', ')', '#', '=', 'A', 'Y', 'R' | 0x80, - '(', 'I', 'Z', ')', '%', '=', 'A', 'Y', - 'Z' | 0x80, '(', 'I', 'S', ')', '%', '=', 'A', - 'Y', 'Z' | 0x80, 'I', '^', '(', 'I', ')', '^', - '#', '=', 'I', 'H' | 0x80, '+', '^', '(', 'I', - ')', '^', '+', '=', 'A', 'Y' | 0x80, '#', ':', - '^', '(', 'I', ')', '^', '+', '=', 'I', - 'H' | 0x80, '(', 'I', ')', '^', '+', '=', 'A', - 'Y' | 0x80, '(', 'I', 'R', ')', '=', 'E', 'R' | 0x80, - '(', 'I', 'G', 'H', ')', '=', 'A', 'Y', - '4' | 0x80, '(', 'I', 'L', 'D', ')', '=', 'A', - 'Y', '5', 'L', 'D' | 0x80, ' ', '(', 'I', 'G', - 'N', ')', '=', 'I', 'H', 'G', 'N' | 0x80, '(', - 'I', 'G', 'N', ')', ' ', '=', 'A', 'Y', - '4', 'N' | 0x80, '(', 'I', 'G', 'N', ')', '^', - '=', 'A', 'Y', '4', 'N' | 0x80, '(', 'I', 'G', - 'N', ')', '%', '=', 'A', 'Y', '4', 'N' | 0x80, - '(', 'I', 'C', 'R', 'O', ')', '=', 'A', - 'Y', '4', 'K', 'R', 'O', 'H' | 0x80, '(', 'I', - 'Q', 'U', 'E', ')', '=', 'I', 'Y', '4', - 'K' | 0x80, '(', 'I', ')', '=', 'I', 'H' | 0x80, - - ']', 'J' | 0x80, ' ', '(', 'J', ')', ' ', '=', - 'J', 'E', 'Y', '4' | 0x80, '(', 'J', ')', '=', - 'J' | 0x80, - - ']', 'K' | 0x80, ' ', '(', 'K', ')', ' ', '=', - 'K', 'E', 'Y', '4' | 0x80, ' ', '(', 'K', ')', - 'N', '=' | 0x80, '(', 'K', ')', '=', 'K' | 0x80, - - ']', 'L' | 0x80, ' ', '(', 'L', ')', ' ', '=', - 'E', 'H', '4', 'L' | 0x80, '(', 'L', 'O', ')', - 'C', '#', '=', 'L', 'O', 'W' | 0x80, 'L', '(', - 'L', ')', '=' | 0x80, '#', ':', '^', '(', 'L', - ')', '%', '=', 'U', 'L' | 0x80, '(', 'L', 'E', - 'A', 'D', ')', '=', 'L', 'I', 'Y', 'D' | 0x80, - ' ', '(', 'L', 'A', 'U', 'G', 'H', ')', - '=', 'L', 'A', 'E', '4', 'F' | 0x80, '(', 'L', - ')', '=', 'L' | 0x80, - - ']', 'M' | 0x80, ' ', '(', 'M', ')', ' ', '=', - 'E', 'H', '4', 'M' | 0x80, ' ', '(', 'M', 'R', - '.', ')', ' ', '=', 'M', 'I', 'H', '4', - 'S', 'T', 'E', 'R' | 0x80, ' ', '(', 'M', 'S', - '.', ')', '=', 'M', 'I', 'H', '5', 'Z' | 0x80, - ' ', '(', 'M', 'R', 'S', '.', ')', ' ', - '=', 'M', 'I', 'H', '4', 'S', 'I', 'X', - 'Z' | 0x80, '(', 'M', 'O', 'V', ')', '=', 'M', - 'U', 'W', '4', 'V' | 0x80, '(', 'M', 'A', 'C', - 'H', 'I', 'N', ')', '=', 'M', 'A', 'H', - 'S', 'H', 'I', 'Y', '5', 'N' | 0x80, 'M', '(', - 'M', ')', '=' | 0x80, '(', 'M', ')', '=', 'M' | 0x80, - - ']', 'N' | 0x80, ' ', '(', 'N', ')', ' ', '=', - 'E', 'H', '4', 'N' | 0x80, 'E', '(', 'N', 'G', - ')', '+', '=', 'N', 'J' | 0x80, '(', 'N', 'G', - ')', 'R', '=', 'N', 'X', 'G' | 0x80, '(', 'N', - 'G', ')', '#', '=', 'N', 'X', 'G' | 0x80, '(', - 'N', 'G', 'L', ')', '%', '=', 'N', 'X', - 'G', 'U', 'L' | 0x80, '(', 'N', 'G', ')', '=', - 'N', 'X' | 0x80, '(', 'N', 'K', ')', '=', 'N', - 'X', 'K' | 0x80, ' ', '(', 'N', 'O', 'W', ')', - ' ', '=', 'N', 'A', 'W', '4' | 0x80, 'N', '(', - 'N', ')', '=' | 0x80, '(', 'N', 'O', 'N', ')', - 'E', '=', 'N', 'A', 'H', '4', 'N' | 0x80, '(', - 'N', ')', '=', 'N' | 0x80, - - ']', 'O' | 0x80, ' ', '(', 'O', ')', ' ', '=', - 'O', 'H', '4', 'W' | 0x80, '(', 'O', 'F', ')', - ' ', '=', 'A', 'H', 'V' | 0x80, ' ', '(', 'O', - 'H', ')', ' ', '=', 'O', 'W', '5' | 0x80, '(', - 'O', 'R', 'O', 'U', 'G', 'H', ')', '=', - 'E', 'R', '4', 'O', 'W' | 0x80, '#', ':', '(', - 'O', 'R', ')', ' ', '=', 'E', 'R' | 0x80, '#', - ':', '(', 'O', 'R', 'S', ')', ' ', '=', - 'E', 'R', 'Z' | 0x80, '(', 'O', 'R', ')', '=', - 'A', 'O', 'R' | 0x80, ' ', '(', 'O', 'N', 'E', - ')', '=', 'W', 'A', 'H', 'N' | 0x80, '#', '(', - 'O', 'N', 'E', ')', ' ', '=', 'W', 'A', - 'H', 'N' | 0x80, '(', 'O', 'W', ')', '=', 'O', - 'W' | 0x80, ' ', '(', 'O', 'V', 'E', 'R', ')', - '=', 'O', 'W', '5', 'V', 'E', 'R' | 0x80, 'P', - 'R', '(', 'O', ')', 'V', '=', 'U', 'W', - '4' | 0x80, '(', 'O', 'V', ')', '=', 'A', 'H', - '4', 'V' | 0x80, '(', 'O', ')', '^', '%', '=', - 'O', 'W', '5' | 0x80, '(', 'O', ')', '^', 'E', - 'N', '=', 'O', 'W' | 0x80, '(', 'O', ')', '^', - 'I', '#', '=', 'O', 'W', '5' | 0x80, '(', 'O', - 'L', ')', 'D', '=', 'O', 'W', '4', 'L' | 0x80, - '(', 'O', 'U', 'G', 'H', 'T', ')', '=', - 'A', 'O', '5', 'T' | 0x80, '(', 'O', 'U', 'G', - 'H', ')', '=', 'A', 'H', '5', 'F' | 0x80, ' ', - '(', 'O', 'U', ')', '=', 'A', 'W' | 0x80, 'H', - '(', 'O', 'U', ')', 'S', '#', '=', 'A', - 'W', '4' | 0x80, '(', 'O', 'U', 'S', ')', '=', - 'A', 'X', 'S' | 0x80, '(', 'O', 'U', 'R', ')', - '=', 'O', 'H', 'R' | 0x80, '(', 'O', 'U', 'L', - 'D', ')', '=', 'U', 'H', '5', 'D' | 0x80, '(', - 'O', 'U', ')', '^', 'L', '=', 'A', 'H', - '5' | 0x80, '(', 'O', 'U', 'P', ')', '=', 'U', - 'W', '5', 'P' | 0x80, '(', 'O', 'U', ')', '=', - 'A', 'W' | 0x80, '(', 'O', 'Y', ')', '=', 'O', - 'Y' | 0x80, '(', 'O', 'I', 'N', 'G', ')', '=', - 'O', 'W', '4', 'I', 'H', 'N', 'X' | 0x80, '(', - 'O', 'I', ')', '=', 'O', 'Y', '5' | 0x80, '(', - 'O', 'O', 'R', ')', '=', 'O', 'H', '5', - 'R' | 0x80, '(', 'O', 'O', 'K', ')', '=', 'U', - 'H', '5', 'K' | 0x80, 'F', '(', 'O', 'O', 'D', - ')', '=', 'U', 'W', '5', 'D' | 0x80, 'L', '(', - 'O', 'O', 'D', ')', '=', 'A', 'H', '5', - 'D' | 0x80, 'M', '(', 'O', 'O', 'D', ')', '=', - 'U', 'W', '5', 'D' | 0x80, '(', 'O', 'O', 'D', - ')', '=', 'U', 'H', '5', 'D' | 0x80, 'F', '(', - 'O', 'O', 'T', ')', '=', 'U', 'H', '5', - 'T' | 0x80, '(', 'O', 'O', ')', '=', 'U', 'W', - '5' | 0x80, '(', 'O', '\'', ')', '=', 'O', 'H' | 0x80, - '(', 'O', ')', 'E', '=', 'O', 'W' | 0x80, '(', - 'O', ')', ' ', '=', 'O', 'W' | 0x80, '(', 'O', - 'A', ')', '=', 'O', 'W', '4' | 0x80, ' ', '(', - 'O', 'N', 'L', 'Y', ')', '=', 'O', 'W', - '4', 'N', 'L', 'I', 'Y' | 0x80, ' ', '(', 'O', - 'N', 'C', 'E', ')', '=', 'W', 'A', 'H', - '4', 'N', 'S' | 0x80, '(', 'O', 'N', '\'', 'T', - ')', '=', 'O', 'W', '4', 'N', 'T' | 0x80, 'C', - '(', 'O', ')', 'N', '=', 'A', 'A' | 0x80, '(', - 'O', ')', 'N', 'G', '=', 'A', 'O' | 0x80, ' ', - ':', '^', '(', 'O', ')', 'N', '=', 'A', - 'H' | 0x80, 'I', '(', 'O', 'N', ')', '=', 'U', - 'N' | 0x80, '#', ':', '(', 'O', 'N', ')', '=', - 'U', 'N' | 0x80, '#', '^', '(', 'O', 'N', ')', - '=', 'U', 'N' | 0x80, '(', 'O', ')', 'S', 'T', - '=', 'O', 'W' | 0x80, '(', 'O', 'F', ')', '^', - '=', 'A', 'O', '4', 'F' | 0x80, '(', 'O', 'T', - 'H', 'E', 'R', ')', '=', 'A', 'H', '5', - 'D', 'H', 'E', 'R' | 0x80, 'R', '(', 'O', ')', - 'B', '=', 'R', 'A', 'A' | 0x80, '^', 'R', '(', - 'O', ')', ':', '#', '=', 'O', 'W', '5' | 0x80, - '(', 'O', 'S', 'S', ')', ' ', '=', 'A', - 'O', '5', 'S' | 0x80, '#', ':', '^', '(', 'O', - 'M', ')', '=', 'A', 'H', 'M' | 0x80, '(', 'O', - ')', '=', 'A', 'A' | 0x80, - - ']', 'P' | 0x80, ' ', '(', 'P', ')', ' ', '=', - 'P', 'I', 'Y', '4' | 0x80, '(', 'P', 'H', ')', - '=', 'F' | 0x80, '(', 'P', 'E', 'O', 'P', 'L', - ')', '=', 'P', 'I', 'Y', '5', 'P', 'U', - 'L' | 0x80, '(', 'P', 'O', 'W', ')', '=', 'P', - 'A', 'W', '4' | 0x80, '(', 'P', 'U', 'T', ')', - ' ', '=', 'P', 'U', 'H', 'T' | 0x80, '(', 'P', - ')', 'P', '=' | 0x80, '(', 'P', ')', 'S', '=' | 0x80, - '(', 'P', ')', 'N', '=' | 0x80, '(', 'P', 'R', - 'O', 'F', '.', ')', '=', 'P', 'R', 'O', - 'H', 'F', 'E', 'H', '4', 'S', 'E', 'R' | 0x80, - '(', 'P', ')', '=', 'P' | 0x80, - - ']', 'Q' | 0x80, ' ', '(', 'Q', ')', ' ', '=', - 'K', 'Y', 'U', 'W', '4' | 0x80, '(', 'Q', 'U', - 'A', 'R', ')', '=', 'K', 'W', 'O', 'H', - '5', 'R' | 0x80, '(', 'Q', 'U', ')', '=', 'K', - 'W' | 0x80, '(', 'Q', ')', '=', 'K' | 0x80, ']', 'R' | 0x80, - ' ', '(', 'R', ')', ' ', '=', 'A', 'A', - '5', 'R' | 0x80, ' ', '(', 'R', 'E', ')', '^', - '#', '=', 'R', 'I', 'Y' | 0x80, '(', 'R', ')', - 'R', '=' | 0x80, '(', 'R', ')', '=', 'R' | 0x80, - - ']', 'S' | 0x80, ' ', '(', 'S', ')', ' ', '=', - 'E', 'H', '4', 'S' | 0x80, '(', 'S', 'H', ')', - '=', 'S', 'H' | 0x80, '#', '(', 'S', 'I', 'O', - 'N', ')', '=', 'Z', 'H', 'U', 'N' | 0x80, '(', - 'S', 'O', 'M', 'E', ')', '=', 'S', 'A', - 'H', 'M' | 0x80, '#', '(', 'S', 'U', 'R', ')', - '#', '=', 'Z', 'H', 'E', 'R' | 0x80, '(', 'S', - 'U', 'R', ')', '#', '=', 'S', 'H', 'E', - 'R' | 0x80, '#', '(', 'S', 'U', ')', '#', '=', - 'Z', 'H', 'U', 'W' | 0x80, '#', '(', 'S', 'S', - 'U', ')', '#', '=', 'S', 'H', 'U', 'W' | 0x80, - '#', '(', 'S', 'E', 'D', ')', '=', 'Z', - 'D' | 0x80, '#', '(', 'S', ')', '#', '=', 'Z' | 0x80, - '(', 'S', 'A', 'I', 'D', ')', '=', 'S', - 'E', 'H', 'D' | 0x80, '^', '(', 'S', 'I', 'O', - 'N', ')', '=', 'S', 'H', 'U', 'N' | 0x80, '(', - 'S', ')', 'S', '=' | 0x80, '.', '(', 'S', ')', - ' ', '=', 'Z' | 0x80, '#', ':', '.', 'E', '(', - 'S', ')', ' ', '=', 'Z' | 0x80, '#', ':', '^', - '#', '(', 'S', ')', ' ', '=', 'S' | 0x80, 'U', - '(', 'S', ')', ' ', '=', 'S' | 0x80, ' ', ':', - '#', '(', 'S', ')', ' ', '=', 'Z' | 0x80, '#', - '#', '(', 'S', ')', ' ', '=', 'Z' | 0x80, ' ', - '(', 'S', 'C', 'H', ')', '=', 'S', 'K' | 0x80, - '(', 'S', ')', 'C', '+', '=' | 0x80, '#', '(', - 'S', 'M', ')', '=', 'Z', 'U', 'M' | 0x80, '#', - '(', 'S', 'N', ')', '\'', '=', 'Z', 'U', - 'M' | 0x80, '(', 'S', 'T', 'L', 'E', ')', '=', - 'S', 'U', 'L' | 0x80, '(', 'S', ')', '=', 'S' | 0x80, - - ']', 'T' | 0x80, ' ', '(', 'T', ')', ' ', '=', - 'T', 'I', 'Y', '4' | 0x80, ' ', '(', 'T', 'H', - 'E', ')', ' ', '#', '=', 'D', 'H', 'I', - 'Y' | 0x80, ' ', '(', 'T', 'H', 'E', ')', ' ', - '=', 'D', 'H', 'A', 'X' | 0x80, '(', 'T', 'O', - ')', ' ', '=', 'T', 'U', 'X' | 0x80, ' ', '(', - 'T', 'H', 'A', 'T', ')', '=', 'D', 'H', - 'A', 'E', 'T' | 0x80, ' ', '(', 'T', 'H', 'I', - 'S', ')', ' ', '=', 'D', 'H', 'I', 'H', - 'S' | 0x80, ' ', '(', 'T', 'H', 'E', 'Y', ')', - '=', 'D', 'H', 'E', 'Y' | 0x80, ' ', '(', 'T', - 'H', 'E', 'R', 'E', ')', '=', 'D', 'H', - 'E', 'H', 'R' | 0x80, '(', 'T', 'H', 'E', 'R', - ')', '=', 'D', 'H', 'E', 'R' | 0x80, '(', 'T', - 'H', 'E', 'I', 'R', ')', '=', 'D', 'H', - 'E', 'H', 'R' | 0x80, ' ', '(', 'T', 'H', 'A', - 'N', ')', ' ', '=', 'D', 'H', 'A', 'E', - 'N' | 0x80, ' ', '(', 'T', 'H', 'E', 'M', ')', - ' ', '=', 'D', 'H', 'A', 'E', 'N' | 0x80, '(', - 'T', 'H', 'E', 'S', 'E', ')', ' ', '=', - 'D', 'H', 'I', 'Y', 'Z' | 0x80, ' ', '(', 'T', - 'H', 'E', 'N', ')', '=', 'D', 'H', 'E', - 'H', 'N' | 0x80, '(', 'T', 'H', 'R', 'O', 'U', - 'G', 'H', ')', '=', 'T', 'H', 'R', 'U', - 'W', '4' | 0x80, '(', 'T', 'H', 'O', 'S', 'E', - ')', '=', 'D', 'H', 'O', 'H', 'Z' | 0x80, '(', - 'T', 'H', 'O', 'U', 'G', 'H', ')', ' ', - '=', 'D', 'H', 'O', 'W' | 0x80, '(', 'T', 'O', - 'D', 'A', 'Y', ')', '=', 'T', 'U', 'X', - 'D', 'E', 'Y' | 0x80, '(', 'T', 'O', 'M', 'O', - ')', 'R', 'R', 'O', 'W', '=', 'T', 'U', - 'M', 'A', 'A', '5' | 0x80, '(', 'T', 'O', ')', - 'T', 'A', 'L', '=', 'T', 'O', 'W', '5' | 0x80, - ' ', '(', 'T', 'H', 'U', 'S', ')', '=', - 'D', 'H', 'A', 'H', '4', 'S' | 0x80, '(', 'T', - 'H', ')', '=', 'T', 'H' | 0x80, '#', ':', '(', - 'T', 'E', 'D', ')', '=', 'T', 'I', 'X', - 'D' | 0x80, 'S', '(', 'T', 'I', ')', '#', 'N', - '=', 'C', 'H' | 0x80, '(', 'T', 'I', ')', 'O', - '=', 'S', 'H' | 0x80, '(', 'T', 'I', ')', 'A', - '=', 'S', 'H' | 0x80, '(', 'T', 'I', 'E', 'N', - ')', '=', 'S', 'H', 'U', 'N' | 0x80, '(', 'T', - 'U', 'R', ')', '#', '=', 'C', 'H', 'E', - 'R' | 0x80, '(', 'T', 'U', ')', 'A', '=', 'C', - 'H', 'U', 'W' | 0x80, ' ', '(', 'T', 'W', 'O', - ')', '=', 'T', 'U', 'W' | 0x80, '&', '(', 'T', - ')', 'E', 'N', ' ', '=' | 0x80, '(', 'T', ')', - '=', 'T' | 0x80, - - ']', 'U' | 0x80, ' ', '(', 'U', ')', ' ', '=', - 'Y', 'U', 'W', '4' | 0x80, ' ', '(', 'U', 'N', - ')', 'I', '=', 'Y', 'U', 'W', 'N' | 0x80, ' ', - '(', 'U', 'N', ')', '=', 'A', 'H', 'N' | 0x80, - ' ', '(', 'U', 'P', 'O', 'N', ')', '=', - 'A', 'X', 'P', 'A', 'O', 'N' | 0x80, '@', '(', - 'U', 'R', ')', '#', '=', 'U', 'H', '4', - 'R' | 0x80, '(', 'U', 'R', ')', '#', '=', 'Y', - 'U', 'H', '4', 'R' | 0x80, '(', 'U', 'R', ')', - '=', 'E', 'R' | 0x80, '(', 'U', ')', '^', ' ', - '=', 'A', 'H' | 0x80, '(', 'U', ')', '^', '^', - '=', 'A', 'H', '5' | 0x80, '(', 'U', 'Y', ')', - '=', 'A', 'Y', '5' | 0x80, ' ', 'G', '(', 'U', - ')', '#', '=' | 0x80, 'G', '(', 'U', ')', '%', - '=' | 0x80, 'G', '(', 'U', ')', '#', '=', 'W' | 0x80, - '#', 'N', '(', 'U', ')', '=', 'Y', 'U', - 'W' | 0x80, '@', '(', 'U', ')', '=', 'U', 'W' | 0x80, - '(', 'U', ')', '=', 'Y', 'U', 'W' | 0x80, - - ']', 'V' | 0x80, ' ', '(', 'V', ')', ' ', '=', - 'V', 'I', 'Y', '4' | 0x80, '(', 'V', 'I', 'E', - 'W', ')', '=', 'V', 'Y', 'U', 'W', '5' | 0x80, - '(', 'V', ')', '=', 'V' | 0x80, - - ']', 'W' | 0x80, ' ', '(', 'W', ')', ' ', '=', - 'D', 'A', 'H', '4', 'B', 'U', 'L', 'Y', - 'U', 'W' | 0x80, ' ', '(', 'W', 'E', 'R', 'E', - ')', '=', 'W', 'E', 'R' | 0x80, '(', 'W', 'A', - ')', 'S', 'H', '=', 'W', 'A', 'A' | 0x80, '(', - 'W', 'A', ')', 'S', 'T', '=', 'W', 'E', - 'Y' | 0x80, '(', 'W', 'A', ')', 'S', '=', 'W', - 'A', 'H' | 0x80, '(', 'W', 'A', ')', 'T', '=', - 'W', 'A', 'A' | 0x80, '(', 'W', 'H', 'E', 'R', - 'E', ')', '=', 'W', 'H', 'E', 'H', 'R' | 0x80, - '(', 'W', 'H', 'A', 'T', ')', '=', 'W', - 'H', 'A', 'H', 'T' | 0x80, '(', 'W', 'H', 'O', - 'L', ')', '=', '/', 'H', 'O', 'W', 'L' | 0x80, - '(', 'W', 'H', 'O', ')', '=', '/', 'H', - 'U', 'W' | 0x80, '(', 'W', 'H', ')', '=', 'W', - 'H' | 0x80, '(', 'W', 'A', 'R', ')', '#', '=', - 'W', 'E', 'H', 'R' | 0x80, '(', 'W', 'A', 'R', - ')', '=', 'W', 'A', 'O', 'R' | 0x80, '(', 'W', - 'O', 'R', ')', '^', '=', 'W', 'E', 'R' | 0x80, - '(', 'W', 'R', ')', '=', 'R' | 0x80, '(', 'W', - 'O', 'M', ')', 'A', '=', 'W', 'U', 'H', - 'M' | 0x80, '(', 'W', 'O', 'M', ')', 'E', '=', - 'W', 'I', 'H', 'M' | 0x80, '(', 'W', 'E', 'A', - ')', 'R', '=', 'W', 'E', 'H' | 0x80, '(', 'W', - 'A', 'N', 'T', ')', '=', 'W', 'A', 'A', - '5', 'N', 'T' | 0x80, 'A', 'N', 'S', '(', 'W', - 'E', 'R', ')', '=', 'E', 'R' | 0x80, '(', 'W', - ')', '=', 'W' | 0x80, - - ']', 'X' | 0x80, ' ', '(', 'X', ')', ' ', '=', - 'E', 'H', '4', 'K', 'R' | 0x80, ' ', '(', 'X', - ')', '=', 'Z' | 0x80, '(', 'X', ')', '=', 'K', - 'S' | 0x80, - - ']', 'Y' | 0x80, ' ', '(', 'Y', ')', ' ', '=', - 'W', 'A', 'Y', '4' | 0x80, '(', 'Y', 'O', 'U', - 'N', 'G', ')', '=', 'Y', 'A', 'H', 'N', - 'X' | 0x80, ' ', '(', 'Y', 'O', 'U', 'R', ')', - '=', 'Y', 'O', 'H', 'R' | 0x80, ' ', '(', 'Y', - 'O', 'U', ')', '=', 'Y', 'U', 'W' | 0x80, ' ', - '(', 'Y', 'E', 'S', ')', '=', 'Y', 'E', - 'H', 'S' | 0x80, ' ', '(', 'Y', ')', '=', 'Y' | 0x80, - 'F', '(', 'Y', ')', '=', 'A', 'Y' | 0x80, 'P', - 'S', '(', 'Y', 'C', 'H', ')', '=', 'A', - 'Y', 'K' | 0x80, '#', ':', '^', '(', 'Y', ')', - '=', 'I', 'Y' | 0x80, '#', ':', '^', '(', 'Y', - ')', 'I', '=', 'I', 'Y' | 0x80, ' ', ':', '(', - 'Y', ')', ' ', '=', 'A', 'Y' | 0x80, ' ', ':', - '(', 'Y', ')', '#', '=', 'A', 'Y' | 0x80, ' ', - ':', '(', 'Y', ')', '^', '+', ':', '#', - '=', 'I', 'H' | 0x80, ' ', ':', '(', 'Y', ')', - '^', '#', '=', 'A', 'Y' | 0x80, '(', 'Y', ')', - '=', 'I', 'H' | 0x80, - - ']', 'Z' | 0x80, ' ', '(', 'Z', ')', ' ', '=', - 'Z', 'I', 'Y', '4' | 0x80, '(', 'Z', ')', '=', - 'Z' | 0x80, 'j' | 0x80}; - -const unsigned char rules2[] = { - '(', 'A', ')', '=' | 0x80, '(', '!', ')', '=', - '.' | 0x80, '(', '"', ')', ' ', '=', '-', 'A', - 'H', '5', 'N', 'K', 'W', 'O', 'W', 'T', - '-' | 0x80, '(', '"', ')', '=', 'K', 'W', 'O', - 'W', '4', 'T', '-' | 0x80, '(', '#', ')', '=', - ' ', 'N', 'A', 'H', '4', 'M', 'B', 'E', - 'R' | 0x80, '(', '$', ')', '=', ' ', 'D', 'A', - 'A', '4', 'L', 'E', 'R' | 0x80, '(', '%', ')', - '=', ' ', 'P', 'E', 'R', 'S', 'E', 'H', - '4', 'N', 'T' | 0x80, '(', '&', ')', '=', ' ', - 'A', 'E', 'N', 'D' | 0x80, '(', '\'', ')', '=' | 0x80, - '(', '*', ')', '=', ' ', 'A', 'E', '4', - 'S', 'T', 'E', 'R', 'I', 'H', 'S', 'K' | 0x80, - '(', '+', ')', '=', ' ', 'P', 'L', 'A', - 'H', '4', 'S' | 0x80, '(', ',', ')', '=', ',' | 0x80, - ' ', '(', '-', ')', ' ', '=', '-' | 0x80, '(', - '-', ')', '=' | 0x80, '(', '.', ')', '=', ' ', - 'P', 'O', 'Y', 'N', 'T' | 0x80, '(', '/', ')', - '=', ' ', 'S', 'L', 'A', 'E', '4', 'S', - 'H' | 0x80, '(', '0', ')', '=', ' ', 'Z', 'I', - 'Y', '4', 'R', 'O', 'W' | 0x80, ' ', '(', '1', - 'S', 'T', ')', '=', 'F', 'E', 'R', '4', - 'S', 'T' | 0x80, ' ', '(', '1', '0', 'T', 'H', - ')', '=', 'T', 'E', 'H', '4', 'N', 'T', - 'H' | 0x80, '(', '1', ')', '=', ' ', 'W', 'A', - 'H', '4', 'N' | 0x80, ' ', '(', '2', 'N', 'D', - ')', '=', 'S', 'E', 'H', '4', 'K', 'U', - 'N', 'D' | 0x80, '(', '2', ')', '=', ' ', 'T', - 'U', 'W', '4' | 0x80, ' ', '(', '3', 'R', 'D', - ')', '=', 'T', 'H', 'E', 'R', '4', 'D' | 0x80, - '(', '3', ')', '=', ' ', 'T', 'H', 'R', - 'I', 'Y', '4' | 0x80, '(', '4', ')', '=', ' ', - 'F', 'O', 'H', '4', 'R' | 0x80, ' ', '(', '5', - 'T', 'H', ')', '=', 'F', 'I', 'H', '4', - 'F', 'T', 'H' | 0x80, '(', '5', ')', '=', ' ', - 'F', 'A', 'Y', '4', 'V' | 0x80, ' ', '(', '6', - '4', ')', ' ', '=', 'S', 'I', 'H', '4', - 'K', 'S', 'T', 'I', 'Y', ' ', 'F', 'O', - 'H', 'R' | 0x80, '(', '6', ')', '=', ' ', 'S', - 'I', 'H', '4', 'K', 'S' | 0x80, '(', '7', ')', - '=', ' ', 'S', 'E', 'H', '4', 'V', 'U', - 'N' | 0x80, ' ', '(', '8', 'T', 'H', ')', '=', - 'E', 'Y', '4', 'T', 'H' | 0x80, '(', '8', ')', - '=', ' ', 'E', 'Y', '4', 'T' | 0x80, '(', '9', - ')', '=', ' ', 'N', 'A', 'Y', '4', 'N' | 0x80, - '(', ':', ')', '=', '.' | 0x80, '(', ';', ')', - '=', '.' | 0x80, '(', '<', ')', '=', ' ', 'L', - 'E', 'H', '4', 'S', ' ', 'D', 'H', 'A', - 'E', 'N' | 0x80, '(', '=', ')', '=', ' ', 'I', - 'Y', '4', 'K', 'W', 'U', 'L', 'Z' | 0x80, '(', - '>', ')', '=', ' ', 'G', 'R', 'E', 'Y', - '4', 'T', 'E', 'R', ' ', 'D', 'H', 'A', - 'E', 'N' | 0x80, '(', '?', ')', '=', '?' | 0x80, '(', - '@', ')', '=', ' ', 'A', 'E', '6', 'T' | 0x80, - '(', '^', ')', '=', ' ', 'K', 'A', 'E', - '4', 'R', 'I', 'X', 'T' | 0x80, ']', 'A' | 0x80}; - -//26 items. From 'A' to 'Z' -// positions for mem62 and mem63 for each character -const unsigned char tab37489[] = {0, 149, 247, 162, 57, 197, 6, 126, 199, 38, 55, 78, 145, - 241, 85, 161, 254, 36, 69, 45, 167, 54, 83, 46, 71, 218}; - -const unsigned char tab37515[] = {125, 126, 126, 127, 128, 129, 130, 130, 130, 132, 132, 132, 132, - 132, 133, 135, 135, 136, 136, 137, 138, 139, 139, 140, 140, 140}; - -void STM32SAM::Output8BitAry(int index, unsigned char ary[5]) { - int k; - - uint32_t bufferposOld = bufferpos; - - bufferpos += timetable[oldtimetableindex][index]; - oldtimetableindex = index; - - int sample_uS = bufferpos - bufferposOld; - - uint32_t f = 0; - - // write a little bit in advance - for(k = 0; k < 5; k++) { - // buffer[bufferpos / 50 + k] = ary[k]; - - // f = micros() + sample_uS / (_STM32SAM_SPEED + 1); - // while(micros() < f) { - // }; - f = sample_uS / (_STM32SAM_SPEED + 1); - furi_delay_us(f); - SetAUDIO(ary[k]); - // delayMicroseconds(sample_uS / 5 ); - } - - // SetAUDIO(ary[0]); -} - -void STM32SAM::Output8Bit(int index, unsigned char A) { - unsigned char ary[5] = {A, A, A, A, A}; - Output8BitAry(index, ary); -} - -//written by me because of different table positions. -// mem[47] = ... -// 168=pitches -// 169=frequency1 -// 170=frequency2 -// 171=frequency3 -// 172=amplitude1 -// 173=amplitude2 -// 174=amplitude3 -unsigned char STM32SAM::Read(unsigned char p, unsigned char Y) { - switch(p) { - case 168: - return pitches[Y]; - case 169: - return frequency1[Y]; - case 170: - return frequency2[Y]; - case 171: - return frequency3[Y]; - case 172: - return amplitude1[Y]; - case 173: - return amplitude2[Y]; - case 174: - return amplitude3[Y]; - } - // Serial1.println("Error reading to tables"); - return 0; -} - -void STM32SAM::Write(unsigned char p, unsigned char Y, unsigned char value) { - switch(p) { - case 168: - pitches[Y] = value; - return; - case 169: - frequency1[Y] = value; - return; - case 170: - frequency2[Y] = value; - return; - case 171: - frequency3[Y] = value; - return; - case 172: - amplitude1[Y] = value; - return; - case 173: - amplitude2[Y] = value; - return; - case 174: - amplitude3[Y] = value; - return; - } - //Serial1.println("Error writing to tables\n"); -} - -// ------------------------------------------------------------------------- -//Code48227 -// Render a sampled sound from the sampleTable. -// -// Phoneme Sample Start Sample End -// 32: S* 15 255 -// 33: SH 257 511 -// 34: F* 559 767 -// 35: TH 583 767 -// 36: /H 903 1023 -// 37: /X 1135 1279 -// 38: Z* 84 119 -// 39: ZH 340 375 -// 40: V* 596 639 -// 41: DH 596 631 -// -// 42: CH -// 43: ** 399 511 -// -// 44: J* -// 45: ** 257 276 -// 46: ** -// -// 66: P* -// 67: ** 743 767 -// 68: ** -// -// 69: T* -// 70: ** 231 255 -// 71: ** -// -// The SampledPhonemesTable[] holds flags indicating if a phoneme is -// voiced or not. If the upper 5 bits are zero, the sample is voiced. -// -// Samples in the sampleTable are compressed, with bits being converted to -// bytes from high bit to low, as follows: -// -// unvoiced 0 bit -> X -// unvoiced 1 bit -> 5 -// -// voiced 0 bit -> 6 -// voiced 1 bit -> 24 -// -// Where X is a value from the table: -// -// { 0x18, 0x1A, 0x17, 0x17, 0x17 }; -// -// The index into this table is determined by masking off the lower -// 3 bits from the SampledPhonemesTable: -// -// index = (SampledPhonemesTable[i] & 7) - 1; -// -// For voices samples, samples are interleaved between voiced output. - -// Code48227() -void STM32SAM::RenderSample(unsigned char* mem66) { - int tempA; - // current phoneme's index - mem49 = Y; - - // mask low three bits and subtract 1 get value to - // convert 0 bits on unvoiced samples. - A = mem39 & 7; - X = A - 1; - - // store the result - mem56 = X; - - // determine which offset to use from table { 0x18, 0x1A, 0x17, 0x17, 0x17 } - // T, S, Z 0 0x18 - // CH, J, SH, ZH 1 0x1A - // P, F*, V, TH, DH 2 0x17 - // /H 3 0x17 - // /X 4 0x17 - - // get value from the table - mem53 = tab48426[X]; - mem47 = X; //46016+mem[56]*256 - - // voiced sample? - A = mem39 & 248; - if(A == 0) { - // voiced phoneme: Z*, ZH, V*, DH - Y = mem49; - A = pitches[mem49] >> 4; - - // jump to voiced portion - goto pos48315; - } - - Y = A ^ 255; -pos48274: - - // step through the 8 bits in the sample - mem56 = 8; - - // get the next sample from the table - // mem47*256 = offset to start of samples - A = sampleTable[mem47 * 256 + Y]; -pos48280: - - // left shift to get the high bit - tempA = A; - A = A << 1; - //48281: BCC 48290 - - // bit not set? - if((tempA & 128) == 0) { - // convert the bit to value from table - X = mem53; - //mem[54296] = X; - // output the byte - Output8Bit(1, (X & 0x0f) * 16); - // if X != 0, exit loop - if(X != 0) goto pos48296; - } - - // output a 5 for the on bit - Output8Bit(2, 5 * 16); - - //48295: NOP -pos48296: - - X = 0; - - // decrement counter - mem56--; - - // if not done, jump to top of loop - if(mem56 != 0) goto pos48280; - - // increment position - Y++; - if(Y != 0) goto pos48274; - - // restore values and return - mem44 = 1; - Y = mem49; - return; - - unsigned char phase1; - -pos48315: - // handle voiced samples here - - // number of samples? - phase1 = A ^ 255; - - Y = *mem66; - do { - //pos48321: - - // shift through all 8 bits - mem56 = 8; - //A = Read(mem47, Y); - - // fetch value from table - A = sampleTable[mem47 * 256 + Y]; - - // loop 8 times - //pos48327: - do { - //48327: ASL A - //48328: BCC 48337 - - // left shift and check high bit - tempA = A; - A = A << 1; - if((tempA & 128) != 0) { - // if bit set, output 26 - X = 26; - Output8Bit(3, (X & 0xf) * 16); - } else { - //timetable 4 - // bit is not set, output a 6 - X = 6; - Output8Bit(4, (X & 0xf) * 16); - } - - mem56--; - } while(mem56 != 0); - - // move ahead in the table - Y++; - - // continue until counter done - phase1++; - - } while(phase1 != 0); - // if (phase1 != 0) goto pos48321; - - // restore values and return - A = 1; - mem44 = 1; - *mem66 = Y; - Y = mem49; - return; -} - -// RENDER THE PHONEMES IN THE LIST -// -// The phoneme list is converted into sound through the steps: -// -// 1. Copy each phoneme number of times into the frames list, -// where each frame represents 10 milliseconds of sound. -// -// 2. Determine the transitions lengths between phonemes, and linearly -// interpolate the values across the frames. -// -// 3. Offset the pitches by the fundamental frequency. -// -// 4. Render the each frame. - -//void Code47574() -void STM32SAM::Render() { - unsigned char phase1 = 0; //mem43 - unsigned char phase2 = 0; - unsigned char phase3 = 0; - unsigned char mem66 = 0; - unsigned char mem38 = 0; - unsigned char mem40 = 0; - unsigned char speedcounter = 0; //mem45 - unsigned char mem48 = 0; - int i; - if(phonemeIndexOutput[0] == 255) return; //exit if no data - - A = 0; - X = 0; - mem44 = 0; - - // CREATE FRAMES - // - // The length parameter in the list corresponds to the number of frames - // to expand the phoneme to. Each frame represents 10 milliseconds of time. - // So a phoneme with a length of 7 = 7 frames = 70 milliseconds duration. - // - // The parameters are copied from the phoneme to the frame verbatim. - - // pos47587: - do { - // get the index - Y = mem44; - // get the phoneme at the index - A = phonemeIndexOutput[mem44]; - mem56 = A; - - // if terminal phoneme, exit the loop - if(A == 255) break; - - // period phoneme *. - if(A == 1) { - // add rising inflection - A = 1; - mem48 = 1; - //goto pos48376; - AddInflection(mem48, phase1); - } - /* - if (A == 2) goto pos48372; - */ - - // question mark phoneme? - if(A == 2) { - // create falling inflection - mem48 = 255; - AddInflection(mem48, phase1); - } - // pos47615: - - // get the stress amount (more stress = higher pitch) - phase1 = tab47492[stressOutput[Y] + 1]; - - // get number of frames to write - phase2 = phonemeLengthOutput[Y]; - Y = mem56; - - // copy from the source to the frames list - do { - frequency1[X] = freq1data[Y]; // F1 frequency - frequency2[X] = freq2data[Y]; // F2 frequency - frequency3[X] = freq3data[Y]; // F3 frequency - amplitude1[X] = ampl1data[Y]; // F1 amplitude - amplitude2[X] = ampl2data[Y]; // F2 amplitude - amplitude3[X] = ampl3data[Y]; // F3 amplitude - sampledConsonantFlag[X] = - sampledConsonantFlags[Y]; // phoneme data for sampled consonants - pitches[X] = pitch + phase1; // pitch - X++; - phase2--; - } while(phase2 != 0); - mem44++; - } while(mem44 != 0); - // ------------------- - //pos47694: - - // CREATE TRANSITIONS - // - // Linear transitions are now created to smoothly connect the - // end of one sustained portion of a phoneme to the following - // phoneme. - // - // To do this, three tables are used: - // - // Table Purpose - // ========= ================================================== - // blendRank Determines which phoneme's blend values are used. - // - // blendOut The number of frames at the end of the phoneme that - // will be used to transition to the following phoneme. - // - // blendIn The number of frames of the following phoneme that - // will be used to transition into that phoneme. - // - // In creating a transition between two phonemes, the phoneme - // with the HIGHEST rank is used. Phonemes are ranked on how much - // their identity is based on their transitions. For example, - // vowels are and diphthongs are identified by their sustained portion, - // rather than the transitions, so they are given low values. In contrast, - // stop consonants (P, B, T, K) and glides (Y, L) are almost entirely - // defined by their transitions, and are given high rank values. - // - // Here are the rankings used by SAM: - // - // Rank Type Phonemes - // 2 All vowels IY, IH, etc. - // 5 Diphthong endings YX, WX, ER - // 8 Terminal liquid consonants LX, WX, YX, N, NX - // 9 Liquid consonants L, RX, W - // 10 Glide R, OH - // 11 Glide WH - // 18 Voiceless fricatives S, SH, F, TH - // 20 Voiced fricatives Z, ZH, V, DH - // 23 Plosives, stop consonants P, T, K, KX, DX, CH - // 26 Stop consonants J, GX, B, D, G - // 27-29 Stop consonants (internal) ** - // 30 Unvoiced consonants /H, /X and Q* - // 160 Nasal M - // - // To determine how many frames to use, the two phonemes are - // compared using the blendRank[] table. The phoneme with the - // higher rank is selected. In case of a tie, a blend of each is used: - // - // if blendRank[phoneme1] == blendRank[phomneme2] - // // use lengths from each phoneme - // outBlendFrames = outBlend[phoneme1] - // inBlendFrames = outBlend[phoneme2] - // else if blendRank[phoneme1] > blendRank[phoneme2] - // // use lengths from first phoneme - // outBlendFrames = outBlendLength[phoneme1] - // inBlendFrames = inBlendLength[phoneme1] - // else - // // use lengths from the second phoneme - // // note that in and out are SWAPPED! - // outBlendFrames = inBlendLength[phoneme2] - // inBlendFrames = outBlendLength[phoneme2] - // - // Blend lengths can't be less than zero. - // - // Transitions are assumed to be symetrical, so if the transition - // values for the second phoneme are used, the inBlendLength and - // outBlendLength values are SWAPPED. - // - // For most of the parameters, SAM interpolates over the range of the last - // outBlendFrames-1 and the first inBlendFrames. - // - // The exception to this is the Pitch[] parameter, which is interpolates the - // pitch from the CENTER of the current phoneme to the CENTER of the next - // phoneme. - // - // Here are two examples. First, For example, consider the word "SUN" (S AH N) - // - // Phoneme Duration BlendWeight OutBlendFrames InBlendFrames - // S 2 18 1 3 - // AH 8 2 4 4 - // N 7 8 1 2 - // - // The formant transitions for the output frames are calculated as follows: - // - // flags ampl1 freq1 ampl2 freq2 ampl3 freq3 pitch - // ------------------------------------------------ - // S - // 241 0 6 0 73 0 99 61 Use S (weight 18) for transition instead of AH (weight 2) - // 241 0 6 0 73 0 99 61 <-- (OutBlendFrames-1) = (1-1) = 0 frames - // AH - // 0 2 10 2 66 0 96 59 * <-- InBlendFrames = 3 frames - // 0 4 14 3 59 0 93 57 * - // 0 8 18 5 52 0 90 55 * - // 0 15 22 9 44 1 87 53 - // 0 15 22 9 44 1 87 53 - // 0 15 22 9 44 1 87 53 Use N (weight 8) for transition instead of AH (weight 2). - // 0 15 22 9 44 1 87 53 Since N is second phoneme, reverse the IN and OUT values. - // 0 11 17 8 47 1 98 56 * <-- (InBlendFrames-1) = (2-1) = 1 frames - // N - // 0 8 12 6 50 1 109 58 * <-- OutBlendFrames = 1 - // 0 5 6 5 54 0 121 61 - // 0 5 6 5 54 0 121 61 - // 0 5 6 5 54 0 121 61 - // 0 5 6 5 54 0 121 61 - // 0 5 6 5 54 0 121 61 - // 0 5 6 5 54 0 121 61 - // - // Now, consider the reverse "NUS" (N AH S): - // - // flags ampl1 freq1 ampl2 freq2 ampl3 freq3 pitch - // ------------------------------------------------ - // N - // 0 5 6 5 54 0 121 61 - // 0 5 6 5 54 0 121 61 - // 0 5 6 5 54 0 121 61 - // 0 5 6 5 54 0 121 61 - // 0 5 6 5 54 0 121 61 - // 0 5 6 5 54 0 121 61 Use N (weight 8) for transition instead of AH (weight 2) - // 0 5 6 5 54 0 121 61 <-- (OutBlendFrames-1) = (1-1) = 0 frames - // AH - // 0 8 11 6 51 0 110 59 * <-- InBlendFrames = 2 - // 0 11 16 8 48 0 99 56 * - // 0 15 22 9 44 1 87 53 Use S (weight 18) for transition instead of AH (weight 2) - // 0 15 22 9 44 1 87 53 Since S is second phoneme, reverse the IN and OUT values. - // 0 9 18 5 51 1 90 55 * <-- (InBlendFrames-1) = (3-1) = 2 - // 0 4 14 3 58 1 93 57 * - // S - // 241 2 10 2 65 1 96 59 * <-- OutBlendFrames = 1 - // 241 0 6 0 73 0 99 61 - - A = 0; - mem44 = 0; - mem49 = 0; // mem49 starts at as 0 - X = 0; - while(1) //while No. 1 - { - // get the current and following phoneme - Y = phonemeIndexOutput[X]; - A = phonemeIndexOutput[X + 1]; - X++; - - // exit loop at end token - if(A == 255) break; //goto pos47970; - - // get the ranking of each phoneme - X = A; - mem56 = blendRank[A]; - A = blendRank[Y]; - - // compare the rank - lower rank value is stronger - if(A == mem56) { - // same rank, so use out blend lengths from each phoneme - phase1 = outBlendLength[Y]; - phase2 = outBlendLength[X]; - } else if(A < mem56) { - // first phoneme is stronger, so us it's blend lengths - phase1 = inBlendLength[X]; - phase2 = outBlendLength[X]; - } else { - // second phoneme is stronger, so use it's blend lengths - // note the out/in are swapped - phase1 = outBlendLength[Y]; - phase2 = inBlendLength[Y]; - } - - Y = mem44; - A = mem49 + phonemeLengthOutput[mem44]; // A is mem49 + length - mem49 = A; // mem49 now holds length + position - A = A + phase2; //Maybe Problem because of carry flag - - //47776: ADC 42 - speedcounter = A; - mem47 = 168; - phase3 = mem49 - phase1; // what is mem49 - A = phase1 + phase2; // total transition? - mem38 = A; - - X = A; - X -= 2; - if((X & 128) == 0) - do //while No. 2 - { - //pos47810: - - // mem47 is used to index the tables: - // 168 pitches[] - // 169 frequency1 - // 170 frequency2 - // 171 frequency3 - // 172 amplitude1 - // 173 amplitude2 - // 174 amplitude3 - - mem40 = mem38; - - if(mem47 == 168) // pitch - { - // unlike the other values, the pitches[] interpolates from - // the middle of the current phoneme to the middle of the - // next phoneme - - unsigned char mem36, mem37; - // half the width of the current phoneme - mem36 = phonemeLengthOutput[mem44] >> 1; - // half the width of the next phoneme - mem37 = phonemeLengthOutput[mem44 + 1] >> 1; - // sum the values - mem40 = mem36 + mem37; // length of both halves - mem37 += mem49; // center of next phoneme - mem36 = mem49 - mem36; // center index of current phoneme - A = Read( - mem47, mem37); // value at center of next phoneme - end interpolation value - //A = mem[address]; - - Y = mem36; // start index of interpolation - mem53 = A - Read(mem47, mem36); // value to center of current phoneme - } else { - // value to interpolate to - A = Read(mem47, speedcounter); - // position to start interpolation from - Y = phase3; - // value to interpolate from - mem53 = A - Read(mem47, phase3); - } - - //Code47503(mem40); - // ML : Code47503 is division with remainder, and mem50 gets the sign - - // calculate change per frame - signed char m53 = (signed char)mem53; - mem50 = mem53 & 128; - unsigned char m53abs = abs(m53); - mem51 = m53abs % mem40; //abs((char)m53) % mem40; - mem53 = (unsigned char)((signed char)(m53) / mem40); - - // interpolation range - X = mem40; // number of frames to interpolate over - Y = phase3; // starting frame - - // linearly interpolate values - - mem56 = 0; - //47907: CLC - //pos47908: - while(1) //while No. 3 - { - A = Read(mem47, Y) + mem53; //carry alway cleared - - mem48 = A; - Y++; - X--; - if(X == 0) break; - - mem56 += mem51; - if(mem56 >= mem40) //??? - { - mem56 -= mem40; //carry? is set - //if ((mem56 & 128)==0) - if((mem50 & 128) == 0) { - //47935: BIT 50 - //47937: BMI 47943 - if(mem48 != 0) mem48++; - } else - mem48--; - } - //pos47945: - Write(mem47, Y, mem48); - } //while No. 3 - - //pos47952: - mem47++; - //if (mem47 != 175) goto pos47810; - } while(mem47 != 175); //while No. 2 - //pos47963: - mem44++; - X = mem44; - } //while No. 1 - - //goto pos47701; - //pos47970: - - // add the length of this phoneme - mem48 = mem49 + phonemeLengthOutput[mem44]; - - // ASSIGN PITCH CONTOUR - // - // This subtracts the F1 frequency from the pitch to create a - // pitch contour. Without this, the output would be at a single - // pitch level (monotone). - - // don't adjust pitch if in sing mode - if(!singmode) { - // iterate through the buffer - for(i = 0; i < 256; i++) { - // subtract half the frequency of the formant 1. - // this adds variety to the voice - pitches[i] -= (frequency1[i] >> 1); - } - } - - phase1 = 0; - phase2 = 0; - phase3 = 0; - mem49 = 0; - speedcounter = 72; //sam standard speed - - // RESCALE AMPLITUDE - // - // Rescale volume from a linear scale to decibels. - // - - //amplitude rescaling - for(i = 255; i >= 0; i--) { - amplitude1[i] = amplitudeRescale[amplitude1[i]]; - amplitude2[i] = amplitudeRescale[amplitude2[i]]; - amplitude3[i] = amplitudeRescale[amplitude3[i]]; - } - - Y = 0; - A = pitches[0]; - mem44 = A; - X = A; - mem38 = A - (A >> 2); // 3/4*A ??? - - // PROCESS THE FRAMES - // - // In traditional vocal synthesis, the glottal pulse drives filters, which - // are attenuated to the frequencies of the formants. - // - // SAM generates these formants directly with sin and rectangular waves. - // To simulate them being driven by the glottal pulse, the waveforms are - // reset at the beginning of each glottal pulse. - - //finally the loop for sound output - //pos48078: - while(1) { - // get the sampled information on the phoneme - A = sampledConsonantFlag[Y]; - mem39 = A; - - // unvoiced sampled phoneme? - A = A & 248; - if(A != 0) { - // render the sample for the phoneme - RenderSample(&mem66); - - // skip ahead two in the phoneme buffer - Y += 2; - mem48 -= 2; - } else { - // simulate the glottal pulse and formants - unsigned char ary[5]; - unsigned int p1 = - phase1 * 256; // Fixed point integers because we need to divide later on - unsigned int p2 = phase2 * 256; - unsigned int p3 = phase3 * 256; - int k; - for(k = 0; k < 5; k++) { - signed char sp1 = (signed char)sinus[0xff & (p1 >> 8)]; - signed char sp2 = (signed char)sinus[0xff & (p2 >> 8)]; - signed char rp3 = (signed char)rectangle[0xff & (p3 >> 8)]; - signed int sin1 = sp1 * ((unsigned char)amplitude1[Y] & 0x0f); - signed int sin2 = sp2 * ((unsigned char)amplitude2[Y] & 0x0f); - signed int rect = rp3 * ((unsigned char)amplitude3[Y] & 0x0f); - signed int mux = sin1 + sin2 + rect; - mux /= 32; - mux += 128; // Go from signed to unsigned amplitude - ary[k] = mux; - p1 += frequency1[Y] * 256 / 4; // Compromise, this becomes a shift and works well - p2 += frequency2[Y] * 256 / 4; - p3 += frequency3[Y] * 256 / 4; - } - // output the accumulated value - Output8BitAry(0, ary); - speedcounter--; - if(speedcounter != 0) goto pos48155; - Y++; //go to next amplitude - - // decrement the frame count - mem48--; - } - - // if the frame count is zero, exit the loop - if(mem48 == 0) return; - speedcounter = speed; - pos48155: - - // decrement the remaining length of the glottal pulse - mem44--; - - // finished with a glottal pulse? - if(mem44 == 0) { - pos48159: - // fetch the next glottal pulse length - A = pitches[Y]; - mem44 = A; - A = A - (A >> 2); - mem38 = A; - - // reset the formant wave generators to keep them in - // sync with the glottal pulse - phase1 = 0; - phase2 = 0; - phase3 = 0; - continue; - } - - // decrement the count - mem38--; - - // is the count non-zero and the sampled flag is zero? - if((mem38 != 0) || (mem39 == 0)) { - // reset the phase of the formants to match the pulse - phase1 += frequency1[Y]; - phase2 += frequency2[Y]; - phase3 += frequency3[Y]; - continue; - } - - // voiced sampled phonemes interleave the sample with the - // glottal pulse. The sample flag is non-zero, so render - // the sample for the phoneme. - RenderSample(&mem66); - goto pos48159; - } //while - - // The following code is never reached. It's left over from when - // the voiced sample code was part of this loop, instead of part - // of RenderSample(); - - //pos48315: - int tempA; - phase1 = A ^ 255; - Y = mem66; - do { - //pos48321: - - mem56 = 8; - A = Read(mem47, Y); - - //pos48327: - do { - //48327: ASL A - //48328: BCC 48337 - tempA = A; - A = A << 1; - if((tempA & 128) != 0) { - X = 26; - // mem[54296] = X; - bufferpos += 150; - // - // - // buffer[bufferpos / 50] = (X & 15) * 16; - // - // - - } else { - //mem[54296] = 6; - X = 6; - bufferpos += 150; - // - // buffer[bufferpos / 50] = (X & 15) * 16; - // - // - } - - for(X = wait2; X > 0; X--) - ; //wait - mem56--; - } while(mem56 != 0); - - Y++; - phase1++; - - } while(phase1 != 0); - // if (phase1 != 0) goto pos48321; - A = 1; - mem44 = 1; - mem66 = Y; - Y = mem49; - return; -} - -// Create a rising or falling inflection 30 frames prior to -// index X. A rising inflection is used for questions, and -// a falling inflection is used for statements. - -void STM32SAM::AddInflection(unsigned char mem48, unsigned char phase1) { - //pos48372: - // mem48 = 255; - //pos48376: - - // store the location of the punctuation - mem49 = X; - A = X; - int Atemp = A; - - // backup 30 frames - A = A - 30; - // if index is before buffer, point to start of buffer - if(Atemp <= 30) A = 0; - X = A; - - // FIXME: Explain this fix better, it's not obvious - // ML : A =, fixes a problem with invalid pitch with '.' - while((A = pitches[X]) == 127) X++; - -pos48398: - //48398: CLC - //48399: ADC 48 - - // add the inflection direction - A += mem48; - phase1 = A; - - // set the inflection - pitches[X] = A; -pos48406: - - // increment the position - X++; - - // exit if the punctuation has been reached - if(X == mem49) return; //goto pos47615; - if(pitches[X] == 255) goto pos48406; - A = phase1; - goto pos48398; -} - -/* - SAM's voice can be altered by changing the frequencies of the - mouth formant (F1) and the throat formant (F2). Only the voiced - phonemes (5-29 and 48-53) are altered. -*/ -void STM32SAM::SetMouthThroat() { - unsigned char initialFrequency; - unsigned char newFrequency = 0; - //unsigned char mouth; //mem38880 - //unsigned char throat; //mem38881 - - // mouth formants (F1) 5..29 - unsigned char mouthFormants5_29[30] = {0, 0, 0, 0, 0, 10, 14, 19, 24, 27, - 23, 21, 16, 20, 14, 18, 14, 18, 18, 16, - 13, 15, 11, 18, 14, 11, 9, 6, 6, 6}; - - // throat formants (F2) 5..29 - unsigned char throatFormants5_29[30] = {255, 255, 255, 255, 255, 84, 73, 67, 63, 40, - 44, 31, 37, 45, 73, 49, 36, 30, 51, 37, - 29, 69, 24, 50, 30, 24, 83, 46, 54, 86}; - - // there must be no zeros in this 2 tables - // formant 1 frequencies (mouth) 48..53 - unsigned char mouthFormants48_53[6] = {19, 27, 21, 27, 18, 13}; - - // formant 2 frequencies (throat) 48..53 - unsigned char throatFormants48_53[6] = {72, 39, 31, 43, 30, 34}; - - unsigned char pos = 5; //mem39216 - //pos38942: - // recalculate formant frequencies 5..29 for the mouth (F1) and throat (F2) - while(pos != 30) { - // recalculate mouth frequency - initialFrequency = mouthFormants5_29[pos]; - if(initialFrequency != 0) newFrequency = trans(mouth, initialFrequency); - freq1data[pos] = newFrequency; - - // recalculate throat frequency - initialFrequency = throatFormants5_29[pos]; - if(initialFrequency != 0) newFrequency = trans(throat, initialFrequency); - freq2data[pos] = newFrequency; - pos++; - } - - //pos39059: - // recalculate formant frequencies 48..53 - pos = 48; - Y = 0; - while(pos != 54) { - // recalculate F1 (mouth formant) - initialFrequency = mouthFormants48_53[Y]; - newFrequency = trans(mouth, initialFrequency); - freq1data[pos] = newFrequency; - - // recalculate F2 (throat formant) - initialFrequency = throatFormants48_53[Y]; - newFrequency = trans(throat, initialFrequency); - freq2data[pos] = newFrequency; - Y++; - pos++; - } -} - -//return = (mem39212*mem39213) >> 1 -unsigned char STM32SAM::trans(unsigned char mem39212, unsigned char mem39213) { - //pos39008: - unsigned char carry; - int temp; - unsigned char mem39214, mem39215; - A = 0; - mem39215 = 0; - mem39214 = 0; - X = 8; - do { - carry = mem39212 & 1; - mem39212 = mem39212 >> 1; - if(carry != 0) { - /* - 39018: LSR 39212 - 39021: BCC 39033 - */ - carry = 0; - A = mem39215; - temp = (int)A + (int)mem39213; - A = A + mem39213; - if(temp > 255) carry = 1; - mem39215 = A; - } - temp = mem39215 & 1; - mem39215 = (mem39215 >> 1) | (carry ? 128 : 0); - carry = temp; - //39033: ROR 39215 - X--; - } while(X != 0); - temp = mem39214 & 128; - mem39214 = (mem39214 << 1) | (carry ? 1 : 0); - carry = temp; - temp = mem39215 & 128; - mem39215 = (mem39215 << 1) | (carry ? 1 : 0); - carry = temp; - - return mem39215; -} - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// Sam -// -//////////////////////////////////////////////////////////////////////////////////////////// - -//char input[]={"/HAALAOAO MAYN NAAMAEAE IHSTT SAEBAASTTIHAAN \x9b\x9b\0"}; -//unsigned char input[]={"/HAALAOAO \x9b\0"}; -//unsigned char input[]={"AA \x9b\0"}; -//unsigned char input[] = {"GUH5DEHN TAEG\x9b\0"}; - -//unsigned char input[]={"AY5 AEM EY TAO4LXKIHNX KAX4MPYUX4TAH. GOW4 AH/HEH3D PAHNK.MEYK MAY8 DEY.\x9b\0"}; -//unsigned char input[]={"/HEH3LOW2, /HAW AH YUX2 TUXDEY. AY /HOH3P YUX AH FIYLIHNX OW4 KEY.\x9b\0"}; -//unsigned char input[]={"/HEY2, DHIHS IH3Z GREY2T. /HAH /HAH /HAH.AYL BIY5 BAEK.\x9b\0"}; -//unsigned char input[]={"/HAH /HAH /HAH \x9b\0"}; -//unsigned char input[]={"/HAH /HAH /HAH.\x9b\0"}; -//unsigned char input[]={".TUW BIY5Y3,, OHR NAA3T - TUW BIY5IYIY., DHAE4T IHZ DHAH KWEH4SCHAHN.\x9b\0"}; -//unsigned char input[]={"/HEY2, DHIHS \x9b\0"}; - -//unsigned char input[]={" IYIHEHAEAAAHAOOHUHUXERAXIX \x9b\0"}; -//unsigned char input[]={" RLWWYMNNXBDGJZZHVDH \x9b\0"}; -//unsigned char input[]={" SSHFTHPTKCH/H \x9b\0"}; - -//unsigned char input[]={" EYAYOYAWOWUW ULUMUNQ YXWXRXLX/XDX\x9b\0"}; - -void STM32SAM::SetInput(char* _input) { - int i, l; - l = strlen(_input); - if(l > 254) l = 254; - for(i = 0; i < l; i++) { - input[i] = _input[i]; - } - input[l] = 0; -} - -// 168=pitches -// 169=frequency1 -// 170=frequency2 -// 171=frequency3 -// 172=amplitude1 -// 173=amplitude2 -// 174=amplitude3 - -void STM32SAM::Init() { - bufferpos = 0; - int i; - SetMouthThroat(); - - bufferpos = 0; - // TODO, check for free the memory, 10 seconds of output should be more than enough - //buffer = malloc(22050*10); - - // buffer = (char*) calloc(1, sizeof(char)); - - /* - freq2data = &mem[45136]; - freq1data = &mem[45056]; - freq3data = &mem[45216]; - */ - //pitches = &mem[43008]; - /* - frequency1 = &mem[43264]; - frequency2 = &mem[43520]; - frequency3 = &mem[43776]; - */ - /* - amplitude1 = &mem[44032]; - amplitude2 = &mem[44288]; - amplitude3 = &mem[44544]; - */ - //phoneme = &mem[39904]; - /* - ampl1data = &mem[45296]; - ampl2data = &mem[45376]; - ampl3data = &mem[45456]; - */ - - for(i = 0; i < 256; i++) { - stress[i] = 0; - phonemeLength[i] = 0; - } - - for(i = 0; i < 60; i++) { - phonemeIndexOutput[i] = 0; - stressOutput[i] = 0; - phonemeLengthOutput[i] = 0; - } - phonemeindex[255] = - 255; //to prevent buffer overflow // ML : changed from 32 to 255 to stop freezing with long inputs -} - -//int Code39771() -int STM32SAM::SAMMain() { - Init(); - phonemeindex[255] = 32; //to prevent buffer overflow - - if(!Parser1()) { - return 0; - } - - Parser2(); - CopyStress(); - SetPhonemeLength(); - AdjustLengths(); - Code41240(); - do { - A = phonemeindex[X]; - if(A > 80) { - phonemeindex[X] = 255; - break; // error: delete all behind it - } - X++; - } while(X != 0); - - //pos39848: - InsertBreath(); - - //mem[40158] = 255; - - PrepareOutput(); - - return 1; -} - -//void Code48547() -void STM32SAM::PrepareOutput() { - A = 0; - X = 0; - Y = 0; - - //pos48551: - while(1) { - A = phonemeindex[X]; - if(A == 255) { - A = 255; - phonemeIndexOutput[Y] = 255; - Render(); - return; - } - if(A == 254) { - X++; - int temp = X; - //mem[48546] = X; - phonemeIndexOutput[Y] = 255; - Render(); - //X = mem[48546]; - X = temp; - Y = 0; - continue; - } - - if(A == 0) { - X++; - continue; - } - - phonemeIndexOutput[Y] = A; - phonemeLengthOutput[Y] = phonemeLength[X]; - stressOutput[Y] = stress[X]; - X++; - Y++; - } -} - -//void Code41014() -void STM32SAM::Insert( - unsigned char position /*var57*/, - unsigned char mem60, - unsigned char mem59, - unsigned char mem58) { - int i; - for(i = 253; i >= position; i--) // ML : always keep last safe-guarding 255 - { - phonemeindex[i + 1] = phonemeindex[i]; - phonemeLength[i + 1] = phonemeLength[i]; - stress[i + 1] = stress[i]; - } - - phonemeindex[position] = mem60; - phonemeLength[position] = mem59; - stress[position] = mem58; - return; -} - -//void Code48431() -void STM32SAM::InsertBreath() { - unsigned char mem54; - unsigned char mem55; - unsigned char index; //variable Y - mem54 = 255; - X++; - mem55 = 0; - unsigned char mem66 = 0; - while(1) { - //pos48440: - X = mem66; - index = phonemeindex[X]; - if(index == 255) return; - mem55 += phonemeLength[X]; - - if(mem55 < 232) { - if(index != 254) // ML : Prevents an index out of bounds problem - { - A = flags2[index] & 1; - if(A != 0) { - X++; - mem55 = 0; - Insert(X, 254, mem59, 0); - mem66++; - mem66++; - continue; - } - } - if(index == 0) mem54 = X; - mem66++; - continue; - } - X = mem54; - phonemeindex[X] = 31; // 'Q*' glottal stop - phonemeLength[X] = 4; - stress[X] = 0; - X++; - mem55 = 0; - Insert(X, 254, mem59, 0); - X++; - mem66 = X; - } -} - -// Iterates through the phoneme buffer, copying the stress value from -// the following phoneme under the following circumstance: - -// 1. The current phoneme is voiced, excluding plosives and fricatives -// 2. The following phoneme is voiced, excluding plosives and fricatives, and -// 3. The following phoneme is stressed -// -// In those cases, the stress value+1 from the following phoneme is copied. -// -// For example, the word LOITER is represented as LOY5TER, with as stress -// of 5 on the diphtong OY. This routine will copy the stress value of 6 (5+1) -// to the L that precedes it. - -//void Code41883() -void STM32SAM::CopyStress() { - // loop thought all the phonemes to be output - unsigned char pos = 0; //mem66 - while(1) { - // get the phomene - Y = phonemeindex[pos]; - - // exit at end of buffer - if(Y == 255) return; - - // if CONSONANT_FLAG set, skip - only vowels get stress - if((flags[Y] & 64) == 0) { - pos++; - continue; - } - // get the next phoneme - Y = phonemeindex[pos + 1]; - if(Y == 255) //prevent buffer overflow - { - pos++; - continue; - } else - // if the following phoneme is a vowel, skip - if((flags[Y] & 128) == 0) { - pos++; - continue; - } - - // get the stress value at the next position - Y = stress[pos + 1]; - - // if next phoneme is not stressed, skip - if(Y == 0) { - pos++; - continue; - } - - // if next phoneme is not a VOWEL OR ER, skip - if((Y & 128) != 0) { - pos++; - continue; - } - - // copy stress from prior phoneme to this one - stress[pos] = Y + 1; - - // advance pointer - pos++; - } -} - -// The input[] buffer contains a string of phonemes and stress markers along -// the lines of: -// -// DHAX KAET IHZ AH5GLIY. <0x9B> -// -// The byte 0x9B marks the end of the buffer. Some phonemes are 2 bytes -// long, such as "DH" and "AX". Others are 1 byte long, such as "T" and "Z". -// There are also stress markers, such as "5" and ".". -// -// The first character of the phonemes are stored in the table signInputTable1[]. -// The second character of the phonemes are stored in the table signInputTable2[]. -// The stress characters are arranged in low to high stress order in stressInputTable[]. -// -// The following process is used to parse the input[] buffer: -// -// Repeat until the <0x9B> character is reached: -// -// First, a search is made for a 2 character match for phonemes that do not -// end with the '*' (wildcard) character. On a match, the index of the phoneme -// is added to phonemeIndex[] and the buffer position is advanced 2 bytes. -// -// If this fails, a search is made for a 1 character match against all -// phoneme names ending with a '*' (wildcard). If this succeeds, the -// phoneme is added to phonemeIndex[] and the buffer position is advanced -// 1 byte. -// -// If this fails, search for a 1 character match in the stressInputTable[]. -// If this succeeds, the stress value is placed in the last stress[] table -// at the same index of the last added phoneme, and the buffer position is -// advanced by 1 byte. -// -// If this fails, return a 0. -// -// On success: -// -// 1. phonemeIndex[] will contain the index of all the phonemes. -// 2. The last index in phonemeIndex[] will be 255. -// 3. stress[] will contain the stress value for each phoneme - -// input[] holds the string of phonemes, each two bytes wide -// signInputTable1[] holds the first character of each phoneme -// signInputTable2[] holds te second character of each phoneme -// phonemeIndex[] holds the indexes of the phonemes after parsing input[] -// -// The parser scans through the input[], finding the names of the phonemes -// by searching signInputTable1[] and signInputTable2[]. On a match, it -// copies the index of the phoneme into the phonemeIndexTable[]. -// -// The character <0x9B> marks the end of text in input[]. When it is reached, -// the index 255 is placed at the end of the phonemeIndexTable[], and the -// function returns with a 1 indicating success. -int STM32SAM::Parser1() { - int i; - unsigned char sign1; - unsigned char sign2; - unsigned char position = 0; - X = 0; - A = 0; - Y = 0; - - // CLEAR THE STRESS TABLE - for(i = 0; i < 256; i++) stress[i] = 0; - - // THIS CODE MATCHES THE PHONEME LETTERS TO THE TABLE - // pos41078: - while(1) { - // GET THE FIRST CHARACTER FROM THE PHONEME BUFFER - sign1 = input[X]; - // TEST FOR 155 (�) END OF LINE MARKER - if(sign1 == 155) { - // MARK ENDPOINT AND RETURN - phonemeindex[position] = 255; //mark endpoint - // REACHED END OF PHONEMES, SO EXIT - return 1; //all ok - } - - // GET THE NEXT CHARACTER FROM THE BUFFER - X++; - sign2 = input[X]; - - // NOW sign1 = FIRST CHARACTER OF PHONEME, AND sign2 = SECOND CHARACTER OF PHONEME - - // TRY TO MATCH PHONEMES ON TWO TWO-CHARACTER NAME - // IGNORE PHONEMES IN TABLE ENDING WITH WILDCARDS - - // SET INDEX TO 0 - Y = 0; - pos41095: - - // GET FIRST CHARACTER AT POSITION Y IN signInputTable - // --> should change name to PhonemeNameTable1 - A = signInputTable1[Y]; - - // FIRST CHARACTER MATCHES? - if(A == sign1) { - // GET THE CHARACTER FROM THE PhonemeSecondLetterTable - A = signInputTable2[Y]; - // NOT A SPECIAL AND MATCHES SECOND CHARACTER? - if((A != '*') && (A == sign2)) { - // STORE THE INDEX OF THE PHONEME INTO THE phomeneIndexTable - phonemeindex[position] = Y; - - // ADVANCE THE POINTER TO THE phonemeIndexTable - position++; - // ADVANCE THE POINTER TO THE phonemeInputBuffer - X++; - - // CONTINUE PARSING - continue; - } - } - - // NO MATCH, TRY TO MATCH ON FIRST CHARACTER TO WILDCARD NAMES (ENDING WITH '*') - - // ADVANCE TO THE NEXT POSITION - Y++; - // IF NOT END OF TABLE, CONTINUE - if(Y != 81) goto pos41095; - - // REACHED END OF TABLE WITHOUT AN EXACT (2 CHARACTER) MATCH. - // THIS TIME, SEARCH FOR A 1 CHARACTER MATCH AGAINST THE WILDCARDS - - // RESET THE INDEX TO POINT TO THE START OF THE PHONEME NAME TABLE - Y = 0; - pos41134: - // DOES THE PHONEME IN THE TABLE END WITH '*'? - if(signInputTable2[Y] == '*') { - // DOES THE FIRST CHARACTER MATCH THE FIRST LETTER OF THE PHONEME - if(signInputTable1[Y] == sign1) { - // SAVE THE POSITION AND MOVE AHEAD - phonemeindex[position] = Y; - - // ADVANCE THE POINTER - position++; - - // CONTINUE THROUGH THE LOOP - continue; - } - } - Y++; - if(Y != 81) goto pos41134; //81 is size of PHONEME NAME table - - // FAILED TO MATCH WITH A WILDCARD. ASSUME THIS IS A STRESS - // CHARACTER. SEARCH THROUGH THE STRESS TABLE - - // SET INDEX TO POSITION 8 (END OF STRESS TABLE) - Y = 8; - - // WALK BACK THROUGH TABLE LOOKING FOR A MATCH - while((sign1 != stressInputTable[Y]) && (Y > 0)) { - // DECREMENT INDEX - Y--; - } - - // REACHED THE END OF THE SEARCH WITHOUT BREAKING OUT OF LOOP? - if(Y == 0) { - //mem[39444] = X; - //41181: JSR 42043 //Error - // FAILED TO MATCH ANYTHING, RETURN 0 ON FAILURE - return 0; - } - // SET THE STRESS FOR THE PRIOR PHONEME - stress[position - 1] = Y; - } //while -} - -//change phonemelength depedendent on stress -//void Code41203() -void STM32SAM::SetPhonemeLength() { - unsigned char A; - int position = 0; - while(phonemeindex[position] != 255) { - A = stress[position]; - //41218: BMI 41229 - if((A == 0) || ((A & 128) != 0)) { - phonemeLength[position] = phonemeLengthTable[phonemeindex[position]]; - } else { - phonemeLength[position] = phonemeStressedLengthTable[phonemeindex[position]]; - } - position++; - } -} - -void STM32SAM::Code41240() { - unsigned char pos = 0; - - while(phonemeindex[pos] != 255) { - unsigned char index; //register AC - X = pos; - index = phonemeindex[pos]; - if((flags[index] & 2) == 0) { - pos++; - continue; - } else if((flags[index] & 1) == 0) { - Insert(pos + 1, index + 1, phonemeLengthTable[index + 1], stress[pos]); - Insert(pos + 2, index + 2, phonemeLengthTable[index + 2], stress[pos]); - pos += 3; - continue; - } - - do { - X++; - A = phonemeindex[X]; - } while(A == 0); - - if(A != 255) { - if((flags[A] & 8) != 0) { - pos++; - continue; - } - if((A == 36) || (A == 37)) { - pos++; // '/H' '/X' - continue; - } - } - - Insert(pos + 1, index + 1, phonemeLengthTable[index + 1], stress[pos]); - Insert(pos + 2, index + 2, phonemeLengthTable[index + 2], stress[pos]); - pos += 3; - } -} - -// Rewrites the phonemes using the following rules: -// -// -> WX -// -> YX -// UL -> AX L -// UM -> AX M -// -> Q -// T R -> CH R -// D R -> J R -// R -> RX -// L -> LX -// G S -> G Z -// K -> KX -// G -> GX -// S P -> S B -// S T -> S D -// S K -> S G -// S KX -> S GX -// UW -> UX -// CH -> CH CH' (CH requires two phonemes to represent it) -// J -> J J' (J requires two phonemes to represent it) -// T -> DX -// D -> DX - -//void Code41397() -void STM32SAM::Parser2() { - unsigned char pos = 0; //mem66; - unsigned char mem58 = 0; - - // Loop through phonemes - while(1) { - // SET X TO THE CURRENT POSITION - X = pos; - // GET THE PHONEME AT THE CURRENT POSITION - A = phonemeindex[pos]; - - // Is phoneme pause? - if(A == 0) { - // Move ahead to the - pos++; - continue; - } - - // If end of phonemes flag reached, exit routine - if(A == 255) return; - - // Copy the current phoneme index to Y - Y = A; - - // RULE: - // -> WX - // -> YX - // Example: OIL, COW - - // Check for DIPHTONG - if((flags[A] & 16) == 0) goto pos41457; - - // Not a diphthong. Get the stress - mem58 = stress[pos]; - - // End in IY sound? - A = flags[Y] & 32; - - // If ends with IY, use YX, else use WX - if(A == 0) - A = 20; - else - A = 21; // 'WX' = 20 'YX' = 21 - //pos41443: - // Insert at WX or YX following, copying the stress - - Insert(pos + 1, A, mem59, mem58); - X = pos; - // Jump to ??? - goto pos41749; - - pos41457: - - // RULE: - // UL -> AX L - // Example: MEDDLE - - // Get phoneme - A = phonemeindex[X]; - // Skip this rule if phoneme is not UL - if(A != 78) goto pos41487; // 'UL' - A = 24; // 'L' //change 'UL' to 'AX L' - - pos41466: - // Get current phoneme stress - mem58 = stress[X]; - - // Change UL to AX - phonemeindex[X] = 13; // 'AX' - // Perform insert. Note code below may jump up here with different values - Insert(X + 1, A, mem59, mem58); - pos++; - // Move to next phoneme - continue; - - pos41487: - - // RULE: - // UM -> AX M - // Example: ASTRONOMY - - // Skip rule if phoneme != UM - if(A != 79) goto pos41495; // 'UM' - // Jump up to branch - replaces current phoneme with AX and continues - A = 27; // 'M' //change 'UM' to 'AX M' - - goto pos41466; - pos41495: - - // RULE: - // UN -> AX N - // Example: FUNCTION - - // Skip rule if phoneme != UN - if(A != 80) goto pos41503; // 'UN' - - // Jump up to branch - replaces current phoneme with AX and continues - A = 28; // 'N' //change UN to 'AX N' - - goto pos41466; - pos41503: - - // RULE: - // -> Q - // EXAMPLE: AWAY EIGHT - - Y = A; - // VOWEL set? - A = flags[A] & 128; - - // Skip if not a vowel - if(A != 0) { - // Get the stress - A = stress[X]; - - // If stressed... - if(A != 0) { - // Get the following phoneme - X++; - A = phonemeindex[X]; - // If following phoneme is a pause - - if(A == 0) { - // Get the phoneme following pause - X++; - Y = phonemeindex[X]; - - // Check for end of buffer flag - if(Y == 255) //buffer overflow - // ??? Not sure about these flags - A = 65 & 128; - else - // And VOWEL flag to current phoneme's flags - A = flags[Y] & 128; - - // If following phonemes is not a pause - if(A != 0) { - // If the following phoneme is not stressed - A = stress[X]; - if(A != 0) { - // 31 = 'Q' - Insert(X, 31, mem59, 0); - pos++; - continue; - } - } - } - } - } - - // RULES FOR PHONEMES BEFORE R - // T R -> CH R - // Example: TRACK - - // Get current position and phoneme - X = pos; - A = phonemeindex[pos]; - if(A != 23) goto pos41611; // 'R' - - // Look at prior phoneme - X--; - A = phonemeindex[pos - 1]; - //pos41567: - if(A == 69) // 'T' - { - phonemeindex[pos - 1] = 42; - goto pos41779; - } - - // RULES FOR PHONEMES BEFORE R - // D R -> J R - // Example: DRY - - // Prior phonemes D? - if(A == 57) // 'D' - { - // Change D to J - phonemeindex[pos - 1] = 44; - - goto pos41788; - } - - // RULES FOR PHONEMES BEFORE R - // R -> RX - // Example: ART - - // If vowel flag is set change R to RX - A = flags[A] & 128; - - if(A != 0) phonemeindex[pos] = 18; // 'RX' - - // continue to next phoneme - pos++; - continue; - - pos41611: - - // RULE: - // L -> LX - // Example: ALL - - // Is phoneme L? - if(A == 24) // 'L' - { - // If prior phoneme does not have VOWEL flag set, move to next phoneme - if((flags[phonemeindex[pos - 1]] & 128) == 0) { - pos++; - continue; - } - // Prior phoneme has VOWEL flag set, so change L to LX and move to next phoneme - - phonemeindex[X] = 19; // 'LX' - pos++; - continue; - } - - // RULE: - // G S -> G Z - // - // Can't get to fire - - // 1. The G -> GX rule intervenes - // 2. Reciter already replaces GS -> GZ - - // Is current phoneme S? - if(A == 32) // 'S' - { - // If prior phoneme is not G, move to next phoneme - if(phonemeindex[pos - 1] != 60) { - pos++; - continue; - } - // Replace S with Z and move on - - phonemeindex[pos] = 38; // 'Z' - pos++; - continue; - } - - // RULE: - // K -> KX - // Example: COW - - // Is current phoneme K? - if(A == 72) // 'K' - { - // Get next phoneme - Y = phonemeindex[pos + 1]; - // If at end, replace current phoneme with KX - if(Y == 255) - phonemeindex[pos] = 75; // ML : prevents an index out of bounds problem - else { - // VOWELS AND DIPHTONGS ENDING WITH IY SOUND flag set? - A = flags[Y] & 32; - - // Replace with KX - if(A == 0) phonemeindex[pos] = 75; // 'KX' - } - } else - - // RULE: - // G -> GX - // Example: GO - - // Is character a G? - if(A == 60) // 'G' - { - // Get the following character - unsigned char index = phonemeindex[pos + 1]; - - // At end of buffer? - if(index == 255) //prevent buffer overflow - { - pos++; - continue; - } else - // If diphtong ending with YX, move continue processing next phoneme - if((flags[index] & 32) != 0) { - pos++; - continue; - } - // replace G with GX and continue processing next phoneme - - phonemeindex[pos] = 63; // 'GX' - pos++; - continue; - } - - // RULE: - // S P -> S B - // S T -> S D - // S K -> S G - // S KX -> S GX - // Examples: SPY, STY, SKY, SCOWL - - Y = phonemeindex[pos]; - //pos41719: - // Replace with softer version? - A = flags[Y] & 1; - if(A == 0) goto pos41749; - A = phonemeindex[pos - 1]; - if(A != 32) // 'S' - { - A = Y; - goto pos41812; - } - // Replace with softer version - - phonemeindex[pos] = Y - 12; - pos++; - continue; - - pos41749: - - // RULE: - // UW -> UX - // - // Example: NEW, DEW, SUE, ZOO, THOO, TOO - - // UW -> UX - - A = phonemeindex[X]; - if(A == 53) // 'UW' - { - // ALVEOLAR flag set? - Y = phonemeindex[X - 1]; - A = flags2[Y] & 4; - // If not set, continue processing next phoneme - if(A == 0) { - pos++; - continue; - } - - phonemeindex[X] = 16; - pos++; - continue; - } - pos41779: - - // RULE: - // CH -> CH CH' (CH requires two phonemes to represent it) - // Example: CHEW - - if(A == 42) // 'CH' - { - // pos41783: - - Insert(X + 1, A + 1, mem59, stress[X]); - pos++; - continue; - } - - pos41788: - - // RULE: - // J -> J J' (J requires two phonemes to represent it) - // Example: JAY - - if(A == 44) // 'J' - { - Insert(X + 1, A + 1, mem59, stress[X]); - pos++; - continue; - } - - // Jump here to continue - pos41812: - - // RULE: Soften T following vowel - // NOTE: This rule fails for cases such as "ODD" - // T -> DX - // D -> DX - // Example: PARTY, TARDY - - // Past this point, only process if phoneme is T or D - - if(A != 69) // 'T' - if(A != 57) { - pos++; // 'D' - continue; - } - //pos41825: - - // If prior phoneme is not a vowel, continue processing phonemes - if((flags[phonemeindex[X - 1]] & 128) == 0) { - pos++; - continue; - } - - // Get next phoneme - X++; - A = phonemeindex[X]; - //pos41841 - // Is the next phoneme a pause? - if(A != 0) { - // If next phoneme is not a pause, continue processing phonemes - if((flags[A] & 128) == 0) { - pos++; - continue; - } - // If next phoneme is stressed, continue processing phonemes - // FIXME: How does a pause get stressed? - if(stress[X] != 0) { - pos++; - continue; - } - //pos41856: - // Set phonemes to DX - - phonemeindex[pos] = 30; // 'DX' - } else { - A = phonemeindex[X + 1]; - if(A == 255) //prevent buffer overflow - A = 65 & 128; - else - // Is next phoneme a vowel or ER? - A = flags[A] & 128; - - if(A != 0) phonemeindex[pos] = 30; // 'DX' - } - - pos++; - - } // while -} // parser 2 - -// Applies various rules that adjust the lengths of phonemes -// -// Lengthen or between and by 1.5 -// - decrease length by 1 -// - decrease vowel by 1/8th -// - increase vowel by 1/2 + 1 -// - set nasal = 5, consonant = 6 -// {optional silence} - shorten both to 1/2 + 1 -// - decrease by 2 - -//void Code48619() -void STM32SAM::AdjustLengths() { - // LENGTHEN VOWELS PRECEDING PUNCTUATION - // - // Search for punctuation. If found, back up to the first vowel, then - // process all phonemes between there and up to (but not including) the punctuation. - // If any phoneme is found that is a either a fricative or voiced, the duration is - // increased by (length * 1.5) + 1 - - // loop index - X = 0; - unsigned char index; - - // iterate through the phoneme list - unsigned char loopIndex = 0; - while(1) { - // get a phoneme - index = phonemeindex[X]; - - // exit loop if end on buffer token - if(index == 255) break; - - // not punctuation? - if((flags2[index] & 1) == 0) { - // skip - X++; - continue; - } - - // hold index - loopIndex = X; - - // Loop backwards from this point - pos48644: - - // back up one phoneme - X--; - - // stop once the beginning is reached - if(X == 0) break; - - // get the preceding phoneme - index = phonemeindex[X]; - - if(index != 255) //inserted to prevent access overrun - if((flags[index] & 128) == 0) goto pos48644; // if not a vowel, continue looping - - //pos48657: - do { - // test for vowel - index = phonemeindex[X]; - - if(index != 255) //inserted to prevent access overrun - // test for fricative/unvoiced or not voiced - if(((flags2[index] & 32) == 0) || ((flags[index] & 4) != 0)) //nochmal �berpr�fen - { - //A = flags[Y] & 4; - //if(A == 0) goto pos48688; - - // get the phoneme length - A = phonemeLength[X]; - - // change phoneme length to (length * 1.5) + 1 - A = (A >> 1) + A + 1; - - phonemeLength[X] = A; - } - // keep moving forward - X++; - } while(X != loopIndex); - // if (X != loopIndex) goto pos48657; - X++; - } // while - - // Similar to the above routine, but shorten vowels under some circumstances - - // Loop throught all phonemes - loopIndex = 0; - //pos48697 - - while(1) { - // get a phoneme - X = loopIndex; - index = phonemeindex[X]; - - // exit routine at end token - if(index == 255) return; - - // vowel? - A = flags[index] & 128; - if(A != 0) { - // get next phoneme - X++; - index = phonemeindex[X]; - - // get flags - if(index == 255) - mem56 = 65; // use if end marker - else - mem56 = flags[index]; - - // not a consonant - if((flags[index] & 64) == 0) { - // RX or LX? - if((index == 18) || (index == 19)) // 'RX' & 'LX' - { - // get the next phoneme - X++; - index = phonemeindex[X]; - - // next phoneme a consonant? - if((flags[index] & 64) != 0) { - // RULE: RX | LX - - // decrease length of vowel by 1 frame - phonemeLength[loopIndex]--; - } - // move ahead - loopIndex++; - continue; - } - // move ahead - loopIndex++; - continue; - } - - // Got here if not - - // not voiced - if((mem56 & 4) == 0) { - // Unvoiced - // *, .*, ?*, ,*, -*, DX, S*, SH, F*, TH, /H, /X, CH, P*, T*, K*, KX - - // not an unvoiced plosive? - if((mem56 & 1) == 0) { - // move ahead - loopIndex++; - continue; - } - - // P*, T*, K*, KX - - // RULE: - // - - // move back - X--; - - // decrease length by 1/8th - mem56 = phonemeLength[X] >> 3; - phonemeLength[X] -= mem56; - - // move ahead - loopIndex++; - continue; - } - - // RULE: - // - - // decrease length - A = phonemeLength[X - 1]; - phonemeLength[X - 1] = (A >> 2) + A + 1; // 5/4*A + 1 - - // move ahead - loopIndex++; - continue; - } - - // WH, R*, L*, W*, Y*, M*, N*, NX, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX - - //pos48821: - - // RULE: - // Set punctuation length to 6 - // Set stop consonant length to 5 - - // nasal? - if((flags2[index] & 8) != 0) { - // M*, N*, NX, - - // get the next phoneme - X++; - index = phonemeindex[X]; - - // end of buffer? - if(index == 255) - A = 65 & 2; //prevent buffer overflow - else - A = flags[index] & 2; // check for stop consonant - - // is next phoneme a stop consonant? - if(A != 0) - - // B*, D*, G*, GX, P*, T*, K*, KX - - { - // set stop consonant length to 6 - phonemeLength[X] = 6; - - // set nasal length to 5 - phonemeLength[X - 1] = 5; - } - // move to next phoneme - loopIndex++; - continue; - } - - // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, B*, D*, G*, GX - - // RULE: {optional silence} - // Shorten both to (length/2 + 1) - - // (voiced) stop consonant? - if((flags[index] & 2) != 0) { - // B*, D*, G*, GX - - // move past silence - do { - // move ahead - X++; - index = phonemeindex[X]; - } while(index == 0); - - // check for end of buffer - if(index == 255) //buffer overflow - { - // ignore, overflow code - if((65 & 2) == 0) { - loopIndex++; - continue; - } - } else if((flags[index] & 2) == 0) { - // if another stop consonant, move ahead - loopIndex++; - continue; - } - - // RULE: {optional silence} - - // X gets overwritten, so hold prior X value for debug statement - // int debugX = X; - // shorten the prior phoneme length to (length/2 + 1) - phonemeLength[X] = (phonemeLength[X] >> 1) + 1; - X = loopIndex; - - // also shorten this phoneme length to (length/2 +1) - phonemeLength[loopIndex] = (phonemeLength[loopIndex] >> 1) + 1; - - // move ahead - loopIndex++; - continue; - } - - // WH, R*, L*, W*, Y*, Q*, Z*, ZH, V*, DH, J*, **, - - // RULE: - // Decrease by 2 - - // liquic consonant? - if((flags2[index] & 16) != 0) { - // R*, L*, W*, Y* - - // get the prior phoneme - index = phonemeindex[X - 1]; - - // prior phoneme a stop consonant> - if((flags[index] & 2) != 0) { - // Rule: - - // decrease the phoneme length by 2 frames (20 ms) - phonemeLength[X] -= 2; - } - } - - // move to next phoneme - loopIndex++; - continue; - } - // goto pos48701; -} - -// ------------------------------------------------------------------------- -// ML : Code47503 is division with remainder, and mem50 gets the sign -void STM32SAM::Code47503(unsigned char mem52) { - Y = 0; - if((mem53 & 128) != 0) { - mem53 = -mem53; - Y = 128; - } - mem50 = Y; - A = 0; - for(X = 8; X > 0; X--) { - int temp = mem53; - mem53 = mem53 << 1; - A = A << 1; - if(temp >= 128) A++; - if(A >= mem52) { - A = A - mem52; - mem53++; - } - } - - mem51 = A; - if((mem50 & 128) != 0) mem53 = -mem53; -} - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// Reciter -// -//////////////////////////////////////////////////////////////////////////////////////////// - -void STM32SAM::Code37055(unsigned char mem59) { - X = mem59; - X--; - A = inputtemp[X]; - Y = A; - A = tab36376[Y]; - return; -} - -void STM32SAM::Code37066(unsigned char mem58) { - X = mem58; - X++; - A = inputtemp[X]; - Y = A; - A = tab36376[Y]; -} - -unsigned char STM32SAM::GetRuleByte(unsigned short mem62, unsigned char Y) { - unsigned int address = mem62; - - if(mem62 >= 37541) { - address -= 37541; - return rules2[address + Y]; - } - address -= 32000; - return rules[address + Y]; -} - -int STM32SAM::TextToPhonemes(unsigned char* input) // Code36484 -{ - //unsigned char *tab39445 = &mem[39445]; //input and output - //unsigned char mem29; - unsigned char mem56; //output position for phonemes - unsigned char mem57; - unsigned char mem58; - unsigned char mem59; - unsigned char mem60; - unsigned char mem61; - unsigned short mem62; // memory position of current rule - - unsigned char mem64; // position of '=' or current character - unsigned char mem65; // position of ')' - unsigned char mem66; // position of '(' - unsigned char mem36653; - - inputtemp[0] = 32; - - // secure copy of input - // because input will be overwritten by phonemes - X = 1; - Y = 0; - do { - //pos36499: - A = input[Y] & 127; - if(A >= 112) - A = A & 95; - else if(A >= 96) - A = A & 79; - - inputtemp[X] = A; - X++; - Y++; - } while(Y != 255); - - X = 255; - inputtemp[X] = 27; - mem61 = 255; - -pos36550: - A = 255; - mem56 = 255; - -pos36554: - while(1) { - mem61++; - X = mem61; - A = inputtemp[X]; - mem64 = A; - if(A == '[') { - mem56++; - X = mem56; - A = 155; - input[X] = 155; - //goto pos36542; - // Code39771(); //Code39777(); - return 1; - } - - //pos36579: - if(A != '.') break; - X++; - Y = inputtemp[X]; - A = tab36376[Y] & 1; - if(A != 0) break; - mem56++; - X = mem56; - A = '.'; - input[X] = '.'; - } //while - - //pos36607: - A = mem64; - Y = A; - A = tab36376[A]; - mem57 = A; - if((A & 2) != 0) { - mem62 = 37541; - goto pos36700; - } - - //pos36630: - A = mem57; - if(A != 0) goto pos36677; - A = 32; - inputtemp[X] = ' '; - mem56++; - X = mem56; - if(X > 120) goto pos36654; - input[X] = A; - goto pos36554; - - // ----- - - //36653 is unknown. Contains position - -pos36654: - input[X] = 155; - A = mem61; - mem36653 = A; - // mem29 = A; // not used - // Code36538(); das ist eigentlich - return 1; - //Code39771(); - //go on if there is more input ??? - mem61 = mem36653; - goto pos36550; - -pos36677: - A = mem57 & 128; - if(A == 0) { - //36683: BRK - return 0; - } - - // go to the right rules for this character. - X = mem64 - 'A'; - mem62 = tab37489[X] | (tab37515[X] << 8); - - // ------------------------------------- - // go to next rule - // ------------------------------------- - -pos36700: - - // find next rule - Y = 0; - do { - mem62 += 1; - A = GetRuleByte(mem62, Y); - } while((A & 128) == 0); - Y++; - - //pos36720: - // find '(' - while(1) { - A = GetRuleByte(mem62, Y); - if(A == '(') break; - Y++; - } - mem66 = Y; - - //pos36732: - // find ')' - do { - Y++; - A = GetRuleByte(mem62, Y); - } while(A != ')'); - mem65 = Y; - - //pos36741: - // find '=' - do { - Y++; - A = GetRuleByte(mem62, Y); - A = A & 127; - } while(A != '='); - mem64 = Y; - - X = mem61; - mem60 = X; - - // compare the string within the bracket - Y = mem66; - Y++; - //pos36759: - while(1) { - mem57 = inputtemp[X]; - A = GetRuleByte(mem62, Y); - if(A != mem57) goto pos36700; - Y++; - if(Y == mem65) break; - X++; - mem60 = X; - } - - // the string in the bracket is correct - - //pos36787: - A = mem61; - mem59 = mem61; - -pos36791: - while(1) { - mem66--; - Y = mem66; - A = GetRuleByte(mem62, Y); - mem57 = A; - //36800: BPL 36805 - if((A & 128) != 0) goto pos37180; - X = A & 127; - A = tab36376[X] & 128; - if(A == 0) break; - X = mem59 - 1; - A = inputtemp[X]; - if(A != mem57) goto pos36700; - mem59 = X; - } - - //pos36833: - A = mem57; - if(A == ' ') goto pos36895; - if(A == '#') goto pos36910; - if(A == '.') goto pos36920; - if(A == '&') goto pos36935; - if(A == '@') goto pos36967; - if(A == '^') goto pos37004; - if(A == '+') goto pos37019; - if(A == ':') goto pos37040; - // Code42041(); //Error - //36894: BRK - return 0; - - // -------------- - -pos36895: - Code37055(mem59); - A = A & 128; - if(A != 0) goto pos36700; -pos36905: - mem59 = X; - goto pos36791; - - // -------------- - -pos36910: - Code37055(mem59); - A = A & 64; - if(A != 0) goto pos36905; - goto pos36700; - - // -------------- - -pos36920: - Code37055(mem59); - A = A & 8; - if(A == 0) goto pos36700; -pos36930: - mem59 = X; - goto pos36791; - - // -------------- - -pos36935: - Code37055(mem59); - A = A & 16; - if(A != 0) goto pos36930; - A = inputtemp[X]; - if(A != 72) goto pos36700; - X--; - A = inputtemp[X]; - if((A == 67) || (A == 83)) goto pos36930; - goto pos36700; - - // -------------- - -pos36967: - Code37055(mem59); - A = A & 4; - if(A != 0) goto pos36930; - A = inputtemp[X]; - if(A != 72) goto pos36700; - if((A != 84) && (A != 67) && (A != 83)) goto pos36700; - mem59 = X; - goto pos36791; - - // -------------- - -pos37004: - Code37055(mem59); - A = A & 32; - if(A == 0) goto pos36700; - -pos37014: - mem59 = X; - goto pos36791; - - // -------------- - -pos37019: - X = mem59; - X--; - A = inputtemp[X]; - if((A == 'E') || (A == 'I') || (A == 'Y')) goto pos37014; - goto pos36700; - // -------------- - -pos37040: - Code37055(mem59); - A = A & 32; - if(A == 0) goto pos36791; - mem59 = X; - goto pos37040; - - //--------------------------------------- - -pos37077: - X = mem58 + 1; - A = inputtemp[X]; - if(A != 'E') goto pos37157; - X++; - Y = inputtemp[X]; - X--; - A = tab36376[Y] & 128; - if(A == 0) goto pos37108; - X++; - A = inputtemp[X]; - if(A != 'R') goto pos37113; -pos37108: - mem58 = X; - goto pos37184; -pos37113: - if((A == 83) || (A == 68)) goto pos37108; // 'S' 'D' - if(A != 76) goto pos37135; // 'L' - X++; - A = inputtemp[X]; - if(A != 89) goto pos36700; - goto pos37108; - -pos37135: - if(A != 70) goto pos36700; - X++; - A = inputtemp[X]; - if(A != 85) goto pos36700; - X++; - A = inputtemp[X]; - if(A == 76) goto pos37108; - goto pos36700; - -pos37157: - if(A != 73) goto pos36700; - X++; - A = inputtemp[X]; - if(A != 78) goto pos36700; - X++; - A = inputtemp[X]; - if(A == 71) goto pos37108; - //pos37177: - goto pos36700; - - // ----------------------------------------- - -pos37180: - - A = mem60; - mem58 = A; - -pos37184: - Y = mem65 + 1; - - //37187: CPY 64 - // if(? != 0) goto pos37194; - if(Y == mem64) goto pos37455; - mem65 = Y; - //37196: LDA (62),y - A = GetRuleByte(mem62, Y); - mem57 = A; - X = A; - A = tab36376[X] & 128; - if(A == 0) goto pos37226; - X = mem58 + 1; - A = inputtemp[X]; - if(A != mem57) goto pos36700; - mem58 = X; - goto pos37184; -pos37226: - A = mem57; - if(A == 32) goto pos37295; // ' ' - if(A == 35) goto pos37310; // '#' - if(A == 46) goto pos37320; // '.' - if(A == 38) goto pos37335; // '&' - if(A == 64) goto pos37367; // '' - if(A == 94) goto pos37404; // '' - if(A == 43) goto pos37419; // '+' - if(A == 58) goto pos37440; // ':' - if(A == 37) goto pos37077; // '%' - //pos37291: - // Code42041(); //Error - //37294: BRK - return 0; - - // -------------- -pos37295: - Code37066(mem58); - A = A & 128; - if(A != 0) goto pos36700; -pos37305: - mem58 = X; - goto pos37184; - - // -------------- - -pos37310: - Code37066(mem58); - A = A & 64; - if(A != 0) goto pos37305; - goto pos36700; - - // -------------- - -pos37320: - Code37066(mem58); - A = A & 8; - if(A == 0) goto pos36700; - -pos37330: - mem58 = X; - goto pos37184; - - // -------------- - -pos37335: - Code37066(mem58); - A = A & 16; - if(A != 0) goto pos37330; - A = inputtemp[X]; - if(A != 72) goto pos36700; - X++; - A = inputtemp[X]; - if((A == 67) || (A == 83)) goto pos37330; - goto pos36700; - - // -------------- - -pos37367: - Code37066(mem58); - A = A & 4; - if(A != 0) goto pos37330; - A = inputtemp[X]; - if(A != 72) goto pos36700; - if((A != 84) && (A != 67) && (A != 83)) goto pos36700; - mem58 = X; - goto pos37184; - - // -------------- - -pos37404: - Code37066(mem58); - A = A & 32; - if(A == 0) goto pos36700; -pos37414: - mem58 = X; - goto pos37184; - - // -------------- - -pos37419: - X = mem58; - X++; - A = inputtemp[X]; - if((A == 69) || (A == 73) || (A == 89)) goto pos37414; - goto pos36700; - - // ---------------------- - -pos37440: - - Code37066(mem58); - A = A & 32; - if(A == 0) goto pos37184; - mem58 = X; - goto pos37440; -pos37455: - Y = mem64; - mem61 = mem60; - -pos37461: - //37461: LDA (62),y - A = GetRuleByte(mem62, Y); - mem57 = A; - A = A & 127; - if(A != '=') { - mem56++; - X = mem56; - input[X] = A; - } - - //37478: BIT 57 - //37480: BPL 37485 //not negative flag - if((mem57 & 128) == 0) goto pos37485; //??? - goto pos36554; -pos37485: - Y++; - goto pos37461; -} - -// Constructor - -STM32SAM::STM32SAM(uint32_t STM32SAM_SPEED /* = 5 */) { - STM32SAM_SPEED = STM32SAM_SPEED & 0x1f; // limit it from 0 to 31 - - _STM32SAM_SPEED = STM32SAM_SPEED; - - // set default voice - - speed = 72; - pitch = 64; - mouth = 128; - throat = 128; - - phonetic = 0; - singmode = 0; - - wait1 = 7; - wait2 = 6; - - mem59 = 0; - - oldtimetableindex = 0; -} - -STM32SAM::STM32SAM() { - _STM32SAM_SPEED = 7; - - // set default voice - - speed = 72; - pitch = 64; - mouth = 128; - throat = 128; - - phonetic = 0; - singmode = 0; - - wait1 = 7; - wait2 = 6; - - mem59 = 0; - - oldtimetableindex = 0; -} - -/* - STM32SAM::~STM32SAM() { - { - // TODO: end(); - } -*/ - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// STM32SAM sam (variable string, phonetic, sing, pitch, speed, mouth, throat) -// STM32SAM say (sing off, phonetic off) (const string) -// STM32SAM say (sing off, phonetic off) (variable string) -// STM32SAM sing (sing on, phonetic off) (const string) -// STM32SAM sing (sing on, phonetic off) (variable string) -// STM32SAM sayPhonetic (sing off, phonetic on) (const string) -// STM32SAM sayPhonetic (sing off, phonetic on) (variable string) -// STM32SAM singPhonetic (sing on, phonetic on) (const string) -// STM32SAM singPhonetic (sing on, phonetic on) (variable string) -// STM32SAM voice (pitch, speed, mouth, throat) -// STM32SAM setPitch (pitch) -// STM32SAM setSpeed (speed) -// STM32SAM setMouth (mouth) -// STM32SAM setThroat (throat) -// -// -//////////////////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// STM32SAM sam (const string, phonetic, sing, pitch, speed, mouth, throat) -// -//////////////////////////////////////////////////////////////////////////////////////////// - -char to_upper_case(char c) { - if(c >= 'a' && c <= 'z') { - return c - 'a' + 'A'; - } - return c; -} - -void STM32SAM::sam( - const char* argv, - unsigned char _phonetic, - unsigned char _singmode, - unsigned char _pitch, - unsigned char _speed, - unsigned char _mouth, - unsigned char _throat) { - phonetic = _phonetic; - singmode = _singmode; - pitch = _pitch; - speed = _speed; - mouth = _mouth; - throat = _throat; - - int i; - - for(i = 0; i < 256; i++) { - input[i] = argv[i]; - } - - for(i = 0; input[i] != 0; i++) { - if(i != 0) { - input[i] = to_upper_case((int)argv[i]); - } - } - - if(!phonetic) { - strncat(input, "[", 256); - if(!TextToPhonemes((unsigned char*)input)) { - // PrintUsage(); - return; - } - - } else { - strncat(input, "\x9b", 256); - } - - SetInput(input); - - if(!SAMMain()) { - return; - } -} - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// STM32SAM sam (variable string, phonetic, sing, pitch, speed, mouth, throat) -// -//////////////////////////////////////////////////////////////////////////////////////////// - -void STM32SAM::sam( - char* argv, - unsigned char _phonetic, - unsigned char _singmode, - unsigned char _pitch, - unsigned char _speed, - unsigned char _mouth, - unsigned char _throat) { - phonetic = _phonetic; - singmode = _singmode; - pitch = _pitch; - speed = _speed; - mouth = _mouth; - throat = _throat; - - int i; - - for(i = 0; i < 256; i++) { - input[i] = argv[i]; - } - - for(i = 0; input[i] != 0; i++) { - if(i != 0) { - input[i] = to_upper_case((int)argv[i]); - } - } - - if(!phonetic) { - strncat(input, "[", 256); - if(!TextToPhonemes((unsigned char*)input)) { - // PrintUsage(); - return; - } - - } else { - strncat(input, "\x9b", 256); - } - - SetInput(input); - - if(!SAMMain()) { - return; - } -} - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// STM32SAM say(sing off, phonetic off) (const string) -// -//////////////////////////////////////////////////////////////////////////////////////////// - -void STM32SAM::say(const char* argv) { - int i; - - phonetic = 0; - singmode = 0; - - char const_input[256]; - - for(i = 0; i < 256; i++) { - const_input[i] = argv[i]; - } - - sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); -} - -void STM32SAM::say(char* argv) { - int i; - - phonetic = 0; - singmode = 0; - - char const_input[256]; - - for(i = 0; i < 256; i++) { - const_input[i] = argv[i]; - } - - sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// STM32SAM sing (sing on, phonetic off) -// -//////////////////////////////////////////////////////////////////////////////////////////// - -void STM32SAM::sing(const char* argv) { - int i; - - phonetic = 0; - singmode = 1; - - char const_input[256]; - - for(i = 0; i < 256; i++) { - const_input[i] = argv[i]; - } - - sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); -} - -void STM32SAM::sing(char* argv) { - int i; - - phonetic = 0; - singmode = 1; - - char const_input[256]; - - for(i = 0; i < 256; i++) { - const_input[i] = argv[i]; - } - - sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// STM32SAM sayPhonetic (sing off, phonetic on) -// -//////////////////////////////////////////////////////////////////////////////////////////// - -void STM32SAM::sayPhonetic(const char* argv) { - int i; - - phonetic = 1; - singmode = 0; - - char const_input[256]; - - for(i = 0; i < 256; i++) { - const_input[i] = argv[i]; - } - - sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); -} - -void STM32SAM::sayPhonetic(char* argv) { - int i; - - phonetic = 1; - singmode = 0; - - char const_input[256]; - - for(i = 0; i < 256; i++) { - const_input[i] = argv[i]; - } - - sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// STM32SAM singPhonetic (sing on, phonetic on) -// -//////////////////////////////////////////////////////////////////////////////////////////// - -void STM32SAM::singPhonetic(const char* argv) { - int i; - - phonetic = 1; - singmode = 1; - - char const_input[256]; - - for(i = 0; i < 256; i++) { - const_input[i] = argv[i]; - } - - sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); -} - -void STM32SAM::singPhonetic(char* argv) { - int i; - - phonetic = 1; - singmode = 0; - - char const_input[256]; - - for(i = 0; i < 256; i++) { - const_input[i] = argv[i]; - } - - sam(const_input, phonetic, singmode, pitch, speed, mouth, throat); -} - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// STM32SAM voice (pitch, speed, mouth, throat) -// -//////////////////////////////////////////////////////////////////////////////////////////// - -void STM32SAM::setVoice( - unsigned char _pitch /* = 64 */, - unsigned char _speed /* = 72 */, - unsigned char _mouth /* = 128 */, - unsigned char _throat /* = 128 */) { - pitch = _pitch; - speed = _speed; - mouth = _mouth; - throat = _throat; -} - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// STM32SAM setPitch (pitch) -// -//////////////////////////////////////////////////////////////////////////////////////////// - -void STM32SAM::setPitch(unsigned char _pitch /* = 64 */) { - pitch = _pitch; -} -//////////////////////////////////////////////////////////////////////////////////////////// -// -// STM32SAM setSpeed (speed) -// -//////////////////////////////////////////////////////////////////////////////////////////// - -void STM32SAM::setSpeed(unsigned char _speed /* = 72 */) { - speed = _speed; -} -//////////////////////////////////////////////////////////////////////////////////////////// -// -// STM32SAM setMouth (mouth) -// -//////////////////////////////////////////////////////////////////////////////////////////// - -void STM32SAM::setMouth(unsigned char _mouth /* = 128 */) { - mouth = _mouth; -} - -//////////////////////////////////////////////////////////////////////////////////////////// -// -// STM32SAM setThroat (throat) -// -//////////////////////////////////////////////////////////////////////////////////////////// - -void STM32SAM::setThroat(unsigned char _throat /* = 128 */) { - throat = _throat; -} -//////////////////////////////////////////////////////////////////////////////////////////// -// -// Hardware -// -//////////////////////////////////////////////////////////////////////////////////////////// -// Hardware specifics, for easier porting to other microcontrollers - -// -// Set PA8 pin as PWM, at 256 timer ticks overflow (8bit resolution) - -#include -#include - -#define FURI_HAL_SPEAKER_TIMER TIM16 -#define FURI_HAL_SPEAKER_CHANNEL LL_TIM_CHANNEL_CH1 - -void STM32SAM::begin(void) { -#ifdef USE_ROGER_CORE - - pinMode(PA8, PWM); // audio output pin - - Timer1.setPeriod( - 4); // Can't set at 256 ticks, only in uS. First nearest uS is 4 (Roger core is only for bluepill, that means 72*4=288 ticks, or 128*4=512 ticks when overclocked. It's ok, just overall volume will be lower, because maximum volume will be 256/288 or 256/512) - -#endif - -#ifdef USE_STM32duino_CORE - pinMode(PA8, OUTPUT); - - PWM->pause(); - PWM->setMode(1, TIMER_OUTPUT_COMPARE_PWM1, PA8); // TIM1 CH1 (PA8) - PWM->setPrescaleFactor(1); - PWM->setOverflow(256, TICK_FORMAT); // 256 ticks overflow, no matter the CPU (timer) speed - PWM->resume(); - -#endif - - LL_TIM_InitTypeDef TIM_InitStruct; - memset(&TIM_InitStruct, 0, sizeof(LL_TIM_InitTypeDef)); - TIM_InitStruct.Prescaler = 4; - TIM_InitStruct.Autoreload = 255; - LL_TIM_Init(FURI_HAL_SPEAKER_TIMER, &TIM_InitStruct); - - LL_TIM_OC_InitTypeDef TIM_OC_InitStruct; - memset(&TIM_OC_InitStruct, 0, sizeof(LL_TIM_OC_InitTypeDef)); - TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1; - TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE; - TIM_OC_InitStruct.CompareValue = 127; - LL_TIM_OC_Init(FURI_HAL_SPEAKER_TIMER, FURI_HAL_SPEAKER_CHANNEL, &TIM_OC_InitStruct); - - LL_TIM_EnableAllOutputs(FURI_HAL_SPEAKER_TIMER); - LL_TIM_EnableCounter(FURI_HAL_SPEAKER_TIMER); -} // begin - -inline void STM32SAM::SetAUDIO(unsigned char main_volume) { -#ifdef USE_ROGER_CORE - Timer1.setCompare(TIMER_CH1, main_volume); -#endif - -#ifdef USE_STM32duino_CORE - PWM->setCaptureCompare(1, main_volume, TICK_COMPARE_FORMAT); -#endif - - // if(main_volume > 64) { - // LL_TIM_OC_SetCompareCH1(FURI_HAL_SPEAKER_TIMER, 127); - // } else { - // LL_TIM_OC_SetCompareCH1(FURI_HAL_SPEAKER_TIMER, main_volume); - // } - - float data = main_volume; - data /= 255.0f; - data -= 0.5f; - data *= 4.0f; - data = tanhf(data); - - data += 0.5f; - data *= 255.0f; - - if(data < 0) { - data = 0; - } else if(data > 255) { - data = 255; - } - - LL_TIM_OC_SetCompareCH1(FURI_HAL_SPEAKER_TIMER, data); -} \ No newline at end of file diff --git a/applications/external/sam/stm32_sam.h b/applications/external/sam/stm32_sam.h deleted file mode 100644 index 910227ac3..000000000 --- a/applications/external/sam/stm32_sam.h +++ /dev/null @@ -1,96 +0,0 @@ -#include - -#ifndef __STM32SAM__ -#define __STM32SAM__ - -// SAM Text-To-Speech (TTS), ported from https://github.com/s-macke/SAM - -class STM32SAM { -public: - STM32SAM(uint32_t STM32SAM_SPEED); - STM32SAM(); - - void begin(void); - - void - sam(const char* argv, - unsigned char phonetic, - unsigned char singmode, - unsigned char pitch, - unsigned char speed, - unsigned char mouth, - unsigned char throat); - void - sam(char* argv, - unsigned char phonetic, - unsigned char singmode, - unsigned char pitch, - unsigned char speed, - unsigned char mouth, - unsigned char throat); - - void say(const char* argv); - void say(char* argv); - void sing(const char* argv); - void sing(char* argv); - void sayPhonetic(const char* argv); - void sayPhonetic(char* argv); - void singPhonetic(const char* argv); - void singPhonetic(char* argv); - void setVoice( - unsigned char _pitch = 64, - unsigned char _speed = 72, - unsigned char _mouth = 128, - unsigned char _throat = 128); - void setPitch(unsigned char _pitch = 64); - void setSpeed(unsigned char _speed = 72); - void setMouth(unsigned char _mouth = 128); - void setThroat(unsigned char _throat = 128); - -private: - void SetAUDIO(unsigned char main_volume); - - void Output8BitAry(int index, unsigned char ary[5]); - void Output8Bit(int index, unsigned char A); - unsigned char Read(unsigned char p, unsigned char Y); - void Write(unsigned char p, unsigned char Y, unsigned char value); - void RenderSample(unsigned char* mem66); - void Render(); - void AddInflection(unsigned char mem48, unsigned char phase1); - void SetMouthThroat(); - unsigned char trans(unsigned char mem39212, unsigned char mem39213); - void SetInput(char* _input); - void Init(); - int SAMMain(); - void PrepareOutput(); - void Insert( - unsigned char position /*var57*/, - unsigned char mem60, - unsigned char mem59, - unsigned char mem58); - void InsertBreath(); - void CopyStress(); - int Parser1(); - void SetPhonemeLength(); - void Code41240(); - void Parser2(); - void AdjustLengths(); - void Code47503(unsigned char mem52); - void Code37055(unsigned char mem59); - void Code37066(unsigned char mem58); - unsigned char GetRuleByte(unsigned short mem62, unsigned char Y); - int TextToPhonemes(unsigned char* input); // Code36484 - - uint32_t _STM32SAM_SPEED; - - unsigned char speed; - unsigned char pitch; - unsigned char mouth; - unsigned char throat; - - unsigned char phonetic; - unsigned char singmode; - -}; // STM32SAM class - -#endif \ No newline at end of file diff --git a/applications/external/uhf_rfid/application.fam b/applications/external/uhf_rfid/application.fam deleted file mode 100644 index eafbc83e1..000000000 --- a/applications/external/uhf_rfid/application.fam +++ /dev/null @@ -1,17 +0,0 @@ -App( - appid="uhf_rfid", - name="[YRM100] UHF RFID", - apptype=FlipperAppType.EXTERNAL, - targets=["f7"], - entry_point="uhf_app_main", - requires=[ - "storage", - "gui", - ], - stack_size=8 * 1024, - order=30, - fap_icon="uhf_10px.png", - fap_category="GPIO", - fap_icon_assets="icons", - fap_icon_assets_symbol="uhf_rfid", -) diff --git a/applications/external/uhf_rfid/scenes/uhf_scene.c b/applications/external/uhf_rfid/scenes/uhf_scene.c deleted file mode 100644 index 23c5cfb0f..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "uhf_scene.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const uhf_on_enter_handlers[])(void*) = { -#include "uhf_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_event handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, -bool (*const uhf_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "uhf_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_exit handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, -void (*const uhf_on_exit_handlers[])(void* context) = { -#include "uhf_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers uhf_scene_handlers = { - .on_enter_handlers = uhf_on_enter_handlers, - .on_event_handlers = uhf_on_event_handlers, - .on_exit_handlers = uhf_on_exit_handlers, - .scene_num = UHFSceneNum, -}; diff --git a/applications/external/uhf_rfid/scenes/uhf_scene.h b/applications/external/uhf_rfid/scenes/uhf_scene.h deleted file mode 100644 index f7c39c3f8..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) UHFScene##id, -typedef enum { -#include "uhf_scene_config.h" - UHFSceneNum, -} UHFScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers uhf_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "uhf_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_event handlers declaration -#define ADD_SCENE(prefix, name, id) \ - bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); -#include "uhf_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_exit handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); -#include "uhf_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_config.h b/applications/external/uhf_rfid/scenes/uhf_scene_config.h deleted file mode 100644 index 2fe83c6c1..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_config.h +++ /dev/null @@ -1,18 +0,0 @@ -ADD_SCENE(uhf, verify, Verify) -ADD_SCENE(uhf, start, Start) -ADD_SCENE(uhf, read_tag, ReadTag) -ADD_SCENE(uhf, read_tag_success, ReadTagSuccess) -ADD_SCENE(uhf, tag_menu, TagMenu) -ADD_SCENE(uhf, save_name, SaveName) -ADD_SCENE(uhf, save_success, SaveSuccess) -ADD_SCENE(uhf, saved_menu, SavedMenu) -ADD_SCENE(uhf, file_select, FileSelect) -ADD_SCENE(uhf, device_info, DeviceInfo) -ADD_SCENE(uhf, delete, Delete) -ADD_SCENE(uhf, delete_success, DeleteSuccess) -ADD_SCENE(uhf, write_tag, WriteTag) -ADD_SCENE(uhf, write_tag_success, WriteTagSuccess) -ADD_SCENE(uhf, settings, Settings) -// ADD_SCENE(uhf, read_factory_success, ReadFactorySuccess) -// ADD_SCENE(uhf, write_key, WriteKey) -// ADD_SCENE(uhf, key_menu, KeyMenu) diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_delete.c b/applications/external/uhf_rfid/scenes/uhf_scene_delete.c deleted file mode 100644 index 001068180..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_delete.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "../uhf_app_i.h" - -void uhf_scene_delete_widget_callback(GuiButtonType result, InputType type, void* context) { - UHFApp* uhf_app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(uhf_app->view_dispatcher, result); - } -} - -void uhf_scene_delete_on_enter(void* context) { - UHFApp* uhf_app = context; - - // Setup Custom Widget view - char temp_str[64]; - snprintf(temp_str, sizeof(temp_str), "\e#Delete %s?\e#", uhf_app->uhf_device->dev_name); - widget_add_text_box_element( - uhf_app->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, temp_str, false); - widget_add_button_element( - uhf_app->widget, GuiButtonTypeLeft, "Back", uhf_scene_delete_widget_callback, uhf_app); - widget_add_button_element( - uhf_app->widget, GuiButtonTypeRight, "Delete", uhf_scene_delete_widget_callback, uhf_app); - - view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewWidget); -} - -bool uhf_scene_delete_on_event(void* context, SceneManagerEvent event) { - UHFApp* uhf_app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - return scene_manager_previous_scene(uhf_app->scene_manager); - } else if(event.event == GuiButtonTypeRight) { - if(uhf_device_delete(uhf_app->uhf_device, true)) { - scene_manager_next_scene(uhf_app->scene_manager, UHFSceneDeleteSuccess); - } else { - scene_manager_search_and_switch_to_previous_scene( - uhf_app->scene_manager, UHFSceneStart); - } - consumed = true; - } - } - return consumed; -} - -void uhf_scene_delete_on_exit(void* context) { - UHFApp* uhf_app = context; - - widget_reset(uhf_app->widget); -} diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_delete_success.c b/applications/external/uhf_rfid/scenes/uhf_scene_delete_success.c deleted file mode 100644 index 3fd3780cc..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_delete_success.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "../uhf_app_i.h" - -void uhf_scene_delete_success_popup_callback(void* context) { - UHFApp* uhf_app = context; - view_dispatcher_send_custom_event(uhf_app->view_dispatcher, UHFCustomEventViewExit); -} - -void uhf_scene_delete_success_on_enter(void* context) { - UHFApp* uhf_app = context; - - // Setup view - Popup* popup = uhf_app->popup; - popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); - popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); - popup_set_timeout(popup, 1500); - popup_set_context(popup, uhf_app); - popup_set_callback(popup, uhf_scene_delete_success_popup_callback); - popup_enable_timeout(popup); - view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewPopup); -} - -bool uhf_scene_delete_success_on_event(void* context, SceneManagerEvent event) { - UHFApp* uhf_app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == UHFCustomEventViewExit) { - consumed = scene_manager_search_and_switch_to_previous_scene( - uhf_app->scene_manager, UHFSceneStart); - } - } - return consumed; -} - -void uhf_scene_delete_success_on_exit(void* context) { - UHFApp* uhf_app = context; - - // Clear view - popup_reset(uhf_app->popup); -} diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_device_info.c b/applications/external/uhf_rfid/scenes/uhf_scene_device_info.c deleted file mode 100644 index 899957fb0..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_device_info.c +++ /dev/null @@ -1,133 +0,0 @@ -#include "../uhf_app_i.h" -#include - -typedef enum { EPC_INFO, TID_INFO, USER_INFO } UHFTagInfo; - -static UHFTagInfo current_info; - -char* get_current_bank_info_str() { - switch(current_info) { - case EPC_INFO: - return "EPC Bank"; - case TID_INFO: - return "TID Bank"; - case USER_INFO: - return "User Bank"; - } - return ""; -} - -char* get_next_bank_info_str() { - switch(current_info) { - case EPC_INFO: - current_info = TID_INFO; - return "TID"; - case TID_INFO: - current_info = USER_INFO; - return "USER"; - case USER_INFO: - current_info = EPC_INFO; - return "EPC"; - } - return ""; -} - -void uhf_scene_device_info_widget_callback(GuiButtonType result, InputType type, void* context) { - UHFApp* uhf_app = context; - if(type == InputTypeShort) { - view_dispatcher_send_custom_event(uhf_app->view_dispatcher, result); - } -} - -void change_view_on_event(UHFApp* uhf_app) { - UHFTag* uhf_tag = uhf_app->uhf_device->uhf_tag_wrapper->uhf_tag; - FuriString* furi_temp_str; - furi_temp_str = furi_string_alloc(); - char* temp_str; - size_t length; - - widget_reset(uhf_app->widget); - widget_add_string_element( - uhf_app->widget, 64, 5, AlignCenter, AlignCenter, FontPrimary, get_current_bank_info_str()); - - switch(current_info) { - case EPC_INFO: - temp_str = convertToHexString(uhf_tag->epc->data, uhf_tag->epc->size); - length = uhf_tag->epc->size; - break; - case TID_INFO: - temp_str = convertToHexString(uhf_tag->tid->data, uhf_tag->tid->size); - length = uhf_tag->tid->size; - break; - case USER_INFO: - temp_str = convertToHexString(uhf_tag->user->data, uhf_tag->user->size); - length = uhf_tag->user->size; - break; - default: - temp_str = NULL; - length = 0; - break; - } - - furi_string_cat_printf(furi_temp_str, "Length: %d bytes", length); - - widget_add_string_element( - uhf_app->widget, - 3, - 12, - AlignLeft, - AlignTop, - FontKeyboard, - furi_string_get_cstr(furi_temp_str)); - - widget_add_string_multiline_element( - uhf_app->widget, 3, 24, AlignLeft, AlignTop, FontKeyboard, temp_str); - - widget_add_button_element( - uhf_app->widget, - GuiButtonTypeRight, - get_next_bank_info_str(), - uhf_scene_device_info_widget_callback, - uhf_app); - - widget_add_button_element( - uhf_app->widget, GuiButtonTypeLeft, "Back", uhf_scene_device_info_widget_callback, uhf_app); - - furi_string_free(furi_temp_str); - free(temp_str); -} - -void uhf_scene_device_info_on_enter(void* context) { - UHFApp* uhf_app = context; - current_info = EPC_INFO; - dolphin_deed(DolphinDeedNfcReadSuccess); - change_view_on_event(uhf_app); - view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewWidget); -} - -bool uhf_scene_device_info_on_event(void* context, SceneManagerEvent event) { - UHFApp* uhf_app = context; - bool consumed = false; - if(event.type == SceneManagerEventTypeTick) return false; - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_previous_scene(uhf_app->scene_manager); - } else if(event.event == GuiButtonTypeRight) { - change_view_on_event(uhf_app); - } else if(event.event == UHFCustomEventViewExit) { - view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewWidget); - consumed = true; - } - } else if(event.type == SceneManagerEventTypeBack) { - scene_manager_previous_scene(uhf_app->scene_manager); - consumed = true; - } - return consumed; -} - -void uhf_scene_device_info_on_exit(void* context) { - UHFApp* uhf_app = context; - - // Clear views - widget_reset(uhf_app->widget); -} diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_file_select.c b/applications/external/uhf_rfid/scenes/uhf_scene_file_select.c deleted file mode 100644 index ccecd78af..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_file_select.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "../uhf_app_i.h" - -void uhf_scene_file_select_on_enter(void* context) { - UHFApp* uhf_app = context; - // Process file_select return - uhf_device_set_loading_callback(uhf_app->uhf_device, uhf_show_loading_popup, uhf_app); - if(uhf_file_select(uhf_app->uhf_device)) { - scene_manager_next_scene(uhf_app->scene_manager, UHFSceneSavedMenu); - } else { - scene_manager_search_and_switch_to_previous_scene(uhf_app->scene_manager, UHFSceneStart); - } - uhf_device_set_loading_callback(uhf_app->uhf_device, NULL, uhf_app); -} - -bool uhf_scene_file_select_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void uhf_scene_file_select_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_read_tag.c b/applications/external/uhf_rfid/scenes/uhf_scene_read_tag.c deleted file mode 100644 index 4e1e98383..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_read_tag.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "../uhf_app_i.h" -#include - -void uhf_read_tag_worker_callback(UHFWorkerEvent event, void* ctx) { - UHFApp* uhf_app = ctx; - if(event == UHFWorkerEventSuccess) { - view_dispatcher_send_custom_event(uhf_app->view_dispatcher, UHFCustomEventWorkerExit); - } -} - -void uhf_scene_read_tag_on_enter(void* ctx) { - UHFApp* uhf_app = ctx; - dolphin_deed(DolphinDeedNfcRead); - - // Setup view - Popup* popup = uhf_app->popup; - popup_set_header(popup, "Detecting\n[UHF] RFID\nTag", 68, 30, AlignLeft, AlignTop); - popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); - - // Start worker - view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewPopup); - uhf_worker_start( - uhf_app->worker, UHFWorkerStateDetectSingle, uhf_read_tag_worker_callback, uhf_app); - - uhf_blink_start(uhf_app); -} - -bool uhf_scene_read_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, UHFSceneReadTagSuccess); - consumed = true; - } - return consumed; -} - -void uhf_scene_read_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); -} diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_read_tag_success.c b/applications/external/uhf_rfid/scenes/uhf_scene_read_tag_success.c deleted file mode 100644 index 1ab724f61..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_read_tag_success.c +++ /dev/null @@ -1,111 +0,0 @@ -#include "../uhf_app_i.h" -#include - -void uhf_read_tag_success_worker_callback(UHFWorkerEvent event, void* ctx) { - UNUSED(event); - UNUSED(ctx); -} - -void uhf_scene_read_card_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_read_tag_success_on_enter(void* ctx) { - UHFApp* uhf_app = ctx; - UHFTag* uhf_tag = uhf_app->worker->uhf_tag_wrapper->uhf_tag; - FuriString* temp_str = furi_string_alloc(); - - dolphin_deed(DolphinDeedNfcReadSuccess); - - // Send notification - notification_message(uhf_app->notifications, &sequence_success); - - widget_add_string_element( - uhf_app->widget, 32, 5, AlignLeft, AlignCenter, FontPrimary, "Read 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 :"); - - 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( - uhf_app->widget, - GuiButtonTypeRight, - "More", - uhf_scene_read_card_success_widget_callback, - uhf_app); - widget_add_button_element( - uhf_app->widget, - GuiButtonTypeLeft, - "Exit", - uhf_scene_read_card_success_widget_callback, - uhf_app); - view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewWidget); - free(epc); - furi_string_free(temp_str); -} - -bool uhf_scene_read_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_read_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); -} \ No newline at end of file diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_save_name.c b/applications/external/uhf_rfid/scenes/uhf_scene_save_name.c deleted file mode 100644 index 3fa9402d3..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_save_name.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "../uhf_app_i.h" -#include -#include -#include - -void uhf_scene_save_name_text_input_callback(void* context) { - UHFApp* uhf_app = context; - - view_dispatcher_send_custom_event(uhf_app->view_dispatcher, UHFCustomEventTextInputDone); -} - -void uhf_scene_save_name_on_enter(void* context) { - UHFApp* uhf_app = context; - - // Setup view - TextInput* text_input = uhf_app->text_input; - name_generator_make_random(uhf_app->text_store, sizeof(uhf_app->text_store)); - text_input_set_header_text(text_input, "Name the tag"); - text_input_set_result_callback( - text_input, - uhf_scene_save_name_text_input_callback, - uhf_app, - uhf_app->text_store, - UHF_DEV_NAME_MAX_LEN, - true); - - FuriString* folder_path; - folder_path = furi_string_alloc_set(STORAGE_APP_DATA_PATH_PREFIX); - - if(furi_string_end_with(uhf_app->uhf_device->load_path, UHF_APP_EXTENSION)) { - path_extract_dirname(furi_string_get_cstr(uhf_app->uhf_device->load_path), folder_path); - } - - ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - furi_string_get_cstr(folder_path), UHF_APP_EXTENSION, uhf_app->uhf_device->dev_name); - text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - - view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewTextInput); - - furi_string_free(folder_path); -} - -bool uhf_scene_save_name_on_event(void* context, SceneManagerEvent event) { - UHFApp* uhf_app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == UHFCustomEventTextInputDone) { - strlcpy( - uhf_app->uhf_device->dev_name, - uhf_app->text_store, - strlen(uhf_app->text_store) + 1); - if(uhf_device_save(uhf_app->uhf_device, uhf_app->text_store)) { - scene_manager_next_scene(uhf_app->scene_manager, UHFSceneSaveSuccess); - consumed = true; - } else { - consumed = scene_manager_search_and_switch_to_previous_scene( - uhf_app->scene_manager, UHFSceneStart); - } - } - } - return consumed; -} - -void uhf_scene_save_name_on_exit(void* context) { - UHFApp* uhf_app = context; - - // Clear view - void* validator_context = text_input_get_validator_callback_context(uhf_app->text_input); - text_input_set_validator(uhf_app->text_input, NULL, NULL); - validator_is_file_free(validator_context); - - text_input_reset(uhf_app->text_input); -} diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_save_success.c b/applications/external/uhf_rfid/scenes/uhf_scene_save_success.c deleted file mode 100644 index 69dc0b296..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_save_success.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "../uhf_app_i.h" -#include - -void uhf_scene_save_success_popup_callback(void* context) { - UHFApp* uhf_app = context; - view_dispatcher_send_custom_event(uhf_app->view_dispatcher, UHFCustomEventViewExit); -} - -void uhf_scene_save_success_on_enter(void* context) { - UHFApp* uhf_app = context; - dolphin_deed(DolphinDeedNfcSave); - - // Setup view - Popup* popup = uhf_app->popup; - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom); - popup_set_timeout(popup, 1500); - popup_set_context(popup, uhf_app); - popup_set_callback(popup, uhf_scene_save_success_popup_callback); - popup_enable_timeout(popup); - view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewPopup); -} - -bool uhf_scene_save_success_on_event(void* context, SceneManagerEvent event) { - UHFApp* uhf_app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == UHFCustomEventViewExit) { - if(scene_manager_has_previous_scene(uhf_app->scene_manager, UHFSceneTagMenu)) { - consumed = scene_manager_search_and_switch_to_previous_scene( - uhf_app->scene_manager, UHFSceneTagMenu); - } else { - consumed = scene_manager_search_and_switch_to_previous_scene( - uhf_app->scene_manager, UHFSceneStart); - } - } - } - return consumed; -} - -void uhf_scene_save_success_on_exit(void* context) { - UHFApp* uhf_app = context; - - // Clear view - popup_reset(uhf_app->popup); -} diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_saved_menu.c b/applications/external/uhf_rfid/scenes/uhf_scene_saved_menu.c deleted file mode 100644 index c06514ced..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_saved_menu.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "../uhf_app_i.h" - -enum SubmenuIndex { - SubmenuIndexDelete, - SubmenuIndexInfo, - SubmenuIndexWrite, -}; - -void uhf_scene_saved_menu_submenu_callback(void* context, uint32_t index) { - UHFApp* uhf_app = context; - - view_dispatcher_send_custom_event(uhf_app->view_dispatcher, index); -} - -void uhf_scene_saved_menu_on_enter(void* context) { - UHFApp* uhf_app = context; - Submenu* submenu = uhf_app->submenu; - - submenu_add_item( - submenu, "Delete", SubmenuIndexDelete, uhf_scene_saved_menu_submenu_callback, uhf_app); - submenu_add_item( - submenu, "Info", SubmenuIndexInfo, uhf_scene_saved_menu_submenu_callback, uhf_app); - submenu_add_item( - submenu, "Write", SubmenuIndexWrite, uhf_scene_saved_menu_submenu_callback, uhf_app); - - submenu_set_selected_item( - uhf_app->submenu, - scene_manager_get_scene_state(uhf_app->scene_manager, UHFSceneSavedMenu)); - - view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewMenu); -} - -bool uhf_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { - UHFApp* uhf_app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - scene_manager_set_scene_state(uhf_app->scene_manager, UHFSceneSavedMenu, event.event); - - if(event.event == SubmenuIndexDelete) { - scene_manager_next_scene(uhf_app->scene_manager, UHFSceneDelete); - consumed = true; - } else if(event.event == SubmenuIndexInfo) { - scene_manager_next_scene(uhf_app->scene_manager, UHFSceneDeviceInfo); - consumed = true; - } else if(event.event == SubmenuIndexWrite) { - scene_manager_next_scene(uhf_app->scene_manager, UHFSceneWriteTag); - consumed = true; - } - } - - return consumed; -} - -void uhf_scene_saved_menu_on_exit(void* context) { - UHFApp* uhf_app = context; - - submenu_reset(uhf_app->submenu); -} diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_settings.c b/applications/external/uhf_rfid/scenes/uhf_scene_settings.c deleted file mode 100644 index f1cb30bcc..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_settings.c +++ /dev/null @@ -1,122 +0,0 @@ -#include "../uhf_app_i.h" -#include "../uhf_module.h" - -void uhf_settings_set_module_baudrate(VariableItem* item) { - M100Module* uhf_module = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - if(index >= BAUD_RATES_COUNT) { - return; - } - uint32_t baudrate = BAUD_RATES[index]; - m100_set_baudrate(uhf_module, baudrate); - char text_buf[10]; - snprintf(text_buf, sizeof(text_buf), "%lu", uhf_module->baudrate); - variable_item_set_current_value_text(item, text_buf); -} - -void uhf_settings_set_module_powerdb(VariableItem* item) { - M100Module* uhf_module = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - if(index >= POWER_DBM_COUNT) { - return; - } - uint16_t power = POWER_DBM[index]; - m100_set_transmitting_power(uhf_module, power); - char text_buf[10]; - snprintf(text_buf, sizeof(text_buf), "%ddBm", uhf_module->transmitting_power); - variable_item_set_current_value_text(item, text_buf); -} - -void uhf_settings_set_module_working_region(VariableItem* item) { - M100Module* uhf_module = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - if(index >= WORKING_REGIONS_COUNT) { - return; - } - WorkingRegion region = WORKING_REGIONS[index]; - m100_set_working_region(uhf_module, region); - variable_item_set_current_value_text(item, WORKING_REGIONS_STR[index]); -} - -uint8_t uhf_settings_get_module_baudrate_index(M100Module* module) { - for(uint8_t i = 0; i < BAUD_RATES_COUNT; i++) { - if(BAUD_RATES[i] == module->baudrate) { - return i; - } - } - return 0; -} - -uint8_t uhf_settings_get_module_power_index(M100Module* module) { - for(uint8_t i = 0; i < BAUD_RATES_COUNT; i++) { - if(POWER_DBM[i] == module->transmitting_power) { - return i; - } - } - return 0; -} - -uint8_t uhf_settings_get_module_working_region_index(M100Module* module) { - for(uint8_t i = 0; i < WORKING_REGIONS_COUNT; i++) { - if(WORKING_REGIONS[i] == module->region) { - return i; - } - } - return 0; -} - -void uhf_scene_settings_on_enter(void* ctx) { - UHFApp* uhf_app = ctx; - M100Module* uhf_module = uhf_app->worker->module; - VariableItem* item; - VariableItemList* variable_item_list = uhf_app->variable_item_list; - - uint8_t value_index = uhf_settings_get_module_baudrate_index(uhf_module); - char text_buf[10]; - snprintf(text_buf, sizeof(text_buf), "%lu", uhf_module->baudrate); - item = variable_item_list_add( - variable_item_list, - "Baudrate:", - BAUD_RATES_COUNT, - uhf_settings_set_module_baudrate, - uhf_module); - - variable_item_set_current_value_text(item, text_buf); - variable_item_set_current_value_index(item, value_index); - - value_index = uhf_settings_get_module_power_index(uhf_module); - item = variable_item_list_add( - variable_item_list, - "Power(DBM):", - POWER_DBM_COUNT, - uhf_settings_set_module_powerdb, - uhf_module); - snprintf(text_buf, sizeof(text_buf), "%ddBm", uhf_module->transmitting_power); - variable_item_set_current_value_text(item, text_buf); - variable_item_set_current_value_index(item, value_index); - - value_index = uhf_settings_get_module_working_region_index(uhf_module); - item = variable_item_list_add( - variable_item_list, - "Region:", - WORKING_REGIONS_COUNT, - uhf_settings_set_module_working_region, - uhf_module); - variable_item_set_current_value_text(item, WORKING_REGIONS_STR[value_index]); - variable_item_set_current_value_index(item, value_index); - - view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewVariableItemList); -} - -bool uhf_scene_settings_on_event(void* ctx, SceneManagerEvent event) { - UHFApp* uhf_app = ctx; - UNUSED(uhf_app); - UNUSED(event); - return false; -} - -void uhf_scene_settings_on_exit(void* ctx) { - UHFApp* uhf_app = ctx; - variable_item_list_set_selected_item(uhf_app->variable_item_list, 0); - variable_item_list_reset(uhf_app->variable_item_list); -} \ No newline at end of file diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_start.c b/applications/external/uhf_rfid/scenes/uhf_scene_start.c deleted file mode 100644 index a38122975..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_start.c +++ /dev/null @@ -1,54 +0,0 @@ -#include "../uhf_app_i.h" - -enum SubmenuIndex { SubmenuIndexRead, SubmenuIndexSaved, SubmenuIndexSettings }; - -void uhf_scene_start_submenu_callback(void* ctx, uint32_t index) { - UHFApp* uhf_app = ctx; - view_dispatcher_send_custom_event(uhf_app->view_dispatcher, index); -} - -void uhf_scene_start_on_enter(void* ctx) { - UHFApp* uhf_app = ctx; - - Submenu* submenu = uhf_app->submenu; - submenu_add_item( - submenu, "Read Tag", SubmenuIndexRead, uhf_scene_start_submenu_callback, uhf_app); - submenu_add_item( - submenu, "Saved", SubmenuIndexSaved, uhf_scene_start_submenu_callback, uhf_app); - submenu_add_item( - submenu, "Settings", SubmenuIndexSettings, uhf_scene_start_submenu_callback, uhf_app); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(uhf_app->scene_manager, UHFSceneStart)); - view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewMenu); -} - -bool uhf_scene_start_on_event(void* ctx, SceneManagerEvent event) { - UHFApp* uhf_app = ctx; - bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexRead) { - scene_manager_set_scene_state(uhf_app->scene_manager, UHFSceneStart, SubmenuIndexRead); - scene_manager_next_scene(uhf_app->scene_manager, UHFSceneReadTag); - consumed = true; - } else if(event.event == SubmenuIndexSaved) { - // Explicitly save state so that the correct item is - // reselected if the user cancels loading a file. - scene_manager_set_scene_state( - uhf_app->scene_manager, UHFSceneStart, SubmenuIndexSaved); - scene_manager_next_scene(uhf_app->scene_manager, UHFSceneFileSelect); - consumed = true; - } else if(event.event == SubmenuIndexSettings) { - scene_manager_set_scene_state( - uhf_app->scene_manager, UHFSceneStart, SubmenuIndexSettings); - scene_manager_next_scene(uhf_app->scene_manager, UHFSceneSettings); - consumed = true; - } - } - return consumed; -} - -void uhf_scene_start_on_exit(void* ctx) { - UHFApp* uhf_app = ctx; - submenu_reset(uhf_app->submenu); -} \ No newline at end of file diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_tag_menu.c b/applications/external/uhf_rfid/scenes/uhf_scene_tag_menu.c deleted file mode 100644 index 194677d91..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_tag_menu.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "../uhf_app_i.h" - -enum SubmenuIndex { - SubmenuIndexSave, - SubmenuIndexChangeKey, -}; - -void uhf_scene_tag_menu_submenu_callback(void* ctx, uint32_t index) { - UHFApp* uhf_app = ctx; - view_dispatcher_send_custom_event(uhf_app->view_dispatcher, index); -} - -void uhf_scene_tag_menu_on_enter(void* ctx) { - UHFApp* uhf_app = ctx; - - Submenu* submenu = uhf_app->submenu; - - submenu_add_item( - submenu, "Save", SubmenuIndexSave, uhf_scene_tag_menu_submenu_callback, uhf_app); - submenu_add_item( - submenu, "Change Key", SubmenuIndexChangeKey, uhf_scene_tag_menu_submenu_callback, uhf_app); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(uhf_app->scene_manager, UHFSceneTagMenu)); - - view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewMenu); -} - -bool uhf_scene_tag_menu_on_event(void* ctx, SceneManagerEvent event) { - UHFApp* uhf_app = ctx; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexSave) { - scene_manager_set_scene_state( - uhf_app->scene_manager, UHFSceneTagMenu, SubmenuIndexSave); - scene_manager_next_scene(uhf_app->scene_manager, UHFSceneSaveName); - consumed = true; - } - // else if(event.event == SubmenuIndexChangeKey) { - // scene_manager_set_scene_state( - // picopass->scene_manager, UHFSceneTagMenu, SubmenuIndexChangeKey); - // scene_manager_next_scene(picopass->scene_manager, PicopassSceneKeyMenu); - // consumed = true; - // } - } else if(event.type == SceneManagerEventTypeBack) { - consumed = scene_manager_search_and_switch_to_previous_scene( - uhf_app->scene_manager, UHFSceneStart); - } - - return consumed; -} - -void uhf_scene_tag_menu_on_exit(void* ctx) { - UHFApp* uhf_app = ctx; - - submenu_reset(uhf_app->submenu); -} diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_verify.c b/applications/external/uhf_rfid/scenes/uhf_scene_verify.c deleted file mode 100644 index 74101beca..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_verify.c +++ /dev/null @@ -1,147 +0,0 @@ -#include "../uhf_app_i.h" - -bool verify_success = false; -FuriString* temp_str; - -void uhf_scene_verify_callback_event(UHFWorkerEvent event, void* ctx) { - UNUSED(ctx); - UHFApp* uhf_app = ctx; - if(event == UHFWorkerEventSuccess) verify_success = true; - - view_dispatcher_send_custom_event(uhf_app->view_dispatcher, UHFCustomEventVerifyDone); -} - -void uhf_scene_verify_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_verify_on_enter(void* ctx) { - UHFApp* uhf_app = ctx; - uhf_worker_start( - uhf_app->worker, UHFWorkerStateVerify, uhf_scene_verify_callback_event, uhf_app); - temp_str = furi_string_alloc(); - view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewWidget); -} - -bool uhf_scene_verify_on_event(void* ctx, SceneManagerEvent event) { - UHFApp* uhf_app = ctx; - bool consumed = false; - if(event.event == SceneManagerEventTypeBack) { - uhf_app->worker->state = UHFWorkerStateStop; - } else if(event.type == SceneManagerEventTypeCustom) { - if(event.event == GuiButtonTypeRight) { - scene_manager_next_scene(uhf_app->scene_manager, UHFSceneStart); - consumed = true; - } else if(event.event == GuiButtonTypeLeft) { - if(!verify_success) { - widget_reset(uhf_app->widget); - furi_string_reset(temp_str); - uhf_worker_stop(uhf_app->worker); - // furi_hal_gpio_write(&gpio_ext, false); - // furi_delay_ms(50); - // furi_hal_gpio_write(&gpio_ext_pa7, true); - // furi_delay_ms(50); - uhf_worker_start( - uhf_app->worker, - UHFWorkerStateVerify, - uhf_scene_verify_callback_event, - uhf_app); - } - } else if(event.event == UHFCustomEventVerifyDone) { - if(verify_success) { - widget_reset(uhf_app->widget); - furi_string_reset(temp_str); - M100Module* module = uhf_app->worker->module; - widget_add_string_element( - uhf_app->widget, 64, 5, AlignCenter, AlignCenter, FontPrimary, "Module Info"); - // hardware info - furi_string_cat_str(temp_str, "HW Version: "); - furi_string_cat_str(temp_str, module->info->hw_version); - widget_add_string_element( - uhf_app->widget, - 1, - 15, - AlignLeft, - AlignTop, - FontSecondary, - furi_string_get_cstr(temp_str)); - furi_string_reset(temp_str); - // software info - furi_string_cat_str(temp_str, "SW Version: "); - furi_string_cat_str(temp_str, module->info->sw_version); - widget_add_string_element( - uhf_app->widget, - 1, - 27, - AlignLeft, - AlignTop, - FontSecondary, - furi_string_get_cstr(temp_str)); - furi_string_reset(temp_str); - // manufacturer info - furi_string_cat_str(temp_str, "Manufacturer: "); - furi_string_cat_str(temp_str, module->info->manufacturer); - widget_add_string_element( - uhf_app->widget, - 1, - 39, - AlignLeft, - AlignTop, - FontSecondary, - furi_string_get_cstr(temp_str)); - - widget_add_button_element( - uhf_app->widget, - GuiButtonTypeRight, - "Continue", - uhf_scene_verify_widget_callback, - uhf_app); - } else { - widget_add_string_element( - uhf_app->widget, - 64, - 5, - AlignCenter, - AlignCenter, - FontPrimary, - "No UHF Module found"); - widget_add_string_multiline_element( - uhf_app->widget, - 64, - 30, - AlignCenter, - AlignCenter, - FontSecondary, - "Please refer to the git@frux-c/uhf_rfid for help."); - widget_add_button_element( - uhf_app->widget, - GuiButtonTypeLeft, - "Retry", - uhf_scene_verify_widget_callback, - uhf_app); - widget_add_button_element( - uhf_app->widget, - GuiButtonTypeRight, - "Skip", - uhf_scene_verify_widget_callback, - uhf_app); - } - } - } - return consumed; -} - -void uhf_scene_verify_on_exit(void* ctx) { - UHFApp* uhf_app = ctx; - // Clear string - furi_string_free(temp_str); - // Stop worker - uhf_worker_stop(uhf_app->worker); - // clear widget - widget_reset(uhf_app->widget); -} \ No newline at end of file diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_write_tag.c b/applications/external/uhf_rfid/scenes/uhf_scene_write_tag.c deleted file mode 100644 index 57c548da9..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_write_tag.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "../uhf_app_i.h" -#include - -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); -} diff --git a/applications/external/uhf_rfid/scenes/uhf_scene_write_tag_success.c b/applications/external/uhf_rfid/scenes/uhf_scene_write_tag_success.c deleted file mode 100644 index 6148e5125..000000000 --- a/applications/external/uhf_rfid/scenes/uhf_scene_write_tag_success.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "../uhf_app_i.h" -#include - -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); -} \ No newline at end of file diff --git a/applications/external/uhf_rfid/uhf_10px.png b/applications/external/uhf_rfid/uhf_10px.png deleted file mode 100644 index aa9a29f89..000000000 Binary files a/applications/external/uhf_rfid/uhf_10px.png and /dev/null differ diff --git a/applications/external/uhf_rfid/uhf_app.c b/applications/external/uhf_rfid/uhf_app.c deleted file mode 100644 index 2e6610a98..000000000 --- a/applications/external/uhf_rfid/uhf_app.c +++ /dev/null @@ -1,214 +0,0 @@ -#include "uhf_app_i.h" - -char* convertToHexString(uint8_t* array, size_t length) { - if(array == NULL || length == 0) { - return " "; - } - FuriString* temp_str = furi_string_alloc(); - - for(size_t i = 0; i < length; i++) { - furi_string_cat_printf(temp_str, "%02X ", array[i]); - } - const char* furi_str = furi_string_get_cstr(temp_str); - - size_t str_len = strlen(furi_str); - char* str = (char*)malloc(sizeof(char) * str_len); - - memcpy(str, furi_str, str_len); - furi_string_free(temp_str); - return str; -} - -bool uhf_custom_event_callback(void* ctx, uint32_t event) { - furi_assert(ctx); - UHFApp* uhf_app = ctx; - return scene_manager_handle_custom_event(uhf_app->scene_manager, event); -} - -bool uhf_back_event_callback(void* ctx) { - furi_assert(ctx); - UHFApp* uhf_app = ctx; - return scene_manager_handle_back_event(uhf_app->scene_manager); -} - -void uhf_tick_event_callback(void* ctx) { - furi_assert(ctx); - UHFApp* uhf_app = ctx; - scene_manager_handle_tick_event(uhf_app->scene_manager); -} - -UHFApp* uhf_alloc() { - UHFApp* uhf_app = (UHFApp*)malloc(sizeof(UHFApp)); - uhf_app->view_dispatcher = view_dispatcher_alloc(); - uhf_app->scene_manager = scene_manager_alloc(&uhf_scene_handlers, uhf_app); - view_dispatcher_enable_queue(uhf_app->view_dispatcher); - view_dispatcher_set_event_callback_context(uhf_app->view_dispatcher, uhf_app); - view_dispatcher_set_custom_event_callback(uhf_app->view_dispatcher, uhf_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - uhf_app->view_dispatcher, uhf_back_event_callback); - view_dispatcher_set_tick_event_callback( - uhf_app->view_dispatcher, uhf_tick_event_callback, 100); - - // Open GUI record - uhf_app->gui = furi_record_open(RECORD_GUI); - view_dispatcher_attach_to_gui( - uhf_app->view_dispatcher, uhf_app->gui, ViewDispatcherTypeFullscreen); - - // Variable Item List - uhf_app->variable_item_list = variable_item_list_alloc(); - - //worker - uhf_app->worker = uhf_worker_alloc(); - - // device - uhf_app->uhf_device = uhf_device_alloc(); - - 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 - uhf_app->notifications = furi_record_open(RECORD_NOTIFICATION); - - // Variable Item List - uhf_app->variable_item_list = variable_item_list_alloc(); - view_dispatcher_add_view( - uhf_app->view_dispatcher, - UHFViewVariableItemList, - variable_item_list_get_view(uhf_app->variable_item_list)); - - // Submenu - uhf_app->submenu = submenu_alloc(); - view_dispatcher_add_view( - uhf_app->view_dispatcher, UHFViewMenu, submenu_get_view(uhf_app->submenu)); - - // Popup - uhf_app->popup = popup_alloc(); - view_dispatcher_add_view( - uhf_app->view_dispatcher, UHFViewPopup, popup_get_view(uhf_app->popup)); - - // Loading - uhf_app->loading = loading_alloc(); - view_dispatcher_add_view( - uhf_app->view_dispatcher, UHFViewLoading, loading_get_view(uhf_app->loading)); - - // Text Input - uhf_app->text_input = text_input_alloc(); - view_dispatcher_add_view( - uhf_app->view_dispatcher, UHFViewTextInput, text_input_get_view(uhf_app->text_input)); - - // Custom Widget - uhf_app->widget = widget_alloc(); - view_dispatcher_add_view( - uhf_app->view_dispatcher, UHFViewWidget, widget_get_view(uhf_app->widget)); - - return uhf_app; -} - -void uhf_free(UHFApp* uhf_app) { - furi_assert(uhf_app); - - // Submenu - view_dispatcher_remove_view(uhf_app->view_dispatcher, UHFViewMenu); - submenu_free(uhf_app->submenu); - - // Popup - view_dispatcher_remove_view(uhf_app->view_dispatcher, UHFViewPopup); - popup_free(uhf_app->popup); - - // Loading - view_dispatcher_remove_view(uhf_app->view_dispatcher, UHFViewLoading); - loading_free(uhf_app->loading); - - // TextInput - view_dispatcher_remove_view(uhf_app->view_dispatcher, UHFViewTextInput); - text_input_free(uhf_app->text_input); - - // Custom Widget - view_dispatcher_remove_view(uhf_app->view_dispatcher, UHFViewWidget); - widget_free(uhf_app->widget); - - // Tag - uhf_tag_wrapper_free(uhf_app->worker->uhf_tag_wrapper); - - // Worker - uhf_worker_stop(uhf_app->worker); - uhf_worker_free(uhf_app->worker); - - // Device - uhf_device_free(uhf_app->uhf_device); - - // View Dispatcher - view_dispatcher_free(uhf_app->view_dispatcher); - - // Scene Manager - scene_manager_free(uhf_app->scene_manager); - - // GUI - furi_record_close(RECORD_GUI); - uhf_app->gui = NULL; - - // Variable Item List - variable_item_list_free(uhf_app->variable_item_list); - - // Notifications - furi_record_close(RECORD_NOTIFICATION); - uhf_app->notifications = NULL; - - free(uhf_app); -} - -static const NotificationSequence uhf_sequence_blink_start_cyan = { - &message_blink_start_10, - &message_blink_set_color_cyan, - &message_do_not_reset, - NULL, -}; - -static const NotificationSequence uhf_sequence_blink_stop = { - &message_blink_stop, - NULL, -}; - -void uhf_blink_start(UHFApp* uhf_app) { - notification_message(uhf_app->notifications, &uhf_sequence_blink_start_cyan); -} - -void uhf_blink_stop(UHFApp* uhf_app) { - notification_message(uhf_app->notifications, &uhf_sequence_blink_stop); -} - -void uhf_show_loading_popup(void* ctx, bool show) { - UHFApp* uhf_app = ctx; - - if(show) { - // Raise timer priority so that animations can play - furi_timer_set_thread_priority(FuriTimerThreadPriorityElevated); - view_dispatcher_switch_to_view(uhf_app->view_dispatcher, UHFViewLoading); - } else { - // Restore default timer priority - furi_timer_set_thread_priority(FuriTimerThreadPriorityNormal); - } -} - -int32_t uhf_app_main(void* ctx) { - UNUSED(ctx); - UHFApp* uhf_app = uhf_alloc(); - - // enable 5v pin - furi_hal_power_enable_otg(); - // init pin a2 - // furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull); - furi_hal_uart_set_br(FuriHalUartIdUSART1, DEFAULT_BAUDRATE); - scene_manager_next_scene(uhf_app->scene_manager, UHFSceneVerify); - view_dispatcher_run(uhf_app->view_dispatcher); - - // disable 5v pin - furi_hal_power_disable_otg(); - // furi_hal_gpio_disable_int_callback() - // exit app - uhf_free(uhf_app); - return 0; -} \ No newline at end of file diff --git a/applications/external/uhf_rfid/uhf_app.h b/applications/external/uhf_rfid/uhf_app.h deleted file mode 100644 index 651386585..000000000 --- a/applications/external/uhf_rfid/uhf_app.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -typedef struct UHFApp UHFApp; diff --git a/applications/external/uhf_rfid/uhf_app_i.h b/applications/external/uhf_rfid/uhf_app_i.h deleted file mode 100644 index d8bc03c91..000000000 --- a/applications/external/uhf_rfid/uhf_app_i.h +++ /dev/null @@ -1,110 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "uhf_app.h" -#include "uhf_worker.h" -#include "uhf_device.h" -#include "scenes/uhf_scene.h" - -#include -#include -#include -#include - -#include - -#include - -#define UHF_TEXT_STORE_SIZE 128 -// #define UHF_APPS_DATA_FOLDER EXT_PATH("apps_data") -// #define UHF_APPS_STORAGE_FOLDER -// UHF_APPS_DATA_FOLDER "/" -// "uhf_rfid" -// #define UHF_FILE_EXTENSION ".uhf" - -enum UHFCustomEvent { - // Reserve first 100 events for button types and indexes, starting from 0 - UHFCustomEventReserved = 100, - - UHFCustomEventVerifyDone, - UHFCustomEventViewExit, - UHFCustomEventWorkerExit, - UHFCustomEventByteInputDone, - UHFCustomEventTextInputDone, - UHFCustomEventSceneSettingLock, -}; - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -struct UHFApp { - UHFWorker* worker; - ViewDispatcher* view_dispatcher; - Gui* gui; - NotificationApp* notifications; - SceneManager* scene_manager; - VariableItemList* variable_item_list; - // Storage* storage; - UHFDevice* uhf_device; - char text_store[UHF_TEXT_STORE_SIZE + 1]; - FuriString* text_box_store; - // Common Views - Submenu* submenu; - Popup* popup; - Loading* loading; - TextInput* text_input; - Widget* widget; -}; - -typedef enum { - UHFViewMenu, - UHFViewPopup, - UHFViewLoading, - UHFViewTextInput, - UHFViewWidget, - UHFViewVariableItemList, -} UHFView; - -UHFApp* uhf_app_alloc(); - -void uhf_text_store_set(UHFApp* uhf, const char* text, ...); - -void uhf_text_store_clear(UHFApp* uhf); - -void uhf_blink_start(UHFApp* uhf); - -void uhf_blink_stop(UHFApp* uhf); - -void uhf_show_loading_popup(void* context, bool show); - -/** Check if memory is set to pattern - * - * @warning zero size will return false - * - * @param[in] data Pointer to the byte array - * @param[in] pattern The pattern - * @param[in] size The byte array size - * - * @return True if memory is set to pattern, false otherwise - */ -bool uhf_is_memset(const uint8_t* data, const uint8_t pattern, size_t size); - -char* convertToHexString(uint8_t* array, size_t length); - -// bool uhf_save_read_data(UHFResponseData* uhf_response_data, Storage* storage, const char* filename); diff --git a/applications/external/uhf_rfid/uhf_buffer.c b/applications/external/uhf_rfid/uhf_buffer.c deleted file mode 100644 index 8e56f88df..000000000 --- a/applications/external/uhf_rfid/uhf_buffer.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "uhf_buffer.h" -#include -#include - -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) { - for(size_t i = 0; i < MAX_BUFFER_SIZE; i++) { - buf->data[i] = 0; - } - buf->size = 0; - buf->closed = false; -} - -void buffer_free(Buffer* buf) { - free(buf->data); - free(buf); -} \ No newline at end of file diff --git a/applications/external/uhf_rfid/uhf_buffer.h b/applications/external/uhf_rfid/uhf_buffer.h deleted file mode 100644 index 045b0e3e4..000000000 --- a/applications/external/uhf_rfid/uhf_buffer.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include -#include -#include - -#define MAX_BUFFER_SIZE 200 - -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); \ No newline at end of file diff --git a/applications/external/uhf_rfid/uhf_device.c b/applications/external/uhf_rfid/uhf_device.c deleted file mode 100644 index 79ab50163..000000000 --- a/applications/external/uhf_rfid/uhf_device.c +++ /dev/null @@ -1,350 +0,0 @@ -#include "uhf_device.h" -#include -#include -#include - -#include - -#define TAG "UHFDevice" - -static const char* uhf_file_header = "Flipper UHF RFID device"; -static const uint32_t uhf_file_version = 1; -// static const uint8_t bank_data_start = 20; -// static const uint8_t bank_data_length = 16; - -UHFDevice* uhf_device_alloc() { - UHFDevice* uhf_device = malloc(sizeof(UHFDevice)); - uhf_device->storage = furi_record_open(RECORD_STORAGE); - uhf_device->dialogs = furi_record_open(RECORD_DIALOGS); - uhf_device->load_path = furi_string_alloc(); - return uhf_device; -} - -void uhf_device_set_name(UHFDevice* dev, const char* name) { - furi_assert(dev); - strlcpy(dev->dev_name, name, UHF_DEV_NAME_MAX_LEN); -} - -static bool uhf_device_save_file( - UHFDevice* dev, - const char* dev_name, - const char* folder, - const char* extension, - bool use_load_path) { - furi_assert(dev); - - UHFTag* uhf_tag = dev->uhf_tag_wrapper->uhf_tag; - bool saved = false; - FlipperFormat* file = flipper_format_file_alloc(dev->storage); - FuriString* temp_str; - temp_str = furi_string_alloc(); - do { - if(use_load_path && !furi_string_empty(dev->load_path)) { - // Get directory name - path_extract_dirname(furi_string_get_cstr(dev->load_path), temp_str); - // Make path to file to save - furi_string_cat_printf(temp_str, "/%s%s", dev_name, extension); - } else { - // First remove uhf device file if it was saved - furi_string_printf(temp_str, "%s/%s%s", folder, dev_name, extension); - } - // Open file - if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break; - - // Write header - if(!flipper_format_write_header_cstr(file, uhf_file_header, uhf_file_version)) break; - - // Reserved bank might be added - // todo : maybe - uint32_t temp_arr[1]; - uint8_t temp_arr2[2]; - // write pc - temp_arr2[0] = (uint8_t)(uhf_tag_get_epc_pc(uhf_tag) >> 8) & 0xFF; - temp_arr2[1] = (uint8_t)(uhf_tag_get_epc_pc(uhf_tag) & 0xFF); - if(!flipper_format_write_hex(file, UHF_EPC_PC_LABEL, temp_arr2, 2)) break; - // write crc - temp_arr2[0] = (uint8_t)(uhf_tag_get_epc_crc(uhf_tag) >> 8) & 0xFF; - temp_arr2[1] = (uint8_t)(uhf_tag_get_epc_crc(uhf_tag) & 0xFF); - if(!flipper_format_write_hex(file, UHF_EPC_CRC_LABEL, temp_arr2, 2)) break; - // write epc - temp_arr[0] = uhf_tag_get_epc_size(uhf_tag); - 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_get_epc(uhf_tag), uhf_tag_get_epc_size(uhf_tag))) - break; - // write tid - temp_arr[0] = uhf_tag_get_tid_size(uhf_tag); - 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_get_tid(uhf_tag), uhf_tag_get_tid_size(uhf_tag))) - break; - // write user - temp_arr[0] = uhf_tag_get_user_size(uhf_tag); - if(!flipper_format_write_uint32(file, UHF_USER_BANK_LENGTH_LABEL, temp_arr, 1)) break; - if(!flipper_format_write_hex( - file, - UHF_USER_BANK_LABEL, - uhf_tag_get_user(uhf_tag), - uhf_tag_get_user_size(uhf_tag))) - break; - saved = true; - } while(0); - - if(!saved) { - dialog_message_show_storage_error(dev->dialogs, "Can not save\nfile"); - } - furi_string_free(temp_str); - flipper_format_free(file); - return saved; -} - -bool uhf_device_save(UHFDevice* dev, const char* dev_name) { - return uhf_device_save_file( - dev, dev_name, STORAGE_APP_DATA_PATH_PREFIX, UHF_APP_EXTENSION, true); - - return false; -} -// uncomment - -static bool uhf_device_load_data(UHFDevice* dev, FuriString* path, bool show_dialog) { - bool parsed = false; - FlipperFormat* file = flipper_format_file_alloc(dev->storage); - // UHFResponseData* uhf_response_data = dev->dev_data; - FuriString* temp_str; - temp_str = furi_string_alloc(); - bool deprecated_version = false; - UHFTag* uhf_tag = uhf_tag_alloc(); - uhf_tag_reset(uhf_tag); - uint32_t temp_arr[1]; - if(dev->loading_cb) { - dev->loading_cb(dev->loading_cb_ctx, true); - } - - do { - if(!flipper_format_file_open_existing(file, furi_string_get_cstr(path))) break; - - // Read and verify file header - uint32_t version = 0; - if(!flipper_format_read_header(file, temp_str, &version)) break; - if(furi_string_cmp_str(temp_str, uhf_file_header) || (version != uhf_file_version)) { - deprecated_version = true; - break; - } - // read pc - uint8_t temp_arr2[2]; - if(!flipper_format_read_hex(file, UHF_EPC_PC_LABEL, temp_arr2, 2)) break; - uhf_tag_set_epc_pc(uhf_tag, (temp_arr2[0] << 8) + temp_arr2[1]); - // read crc - if(!flipper_format_read_hex(file, UHF_EPC_CRC_LABEL, temp_arr2, 2)) break; - uhf_tag_set_epc_crc(uhf_tag, (temp_arr2[0] << 8) + temp_arr2[1]); - // read epc - if(!flipper_format_read_uint32(file, UHF_EPC_BANK_LENGTH_LABEL, temp_arr, 1)) break; - uhf_tag_set_epc_size(uhf_tag, temp_arr[0]); - if(!flipper_format_read_hex( - file, UHF_EPC_BANK_LABEL, uhf_tag_get_epc(uhf_tag), uhf_tag_get_epc_size(uhf_tag))) - break; - - // read tid - if(!flipper_format_read_uint32(file, UHF_TID_BANK_LENGTH_LABEL, temp_arr, 1)) break; - uhf_tag_set_tid_size(uhf_tag, temp_arr[0]); - if(!flipper_format_read_hex( - file, UHF_TID_BANK_LABEL, uhf_tag_get_tid(uhf_tag), uhf_tag_get_tid_size(uhf_tag))) - break; - // read user - if(!flipper_format_read_uint32(file, UHF_USER_BANK_LENGTH_LABEL, temp_arr, 1)) break; - uhf_tag_set_user_size(uhf_tag, temp_arr[0]); - if(!flipper_format_read_hex( - file, - UHF_USER_BANK_LABEL, - uhf_tag_get_user(uhf_tag), - uhf_tag_get_user_size(uhf_tag))) - break; - - parsed = true; - } while(false); - - if(dev->loading_cb) { - dev->loading_cb(dev->loading_cb_ctx, false); - } - - if((!parsed) && (show_dialog)) { - if(deprecated_version) { - dialog_message_show_storage_error(dev->dialogs, "File format deprecated"); - } else { - dialog_message_show_storage_error(dev->dialogs, "Can not parse\nfile"); - } - } - uhf_tag_wrapper_set_tag(dev->uhf_tag_wrapper, uhf_tag); - furi_string_free(temp_str); - flipper_format_free(file); - return parsed; -} - -// void picopass_device_clear(UHFDevice* dev) { -// furi_assert(dev); - -// picopass_device_data_clear(&dev->dev_data); -// memset(&dev->dev_data, 0, sizeof(dev->dev_data)); -// dev->format = PicopassDeviceSaveFormatHF; -// furi_string_reset(dev->load_path); -// } - -void uhf_device_free(UHFDevice* uhf_dev) { - furi_assert(uhf_dev); - furi_record_close(RECORD_STORAGE); - furi_record_close(RECORD_DIALOGS); - furi_string_free(uhf_dev->load_path); - free(uhf_dev); -} - -bool uhf_file_select(UHFDevice* dev) { - furi_assert(dev); - - FuriString* uhf_app_folder; - uhf_app_folder = furi_string_alloc_set(STORAGE_APP_DATA_PATH_PREFIX); - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, UHF_APP_EXTENSION, &I_Nfc_10px); - browser_options.base_path = STORAGE_APP_DATA_PATH_PREFIX; - - bool res = - dialog_file_browser_show(dev->dialogs, dev->load_path, uhf_app_folder, &browser_options); - - furi_string_free(uhf_app_folder); - if(res) { - FuriString* filename; - filename = furi_string_alloc(); - path_extract_filename(dev->load_path, filename, true); - strncpy(dev->dev_name, furi_string_get_cstr(filename), UHF_DEV_NAME_MAX_LEN); - res = uhf_device_load_data(dev, dev->load_path, true); - if(res) { - uhf_device_set_name(dev, dev->dev_name); - } - furi_string_free(filename); - } - - return res; -} - -// void uhf_device_data_clear(UHFDevice* dev_data) { -// for(size_t i = 0; i < PICOPASS_MAX_APP_LIMIT; i++) { -// memset(dev_data->AA1[i].data, 0, sizeof(dev_data->AA1[i].data)); -// } -// dev_data->pacs.legacy = false; -// dev_data->pacs.se_enabled = false; -// dev_data->pacs.elite_kdf = false; -// dev_data->pacs.pin_length = 0; -// } - -bool uhf_device_delete(UHFDevice* dev, bool use_load_path) { - furi_assert(dev); - - bool deleted = false; - FuriString* file_path; - file_path = furi_string_alloc(); - - do { - // Delete original file - if(use_load_path && !furi_string_empty(dev->load_path)) { - furi_string_set(file_path, dev->load_path); - } else { - furi_string_printf(file_path, APP_DATA_PATH("%s%s"), dev->dev_name, UHF_APP_EXTENSION); - } - if(!storage_simply_remove(dev->storage, furi_string_get_cstr(file_path))) break; - deleted = true; - } while(0); - - if(!deleted) { - dialog_message_show_storage_error(dev->dialogs, "Can not remove file"); - } - - furi_string_free(file_path); - return deleted; -} - -void uhf_device_set_loading_callback(UHFDevice* dev, UHFLoadingCallback callback, void* context) { - furi_assert(dev); - - dev->loading_cb = callback; - dev->loading_cb_ctx = context; -} - -// ReturnCode picopass_device_decrypt(uint8_t* enc_data, uint8_t* dec_data) { -// uint8_t key[32] = {0}; -// memcpy(key, picopass_iclass_decryptionkey, sizeof(picopass_iclass_decryptionkey)); -// mbedtls_des3_context ctx; -// mbedtls_des3_init(&ctx); -// mbedtls_des3_set2key_dec(&ctx, key); -// mbedtls_des3_crypt_ecb(&ctx, enc_data, dec_data); -// mbedtls_des3_free(&ctx); -// return ERR_NONE; -// } - -// ReturnCode picopass_device_parse_credential(PicopassBlock* AA1, PicopassPacs* pacs) { -// ReturnCode err; - -// pacs->biometrics = AA1[6].data[4]; -// pacs->pin_length = AA1[6].data[6] & 0x0F; -// pacs->encryption = AA1[6].data[7]; - -// if(pacs->encryption == PicopassDeviceEncryption3DES) { -// FURI_LOG_D(TAG, "3DES Encrypted"); -// err = picopass_device_decrypt(AA1[7].data, pacs->credential); -// if(err != ERR_NONE) { -// FURI_LOG_E(TAG, "decrypt error %d", err); -// return err; -// } - -// err = picopass_device_decrypt(AA1[8].data, pacs->pin0); -// if(err != ERR_NONE) { -// FURI_LOG_E(TAG, "decrypt error %d", err); -// return err; -// } - -// err = picopass_device_decrypt(AA1[9].data, pacs->pin1); -// if(err != ERR_NONE) { -// FURI_LOG_E(TAG, "decrypt error %d", err); -// return err; -// } -// } else if(pacs->encryption == PicopassDeviceEncryptionNone) { -// FURI_LOG_D(TAG, "No Encryption"); -// memcpy(pacs->credential, AA1[7].data, PICOPASS_BLOCK_LEN); -// memcpy(pacs->pin0, AA1[8].data, PICOPASS_BLOCK_LEN); -// memcpy(pacs->pin1, AA1[9].data, PICOPASS_BLOCK_LEN); -// } else if(pacs->encryption == PicopassDeviceEncryptionDES) { -// FURI_LOG_D(TAG, "DES Encrypted"); -// } else { -// FURI_LOG_D(TAG, "Unknown encryption"); -// } - -// pacs->sio = (AA1[10].data[0] == 0x30); // rough check - -// return ERR_NONE; -// } - -// ReturnCode picopass_device_parse_wiegand(uint8_t* data, PicopassWiegandRecord* record) { -// uint32_t* halves = (uint32_t*)data; -// if(halves[0] == 0) { -// uint8_t leading0s = __builtin_clz(REVERSE_BYTES_U32(halves[1])); -// record->bitLength = 31 - leading0s; -// } else { -// uint8_t leading0s = __builtin_clz(REVERSE_BYTES_U32(halves[0])); -// record->bitLength = 63 - leading0s; -// } -// FURI_LOG_D(TAG, "bitLength: %d", record->bitLength); - -// if(record->bitLength == 26) { -// uint8_t* v4 = data + 4; -// uint32_t bot = v4[3] | (v4[2] << 8) | (v4[1] << 16) | (v4[0] << 24); - -// record->CardNumber = (bot >> 1) & 0xFFFF; -// record->FacilityCode = (bot >> 17) & 0xFF; -// FURI_LOG_D(TAG, "FC: %u CN: %u", record->FacilityCode, record->CardNumber); -// record->valid = true; -// } else { -// record->CardNumber = 0; -// record->FacilityCode = 0; -// record->valid = false; -// } -// return ERR_NONE; -// } diff --git a/applications/external/uhf_rfid/uhf_device.h b/applications/external/uhf_rfid/uhf_device.h deleted file mode 100644 index 8af0858b3..000000000 --- a/applications/external/uhf_rfid/uhf_device.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include "uhf_tag.h" - -#define UHF_DEV_NAME_MAX_LEN 22 -#define UHF_EPC_BANK_LENGTH_LABEL "EPC_LENGTH" -#define UHF_TID_BANK_LENGTH_LABEL "TID_LENGTH" -#define UHF_USER_BANK_LENGTH_LABEL "USER_LENGTH" -#define UHF_EPC_PC_LABEL "PC" -#define UHF_EPC_CRC_LABEL "CRC" -#define UHF_RFU_BANK_LABEL "RFU" -#define UHF_EPC_BANK_LABEL "EPC" -#define UHF_TID_BANK_LABEL "TID" -#define UHF_USER_BANK_LABEL "USER" - -#define UHF_APP_EXTENSION ".uhf" - -typedef void (*UHFLoadingCallback)(void* context, bool state); - -typedef struct { - Storage* storage; - DialogsApp* dialogs; - UHFTagWrapper* uhf_tag_wrapper; - char dev_name[UHF_DEV_NAME_MAX_LEN + 1]; - FuriString* load_path; - UHFLoadingCallback loading_cb; - void* loading_cb_ctx; -} UHFDevice; - -UHFDevice* uhf_device_alloc(); - -void uhf_device_free(UHFDevice* uhf_dev); - -void uhf_device_set_name(UHFDevice* dev, const char* name); - -bool uhf_device_save(UHFDevice* dev, const char* dev_name); - -bool uhf_file_select(UHFDevice* dev); - -// void uhf_device_data_clear(PicopassDeviceData* dev_data); - -void uhf_device_clear(UHFDevice* dev); - -bool uhf_device_delete(UHFDevice* dev, bool use_load_path); - -void uhf_device_set_loading_callback(UHFDevice* dev, UHFLoadingCallback callback, void* context); - -// ReturnCode uhf_device_parse_credential(PicopassBlock* AA1, PicopassPacs* pacs); -// ReturnCode uhf_device_parse_wiegand(uint8_t* data, PicopassWiegandRecord* record); diff --git a/applications/external/uhf_rfid/uhf_module.c b/applications/external/uhf_rfid/uhf_module.c deleted file mode 100644 index ee41d6092..000000000 --- a/applications/external/uhf_rfid/uhf_module.c +++ /dev/null @@ -1,388 +0,0 @@ -#include "uhf_module.h" -#include "uhf_module_cmd.h" - -#define DELAY_MS 100 -#define WAIT_TICK 8000 // max wait time in between each byte - -volatile uint16_t tick = 0; - -void rx_callback(UartIrqEvent event, uint8_t data, void* ctx) { - UNUSED(event); - Buffer* buffer = ctx; - if(buffer->closed) return; // buffer closed - buffer_append_single(buffer, data); // append data - if(data == FRAME_END) buffer_close(buffer); // end of frame - tick = WAIT_TICK; // reset tick -} - -static M100ResponseType setup_and_send_rx(M100Module* module, uint8_t* cmd, size_t cmd_length) { - buffer_reset(module->buf); - tick = WAIT_TICK; - furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, cmd_length); - while(--tick) { - furi_delay_us(5); - } - buffer_close(module->buf); - // Validation Checks - uint8_t* data = buffer_get_data(module->buf); - size_t length = buffer_get_size(module->buf); - // check if size > 0 - if(!length) return M100EmptyResponse; - // check if data is valid - if(data[0] != FRAME_START || data[length - 1] != FRAME_END) return M100ValidationFail; - // check if checksum is correct - if(checksum(data + 1, length - 3) != data[length - 2]) return M100ChecksumFail; - return M100SuccessResponse; -} - -M100ModuleInfo* m100_module_info_alloc() { - M100ModuleInfo* module_info = (M100ModuleInfo*)malloc(sizeof(M100ModuleInfo)); - 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(MAX_BUFFER_SIZE); - module->baudrate = DEFAULT_BAUDRATE; - module->transmitting_power = DEFAULT_TRANSMITTING_POWER; - module->region = DEFAULT_WORKING_REGION; - furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, rx_callback, module->buf); - return module; -} - -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_info_helper(M100Module* module, char** info) { - 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]); - } - if(*info == NULL) { - *info = (char*)malloc(sizeof(char) * payload_len); - } else { - for(size_t i = 0; i < strlen(*info); i++) { - (*info)[i] = 0; - } - } - memcpy(*info, furi_string_get_cstr(temp_str), payload_len); - furi_string_free(temp_str); - return *info; -} - -char* m100_get_hardware_version(M100Module* module) { - setup_and_send_rx(module, (uint8_t*)&CMD_HW_VERSION.cmd[0], CMD_HW_VERSION.length); - return _m100_info_helper(module, &module->info->hw_version); -} -char* m100_get_software_version(M100Module* module) { - setup_and_send_rx(module, (uint8_t*)&CMD_SW_VERSION.cmd[0], CMD_SW_VERSION.length); - return _m100_info_helper(module, &module->info->sw_version); -} -char* m100_get_manufacturers(M100Module* module) { - setup_and_send_rx(module, (uint8_t*)&CMD_MANUFACTURERS.cmd[0], CMD_MANUFACTURERS.length); - return _m100_info_helper(module, &module->info->manufacturer); -} - -M100ResponseType m100_single_poll(M100Module* module, UHFTag* uhf_tag) { - M100ResponseType rp_type = - setup_and_send_rx(module, (uint8_t*)&CMD_SINGLE_POLLING.cmd[0], CMD_SINGLE_POLLING.length); - if(rp_type != M100SuccessResponse) return rp_type; - uint8_t* data = buffer_get_data(module->buf); - size_t length = buffer_get_size(module->buf); - 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 - if(checksum(data + 1, length - 3) != data[length - 2]) return M100ValidationFail; - // validate crc - if(crc16_genibus(data + 6, epc_len + 2) != crc) return M100ValidationFail; - 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); - return M100SuccessResponse; -} - -M100ResponseType m100_set_select(M100Module* module, UHFTag* uhf_tag) { - // 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 new length - cmd_length = 12 + mask_length_bytes + 2; - // 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[cmd_length - 2] = checksum(cmd + 1, 11 + mask_length_bytes); - // end frame - cmd[cmd_length - 1] = FRAME_END; - - setup_and_send_rx(module, cmd, 12 + mask_length_bytes + 3); - - uint8_t* data = buffer_get_data(module->buf); - if(checksum(data + 1, 5) != data[6]) return M100ValidationFail; // error in rx - if(data[5] != 0x00) return M100ValidationFail; // error if not 0 - - return M100SuccessResponse; -} - -UHFTag* m100_get_select_param(M100Module* module) { - buffer_reset(module->buf); - furi_hal_uart_set_irq_cb(FuriHalUartIdLPUART1, rx_callback, module->buf); - furi_hal_uart_tx( - FuriHalUartIdUSART1, - (uint8_t*)&CMD_GET_SELECT_PARAMETER.cmd, - CMD_GET_SELECT_PARAMETER.length); - furi_delay_ms(DELAY_MS); - // UHFTag* uhf_tag = uhf_tag_alloc(); - // uint8_t* data = buffer_get_data(module->buf); - // size_t mask_length = - // uhf_tag_set_epc(uhf_tag, data + 12, ) - // TODO : implement - return NULL; -} - -M100ResponseType m100_read_label_data_storage( - M100Module* module, - UHFTag* uhf_tag, - BankType bank, - uint32_t access_pwd, - uint16_t word_count) { - /* - Will probably remove UHFTag as param and get it from get selected tag - */ - if(bank == EPCBank) return M100SuccessResponse; - uint8_t cmd[MAX_BUFFER_SIZE]; - size_t cmd_length = CMD_READ_LABEL_DATA_STORAGE_AREA.length; - memcpy(cmd, CMD_READ_LABEL_DATA_STORAGE_AREA.cmd, 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; - // set word counter - cmd[12] = (word_count >> 8) & 0xFF; - cmd[13] = word_count & 0xFF; - // calc checksum - cmd[cmd_length - 2] = checksum(cmd + 1, cmd_length - 3); - - M100ResponseType rp_type = setup_and_send_rx(module, cmd, cmd_length); - if(rp_type != M100SuccessResponse) return rp_type; - - uint8_t* data = buffer_get_data(module->buf); - - uint8_t rtn_command = data[2]; - uint16_t payload_len = data[3]; - payload_len = (payload_len << 8) + data[4]; - - if(rtn_command == 0xFF) { - if(payload_len == 0x01) return M100NoTagResponse; - return M100MemoryOverrun; - } - - size_t ptr_offset = 5 /*<-ptr offset*/ + uhf_tag_get_epc_size(uhf_tag) + 3 /*<-pc + ul*/; - size_t bank_data_length = payload_len - (ptr_offset - 5 /*dont include the offset*/); - - if(bank == TIDBank) { - uhf_tag_set_tid(uhf_tag, data + ptr_offset, bank_data_length); - } else if(bank == UserBank) { - uhf_tag_set_user(uhf_tag, data + ptr_offset, bank_data_length); - } - - return M100SuccessResponse; -} - -M100ResponseType m100_write_label_data_storage( - M100Module* module, - UHFTag* saved_tag, - UHFTag* selected_tag, - BankType bank, - uint16_t source_address, - uint32_t access_pwd) { - uint8_t cmd[MAX_BUFFER_SIZE]; - size_t cmd_length = CMD_WRITE_LABEL_DATA_STORE.length; - memcpy(cmd, CMD_WRITE_LABEL_DATA_STORE.cmd, cmd_length); - uint16_t payload_len = 9; - uint16_t data_length = 0; - if(bank == ReservedBank) { - // access pwd len + kill pwd len - payload_len += 4; - data_length = 4; - } else if(bank == EPCBank) { - // epc len + pc len - payload_len += 4 + uhf_tag_get_epc_size(saved_tag); - data_length = 4 + uhf_tag_get_epc_size(saved_tag); - // set data - uint8_t tmp_arr[4]; - tmp_arr[0] = (uint8_t)((uhf_tag_get_epc_crc(selected_tag) >> 8) & 0xFF); - tmp_arr[1] = (uint8_t)(uhf_tag_get_epc_crc(selected_tag) & 0xFF); - tmp_arr[2] = (uint8_t)((uhf_tag_get_epc_pc(saved_tag) >> 8) & 0xFF); - tmp_arr[3] = (uint8_t)(uhf_tag_get_epc_pc(saved_tag) & 0xFF); - memcpy(cmd + 14, tmp_arr, 4); - memcpy(cmd + 18, uhf_tag_get_epc(saved_tag), uhf_tag_get_epc_size(saved_tag)); - } else if(bank == UserBank) { - payload_len += uhf_tag_get_user_size(saved_tag); - data_length = uhf_tag_get_user_size(saved_tag); - // set data - memcpy(cmd + 14, uhf_tag_get_user(saved_tag), uhf_tag_get_user_size(saved_tag)); - } - // set payload length - cmd[3] = (payload_len >> 8) & 0xFF; - cmd[4] = payload_len & 0xFF; - // 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 membank - cmd[9] = (uint8_t)bank; - // set source address - cmd[10] = (source_address >> 8) & 0xFF; - cmd[11] = source_address & 0xFF; - // set data length - size_t data_length_words = data_length / 2; - cmd[12] = (data_length_words >> 8) & 0xFF; - cmd[13] = data_length_words & 0xFF; - // update cmd len - cmd_length = 7 + payload_len; - // calculate checksum - cmd[cmd_length - 2] = checksum(cmd + 1, cmd_length - 3); - cmd[cmd_length - 1] = FRAME_END; - // send cmd - // furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, rx_callback, module->buf); - // furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, cmd_length); - // unsigned int delay = DELAY_MS / 2; - // unsigned int timeout = 15; - // while(!buffer_get_size(module->buf)) { - // furi_delay_ms(delay); - // if(!timeout--) break; - // } - setup_and_send_rx(module, cmd, cmd_length); - uint8_t* buff_data = buffer_get_data(module->buf); - size_t buff_length = buffer_get_size(module->buf); - if(buff_data[2] == 0xFF && buff_length == 8) - return M100NoTagResponse; - else if(buff_data[2] == 0xFF) - return M100ValidationFail; - return M100SuccessResponse; -} -void m100_set_baudrate(M100Module* module, uint32_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 >> 8); // pow MSB - cmd[length - 2] = checksum(cmd + 1, length - 3); - furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, length); - furi_hal_uart_set_br(FuriHalUartIdUSART1, baudrate); - module->baudrate = baudrate; -} - -bool m100_set_working_region(M100Module* module, WorkingRegion region) { - size_t length = CMD_SET_WORK_AREA.length; - uint8_t cmd[length]; - memcpy(cmd, CMD_SET_WORK_AREA.cmd, length); - cmd[5] = (uint8_t)region; - cmd[length - 2] = checksum(cmd + 1, length - 3); - setup_and_send_rx(module, cmd, length); - module->region = region; - return true; -} - -bool m100_set_transmitting_power(M100Module* module, uint16_t power) { - size_t length = CMD_SET_TRANSMITTING_POWER.length; - uint8_t cmd[length]; - memcpy(cmd, CMD_SET_TRANSMITTING_POWER.cmd, length); - cmd[5] = (power >> 8) & 0xFF; - cmd[6] = power & 0xFF; - cmd[length - 2] = checksum(cmd + 1, length - 3); - setup_and_send_rx(module, cmd, length); - module->transmitting_power = power; - return true; -} - -bool m100_set_freq_hopping(M100Module* module, bool hopping) { - UNUSED(module); - UNUSED(hopping); - return true; -} - -bool m100_set_power(M100Module* module, uint8_t* power) { - UNUSED(module); - UNUSED(power); - return true; -} - -uint32_t m100_get_baudrate(M100Module* module) { - return module->baudrate; -} \ No newline at end of file diff --git a/applications/external/uhf_rfid/uhf_module.h b/applications/external/uhf_rfid/uhf_module.h deleted file mode 100644 index 2ac889f2f..000000000 --- a/applications/external/uhf_rfid/uhf_module.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "uhf_tag.h" -#include "uhf_buffer.h" -#include "uhf_tag.h" -#include -#include "uhf_module_settings.h" - -#define FRAME_START 0xBB -#define FRAME_END 0x7E -#define DEFAULT_BAUDRATE BAUD_RATES[BAUD_RATES_COUNT - 1] -#define DEFAULT_TRANSMITTING_POWER POWER_DBM[POWER_DBM_COUNT - 1] -#define DEFAULT_WORKING_REGION WR_US - -typedef struct { - char* hw_version; - char* sw_version; - char* manufacturer; -} M100ModuleInfo; - -typedef enum { - M100SuccessResponse, - M100ValidationFail, - M100NoTagResponse, - M100MemoryOverrun, - M100EmptyResponse, - M100ChecksumFail -} M100ResponseType; - -typedef struct { - M100ModuleInfo* info; - uint32_t baudrate; - WorkingRegion region; - uint16_t region_frequency; - 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); -uint8_t get_baudrate_count(); - -// Function prototypes -char* m100_get_hardware_version(M100Module* module); -char* m100_get_software_version(M100Module* module); -char* m100_get_manufacturers(M100Module* module); - -void m100_set_baudrate(M100Module* module, uint32_t baudrate); -bool m100_set_working_region(M100Module* module, WorkingRegion region); -bool m100_set_transmitting_power(M100Module* module, uint16_t power); -bool m100_set_freq_hopping(M100Module* module, bool hopping); -bool m100_set_power(M100Module* module, uint8_t* power); - -// gen2 cmds -M100ResponseType m100_single_poll(M100Module* module, UHFTag* uhf_tag); -M100ResponseType m100_set_select(M100Module* module, UHFTag* uhf_tag); -M100ResponseType m100_read_label_data_storage( - M100Module* module, - UHFTag* uhf_tag, - BankType bank, - uint32_t access_pwd, - uint16_t word_count); - -M100ResponseType m100_write_label_data_storage( - M100Module* module, - UHFTag* saved_tag, - UHFTag* selected_tag, - BankType bank, - uint16_t source_address, - uint32_t access_pwd); - -uint32_t m100_get_baudrate(M100Module* module); diff --git a/applications/external/uhf_rfid/uhf_module_cmd.h b/applications/external/uhf_rfid/uhf_module_cmd.h deleted file mode 100644 index 86605d8e9..000000000 --- a/applications/external/uhf_rfid/uhf_module_cmd.h +++ /dev/null @@ -1,89 +0,0 @@ -#pragma once - -#include -#include - -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}; -static const uint8_t CMD_SET_TRANSMITTING_POWER_DATA[] = - {0xBB, 0x00, 0xB6, 0x00, 0x02, 0x07, 0xD0, 0x8F, 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)}; -static const Command CMD_SET_TRANSMITTING_POWER = { - CMD_SET_TRANSMITTING_POWER_DATA, - sizeof(CMD_SET_TRANSMITTING_POWER_DATA)}; diff --git a/applications/external/uhf_rfid/uhf_module_settings.h b/applications/external/uhf_rfid/uhf_module_settings.h deleted file mode 100644 index d20a6f1a2..000000000 --- a/applications/external/uhf_rfid/uhf_module_settings.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// UHF module regions -typedef enum { - WR_CHINA_900 = 1, // Freq_CH-920.125M - WR_US, // Freq_CH-902.25M - WR_EU, // Freq_CH-865.1M - WR_CHINA_800, // Freq_CH-840.125M - WR_KOREA = 6 // Freq_CH-917.1M -} WorkingRegion; - -// UHF module baudrates -static const uint32_t BAUD_RATES[] = {9600, 19200, 115200}; -static const uint8_t BAUD_RATES_COUNT = sizeof(BAUD_RATES) / sizeof(BAUD_RATES[0]); -// RF Power Setting -static const uint8_t POWER_DBM[] = {12, 14, 17, 20}; // To be determined ... -static const uint8_t POWER_DBM_COUNT = sizeof(POWER_DBM) / sizeof(POWER_DBM[0]); -// UHF WorkingArea -static const char* WORKING_REGIONS_STR[] = {"CN1", "US", "EU", "CN2", "KR"}; -static const uint8_t __working_region_str = - sizeof(WORKING_REGIONS_STR) / sizeof(WORKING_REGIONS_STR[0]); -static const WorkingRegion WORKING_REGIONS[] = {WR_CHINA_900, WR_US, WR_EU, WR_CHINA_800, WR_KOREA}; -static const uint8_t WORKING_REGIONS_COUNT = sizeof(WORKING_REGIONS) / sizeof(WORKING_REGIONS[0]); -// UHF WorkingChannel -// static const string WORKING_CHANNELS_STR[] = {"China 900MHz", "US", "EU", "China 800MHz", "Korea"}; -// static const WorkingChannel WORKING_CHANNELS[] = {WC_CHINA_900, WC_US, WC_EU, WC_CHINA_800, WC_KOREA}; -// static const uint8_t WORKING_CHANNELS_COUNT = sizeof(WORKING_CHANNELS) / sizeof(WORKING_CHANNELS[0]); diff --git a/applications/external/uhf_rfid/uhf_tag.c b/applications/external/uhf_rfid/uhf_tag.c deleted file mode 100644 index d1142c291..000000000 --- a/applications/external/uhf_rfid/uhf_tag.c +++ /dev/null @@ -1,116 +0,0 @@ -#include "uhf_tag.h" -#include -#include - -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) { - if(uhf_tag_wrapper->uhf_tag != NULL) { - uhf_tag_free(uhf_tag_wrapper->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; -} - -void uhf_tag_set_epc_size(UHFTag* uhf_tag, size_t size) { - uhf_tag->epc->size = size; -} - -void uhf_tag_set_tid(UHFTag* uhf_tag, uint8_t* data_in, size_t size) { - memcpy(uhf_tag->tid->data, data_in, size); - uhf_tag->tid->size = size; -} - -void uhf_tag_set_tid_size(UHFTag* uhf_tag, size_t size) { - uhf_tag->tid->size = size; -} - -void uhf_tag_set_user(UHFTag* uhf_tag, uint8_t* data_in, size_t size) { - memcpy(uhf_tag->user->data, data_in, size); - uhf_tag->user->size = size; -} - -void uhf_tag_set_user_size(UHFTag* uhf_tag, size_t size) { - uhf_tag->user->size = size; -} - -// getters - -uint8_t* uhf_tag_get_epc(UHFTag* uhf_tag) { - return uhf_tag->epc->data; -} - -size_t uhf_tag_get_epc_size(UHFTag* uhf_tag) { - return uhf_tag->epc->size; -} - -uint16_t uhf_tag_get_epc_pc(UHFTag* uhf_tag) { - return uhf_tag->epc->pc; -} - -uint16_t uhf_tag_get_epc_crc(UHFTag* uhf_tag) { - return uhf_tag->epc->crc; -} - -uint8_t* uhf_tag_get_tid(UHFTag* uhf_tag) { - return uhf_tag->tid->data; -} - -size_t uhf_tag_get_tid_size(UHFTag* uhf_tag) { - return uhf_tag->tid->size; -} - -uint8_t* uhf_tag_get_user(UHFTag* uhf_tag) { - return uhf_tag->user->data; -} - -size_t uhf_tag_get_user_size(UHFTag* uhf_tag) { - return uhf_tag->user->size; -} diff --git a/applications/external/uhf_rfid/uhf_tag.h b/applications/external/uhf_rfid/uhf_tag.h deleted file mode 100644 index bfc045ceb..000000000 --- a/applications/external/uhf_rfid/uhf_tag.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include -#include -#include - -#define MAX_BANK_SIZE 256 -// 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[MAX_BANK_SIZE]; // 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[MAX_BANK_SIZE]; // 4 bytes for Class ID -} TIDMemoryBank; - -// User Memory Bank -typedef struct { - size_t size; // Size of user memory data - uint8_t data[MAX_BANK_SIZE]; // 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_epc_size(UHFTag* uhf_tag, size_t size); -void uhf_tag_set_tid(UHFTag* uhf_tag, uint8_t* data_in, size_t size); -void uhf_tag_set_tid_size(UHFTag* uhf_tag, size_t size); -void uhf_tag_set_user(UHFTag* uhf_tag, uint8_t* data_in, size_t size); -void uhf_tag_set_user_size(UHFTag* uhf_tag, 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); -uint16_t uhf_tag_get_epc_pc(UHFTag* uhf_tag); -uint16_t uhf_tag_get_epc_crc(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); diff --git a/applications/external/uhf_rfid/uhf_worker.c b/applications/external/uhf_rfid/uhf_worker.c deleted file mode 100644 index 759114631..000000000 --- a/applications/external/uhf_rfid/uhf_worker.c +++ /dev/null @@ -1,138 +0,0 @@ -#include "uhf_worker.h" -#include "uhf_tag.h" - -// yrm100 module commands -UHFWorkerEvent verify_module_connected(UHFWorker* uhf_worker) { - 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; -} - -UHFTag* send_polling_command(UHFWorker* uhf_worker) { - // read epc bank - UHFTag* uhf_tag = uhf_tag_alloc(); - while(true) { - M100ResponseType status = m100_single_poll(uhf_worker->module, uhf_tag); - if(uhf_worker->state == UHFWorkerStateStop) { - uhf_tag_free(uhf_tag); - return NULL; - } - if(status == M100SuccessResponse) break; - } - return uhf_tag; -} - -UHFWorkerEvent read_bank_till_max_length(UHFWorker* uhf_worker, UHFTag* uhf_tag, BankType bank) { - unsigned int word_low = 0, word_high = 64; - unsigned int word_size; - M100ResponseType status; - do { - if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted; - if(word_low >= word_high) return UHFWorkerEventSuccess; - word_size = (word_low + word_high) / 2; - status = m100_read_label_data_storage(uhf_worker->module, uhf_tag, bank, 0, word_size); - if(status == M100SuccessResponse) { - word_low = word_size + 1; - } else if(status == M100MemoryOverrun) { - word_high = word_size - 1; - } - } while(true); - return UHFWorkerEventSuccess; -} - -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); - // set select - if(m100_set_select(uhf_worker->module, uhf_tag) != M100SuccessResponse) - return UHFWorkerEventFail; - // read tid - UHFWorkerEvent event; - event = read_bank_till_max_length(uhf_worker, uhf_tag, TIDBank); - if(event != UHFWorkerEventSuccess) return event; - // read user - event = read_bank_till_max_length(uhf_worker, uhf_tag, UserBank); - if(event != UHFWorkerEventSuccess) return event; - return UHFWorkerEventSuccess; -} - -UHFWorkerEvent write_single_card(UHFWorker* uhf_worker) { - UHFTag* uhf_tag_des = send_polling_command(uhf_worker); - if(uhf_tag_des == NULL) return UHFWorkerEventAborted; - UHFTag* uhf_tag_from = uhf_worker->uhf_tag_wrapper->uhf_tag; - if(m100_set_select(uhf_worker->module, uhf_tag_des) != M100SuccessResponse) - return UHFWorkerEventFail; - do { - M100ResponseType rp_type = m100_write_label_data_storage( - uhf_worker->module, uhf_tag_from, uhf_tag_des, UserBank, 0, 0); - if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted; - if(rp_type == M100SuccessResponse) break; - } while(true); - do { - M100ResponseType rp_type = m100_write_label_data_storage( - uhf_worker->module, uhf_tag_from, uhf_tag_des, EPCBank, 0, 0); - if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted; - if(rp_type == M100SuccessResponse) break; - } while(true); - return UHFWorkerEventSuccess; -} - -int32_t uhf_worker_task(void* ctx) { - UHFWorker* uhf_worker = ctx; - if(uhf_worker->state == UHFWorkerStateVerify) { - UHFWorkerEvent event = verify_module_connected(uhf_worker); - uhf_worker->callback(event, uhf_worker->ctx); - } else if(uhf_worker->state == UHFWorkerStateDetectSingle) { - UHFWorkerEvent event = read_single_card(uhf_worker); - 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; -} - -UHFWorker* uhf_worker_alloc() { - UHFWorker* uhf_worker = (UHFWorker*)malloc(sizeof(UHFWorker)); - uhf_worker->thread = furi_thread_alloc_ex("UHFWorker", 8 * 1024, uhf_worker_task, uhf_worker); - uhf_worker->module = m100_module_alloc(); - uhf_worker->callback = NULL; - uhf_worker->ctx = NULL; - return uhf_worker; -} - -void uhf_worker_change_state(UHFWorker* worker, UHFWorkerState state) { - worker->state = state; -} - -void uhf_worker_start( - UHFWorker* uhf_worker, - UHFWorkerState state, - UHFWorkerCallback callback, - void* ctx) { - uhf_worker->state = state; - uhf_worker->callback = callback; - uhf_worker->ctx = ctx; - furi_thread_start(uhf_worker->thread); -} - -void uhf_worker_stop(UHFWorker* uhf_worker) { - furi_assert(uhf_worker); - furi_assert(uhf_worker->thread); - - if(furi_thread_get_state(uhf_worker->thread) != FuriThreadStateStopped) { - uhf_worker_change_state(uhf_worker, UHFWorkerStateStop); - furi_thread_join(uhf_worker->thread); - } -} - -void uhf_worker_free(UHFWorker* uhf_worker) { - furi_assert(uhf_worker); - furi_thread_free(uhf_worker->thread); - m100_module_free(uhf_worker->module); - free(uhf_worker); -} \ No newline at end of file diff --git a/applications/external/uhf_rfid/uhf_worker.h b/applications/external/uhf_rfid/uhf_worker.h deleted file mode 100644 index b4f5aef1f..000000000 --- a/applications/external/uhf_rfid/uhf_worker.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include -#include -#include "uhf_module.h" - -typedef enum { - // Init states - UHFWorkerStateNone, - UHFWorkerStateBroken, - UHFWorkerStateReady, - UHFWorkerStateVerify, - // Main worker states - UHFWorkerStateDetectSingle, - UHFWorkerStateWriteSingle, - UHFWorkerStateWriteKey, - // Transition - UHFWorkerStateStop, -} UHFWorkerState; - -typedef enum { - UHFWorkerEventSuccess, - UHFWorkerEventFail, - UHFWorkerEventNoTagDetected, - UHFWorkerEventAborted, - UHFWorkerEventCardDetected, -} UHFWorkerEvent; - -typedef void (*UHFWorkerCallback)(UHFWorkerEvent event, void* ctx); - -typedef struct UHFWorker { - FuriThread* thread; - M100Module* module; - UHFWorkerCallback callback; - UHFWorkerState state; - UHFTagWrapper* uhf_tag_wrapper; - void* ctx; -} UHFWorker; - -int32_t uhf_worker_task(void* ctx); -UHFWorker* uhf_worker_alloc(); -void uhf_worker_change_state(UHFWorker* worker, UHFWorkerState state); -void uhf_worker_start( - UHFWorker* uhf_worker, - UHFWorkerState state, - UHFWorkerCallback callback, - void* ctx); -void uhf_worker_stop(UHFWorker* uhf_worker); -void uhf_worker_free(UHFWorker* uhf_worker); \ No newline at end of file diff --git a/applications/external/wifi_deauther/LICENSE b/applications/external/wifi_deauther/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/applications/external/wifi_deauther/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/applications/external/wifi_deauther/application.fam b/applications/external/wifi_deauther/application.fam deleted file mode 100644 index 770e99585..000000000 --- a/applications/external/wifi_deauther/application.fam +++ /dev/null @@ -1,15 +0,0 @@ -App( - appid="esp8266_wifi_deauther_v2", - name="[ESP8266] Deauther v2", - apptype=FlipperAppType.EXTERNAL, - entry_point="wifi_deauther_app", - cdefines=["APP_WIFI_deauther"], - requires=["gui"], - stack_size=1 * 1024, - fap_icon="wifi_10px.png", - fap_category="WiFi", - fap_author="@Timmotools & @xMasterX", - fap_weburl="https://github.com/Timmotools/flipperzero_esp8266_deautherv2", - fap_version="1.0", - fap_description="Works with ESP8266 Deauther v2 by @SpacehuhnTech (github)", -) diff --git a/applications/external/wifi_deauther/scenes/wifi_deauther_scene.c b/applications/external/wifi_deauther/scenes/wifi_deauther_scene.c deleted file mode 100644 index a974beea9..000000000 --- a/applications/external/wifi_deauther/scenes/wifi_deauther_scene.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "wifi_deauther_scene.h" - -// Generate scene on_enter handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, -void (*const wifi_deauther_scene_on_enter_handlers[])(void*) = { -#include "wifi_deauther_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_event handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, -bool (*const wifi_deauther_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = { -#include "wifi_deauther_scene_config.h" -}; -#undef ADD_SCENE - -// Generate scene on_exit handlers array -#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, -void (*const wifi_deauther_scene_on_exit_handlers[])(void* context) = { -#include "wifi_deauther_scene_config.h" -}; -#undef ADD_SCENE - -// Initialize scene handlers configuration structure -const SceneManagerHandlers wifi_deauther_scene_handlers = { - .on_enter_handlers = wifi_deauther_scene_on_enter_handlers, - .on_event_handlers = wifi_deauther_scene_on_event_handlers, - .on_exit_handlers = wifi_deauther_scene_on_exit_handlers, - .scene_num = WifideautherSceneNum, -}; diff --git a/applications/external/wifi_deauther/scenes/wifi_deauther_scene.h b/applications/external/wifi_deauther/scenes/wifi_deauther_scene.h deleted file mode 100644 index a6ef08553..000000000 --- a/applications/external/wifi_deauther/scenes/wifi_deauther_scene.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) WifideautherScene##id, -typedef enum { -#include "wifi_deauther_scene_config.h" - WifideautherSceneNum, -} WifideautherScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers wifi_deauther_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "wifi_deauther_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_event handlers declaration -#define ADD_SCENE(prefix, name, id) \ - bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); -#include "wifi_deauther_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_exit handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); -#include "wifi_deauther_scene_config.h" -#undef ADD_SCENE diff --git a/applications/external/wifi_deauther/scenes/wifi_deauther_scene_config.h b/applications/external/wifi_deauther/scenes/wifi_deauther_scene_config.h deleted file mode 100644 index 5f21cdc50..000000000 --- a/applications/external/wifi_deauther/scenes/wifi_deauther_scene_config.h +++ /dev/null @@ -1,3 +0,0 @@ -ADD_SCENE(wifi_deauther, start, Start) -ADD_SCENE(wifi_deauther, console_output, ConsoleOutput) -ADD_SCENE(wifi_deauther, text_input, TextInput) diff --git a/applications/external/wifi_deauther/scenes/wifi_deauther_scene_console_output.c b/applications/external/wifi_deauther/scenes/wifi_deauther_scene_console_output.c deleted file mode 100644 index 593c1daab..000000000 --- a/applications/external/wifi_deauther/scenes/wifi_deauther_scene_console_output.c +++ /dev/null @@ -1,90 +0,0 @@ -#include "../wifi_deauther_app_i.h" - -void wifi_deauther_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) { - furi_assert(context); - WifideautherApp* app = context; - - // If text box store gets too big, then truncate it - app->text_box_store_strlen += len; - if(app->text_box_store_strlen >= WIFI_deauther_TEXT_BOX_STORE_SIZE - 1) { - furi_string_right(app->text_box_store, app->text_box_store_strlen / 2); - app->text_box_store_strlen = furi_string_size(app->text_box_store); - } - - // Null-terminate buf and append to text box store - buf[len] = '\0'; - furi_string_cat_printf(app->text_box_store, "%s", buf); - - view_dispatcher_send_custom_event(app->view_dispatcher, WifideautherEventRefreshConsoleOutput); -} - -void wifi_deauther_scene_console_output_on_enter(void* context) { - WifideautherApp* app = context; - - TextBox* text_box = app->text_box; - text_box_reset(app->text_box); - text_box_set_font(text_box, TextBoxFontText); - if(app->focus_console_start) { - text_box_set_focus(text_box, TextBoxFocusStart); - } else { - text_box_set_focus(text_box, TextBoxFocusEnd); - } - if(app->is_command) { - furi_string_reset(app->text_box_store); - app->text_box_store_strlen = 0; - if(0 == strncmp("help", app->selected_tx_string, strlen("help"))) { - const char* help_msg = "No help here\nonly pain\n"; - furi_string_cat_str(app->text_box_store, help_msg); - app->text_box_store_strlen += strlen(help_msg); - } - - if(app->show_stopscan_tip) { - const char* help_msg = "Press BACK to send stopscan\n"; - furi_string_cat_str(app->text_box_store, help_msg); - app->text_box_store_strlen += strlen(help_msg); - } - } - // "View Log" menu action - text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store)); - - scene_manager_set_scene_state(app->scene_manager, WifideautherSceneConsoleOutput, 0); - view_dispatcher_switch_to_view(app->view_dispatcher, WifideautherAppViewConsoleOutput); - - // Register callback to receive data - wifi_deauther_uart_set_handle_rx_data_cb( - app->uart, wifi_deauther_console_output_handle_rx_data_cb); // setup callback for rx thread - - // Send command with newline '\n' - if(app->is_command && app->selected_tx_string) { - wifi_deauther_uart_tx( - (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string)); - wifi_deauther_uart_tx((uint8_t*)("\n"), 1); - } -} - -bool wifi_deauther_scene_console_output_on_event(void* context, SceneManagerEvent event) { - WifideautherApp* app = context; - - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store)); - consumed = true; - } else if(event.type == SceneManagerEventTypeTick) { - consumed = true; - } - - return consumed; -} - -void wifi_deauther_scene_console_output_on_exit(void* context) { - WifideautherApp* app = context; - - // Unregister rx callback - wifi_deauther_uart_set_handle_rx_data_cb(app->uart, NULL); - - // Automatically stop the scan when exiting view - if(app->is_command) { - wifi_deauther_uart_tx((uint8_t*)("stopscan\n"), strlen("stopscan\n")); - } -} \ No newline at end of file diff --git a/applications/external/wifi_deauther/scenes/wifi_deauther_scene_start.c b/applications/external/wifi_deauther/scenes/wifi_deauther_scene_start.c deleted file mode 100644 index 92b80b2cf..000000000 --- a/applications/external/wifi_deauther/scenes/wifi_deauther_scene_start.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "../wifi_deauther_app_i.h" - -// For each command, define whether additional arguments are needed -// (enabling text input to fill them out), and whether the console -// text box should focus at the start of the output or the end -typedef enum { NO_ARGS = 0, INPUT_ARGS, TOGGLE_ARGS } InputArgs; - -typedef enum { FOCUS_CONSOLE_END = 0, FOCUS_CONSOLE_START, FOCUS_CONSOLE_TOGGLE } FocusConsole; - -#define SHOW_STOPSCAN_TIP (true) -#define NO_TIP (false) - -#define MAX_OPTIONS (6) -typedef struct { - const char* item_string; - const char* options_menu[MAX_OPTIONS]; - int num_options_menu; - const char* actual_commands[MAX_OPTIONS]; - InputArgs needs_keyboard; - FocusConsole focus_console; - bool show_stopscan_tip; -} WifideautherItem; - -// NUM_MENU_ITEMS defined in wifi_deauther_app_i.h - if you add an entry here, increment it! -const WifideautherItem MenuItems[NUM_MENU_ITEMS] = { - {"View Log from", {"start", "end"}, 2, {}, NO_ARGS, FOCUS_CONSOLE_TOGGLE, NO_TIP}, - {"Help", {""}, 1, {"help"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP}, - {"Stop", {""}, 1, {"stop all"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP}, - {"Scan", - {"All", "SSIDs", "Stations"}, - 3, - {"scan", "scan aps", "scan stations"}, - NO_ARGS, - FOCUS_CONSOLE_END, - NO_TIP}, - {"Select", - {"All", "SSIDs", "Stations"}, - 3, - {"select all", "select aps", "select stations"}, - INPUT_ARGS, - FOCUS_CONSOLE_END, - NO_TIP}, - {"Deselect", - {"All", "SSIDs", "Stations"}, - 3, - {"deselect all", "deselect aps", "deselect stations"}, - INPUT_ARGS, - FOCUS_CONSOLE_END, - NO_TIP}, - {"Show", - {"SSIDs", "Stations", "All", "Selected"}, - 4, - {"show ap", "show station", "show all", "show selected"}, - NO_ARGS, - FOCUS_CONSOLE_END, - NO_TIP}, - {"Attack", - {"deauth", "deauthall", "beacon", "probe"}, - 4, - {"attack deauth", "attack deauthall", "attack beacon", "attack probe"}, - NO_ARGS, - FOCUS_CONSOLE_END, - SHOW_STOPSCAN_TIP}, - {"Settings", - {"Get", "Remove AP", "Set SSID", "Set Pass", "Save"}, - 5, - {"get settings", - "set webinterface false", - "set ssid: pwned", - "set password: deauther", - "save settings"}, - INPUT_ARGS, - FOCUS_CONSOLE_END, - NO_TIP}, - {"Sysinfo", {""}, 1, {"sysinfo"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP}, - {"Reboot", {""}, 1, {"reboot"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP}, -}; - -static void wifi_deauther_scene_start_var_list_enter_callback(void* context, uint32_t index) { - furi_assert(context); - WifideautherApp* app = context; - if(app->selected_option_index[index] < MenuItems[index].num_options_menu) { - app->selected_tx_string = - MenuItems[index].actual_commands[app->selected_option_index[index]]; - } - app->is_command = (1 <= index); - app->is_custom_tx_string = false; - app->selected_menu_index = index; - app->focus_console_start = (MenuItems[index].focus_console == FOCUS_CONSOLE_TOGGLE) ? - (app->selected_option_index[index] == 0) : - MenuItems[index].focus_console; - app->show_stopscan_tip = MenuItems[index].show_stopscan_tip; - - bool needs_keyboard = (MenuItems[index].needs_keyboard == TOGGLE_ARGS) ? - (app->selected_option_index[index] != 0) : - MenuItems[index].needs_keyboard; - if(needs_keyboard) { - view_dispatcher_send_custom_event(app->view_dispatcher, WifideautherEventStartKeyboard); - } else { - view_dispatcher_send_custom_event(app->view_dispatcher, WifideautherEventStartConsole); - } -} - -static void wifi_deauther_scene_start_var_list_change_callback(VariableItem* item) { - furi_assert(item); - - WifideautherApp* app = variable_item_get_context(item); - furi_assert(app); - - const WifideautherItem* menu_item = &MenuItems[app->selected_menu_index]; - uint8_t item_index = variable_item_get_current_value_index(item); - furi_assert(item_index < menu_item->num_options_menu); - variable_item_set_current_value_text(item, menu_item->options_menu[item_index]); - app->selected_option_index[app->selected_menu_index] = item_index; -} - -void wifi_deauther_scene_start_on_enter(void* context) { - WifideautherApp* app = context; - VariableItemList* var_item_list = app->var_item_list; - - variable_item_list_set_enter_callback( - var_item_list, wifi_deauther_scene_start_var_list_enter_callback, app); - - VariableItem* item; - for(int i = 0; i < NUM_MENU_ITEMS; ++i) { - item = variable_item_list_add( - var_item_list, - MenuItems[i].item_string, - MenuItems[i].num_options_menu, - wifi_deauther_scene_start_var_list_change_callback, - app); - if(MenuItems[i].num_options_menu) { - variable_item_set_current_value_index(item, app->selected_option_index[i]); - variable_item_set_current_value_text( - item, MenuItems[i].options_menu[app->selected_option_index[i]]); - } - } - - variable_item_list_set_selected_item( - var_item_list, scene_manager_get_scene_state(app->scene_manager, WifideautherSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, WifideautherAppViewVarItemList); -} - -bool wifi_deauther_scene_start_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - WifideautherApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == WifideautherEventStartKeyboard) { - scene_manager_set_scene_state( - app->scene_manager, WifideautherSceneStart, app->selected_menu_index); - scene_manager_next_scene(app->scene_manager, WifideautherAppViewTextInput); - } else if(event.event == WifideautherEventStartConsole) { - scene_manager_set_scene_state( - app->scene_manager, WifideautherSceneStart, app->selected_menu_index); - scene_manager_next_scene(app->scene_manager, WifideautherAppViewConsoleOutput); - } - consumed = true; - } else if(event.type == SceneManagerEventTypeTick) { - app->selected_menu_index = variable_item_list_get_selected_item_index(app->var_item_list); - consumed = true; - } - - return consumed; -} - -void wifi_deauther_scene_start_on_exit(void* context) { - WifideautherApp* app = context; - variable_item_list_reset(app->var_item_list); -} diff --git a/applications/external/wifi_deauther/scenes/wifi_deauther_scene_text_input.c b/applications/external/wifi_deauther/scenes/wifi_deauther_scene_text_input.c deleted file mode 100644 index 339b2f2a3..000000000 --- a/applications/external/wifi_deauther/scenes/wifi_deauther_scene_text_input.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "../wifi_deauther_app_i.h" - -void wifi_deauther_scene_text_input_callback(void* context) { - WifideautherApp* app = context; - - view_dispatcher_send_custom_event(app->view_dispatcher, WifideautherEventStartConsole); -} - -void wifi_deauther_scene_text_input_on_enter(void* context) { - WifideautherApp* app = context; - - if(false == app->is_custom_tx_string) { - // Fill text input with selected string so that user can add to it - size_t length = strlen(app->selected_tx_string); - furi_assert(length < WIFI_deauther_TEXT_INPUT_STORE_SIZE); - bzero(app->text_input_store, WIFI_deauther_TEXT_INPUT_STORE_SIZE); - strncpy(app->text_input_store, app->selected_tx_string, length); - - // Add space - because flipper keyboard currently doesn't have a space - app->text_input_store[length] = ' '; - app->text_input_store[length + 1] = '\0'; - app->is_custom_tx_string = true; - } - - // Setup view - TextInput* text_input = app->text_input; - // Add help message to header - if(0 == strncmp("ssid -a -g", app->selected_tx_string, strlen("ssid -a -g"))) { - text_input_set_header_text(text_input, "Enter # SSIDs to generate"); - } else if(0 == strncmp("ssid -a -n", app->selected_tx_string, strlen("ssid -a -n"))) { - text_input_set_header_text(text_input, "Enter SSID name to add"); - } else if(0 == strncmp("ssid -r", app->selected_tx_string, strlen("ssid -r"))) { - text_input_set_header_text(text_input, "Remove target from SSID list"); - } else if(0 == strncmp("select -a", app->selected_tx_string, strlen("select -a"))) { - text_input_set_header_text(text_input, "Add target from AP list"); - } else if(0 == strncmp("select -s", app->selected_tx_string, strlen("select -s"))) { - text_input_set_header_text(text_input, "Add target from SSID list"); - } else { - text_input_set_header_text(text_input, "Add command arguments"); - } - text_input_set_result_callback( - text_input, - wifi_deauther_scene_text_input_callback, - app, - app->text_input_store, - WIFI_deauther_TEXT_INPUT_STORE_SIZE, - false); - - view_dispatcher_switch_to_view(app->view_dispatcher, WifideautherAppViewTextInput); -} - -bool wifi_deauther_scene_text_input_on_event(void* context, SceneManagerEvent event) { - WifideautherApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == WifideautherEventStartConsole) { - // Point to custom string to send - app->selected_tx_string = app->text_input_store; - scene_manager_next_scene(app->scene_manager, WifideautherAppViewConsoleOutput); - consumed = true; - } - } - - return consumed; -} - -void wifi_deauther_scene_text_input_on_exit(void* context) { - WifideautherApp* app = context; - - text_input_reset(app->text_input); -} diff --git a/applications/external/wifi_deauther/wifi_10px.png b/applications/external/wifi_deauther/wifi_10px.png deleted file mode 100644 index c13534660..000000000 Binary files a/applications/external/wifi_deauther/wifi_10px.png and /dev/null differ diff --git a/applications/external/wifi_deauther/wifi_deauther_app.c b/applications/external/wifi_deauther/wifi_deauther_app.c deleted file mode 100644 index 28fb28d88..000000000 --- a/applications/external/wifi_deauther/wifi_deauther_app.c +++ /dev/null @@ -1,106 +0,0 @@ -#include "wifi_deauther_app_i.h" - -#include -#include -#include - -static bool wifi_deauther_app_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - WifideautherApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool wifi_deauther_app_back_event_callback(void* context) { - furi_assert(context); - WifideautherApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void wifi_deauther_app_tick_event_callback(void* context) { - furi_assert(context); - WifideautherApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -WifideautherApp* wifi_deauther_app_alloc() { - WifideautherApp* app = malloc(sizeof(WifideautherApp)); - - app->gui = furi_record_open(RECORD_GUI); - - app->view_dispatcher = view_dispatcher_alloc(); - app->scene_manager = scene_manager_alloc(&wifi_deauther_scene_handlers, app); - view_dispatcher_enable_queue(app->view_dispatcher); - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, wifi_deauther_app_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, wifi_deauther_app_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, wifi_deauther_app_tick_event_callback, 100); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - app->var_item_list = variable_item_list_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - WifideautherAppViewVarItemList, - variable_item_list_get_view(app->var_item_list)); - - for(int i = 0; i < NUM_MENU_ITEMS; ++i) { - app->selected_option_index[i] = 0; - } - - app->text_box = text_box_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, WifideautherAppViewConsoleOutput, text_box_get_view(app->text_box)); - app->text_box_store = furi_string_alloc(); - furi_string_reserve(app->text_box_store, WIFI_deauther_TEXT_BOX_STORE_SIZE); - - app->text_input = text_input_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, WifideautherAppViewTextInput, text_input_get_view(app->text_input)); - - scene_manager_next_scene(app->scene_manager, WifideautherSceneStart); - - return app; -} - -void wifi_deauther_app_free(WifideautherApp* app) { - furi_assert(app); - - // Views - view_dispatcher_remove_view(app->view_dispatcher, WifideautherAppViewVarItemList); - view_dispatcher_remove_view(app->view_dispatcher, WifideautherAppViewConsoleOutput); - view_dispatcher_remove_view(app->view_dispatcher, WifideautherAppViewTextInput); - text_box_free(app->text_box); - furi_string_free(app->text_box_store); - text_input_free(app->text_input); - - // View dispatcher - view_dispatcher_free(app->view_dispatcher); - scene_manager_free(app->scene_manager); - - wifi_deauther_uart_free(app->uart); - - // Close records - furi_record_close(RECORD_GUI); - - free(app); -} - -int32_t wifi_deauther_app(void* p) { - furi_hal_power_enable_otg(); - furi_delay_ms(600); - UNUSED(p); - WifideautherApp* wifi_deauther_app = wifi_deauther_app_alloc(); - - wifi_deauther_app->uart = wifi_deauther_uart_init(wifi_deauther_app); - - view_dispatcher_run(wifi_deauther_app->view_dispatcher); - - wifi_deauther_app_free(wifi_deauther_app); - furi_hal_power_disable_otg(); - - return 0; -} diff --git a/applications/external/wifi_deauther/wifi_deauther_app.h b/applications/external/wifi_deauther/wifi_deauther_app.h deleted file mode 100644 index bb2f6fbfb..000000000 --- a/applications/external/wifi_deauther/wifi_deauther_app.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct WifideautherApp WifideautherApp; - -#ifdef __cplusplus -} -#endif diff --git a/applications/external/wifi_deauther/wifi_deauther_app_i.h b/applications/external/wifi_deauther/wifi_deauther_app_i.h deleted file mode 100644 index 91d837d0c..000000000 --- a/applications/external/wifi_deauther/wifi_deauther_app_i.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include "wifi_deauther_app.h" -#include "scenes/wifi_deauther_scene.h" -#include "wifi_deauther_custom_event.h" -#include "wifi_deauther_uart.h" - -#include -#include -#include -#include -#include -#include - -#include - -#define UART_CH \ - (xtreme_settings.uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) - -#define NUM_MENU_ITEMS (11) - -#define WIFI_deauther_TEXT_BOX_STORE_SIZE (4096) -#define WIFI_deauther_TEXT_INPUT_STORE_SIZE (512) - -struct WifideautherApp { - Gui* gui; - ViewDispatcher* view_dispatcher; - SceneManager* scene_manager; - - char text_input_store[WIFI_deauther_TEXT_INPUT_STORE_SIZE + 1]; - FuriString* text_box_store; - size_t text_box_store_strlen; - TextBox* text_box; - TextInput* text_input; - //Widget* widget; - - VariableItemList* var_item_list; - - WifideautherUart* uart; - int selected_menu_index; - int selected_option_index[NUM_MENU_ITEMS]; - const char* selected_tx_string; - bool is_command; - bool is_custom_tx_string; - bool focus_console_start; - bool show_stopscan_tip; -}; - -// Supported commands: -// https://github.com/justcallmekoko/ESP32deauther/wiki/cli -// Scan -// -> If list is empty, then start a new scanap. (Tap any button to stop.) -// -> If there's a list, provide option to rescan and dump list of targets to select. -// -> Press BACK to go back to top-level. -// Attack -// -> Beacon -// -> Deauth -// -> Probe -// -> Rickroll -// Sniff -// -> Beacon -// -> Deauth -// -> ESP -// -> PMKID -// -> Pwnagotchi -// Channel -// Update -// Reboot - -typedef enum { - WifideautherAppViewVarItemList, - WifideautherAppViewConsoleOutput, - WifideautherAppViewTextInput, -} WifideautherAppView; diff --git a/applications/external/wifi_deauther/wifi_deauther_custom_event.h b/applications/external/wifi_deauther/wifi_deauther_custom_event.h deleted file mode 100644 index 142961b1d..000000000 --- a/applications/external/wifi_deauther/wifi_deauther_custom_event.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -typedef enum { - WifideautherEventRefreshConsoleOutput = 0, - WifideautherEventStartConsole, - WifideautherEventStartKeyboard, -} WifideautherCustomEvent; diff --git a/applications/external/wifi_deauther/wifi_deauther_uart.c b/applications/external/wifi_deauther/wifi_deauther_uart.c deleted file mode 100644 index 8e5f76e14..000000000 --- a/applications/external/wifi_deauther/wifi_deauther_uart.c +++ /dev/null @@ -1,106 +0,0 @@ -#include "wifi_deauther_app_i.h" -#include "wifi_deauther_uart.h" - -#include -#include - -#define BAUDRATE (115200) - -struct WifideautherUart { - WifideautherApp* app; - FuriHalUartId channel; - FuriThread* rx_thread; - FuriStreamBuffer* rx_stream; - uint8_t rx_buf[RX_BUF_SIZE + 1]; - void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context); -}; - -typedef enum { - WorkerEvtStop = (1 << 0), - WorkerEvtRxDone = (1 << 1), -} WorkerEvtFlags; - -void wifi_deauther_uart_set_handle_rx_data_cb( - WifideautherUart* uart, - void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context)) { - furi_assert(uart); - uart->handle_rx_data_cb = handle_rx_data_cb; -} - -#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone) - -void wifi_deauther_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { - WifideautherUart* uart = (WifideautherUart*)context; - - if(ev == UartIrqEventRXNE) { - furi_stream_buffer_send(uart->rx_stream, &data, 1, 0); - furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone); - } -} - -static int32_t uart_worker(void* context) { - WifideautherUart* uart = (void*)context; - - while(1) { - uint32_t events = - furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever); - furi_check((events & FuriFlagError) == 0); - if(events & WorkerEvtStop) break; - if(events & WorkerEvtRxDone) { - size_t len = furi_stream_buffer_receive(uart->rx_stream, uart->rx_buf, RX_BUF_SIZE, 0); - if(len > 0) { - if(uart->handle_rx_data_cb) uart->handle_rx_data_cb(uart->rx_buf, len, uart->app); - } - } - } - - furi_hal_uart_set_irq_cb(UART_CH, NULL, NULL); - furi_stream_buffer_free(uart->rx_stream); - - return 0; -} - -void wifi_deauther_uart_tx(uint8_t* data, size_t len) { - furi_hal_uart_tx(UART_CH, data, len); -} - -WifideautherUart* wifi_deauther_uart_init(WifideautherApp* app) { - WifideautherUart* uart = malloc(sizeof(WifideautherUart)); - - uart->app = app; - uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1); - uart->rx_thread = furi_thread_alloc(); - furi_thread_set_name(uart->rx_thread, "WifideautherUartRxThread"); - furi_thread_set_stack_size(uart->rx_thread, 1024); - furi_thread_set_context(uart->rx_thread, uart); - furi_thread_set_callback(uart->rx_thread, uart_worker); - - furi_thread_start(uart->rx_thread); - - if(UART_CH == FuriHalUartIdUSART1) { - furi_hal_console_disable(); - } else if(UART_CH == FuriHalUartIdLPUART1) { - furi_hal_uart_init(UART_CH, BAUDRATE); - } - - furi_hal_uart_set_br(UART_CH, BAUDRATE); - furi_hal_uart_set_irq_cb(UART_CH, wifi_deauther_uart_on_irq_cb, uart); - - return uart; -} - -void wifi_deauther_uart_free(WifideautherUart* uart) { - furi_assert(uart); - - furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtStop); - furi_thread_join(uart->rx_thread); - furi_thread_free(uart->rx_thread); - - if(UART_CH == FuriHalUartIdLPUART1) { - furi_hal_uart_deinit(UART_CH); - } else { - furi_hal_console_enable(); - } - - free(uart); -} \ No newline at end of file diff --git a/applications/external/wifi_deauther/wifi_deauther_uart.h b/applications/external/wifi_deauther/wifi_deauther_uart.h deleted file mode 100644 index 534c2fdf7..000000000 --- a/applications/external/wifi_deauther/wifi_deauther_uart.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "furi_hal.h" - -#define RX_BUF_SIZE (320) - -typedef struct WifideautherUart WifideautherUart; - -void wifi_deauther_uart_set_handle_rx_data_cb( - WifideautherUart* uart, - void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context)); -void wifi_deauther_uart_tx(uint8_t* data, size_t len); -WifideautherUart* wifi_deauther_uart_init(WifideautherApp* app); -void wifi_deauther_uart_free(WifideautherUart* uart); diff --git a/applications/external/wifi_scanner/FlipperZeroWiFiModuleDefines.h b/applications/external/wifi_scanner/FlipperZeroWiFiModuleDefines.h deleted file mode 100644 index f05c9bb9d..000000000 --- a/applications/external/wifi_scanner/FlipperZeroWiFiModuleDefines.h +++ /dev/null @@ -1,22 +0,0 @@ -#define WIFI_MODULE_INIT_VERSION "WFSM_0.1" - -#define MODULE_CONTEXT_INITIALIZATION WIFI_MODULE_INIT_VERSION -#define MODULE_CONTEXT_MONITOR "monitor" -#define MODULE_CONTEXT_SCAN "scan" -#define MODULE_CONTEXT_SCAN_ANIMATION "scan_anim" -#define MODULE_CONTEXT_MONITOR_ANIMATION "monitor_anim" - -#define MODULE_CONTROL_COMMAND_NEXT 'n' -#define MODULE_CONTROL_COMMAND_PREVIOUS 'p' -#define MODULE_CONTROL_COMMAND_SCAN 's' -#define MODULE_CONTROL_COMMAND_MONITOR 'm' -#define MODULE_CONTROL_COMMAND_RESTART 'r' - -#define FLIPPERZERO_SERIAL_BAUD 115200 - -#define NA 0 - -#include - -#define UART_CH \ - (xtreme_settings.uart_esp_channel == UARTDefault ? FuriHalUartIdUSART1 : FuriHalUartIdLPUART1) diff --git a/applications/external/wifi_scanner/application.fam b/applications/external/wifi_scanner/application.fam deleted file mode 100644 index cd007eb48..000000000 --- a/applications/external/wifi_scanner/application.fam +++ /dev/null @@ -1,13 +0,0 @@ -App( - appid="wifi_scanner", - name="[ESP] WiFi Scanner", - apptype=FlipperAppType.EXTERNAL, - entry_point="wifi_scanner_app", - requires=["gui"], - stack_size=2 * 1024, - fap_icon="wifi_10px.png", - fap_category="WiFi", - fap_author="@SequoiaSan & @xMasterX", - fap_version="1.0", - fap_description="WiFi scanner module interface, based on ESP8266", -) diff --git a/applications/external/wifi_scanner/wifi_10px.png b/applications/external/wifi_scanner/wifi_10px.png deleted file mode 100644 index c13534660..000000000 Binary files a/applications/external/wifi_scanner/wifi_10px.png and /dev/null differ diff --git a/applications/external/wifi_scanner/wifi_scanner.c b/applications/external/wifi_scanner/wifi_scanner.c deleted file mode 100644 index 07de32189..000000000 --- a/applications/external/wifi_scanner/wifi_scanner.c +++ /dev/null @@ -1,1075 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "FlipperZeroWiFiModuleDefines.h" - -#define WIFI_APP_DEBUG 0 - -#if WIFI_APP_DEBUG -#define APP_NAME_TAG "WiFi_Scanner" -#define WIFI_APP_LOG_I(format, ...) FURI_LOG_I(APP_NAME_TAG, format, ##__VA_ARGS__) -#define WIFI_APP_LOG_D(format, ...) FURI_LOG_D(APP_NAME_TAG, format, ##__VA_ARGS__) -#define WIFI_APP_LOG_E(format, ...) FURI_LOG_E(APP_NAME_TAG, format, ##__VA_ARGS__) -#else -#define WIFI_APP_LOG_I(format, ...) -#define WIFI_APP_LOG_D(format, ...) -#define WIFI_APP_LOG_E(format, ...) -#endif // WIFI_APP_DEBUG - -#define DISABLE_CONSOLE !WIFI_APP_DEBUG - -#define ENABLE_MODULE_POWER 1 -#define ENABLE_MODULE_DETECTION 1 - -#define ANIMATION_TIME 350 - -typedef enum EChunkArrayData { - EChunkArrayData_Context = 0, - EChunkArrayData_SSID, - EChunkArrayData_EncryptionType, - EChunkArrayData_RSSI, - EChunkArrayData_BSSID, - EChunkArrayData_Channel, - EChunkArrayData_IsHidden, - EChunkArrayData_CurrentAPIndex, - EChunkArrayData_TotalAps, - EChunkArrayData_ENUM_MAX -} EChunkArrayData; - -typedef enum EEventType // app internally defined event types -{ EventTypeKey // flipper input.h type -} EEventType; - -typedef struct SPluginEvent { - EEventType m_type; - InputEvent m_input; -} SPluginEvent; - -typedef struct EAccessPointDesc { - FuriString* m_accessPointName; - int16_t m_rssi; - FuriString* m_secType; - FuriString* m_bssid; - unsigned short m_channel; - bool m_isHidden; -} EAccessPointDesc; - -typedef enum EAppContext { - Undefined, - WaitingForModule, - Initializing, - ScanMode, - MonitorMode, - ScanAnimation, - MonitorAnimation -} EAppContext; - -typedef enum EWorkerEventFlags { - WorkerEventReserved = (1 << 0), // Reserved for StreamBuffer internal event - WorkerEventStop = (1 << 1), - WorkerEventRx = (1 << 2), -} EWorkerEventFlags; - -typedef struct SWiFiScannerApp { - FuriMutex* mutex; - Gui* m_gui; - FuriThread* m_worker_thread; - NotificationApp* m_notification; - FuriStreamBuffer* m_rx_stream; - - bool m_wifiModuleInitialized; - bool m_wifiModuleAttached; - - EAppContext m_context; - - EAccessPointDesc m_currentAccesspointDescription; - - unsigned short m_totalAccessPoints; - unsigned short m_currentIndexAccessPoint; - - uint32_t m_prevAnimationTime; - uint32_t m_animationTime; - uint8_t m_animtaionCounter; -} SWiFiScannerApp; - -/* - Fontname: -FreeType-Inconsolata LGC-Bold-R-Normal--36-360-72-72-P-176-ISO10646-1 - Copyright: Original Roman version created by Raph Levien using his own tools and FontForge. Copyright 2006 Raph Levien. Hellenisation of the Roman font, by Dimosthenis Kaponis, using FontForge. Hellenic glyphs Copyright 2010-2012 Dimosthenis Kaponis. Released under the SIL Open Font License, http://scripts.sil.org/OFL. Cyrillic glyphs added by MihailJP, using FontForge. Cyrillic glyphs Copyright 2012 MihailJP. Released under the SIL Open Font License, http://scripts.sil.org/OFL. Emboldened by MihailJP. Some glyphs modified by Greg Omelaenko, using FontForge. - Glyphs: 95/658 - BBX Build Mode: 2 -*/ -const uint8_t u8g2_font_inb27_mr[4414] = - "_\2\5\4\5\6\1\4\6\26%\0\370\33\371\35\371\5e\13\313\21! \13\266\14\366\207\377\377\377" - "\20\0!\30\266\14\366\7`\310\22\353E\42\351\177r|(\220h\240-\222\17\37\42%\266\14v\37" - "d,\62\310\42\203,\62\310\42\203,\62\310\42\203,\62\310\42\203,\62\310\42\203|\370\377\307\1#" - "M\266\14\366\7u\220\261\310 \213\14\262\310 \213\14\262\310 k\20b\36 \343\1\62\36 \3;" - "d\220E\6Yd\220\65\10Y\203\220\365\306\3c<@\306\3\344\220A\26\31d\221A\326 d\15" - "\62\330 \203\15\62\26!\343\303\63\0$A\266\14\366\7\200H\352\251\325\320;$\220P\14\21d\210" - "C\4\31\1\21AX\11\244e.\271\325\64F\202YD\224E\6Yd\20\23\10\31\244\214AD!" - "&\220P\314Cm\251G$\365\341\42\0%I\266\14\366\7\261\34RN!%\21B\226 \205\14\42" - "H!\203\4b\310H\346!\227N \253\204\22I,\221\222d\10F\302Q\15\221\220N\32\304\220@" - "\6)%\220A\12\21d\20R\304\42\204$R\312)\344\224\17/\3&F\266\14\366\7\264\274\304\326" - "b\251\214\222H!\211\24\222H!\212\14\262\310 \214\4\322\220;\16\65E\302!\202\220A\250A\221" - "\22\310 &\15r\16!\250\224bL)\5\225\7Fa\241\224\64\310\61F|x\30\0'\17\266\14" - "\366\7aH\372\357\303\377\177\1\0((\266\14v\14sD\363\216\63\317@\22\13,\221\304\22\211$" - "\261D\42\351\223ER\262\304\42K,\262\212v\261L\241\1)$\266\14\266\26\263D\233\254\305\42K" - ",\222\310\42\351_$\222\304\22I,\260\304\2\313\263\301\22\307\7\7\0*/\266\14\366\207\207\210\244" - "\261PH\11\205\14\62F\61a\10C\36\30\306\261\2\317C\215\10\262\310(\251\20\202\212!h\234\261" - "\2\12\37\376,\0+\33\266\14\366\207\207\210\244\267\36\30\344\201A\36\30\344\201\261\210\244\337\207\277\14" - "\0,\30\266\14\366\207\377\377\300\220%\32hI\42\307\34rH\42\7\15\15\0-\26\266\14\366\207\177" - "\352\201`\36\10\346\201`\36\10\37\376\277\4\0.\21\266\14\366\207\377\377\0\211\6\332\42\371p\22\0" - "/.\266\14\366\33\223\304\22I,\221H\22\211$\221H\22\211$\221H\22K$\261D\22K$\261" - "D\42I$\222D\42\211\34\65|x\17\0\60I\266\14\366\7\266<\324\324b\251\220\202\210!\247\230" - "b\310)\206\30SJA\204\24\22\10!e\10B\10\31\203\20\62(B\306 \224\30\205\20\22\206!" - "\4\31R\214)\245\34b\312!\247\224r\12)\211-\325\20,\37^\7\61\26\266\14\366\7\226@\363" - "NKL\265!\210\244\377\377\367\341y\0\62'\266\14\366\7\325\70\265Xr\247\24s\306)($\42" - "i\261D\22\13\254\277H\311g\36\10\346\201`\36\10\37\36\6\63-\266\14\366\7\324\70\265Xri" - "\230\222\2\42\222\26\313\63,\265\363RS\261\310\42i) \202\304)\207\224r\36jj\265\363\341y" - "\0\64\65\266\14\366\7\232H\22\13\264\336q\310\215@\32\11\204\21A\330\30d\221A\24!$\221B" - "\22)\4\21C\316\3\203<\60\310\3\203<\60\36\221\364}x\32\0\65*\266\14\366\7\361\235\337!" - "\222N\20\306TK\16\25b\316\70%\5T$\275#P)\4\21cJ\61\17\265\245\234\371\360:\0" - "\66>\266\14\366\7\327\70\265Xj\250\224\221\310\11\211H\22K$\243(\22\22z\347\201`L)\246" - "\234R\10*\205$RH\42\205$R\12\42\206\234b\212!\250\220\202\232b+=\363\341q\0\67-" - "\266\14\366\7\360\201`\36\10\346\201`\236$\261D\22K$\222\304\22I,\221H\22K$\222\304\22" - "I\254\42\211U$\261|\370\4\0\70;\266\14\366\7\325\70\265Xj\250\224r\212!\207\356\24C\20" - ")$\225Q\324b\251)U\204I\244\224C\31\202J!\211\24\222H!\211\224r\212)\245\234\207\232" - "Z\355|x\35\0\71\71\266\14\366\7\265\274\304\326b\251\220\202\210!\247\230b\10\42\206 b\10\42" - "\206 b\312\241L\71\205\30\344\251\23\10\33\203H\42\207$*\34\222D)\251%\266\322+\37>:" - "\27\266\14\366\207\77A\242\201\266H>|\210D\3m\221|\70\11\0;\34\266\14\366\207\77A\242\201" - "\266H>|\210D\3\255X$\221C\222HM\361\1\1< \266\14\366\207\271\60G,\357\264\304\360" - "\265\363J<\20\301\23/\210\301\3\215$T|\370\25\0= \266\14\366\207\317=\60\310\3\203<\60" - "\310\3\343\303\352\3\203<\60\310\3\203<\60>\374g\1>\36\266\14\366\207\266\240D\32\210\37<\261" - "\274\323\20\303\332\325P;\257\304\61\305\207\277\6\0\77%\266\14\266\67N\251\206\236\61\245\34r\312\21" - "\211H*\226Hb\201u\221H\352C\226D\3m\221|x\36\0@G\266\14\366\7\266\274\264\32r" - "\247\230b\10\42\205(B\306Ad\24\65\6ac\20\66\306(\204\214\61H!c\14R\310\30\203\24" - "\62\306\250\306\30m\220\301\310 \213\20R\2!d\222YNH.\265\245\234\371\360\70\0A<\266\14" - "\366\7\67PA\307\34\262\304\2\15<\357\70\22H#\201\264!\10#\203,\62\310\32e(RHj" - "\311\235\357\220S\12I\244\220T\6Yd\220E\6Y%\220F><\13\0BD\266\14\366\7\217)" - "\207\36\10\346\201`\310\61\205\240RH\42\205$RH\42\205\240R\310)\346\201`\336\371@\60\4\225" - "BR!D\21B\24!D\21B\24!$\25B\220!\17\210\362@\60\357\264\17\217\3C/\266\14" - "\366\7\327\264\245\32z\306\24S\312)\244$B\210\22\206\304\22\211\244'K,\222\310\22\213\12\247\240" - "a\214)\346\241\246V\63\37\36\7DC\266\14\366\7o\255\226\336y\207\30c\10*\205\240RH\42" - "\205\244B\210\42\204(B\210\42\204(B\210\42\204(B\210\42\204(B\210\42\204\244BH\42\205\240" - "R\10\42\206\30c\336q\250\245\365\341y\0E'\266\14\366\7\357\1Q\36\20\345\1Q\36\20\205H" - "\372\344;\277C$\375\344\3\242< \312\3\242< ><\14\0F\35\266\14\366\7\360\201`\36\10" - "\346\201`\36\10\206H\372\244C>D$\375\357\303W\0G:\266\14\366\7\326\70\245\32z\306\24S" - "\312)\244$a\210$\261D\42i&\15b\322 &\15b\322(\212\20\242\10!\212\220\222H)\210" - "\24c\212y \34\227\30;\37\36\7HM\266\14\366\7\217$RH\42\205$RH\42\205$RH" - "\42\205$RH\42\205$RH\42\205$R\36\20\345\1Q\36\20\345\1QH\42\205$RH\42\205" - "$RH\42\205$RH\42\205$RH\42\205$RH\42\205$\362\341a\0I\24\266\14\366\7\320" - "!_#\222\376\377k\357\374>\274\14\0J\33\266\14\366\7\264\245\236#\222\376\377\222\60%\215BR" - "S\213\245W>|\1\0KI\266\14\366\7\257\244\62H*\204\240R\310)\206\230rH)\210\24\222" - "\10!\212\14\262\210(\213\204\302RKM\261\22\312\42\203,\62\212\42\244$RH\42\245 b\312!" - "\247\30r\212!\250\24\222\12!\251\20\242\312\207g\1L\32\266\14\366\7\260D\42\351\377\377\311\7D" - "y@\224\7Dy@|x\27\0MU\266\14\366\7\217,\62\310\42\243\244\62J*\303\34\63\314\61" - "\343\224\63N\71\3\33$\214\61\2\31$\320\6\21#\14A\6\21#\14A\6\31eP\243\14\32!" - "\203\220A\310 \213\14\262\310 \213\14\262\310 \213\14\262\310 \213\14\262\310 \213\14\262\310\207g\1" - "NS\266\14\366\7\217(BJ\42\244$B\14\42\304 B\316!\344\34B\220!\204\4R\10!\201" - "\24B\210 \204\22\204P\203\42dP\204\22\204P\202\20RH \204\230\21\10!\6\21r\16!\347" - "\20\202\14!\310\20\222\12!\251\20\242\10!\212|x\27\0OC\266\14\366\7\325\70\265Xr\247\224" - "r\310)\245 RH*\204(\62\212\42\203,\62\310\42\203,\62\310\42\203,\62\310\42\203,\62\212" - "\42\204(BH*\244 b\310)\246\224\202\134bK\71\363\341u\0P\60\266\14\366\7\257\245w\36" - "\10\346\1Q\10*\205\244B\210\42\204(B\210\42\204(BH*\204\240R\36\20\345\201`\34b\212" - "H\372\357\303g\0QJ\266\14\366\7\325\70\265Xr\247\224r\310)\245 RH*\204\244\62\212\42" - "\203,\62\310\42\203,\62\310\42\203,\62\310\42\203,\62\212\42\204\244BH*\244 b\310)\246\224" - "\202\134b+\271\23\211$R\265\344\20\64\37@\0RC\266\14\366\7\217)\207\336y \30rL!" - "\250\24\222H!\211\24\222H!\211\24\202J!\247\230\7\202y\307!\246H!\211\24\222H)\210\30" - "\202\210)\207v\212!\210\30\202J!\211\24\222\312\207w\1S\61\266\14\366\7\365\264\245\32z\207\230" - "\12\211C\222\70DV\321D\364\262\207\242\221ER&,b\302\42e\244B\214)\345\1a^b\354" - "|x\35\0T\27\266\14\366\7\356\1\62\36 \343\1\62\36 \212H\372\377\377>|UH\266\14\366" - "\7\257$B\210\42\204(B\210\42\204(B\210\42\204(B\210\42\204(B\210\42\204(B\210\42\204" - "(B\210\42\204(B\210\42\204(B\210\42\204(B\210\42\244\240B\12*\245\230b\36rJ\71\363" - "\341u\0V>\266\14\366\7\216\60\42\10#\203(B\210\42\204(R\10\42\206 b\10\42\207\30\202" - "\210!\210\30\222H\31\212\20\242\10!\213\214\301\210 \214\10\322H\30\16{\6Z\221H\42\7\25\37" - ">W\134\266\14\366\7n\22\303\15A\212(D\220\62\10\21\244\14B\4!\204\214A\10!\23)c" - "\20\62\312\30\204\10\63\6!\302\10B\210\70\201\20\42N\30f\204!F\30\346\210\21\206\71\342\230#" - "\216\61\304\30C\12*\244\240B\12\42\206 b\10\42\206\240q\206\22H(\201\304\207\247\1XB\266" - "\14\366\7\217(BH\42\206 b\212!\210\224\202\12!\212\214\242\212 \214\204\302\222;\320\300\22K" - "\64\357<\324\24#\202,\62\212\42\204$R\12\42\206\34rJ)\210\24\222\312(\252|x\26\0Y" - "\60\266\14\366\7\216\254\42\212\42\204\244B\12\42\206 b\212!\210\30\202\12!\212\20\242\212 \214\10" - "\322H\30\16\275\363L,\221H\372\357\303\363\0Z\63\266\14\366\7\360\1Q\36\20\345\1Q\36\10\222" - "D\22K\244b\211$\226H\305\22I,\260D\22\13,\261\300\22\37\20\344\201A\36\30\344\201\361\341" - "]\0[\23\266\14\366n\251\227\210\244\377\377\77\331R\357C\10\0\134+\266\14\66\21\262H\42\213$" - "\262H\42\213$\262Hj\22I&\221d\22Id\221D\26Id\221D\26IM\42\311\14\37\36\1" - "]\20\266\14vn\251'\351\377\377_\352\373\220\2^!\266\14\366\7WL\42I\64\357<\324\210 " - "\213\14\262\10!\211\24\222\210!I\34\361\341\377\17\2_\26\266\14\366\207\377\377\247\36 \343\1\62\36" - " \343\1\362!\3\0`\33\266\14\266\11UPA\307$\222\310\22\213,\261\310\42\251\71Q\361\341\377" - "g\0a\60\266\14\366\207\217\236\266\222C.\15S$\325Rj\347\231\7\202)\207\224\202H!\211\24" - "\202J)\345\230\7\202y \34\25H\62\203|x\30\0b;\266\14\66.\221H\372\215\242HH\350" - "\235\7\202\61\305\224rJ!\251\20\222\12!\212\20\242\10!\212\20\242\10!\212\20\222\12)\210\24c" - "Jy \230w\206Hh\220\362\341u\0c(\266\14\366\207\257\32\247\224;\17\4S\225\202\206!I" - "\230\22\211\244\311\42\211,H\240b\310y \34\247\224\63\37\36\7d;\266\14\366\7\207H\372\251\62" - "\10J\201\234g\36\10\245\30S\10*\244\240BH*\204(B\210\42\204(B\210\42\244\240B\12*" - "\245\234R,\363@\70\17\245@T\31\344\303\273\0e,\266\14\366\207\217\236\266TC\317T\206 b" - "H\42\344\201A\36\30\344\201A\36\30\204H\42\253\24\216\61\344<\344\322r\346\303\343\0f\35\266\14" - "\366\7\302\70\265Xj\250\230\201\312\11\211H\312\71\344cD\322\377\367\341\23\0g=\266\14\366\207o" - "\26R\314\3\241< \10!j\224R\16}\247\224r\314(\251\251\265\324\42a\64\42[z \234\7" - "\202y@\20\222\312 \213\14\262\310(\251\214\7Fy \34\267\220\7h<\266\14v.\221H\372\215" - "\242\210@\210\4u\336\71\244\30c\210)\207\30\202\210!\210\30\202\210!\210\30\202\210!\210\30\202\210" - "!\210\30\202\210!\210\30\202\210!\210\30\202\310\207\207\1i\30\266\14\366\7`\310\22+\71>$S" - "\313I\372\277\326R\357\303\323\0j\37\266\14\366\7d\310\22+\71>\364\230\342I\372\377\227\204)\210" - "\220\202\134bK\71\363A\0k\71\266\14v.\221H\372\241R\310)\206\230rH)\210\220\222\310(" - "\212\210\262H(Lck\25Q\24!%\221R\20)\5\21S\16\71\305\20T\12A\206\220d>\274" - "\12\0l\21\266\14vVL'\351\377\377\330;\277\17/\3m@\266\14\366\207\257\221PF!+\234" - "\361\0\31\17\24QF\21\325 \204\10B(A\10%\10\241\4!\224 \204\22\204P\202\20J\20B" - "\11B(A\10%\10\241\4!\224 \204\22\204P\37\236\5n:\266\14\366\207\357\221Q\24\21\10\275" - "\363\316!\305\224CL\71\304\20D\14A\304\20D\14A\304\20D\14A\304\20D\14A\304\20D\14" - "A\304\20D\14A\304\20D><\14\0o\62\266\14\366\207\257\32\247TC\357\224bJ\71\245\220T" - "FIe\220E\6Yd\220E\6Yd\24E\10I\244\224SL)\306<\324\324r\346\303\343\0p" - "=\266\14\366\207\317\221Q\24\11\11=\20\314\3\301\230bJ\71\245\220T\10I\205\20E\10Q\204\20" - "E\10Q\204\20E\10I\205\24D\212\61\245<\20\314;$$DFQD\322\367\301\1q\71\266\14" - "\366\207\217\32AP\12\344<\363@(\305\230BP!\5\25B\24!D\21B\24!D\21B\24!" - "%\221BP)\345\224b\231\7\302y(\5\242\312 \222~\30\0r\37\266\14\366\207\17\22R\22\21" - "\351<\20\314\3\301\34#\216\71\342\224X\42\221\364\277\17\37\1s,\266\14\366\207\217\232\306\222C\317" - "\24C\16A\343\24\24R\211\351)\227\340\221\305\10E\214P\244\224S\312\3\341\270\304\332\371\360:\0" - "t\35\266\14\366\207\234\220\364\332;\277E$\375\223\305\4U\212XL\261\245\232\371\360\66\0u;\266" - "\14\366\207\317\221D\12I\244\220D\12I\244\220D\12I\244\220D\12I\244\220D\12I\244\220D\12" - "I\244\220DJ\71\245\224SL)\306<\20\316C)\20U\6\371\360\60\0v\63\266\14\366\207\257\25" - "E\10Q\204\20E\12I\303\20DL\71\3\21C\20\61$\221\62\24!D\21\62\30\21\204\21A\32" - "\11\303!w\240\201E\22\71>|wH\266\14\366\207\217Q\202\60\42H\31\204\214Q\6!c\224A" - "\310 \243\14j\224A\215\62F\31\303\210Q\206\30a\210QH\230\304($Lb\24\22\204@\306\14" - "s\314\60\307\14sJ)\247\224\202H!\211\24\362\341i\0x\63\266\14\366\207\317\221DJ\71\305\24" - "C\20)D\221QT\21\204%\207\334\201%\232w\36j$\224U\4Q\205\220DJ\71\305\224R\20" - ")$\225\17\357\2y<\266\14\366\207\317\225T\10I\244\220DJA\304\220CC\304\20D\12I\205" - "\20E\310Xd\20F\4aD\14\67\2q\347\35h`\221T$,\24\262\4!L-\325\320+\37" - "\24\0z&\266\14\366\207\357=\20\314\3\301<\20\314\213$\26X\213$\26X\27\13|@\220\7\6" - "y`\220\7\306\207w\1{$\266\14\366\7\342\264\304\324Z\253\300\22\211\244_$\357<\3\15<\262" - "H\372'K,r\255\305\224C\32\0|\16\266\14\366\7\200H\372\377\377\377\357\3}#\266\14\266\66" - "\20\271\324\224,\222\376d\221d\36h\336q\310\221H$\375\213e)\246Xj\347\3\1\0~\31\266" - "\14\366\207/\232\23\214\42d<\60\306\3\303\210\202`\371\360\377\303\0\0\0\0\4\377\377\0"; - -/* - Fontname: open_iconic_arrow_2x - Copyright: https://github.com/iconic/open-iconic, SIL OPEN FONT LICENSE - Glyphs: 28/28 - BBX Build Mode: 0 -*/ -const uint8_t u8g2_font_open_iconic_arrow_2x_t[644] = - "\34\0\4\4\5\5\4\4\6\20\20\0\0\16\0\16\0\0\17\0\0\2g@\17\352i\302$P\376\221" - "\12\64\246\310\11\2A\22O%\303\24Z\360X\242\17^\20\36-<(\0B\22O!\303\32\134\364" - "`\22\17\236\222\35,:\20\0C\17\352)\302$\216\224\31\24\212\4\312\77\2D\37\20\42\302eP" - "\25!\62\205\212\24*a\210#\304E\17\222 F\244P\231\42\245\24\232\2E \20\42\302ePU" - "\11\63E\216\220\71Ah-a\302e\15\241 s\244\310\231\22\246\24\232\2F\37\20\42\302eP\225" - "\211\62G\212\234!\201\310laj\27\221\70C\344H\31\23\245\24\232\2G\37\20\42\302ePU\221" - "\62\205\212\20#A\360haD\34\231(T\244P\31B\244\24\232\2H\21\12.\302C\214\376\215\212" - "$\207\212\15\14\4\0I\23P\341\302\25\134\364`\27\17\36\204xBz\270P\0J\23P\341\302*" - "|\64\221\27\17\36\204px \0U\23\20\42" - "\302\360\201x\230\212&k\22\235J\302\364\14\0V\34\320\241\302\34\36\200\30\27/\204\12\21\32\36\302" - "\240B\204\212x\341F<\200\300\0W\32\220\241\302&\230\354hq\202\304\221\21\306L\14\71A\342D" - "\217%,\14\0X\37\20\42\302\302\210\221@A\2\205K$\314\210\70\42\344\204\30\23$\134BA\2" - "\5q\2\0Y$\17\42\302\34\134\304\270TF\306\214\20\64bH\260\262\203\211\226\34\42$\320\230\21" - "\42H\245+,:\10\0Z\30\220!\303\32\36\200\360\321\4S\61\351\206\324 q\202\4\206\12\17\0" - "[\34\320\241\302`\324X\30q&D-J!&\211\230`a\204\313P\220@A\34\1\0\0\0\4" - "\377\377\0"; - -/* - Fontname: -Adobe-Courier-Bold-R-Normal--11-80-100-100-M-60-ISO10646-1 - Copyright: Copyright (c) 1984, 1987 Adobe Systems Incorporated. All Rights Reserved. Copyright (c) 1988, 1991 Digital Equipment Corporation. All Rights Reserved. - Glyphs: 18/873 - BBX Build Mode: 0 -*/ -const uint8_t u8g2_font_courB08_tn[199] = - "\22\0\3\3\3\4\2\3\4\6\11\0\376\6\376\7\377\0\0\0\0\0\252 \5\0\353\0*\11$\357" - "\212P$\241\0+\12-\353\12\206J\301\20\0,\7\233\345\221$\1-\5\15\357(.\5\212\351\20" - "/\14\304\347K\212\205b\241X\14\0\60\12=\351\231Hx\221L\0\61\10>\351\22\21u\62\62\11" - "=\351\231\250\211\264\34\63\14=\351\231\250I\206\24\311\4\0\64\14>\351\223\215\42ZlB\11\0\65" - "\12=\351\270Q\324F\26\0\66\14=\351\231Hh\24\11E\62\1\67\13=\351\270\310D\62\221L\4" - "\70\15=\351\231H(\222\211\204\42\231\0\71\14=\351\231H(\22\32E\62\1:\6\242\351\20\12\0" - "\0\0\4\377\377\0"; - -/* - Fontname: -Misc-Fixed-Bold-R-Normal--13-120-75-75-C-70-ISO10646-1 - Copyright: Public domain font. Share and enjoy. - Glyphs: 95/1003 - BBX Build Mode: 0 -*/ -const uint8_t u8g2_font_7x13B_tr[1083] = - "_\0\3\3\3\4\3\5\4\6\15\0\376\11\376\11\0\1}\2\330\4\36 \5\0\356\7!\7J\303" - "\307\241D\42\10\235\332\207\204E\0#\20\315\302OR$r\230\244\34&I\221\10\0$\17N\302\227" - "\214\22\321F\223\250Dh\42\0%\17N\302\307H\22\251\4e\212\221JD\64&\17N\302\317H\242" - "\247\221$\62\251\210&\1'\7\42\327\307!\0(\14\314\302\227D$\21\251\211d\2)\15\314\302\207" - "L$\23\251\210$\42\0*\15\66\306O(&:\224d\241\10\0+\13\66\306\227Pt(\11E\0" - ",\10\244\276\317\212\22\0-\6\16\316\207\1.\10\234\276\217\204\42\1/\14N\302\247\232P\246(\23" - "\12\1\60\16N\302\227,\24\21\361$\11\305D\0\61\13N\302\227l\24\21\352\311\0\62\16N\302\17" - "ED\22\212F\62\241\320\0\63\15N\302\207Q\246F\25\222$\24\0\64\15N\302\247lD\221\220H" - "\207\240\2\65\16N\302\307!(\254\210\204B\222\204\2\66\16N\302\17ED\24VDL\22\12\0\67" - "\15N\302\207QM(\23\312\204\62\0\70\16N\302\17E\304$\241\210\230$\24\0\71\16N\302\17E" - "\304$)\12I\22\12\0:\14\304\276\217\204\42\207I(\22\0;\13\304\276\217\204\42\236L\224\0<" - "\10N\302\247LW\35=\7&\312\207\35j>\11N\302\207T\67\35\1\77\16N\302\17ED\22\212" - "fr\230P\4@\17N\302\17%\266R\211L\252\61\11\5\0A\13N\302\17E\304t\30q\22B" - "\14N\302GE\304t\21\61]\0C\13N\302\17ED\324\223\204\2D\12N\302GE\304O\27\0" - "E\13N\302\307!\250X\21*\32F\13N\302\307!\250X\21j\4G\14N\302\17EDT)\61" - "I\12H\13N\302\207\210\323a\304I\0I\11N\302\207I\250O\6J\12N\302\247>\222$\24\0" - "K\17N\302\207lD\221\220f$\211\22-\0L\10N\302\207P\77\32M\13N\302Gpt\70\210" - "x\22N\15N\302\207\210T\251\34&M$\1O\13N\302\17E\304O\22\12\0P\13N\302GE" - "\304t\21j\4Q\14V\276\17E\304S\205\62\241\12R\15N\302GE\304t!I\224h\1S\16" - "N\302\17ED\224R\205$\11\5\0T\11N\302\207I\250\237\0U\12N\302\207\210\77I(\0V" - "\15N\302\207\210I\22\312D\23*\1W\13N\302\207\210\247\303A\64\14X\17N\302Gp$\11\205" - "h\62R\212h\30Y\14N\302\207\210$!\321\204:\1Z\12N\302\207QMG\241\1[\10\314\302" - "\207I\237\10\134\14N\302\207P*\224*J\205\2]\10\314\302\7I\237\14^\11&\326\227\214\42\32" - "\6_\7\26\276\307\241\0`\7\234\336\207L\1a\12\66\302\17Ur\42I\12b\13N\302\207P\261" - "\42\342t\1c\13\66\302\17EDT\222P\0d\12N\302\247\226\23'I\1e\14\66\302\17Et" - "\30\212$\24\0f\14N\302\327H\242(\243\11\265\1g\16F\272\317\22IB\221RD\22\12\0h" - "\13N\302\207P\261\42\342I\0i\12N\302\227P\16\32\352dj\14^\272\247:L\250#IB\1" - "k\15N\302\207P\23EB\42I\224\4l\10N\302\317P\77\31m\12\66\302\207Dr\70\61\11n" - "\11\66\302GE\304\223\0o\12\66\302\17E\304IB\1p\13F\272GE\304t\21*\2q\12F" - "\272\317\211IR\324\0r\11\66\302GED\324\10s\15\66\302\17E$\21KD\22\12\0t\14F" - "\302\217PV\22j\21M\0u\11\66\302\207\210'I\1v\13\66\302\207\210IB\242\211\0w\13\66" - "\302\207\210\351p\11E\0x\14\66\302\207\210$!QD$\1y\14F\272\207\210\223\244H\222P\0" - "z\12\66\302\207Q&\222\11\15{\14\314\302OI&\221ID\262\1|\7J\303\307\3\1}\15\314" - "\302\307L$\221Id\242\12\0~\11\36\332\217\350\20\222\0\0\0\0\4\377\377\0"; - -/////// INIT STATE /////// -static void wifi_scanner_app_init(SWiFiScannerApp* const app) { - app->m_context = Undefined; - - app->m_totalAccessPoints = 0; - app->m_currentIndexAccessPoint = 0; - - app->m_currentAccesspointDescription.m_accessPointName = furi_string_alloc(); - furi_string_set(app->m_currentAccesspointDescription.m_accessPointName, "N/A\n"); - app->m_currentAccesspointDescription.m_channel = 0; - app->m_currentAccesspointDescription.m_bssid = furi_string_alloc(); - furi_string_set(app->m_currentAccesspointDescription.m_bssid, "N/A\n"); - app->m_currentAccesspointDescription.m_secType = furi_string_alloc(); - furi_string_set(app->m_currentAccesspointDescription.m_secType, "N/A\n"); - app->m_currentAccesspointDescription.m_rssi = 0; - app->m_currentAccesspointDescription.m_isHidden = false; - - app->m_prevAnimationTime = 0; - app->m_animationTime = ANIMATION_TIME; - app->m_animtaionCounter = 0; - - app->m_wifiModuleInitialized = false; - -#if ENABLE_MODULE_DETECTION - app->m_wifiModuleAttached = false; -#else - app->m_wifiModuleAttached = true; -#endif -} - -int16_t dBmtoPercentage(int16_t dBm) { - const int16_t RSSI_MAX = -50; // define maximum strength of signal in dBm - const int16_t RSSI_MIN = -100; // define minimum strength of signal in dBm - - int16_t quality; - if(dBm <= RSSI_MIN) { - quality = 0; - } else if(dBm >= RSSI_MAX) { - quality = 100; - } else { - quality = 2 * (dBm + 100); - } - - return quality; -} - -void DrawSignalStrengthBar(Canvas* canvas, int rssi, int x, int y, int width, int height) { - int16_t percents = dBmtoPercentage(rssi); - - //u8g2_DrawHLine(&canvas->fb, x, y, width); - //u8g2_DrawHLine(&canvas->fb, x, y + height, width); - - if(rssi != NA && height > 0) { - uint8_t barHeight = floor((height / 100.f) * percents); - canvas_draw_box(canvas, x, y + height - barHeight, width, barHeight); - } -} - -static void wifi_module_render_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - SWiFiScannerApp* app = ctx; - furi_mutex_acquire(app->mutex, FuriWaitForever); - - canvas_clear(canvas); - - { - switch(app->m_context) { - case Undefined: { - canvas_set_font(canvas, FontPrimary); - - const char* strError = "Something wrong"; - canvas_draw_str( - canvas, - (128 / 2) - (canvas_string_width(canvas, strError) / 2), - (64 / 2) /* - (canvas_current_font_height(canvas) / 2)*/, - strError); - } break; - case WaitingForModule: -#if ENABLE_MODULE_DETECTION - furi_assert(!app->m_wifiModuleAttached); - if(!app->m_wifiModuleAttached) { - canvas_set_font(canvas, FontSecondary); - - const char* strConnectModule = "Attach WiFi scanner module"; - canvas_draw_str( - canvas, - (128 / 2) - (canvas_string_width(canvas, strConnectModule) / 2), - (64 / 2) /* - (canvas_current_font_height(canvas) / 2)*/, - strConnectModule); - } -#endif - break; - case Initializing: { - furi_assert(!app->m_wifiModuleInitialized); - if(!app->m_wifiModuleInitialized) { - canvas_set_font(canvas, FontPrimary); - - const char* strInitializing = "Initializing..."; - canvas_draw_str( - canvas, - (128 / 2) - (canvas_string_width(canvas, strInitializing) / 2), - (64 / 2) - (canvas_current_font_height(canvas) / 2), - strInitializing); - } - } break; - case ScanMode: { - uint8_t offsetY = 0; - uint8_t offsetX = 0; - canvas_draw_frame(canvas, 0, 0, 128, 64); - - //canvas_set_font(canvas, FontPrimary); - canvas_set_custom_u8g2_font(canvas, u8g2_font_7x13B_tr); - uint8_t fontHeight = canvas_current_font_height(canvas); - - offsetX += 5; - offsetY += fontHeight; - canvas_draw_str( - canvas, - offsetX, - offsetY, - app->m_currentAccesspointDescription.m_isHidden ? - "(Hidden SSID)" : - furi_string_get_cstr(app->m_currentAccesspointDescription.m_accessPointName)); - - offsetY += fontHeight; - - canvas_draw_str( - canvas, - offsetX, - offsetY, - furi_string_get_cstr(app->m_currentAccesspointDescription.m_bssid)); - - canvas_set_font(canvas, FontSecondary); - //canvas_set_custom_u8g2_font(canvas, u8g2_font_tinytim_tf); - fontHeight = canvas_current_font_height(canvas); - - offsetY += fontHeight + 1; - - char string[15]; - snprintf( - string, sizeof(string), "RSSI: %d", app->m_currentAccesspointDescription.m_rssi); - canvas_draw_str(canvas, offsetX, offsetY, string); - - offsetY += fontHeight + 1; - - snprintf( - string, sizeof(string), "CHNL: %d", app->m_currentAccesspointDescription.m_channel); - canvas_draw_str(canvas, offsetX, offsetY, string); - - offsetY += fontHeight + 1; - - snprintf( - string, - sizeof(string), - "ENCR: %s", - furi_string_get_cstr(app->m_currentAccesspointDescription.m_secType)); - canvas_draw_str(canvas, offsetX, offsetY, string); - - offsetY += fontHeight; - offsetY -= fontHeight; - - canvas_set_custom_u8g2_font(canvas, u8g2_font_courB08_tn); - snprintf( - string, - sizeof(string), - "%d/%d", - app->m_currentIndexAccessPoint, - app->m_totalAccessPoints); - offsetX = 128 - canvas_string_width(canvas, string) - 5; - canvas_draw_str(canvas, offsetX, offsetY, string); - - canvas_draw_frame( - canvas, offsetX - 6, offsetY - canvas_current_font_height(canvas) - 3, 128, 64); - - canvas_set_custom_u8g2_font(canvas, u8g2_font_open_iconic_arrow_2x_t); - if(app->m_currentIndexAccessPoint != app->m_totalAccessPoints) { - //canvas_draw_triangle(canvas, offsetX - 5 - 20, offsetY + 5, 4, 4, CanvasDirectionBottomToTop); - canvas_draw_str(canvas, offsetX - 0 - 35, offsetY + 5, "\x4C"); - } - - if(app->m_currentIndexAccessPoint != 1) { - //canvas_draw_triangle(canvas, offsetX - 6 - 35, offsetY + 5, 4, 4, CanvasDirectionTopToBottom); - canvas_draw_str(canvas, offsetX - 4 - 20, offsetY + 5, "\x4F"); - } - } break; - case MonitorMode: { - uint8_t offsetY = 0; - uint8_t offsetX = 0; - - canvas_draw_frame(canvas, 0, 0, 128, 64); - - //canvas_set_font(canvas, FontBigNumbers); - //canvas_set_custom_u8g2_font(canvas, u8g2_font_inb27_mr); - canvas_set_custom_u8g2_font(canvas, u8g2_font_inb27_mr); - uint8_t fontHeight = canvas_current_font_height(canvas); - uint8_t fontWidth = canvas_current_font_width(canvas); - - if(app->m_currentAccesspointDescription.m_rssi == NA) { - offsetX += floor(128 / 2) - fontWidth - 10; - offsetY += fontHeight - 5; - - canvas_draw_str(canvas, offsetX, offsetY, "N/A"); - } else { - offsetX += floor(128 / 2) - 2 * fontWidth; - offsetY += fontHeight - 5; - - char rssi[8]; - snprintf(rssi, sizeof(rssi), "%d", app->m_currentAccesspointDescription.m_rssi); - canvas_draw_str(canvas, offsetX, offsetY, rssi); - } - - //canvas_set_font(canvas, FontPrimary); - canvas_set_custom_u8g2_font(canvas, u8g2_font_7x13B_tr); - fontHeight = canvas_current_font_height(canvas); - fontWidth = canvas_current_font_width(canvas); - - offsetX = 5; - offsetY = 64 - 7 - fontHeight; - canvas_draw_str( - canvas, - offsetX, - offsetY, - furi_string_get_cstr(app->m_currentAccesspointDescription.m_accessPointName)); - - offsetY += fontHeight + 2; - - canvas_draw_str( - canvas, - offsetX, - offsetY, - furi_string_get_cstr(app->m_currentAccesspointDescription.m_bssid)); - - DrawSignalStrengthBar( - canvas, app->m_currentAccesspointDescription.m_rssi, 5, 5, 12, 25); - DrawSignalStrengthBar( - canvas, app->m_currentAccesspointDescription.m_rssi, 128 - 5 - 12, 5, 12, 25); - } break; - case ScanAnimation: { - uint32_t currentTime = furi_get_tick(); - if(currentTime - app->m_prevAnimationTime > app->m_animationTime) { - app->m_prevAnimationTime = currentTime; - app->m_animtaionCounter += 1; - app->m_animtaionCounter = app->m_animtaionCounter % 3; - } - - uint8_t offsetX = 10; - uint8_t mutliplier = 2; - - for(uint8_t i = 0; i < 3; ++i) { - canvas_draw_disc( - canvas, - offsetX + 30 + 25 * i, - 64 / 2 - 7, - 5 * (app->m_animtaionCounter == i ? mutliplier : 1)); - } - - canvas_set_custom_u8g2_font(canvas, u8g2_font_7x13B_tr); - //canvas_set_font(canvas, FontPrimary); - const char* message = "Scanning"; - canvas_draw_str( - canvas, 128 / 2 - canvas_string_width(canvas, message) / 2, 55, message); - } break; - case MonitorAnimation: { - uint32_t currentTime = furi_get_tick(); - if(currentTime - app->m_prevAnimationTime > app->m_animationTime) { - app->m_prevAnimationTime = currentTime; - app->m_animtaionCounter += 1; - app->m_animtaionCounter = app->m_animtaionCounter % 2; - } - - uint8_t offsetX = 10; - uint8_t mutliplier = 2; - - canvas_draw_disc( - canvas, - offsetX + 30, - 64 / 2 - 7, - 5 * (app->m_animtaionCounter == 0 ? mutliplier : 1)); - canvas_draw_disc( - canvas, - offsetX + 55, - 64 / 2 - 7, - 5 * (app->m_animtaionCounter == 1 ? mutliplier : 1)); - canvas_draw_disc( - canvas, - offsetX + 80, - 64 / 2 - 7, - 5 * (app->m_animtaionCounter == 0 ? mutliplier : 1)); - - canvas_set_custom_u8g2_font(canvas, u8g2_font_7x13B_tr); - //canvas_set_font(canvas, FontPrimary); - const char* message = "Monitor Mode"; - canvas_draw_str( - canvas, 128 / 2 - canvas_string_width(canvas, message) / 2, 55, message); - } break; - default: - break; - } - } - furi_mutex_release(app->mutex); -} - -static void wifi_module_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - SPluginEvent event = {.m_type = EventTypeKey, .m_input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) { - furi_assert(context); - - SWiFiScannerApp* app = context; - - WIFI_APP_LOG_I("uart_echo_on_irq_cb"); - - if(ev == UartIrqEventRXNE) { - WIFI_APP_LOG_I("ev == UartIrqEventRXNE"); - furi_stream_buffer_send(app->m_rx_stream, &data, 1, 0); - furi_thread_flags_set(furi_thread_get_id(app->m_worker_thread), WorkerEventRx); - } -} - -static int32_t uart_worker(void* context) { - furi_assert(context); - - SWiFiScannerApp* app = context; - furi_mutex_acquire(app->mutex, FuriWaitForever); - if(app == NULL) { - return 1; - } - - FuriStreamBuffer* rx_stream = app->m_rx_stream; - - furi_mutex_release(app->mutex); - - while(true) { - uint32_t events = furi_thread_flags_wait( - WorkerEventStop | WorkerEventRx, FuriFlagWaitAny, FuriWaitForever); - furi_check((events & FuriFlagError) == 0); - - if(events & WorkerEventStop) break; - if(events & WorkerEventRx) { - size_t length = 0; - FuriString* receivedString; - receivedString = furi_string_alloc(); - do { - uint8_t data[64]; - length = furi_stream_buffer_receive(rx_stream, data, 64, 25); - if(length > 0) { - WIFI_APP_LOG_I("Received Data - length: %i", length); - - for(uint16_t i = 0; i < length; i++) { - furi_string_push_back(receivedString, data[i]); - } - - //notification_message(app->notification, &sequence_set_only_red_255); - } - } while(length > 0); - if(furi_string_size(receivedString) > 0) { - FuriString* chunk; - chunk = furi_string_alloc(); - size_t begin = 0; - size_t end = 0; - size_t stringSize = furi_string_size(receivedString); - - WIFI_APP_LOG_I("Received string: %s", furi_string_get_cstr(receivedString)); - - FuriString* chunksArray[EChunkArrayData_ENUM_MAX]; - for(uint8_t i = 0; i < EChunkArrayData_ENUM_MAX; ++i) { - chunksArray[i] = furi_string_alloc(); - } - - uint8_t index = 0; - do { - end = furi_string_search_char(receivedString, '+', begin); - - if(end == FURI_STRING_FAILURE) { - end = stringSize; - } - - WIFI_APP_LOG_I("size: %i, begin: %i, end: %i", stringSize, begin, end); - - furi_string_set_strn( - chunk, &furi_string_get_cstr(receivedString)[begin], end - begin); - - WIFI_APP_LOG_I("String chunk: %s", furi_string_get_cstr(chunk)); - - furi_string_set(chunksArray[index++], chunk); - - begin = end + 1; - } while(end < stringSize); - furi_string_free(chunk); - - app = context; - furi_mutex_acquire(app->mutex, FuriWaitForever); - if(app == NULL) { - return 1; - } - - if(!app->m_wifiModuleInitialized) { - if(furi_string_cmp_str( - chunksArray[EChunkArrayData_Context], MODULE_CONTEXT_INITIALIZATION) == - 0) { - app->m_wifiModuleInitialized = true; - app->m_context = ScanAnimation; - } - - } else { - if(furi_string_cmp_str( - chunksArray[EChunkArrayData_Context], MODULE_CONTEXT_MONITOR) == 0) { - app->m_context = MonitorMode; - } else if( - furi_string_cmp_str( - chunksArray[EChunkArrayData_Context], MODULE_CONTEXT_SCAN) == 0) { - app->m_context = ScanMode; - } else if( - furi_string_cmp_str( - chunksArray[EChunkArrayData_Context], MODULE_CONTEXT_SCAN_ANIMATION) == - 0) { - app->m_context = ScanAnimation; - } else if( - furi_string_cmp_str( - chunksArray[EChunkArrayData_Context], - MODULE_CONTEXT_MONITOR_ANIMATION) == 0) { - app->m_context = MonitorAnimation; - } - - if(app->m_context == MonitorMode || app->m_context == ScanMode) { - furi_string_set( - app->m_currentAccesspointDescription.m_accessPointName, - chunksArray[EChunkArrayData_SSID]); - furi_string_set( - app->m_currentAccesspointDescription.m_secType, - chunksArray[EChunkArrayData_EncryptionType]); - app->m_currentAccesspointDescription.m_rssi = - atoi(furi_string_get_cstr(chunksArray[EChunkArrayData_RSSI])); - furi_string_set( - app->m_currentAccesspointDescription.m_bssid, - chunksArray[EChunkArrayData_BSSID]); - app->m_currentAccesspointDescription.m_channel = - atoi(furi_string_get_cstr(chunksArray[EChunkArrayData_Channel])); - app->m_currentAccesspointDescription.m_isHidden = - atoi(furi_string_get_cstr(chunksArray[EChunkArrayData_IsHidden])); - - app->m_currentIndexAccessPoint = atoi( - furi_string_get_cstr(chunksArray[EChunkArrayData_CurrentAPIndex])); - app->m_totalAccessPoints = - atoi(furi_string_get_cstr(chunksArray[EChunkArrayData_TotalAps])); - } - } - - furi_mutex_release(app->mutex); - - // Clear string array - for(index = 0; index < EChunkArrayData_ENUM_MAX; ++index) { - furi_string_free(chunksArray[index]); - } - } - furi_string_free(receivedString); - } - } - - return 0; -} - -typedef enum ESerialCommand { - ESerialCommand_Next, - ESerialCommand_Previous, - ESerialCommand_Scan, - ESerialCommand_MonitorMode, - ESerialCommand_Restart -} ESerialCommand; - -void send_serial_command(ESerialCommand command) { -#if !DISABLE_CONSOLE - return; -#endif - - uint8_t data[1] = {0}; - - switch(command) { - case ESerialCommand_Next: - data[0] = MODULE_CONTROL_COMMAND_NEXT; - break; - case ESerialCommand_Previous: - data[0] = MODULE_CONTROL_COMMAND_PREVIOUS; - break; - case ESerialCommand_Scan: - data[0] = MODULE_CONTROL_COMMAND_SCAN; - break; - case ESerialCommand_MonitorMode: - data[0] = MODULE_CONTROL_COMMAND_MONITOR; - break; - case ESerialCommand_Restart: - data[0] = MODULE_CONTROL_COMMAND_RESTART; - break; - default: - return; - }; - - furi_hal_uart_tx(UART_CH, data, 1); -} - -int32_t wifi_scanner_app(void* p) { - UNUSED(p); - - WIFI_APP_LOG_I("Init"); - - // FuriTimer* timer = furi_timer_alloc(blink_test_update, FuriTimerTypePeriodic, event_queue); - // furi_timer_start(timer, furi_kernel_get_tick_frequency()); - - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(SPluginEvent)); - - SWiFiScannerApp* app = malloc(sizeof(SWiFiScannerApp)); - - wifi_scanner_app_init(app); - -#if ENABLE_MODULE_DETECTION - furi_hal_gpio_init( - &gpio_ext_pc0, - GpioModeInput, - GpioPullUp, - GpioSpeedLow); // Connect to the Flipper's ground just to be sure - //furi_hal_gpio_add_int_callback(pinD0, input_isr_d0, this); - app->m_context = WaitingForModule; -#else - app->m_context = Initializing; -#if ENABLE_MODULE_POWER - uint8_t attempts = 0; - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - furi_delay_ms(10); - } - furi_delay_ms(200); -#endif // ENABLE_MODULE_POWER -#endif // ENABLE_MODULE_DETECTION - - app->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - - if(!app->mutex) { - WIFI_APP_LOG_E("cannot create mutex\r\n"); - free(app); - return 255; - } - - WIFI_APP_LOG_I("Mutex created"); - - app->m_notification = furi_record_open(RECORD_NOTIFICATION); - - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, wifi_module_render_callback, app); - view_port_input_callback_set(view_port, wifi_module_input_callback, event_queue); - - // Open GUI and register view_port - app->m_gui = furi_record_open(RECORD_GUI); - gui_add_view_port(app->m_gui, view_port, GuiLayerFullscreen); - - //notification_message(app->notification, &sequence_set_only_blue_255); - - app->m_rx_stream = furi_stream_buffer_alloc(1 * 1024, 1); - - app->m_worker_thread = furi_thread_alloc(); - furi_thread_set_name(app->m_worker_thread, "WiFiModuleUARTWorker"); - furi_thread_set_stack_size(app->m_worker_thread, 1024); - furi_thread_set_context(app->m_worker_thread, app); - furi_thread_set_callback(app->m_worker_thread, uart_worker); - furi_thread_start(app->m_worker_thread); - WIFI_APP_LOG_I("UART thread allocated"); - - // Enable uart listener - if(UART_CH == FuriHalUartIdUSART1) { - furi_hal_console_disable(); - } else if(UART_CH == FuriHalUartIdLPUART1) { - furi_hal_uart_init(UART_CH, FLIPPERZERO_SERIAL_BAUD); - } - - furi_hal_uart_set_br(UART_CH, FLIPPERZERO_SERIAL_BAUD); - furi_hal_uart_set_irq_cb(UART_CH, uart_on_irq_cb, app); - WIFI_APP_LOG_I("UART Listener created"); - - // Because we assume that module was on before we launched the app. We need to ensure that module will be in initial state on app start - send_serial_command(ESerialCommand_Restart); - - SPluginEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - furi_mutex_acquire(app->mutex, FuriWaitForever); - -#if ENABLE_MODULE_DETECTION - if(!app->m_wifiModuleAttached) { - if(furi_hal_gpio_read(&gpio_ext_pc0) == false) { - WIFI_APP_LOG_I("Module Attached"); - app->m_wifiModuleAttached = true; - app->m_context = Initializing; -#if ENABLE_MODULE_POWER - uint8_t attempts2 = 0; - while(!furi_hal_power_is_otg_enabled() && attempts2++ < 3) { - furi_hal_power_enable_otg(); - furi_delay_ms(10); - } - -#endif - } - } -#endif // ENABLE_MODULE_DETECTION - - if(event_status == FuriStatusOk) { - if(event.m_type == EventTypeKey) { - if(app->m_wifiModuleInitialized) { - if(app->m_context == ScanMode) { - switch(event.m_input.key) { - case InputKeyUp: - case InputKeyLeft: - if(event.m_input.type == InputTypeShort) { - WIFI_APP_LOG_I("Previous"); - send_serial_command(ESerialCommand_Previous); - } else if(event.m_input.type == InputTypeRepeat) { - WIFI_APP_LOG_I("Previous Repeat"); - send_serial_command(ESerialCommand_Previous); - } - break; - case InputKeyDown: - case InputKeyRight: - if(event.m_input.type == InputTypeShort) { - WIFI_APP_LOG_I("Next"); - send_serial_command(ESerialCommand_Next); - } else if(event.m_input.type == InputTypeRepeat) { - WIFI_APP_LOG_I("Next Repeat"); - send_serial_command(ESerialCommand_Next); - } - break; - default: - break; - } - } - - switch(event.m_input.key) { - case InputKeyOk: - if(event.m_input.type == InputTypeShort) { - if(app->m_context == ScanMode) { - WIFI_APP_LOG_I("Monitor Mode"); - send_serial_command(ESerialCommand_MonitorMode); - } - } else if(event.m_input.type == InputTypeLong) { - WIFI_APP_LOG_I("Scan"); - send_serial_command(ESerialCommand_Scan); - } - break; - case InputKeyBack: - if(event.m_input.type == InputTypeShort) { - switch(app->m_context) { - case MonitorMode: - send_serial_command(ESerialCommand_Scan); - break; - case ScanMode: - processing = false; - break; - default: - break; - } - } else if(event.m_input.type == InputTypeLong) { - processing = false; - } - break; - default: - break; - } - } else { - if(event.m_input.key == InputKeyBack) { - if(event.m_input.type == InputTypeShort || - event.m_input.type == InputTypeLong) { - processing = false; - } - } - } - } - } - -#if ENABLE_MODULE_DETECTION - if(app->m_wifiModuleAttached && furi_hal_gpio_read(&gpio_ext_pc0) == true) { - WIFI_APP_LOG_D("Module Disconnected - Exit"); - processing = false; - app->m_wifiModuleAttached = false; - app->m_wifiModuleInitialized = false; - } -#endif - - view_port_update(view_port); - furi_mutex_release(app->mutex); - } - - WIFI_APP_LOG_I("Start exit app"); - - furi_thread_flags_set(furi_thread_get_id(app->m_worker_thread), WorkerEventStop); - furi_thread_join(app->m_worker_thread); - furi_thread_free(app->m_worker_thread); - - WIFI_APP_LOG_I("Thread Deleted"); - - // Reset GPIO pins to default state - furi_hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - - if(UART_CH == FuriHalUartIdLPUART1) { - furi_hal_uart_deinit(UART_CH); - } else { - furi_hal_console_enable(); - } - - view_port_enabled_set(view_port, false); - - gui_remove_view_port(app->m_gui, view_port); - - // Close gui record - furi_record_close(RECORD_GUI); - furi_record_close(RECORD_NOTIFICATION); - app->m_gui = NULL; - - view_port_free(view_port); - - furi_message_queue_free(event_queue); - - furi_stream_buffer_free(app->m_rx_stream); - - furi_mutex_free(app->mutex); - - // Free rest - free(app); - - WIFI_APP_LOG_I("App freed"); - -#if ENABLE_MODULE_POWER - if(furi_hal_power_is_otg_enabled()) { - furi_hal_power_disable_otg(); - } -#endif - - return 0; -} \ No newline at end of file