Willy-JL 1 год назад
Родитель
Сommit
15979a9347

+ 0 - 52
usb_consumer_control/.gitignore

@@ -1,52 +0,0 @@
-# Prerequisites
-*.d
-
-# Object files
-*.o
-*.ko
-*.obj
-*.elf
-
-# Linker output
-*.ilk
-*.map
-*.exp
-
-# Precompiled Headers
-*.gch
-*.pch
-
-# Libraries
-*.lib
-*.a
-*.la
-*.lo
-
-# Shared objects (inc. Windows DLLs)
-*.dll
-*.so
-*.so.*
-*.dylib
-
-# Executables
-*.exe
-*.out
-*.app
-*.i*86
-*.x86_64
-*.hex
-
-# Debug files
-*.dSYM/
-*.su
-*.idb
-*.pdb
-
-# Kernel Module Compile Results
-*.mod*
-*.cmd
-.tmp_versions/
-modules.order
-Module.symvers
-Mkfile.old
-dkms.conf

+ 0 - 1
usb_consumer_control/.gitsubtree

@@ -1 +0,0 @@
-https://github.com/xMasterX/all-the-plugins dev non_catalog_apps/usb_consumer_control

+ 0 - 201
usb_consumer_control/LICENSE

@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.

+ 0 - 9
usb_consumer_control/README.md

@@ -1,9 +0,0 @@
-# USB Consumer Control
-This is a Flipper Zero application for sending Consumer Control Button (CCB) presses as a USB HID device. This is useful for researching how various devices handle USB CCBs, for example in the context of kiosk breakouts. 
-
-A more detailed writeup of the topic can be found [here](https://github.com/piraija/usb-hid-and-run).
-
-# Credits
-Project built by [Erik Alm](https://www.linkedin.com/in/erik-alm).
-
-Inspiration drawn from [FlipperZeroUSBKeyboard](https://github.com/huuck/FlipperZeroUSBKeyboard) and [usb_hid_autofire](https://github.com/pbek/usb_hid_autofire).

+ 0 - 12
usb_consumer_control/application.fam

@@ -1,12 +0,0 @@
-App(
-    appid="usb_ccb",
-    name="USB Consumer Control",
-    apptype=FlipperAppType.EXTERNAL,
-    entry_point="usb_ccb_app",
-    stack_size=1 * 1024,
-    fap_author="piraija",
-    fap_category="USB",
-    fap_description="USB Consumer Control",
-    fap_icon="usb_ccb_10px.png",
-    fap_version="1.0", 
-)

+ 0 - 18
usb_consumer_control/docs/building.md

@@ -1,18 +0,0 @@
-# Building
-
-```shell
-# Clone Flipper Zero firmware
-git clone --recursive https://github.com/flipperdevices/flipperzero-firmware.git
-
-# Clone application
-cd firmware/applications_user && git clone https://github.com/WithSecureLabs/usb-consumer-control.git
-
-# Install toolchain
-cd .. && ./fbt
-
-# Build application
-./fbt fap_usb_ccb
-
-# Copy built application to your SD card
-cp build/f7-firmware-D/.extapps/usb_ccb.fap <SD Card root>/apps/usb/ 
-```

+ 0 - 3
usb_consumer_control/docs/changelog.md

@@ -1,3 +0,0 @@
-## v.1.0
-
-Initial release.

BIN
usb_consumer_control/screenshots/1.png


BIN
usb_consumer_control/screenshots/2.png


+ 0 - 149
usb_consumer_control/usb_ccb.c

@@ -1,149 +0,0 @@
-#include "usb_ccb.h"
-#include <furi.h>
-#include <furi_hal.h>
-#include <notification/notification_messages.h>
-
-#define TAG "UsbCcbApp"
-
-enum UsbDebugSubmenuIndex {
-    UsbCcbSubmenuIndexAbout,
-    UsbCcbSubmenuIndexHelp,
-    UsbCcbSubmenuIndexStart,
-};
-
-void usb_ccb_submenu_callback(void* context, uint32_t index) {
-    furi_assert(context);
-    UsbCcb* app = context;
-    if(index == UsbCcbSubmenuIndexAbout) {
-        app->view_id = UsbCcbViewAbout;
-        view_dispatcher_switch_to_view(app->view_dispatcher, UsbCcbViewAbout);
-    } else if(index == UsbCcbSubmenuIndexHelp) {
-        app->view_id = UsbCcbViewHelp;
-        view_dispatcher_switch_to_view(app->view_dispatcher, UsbCcbViewHelp);
-    } else if(index == UsbCcbSubmenuIndexStart) {
-        app->view_id = UsbCcbViewStart;
-        view_dispatcher_switch_to_view(app->view_dispatcher, UsbCcbViewStart);
-    }
-}
-
-void usb_ccb_dialog_callback(DialogExResult result, void* context) {
-    furi_assert(context);
-    UsbCcb* app = context;
-    if(result == DialogExResultLeft) {
-        view_dispatcher_stop(app->view_dispatcher);
-    } else if(result == DialogExResultRight) {
-        view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id); // Show last view
-    } else if(result == DialogExResultCenter) {
-        view_dispatcher_switch_to_view(app->view_dispatcher, UsbCcbViewSubmenu);
-    }
-}
-
-uint32_t usb_ccb_exit_confirm_view(void* context) {
-    UNUSED(context);
-    return UsbCcbViewExitConfirm;
-}
-
-uint32_t usb_ccb_exit(void* context) {
-    UNUSED(context);
-    return VIEW_NONE;
-}
-
-UsbCcb* usb_ccb_app_alloc() {
-    UsbCcb* app = malloc(sizeof(UsbCcb));
-
-    // Gui
-    app->gui = furi_record_open(RECORD_GUI);
-
-    // Notifications
-    app->notifications = furi_record_open(RECORD_NOTIFICATION);
-
-    // View dispatcher
-    app->view_dispatcher = view_dispatcher_alloc();
-    view_dispatcher_enable_queue(app->view_dispatcher);
-    view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
-
-    // Submenu view
-    app->submenu = submenu_alloc();
-    submenu_set_header(app->submenu, "USB Consumer Control");
-    submenu_add_item(app->submenu, "About", UsbCcbSubmenuIndexAbout, usb_ccb_submenu_callback, app);
-    submenu_add_item(app->submenu, "Help", UsbCcbSubmenuIndexHelp, usb_ccb_submenu_callback, app);
-    submenu_add_item(app->submenu, "Start", UsbCcbSubmenuIndexStart, usb_ccb_submenu_callback, app);
-    view_set_previous_callback(submenu_get_view(app->submenu), usb_ccb_exit);
-    view_dispatcher_add_view(app->view_dispatcher, UsbCcbViewSubmenu, submenu_get_view(app->submenu));
-
-    // Dialog view
-    app->dialog = dialog_ex_alloc();
-    dialog_ex_set_result_callback(app->dialog, usb_ccb_dialog_callback);
-    dialog_ex_set_context(app->dialog, app);
-    dialog_ex_set_left_button_text(app->dialog, "Exit");
-    dialog_ex_set_right_button_text(app->dialog, "Stay");
-    dialog_ex_set_center_button_text(app->dialog, "Menu");
-    dialog_ex_set_header(app->dialog, "Exit or return to menu?", 64, 11, AlignCenter, AlignTop);
-    view_dispatcher_add_view(app->view_dispatcher, UsbCcbViewExitConfirm, dialog_ex_get_view(app->dialog));
-
-    // About view
-    app->usb_ccb_about = usb_ccb_about_alloc();
-    view_set_previous_callback(usb_ccb_about_get_view(app->usb_ccb_about), usb_ccb_exit_confirm_view);
-    view_dispatcher_add_view(app->view_dispatcher, UsbCcbViewAbout, usb_ccb_about_get_view(app->usb_ccb_about));
-
-    // Help view
-    app->usb_ccb_help = usb_ccb_help_alloc();
-    view_set_previous_callback(usb_ccb_help_get_view(app->usb_ccb_help), usb_ccb_exit_confirm_view);
-    view_dispatcher_add_view(app->view_dispatcher, UsbCcbViewHelp, usb_ccb_help_get_view(app->usb_ccb_help));
-
-    // Start view
-    app->usb_ccb_start = usb_ccb_start_alloc();
-    view_set_previous_callback(usb_ccb_start_get_view(app->usb_ccb_start), usb_ccb_exit_confirm_view);
-    view_dispatcher_add_view(app->view_dispatcher, UsbCcbViewStart, usb_ccb_start_get_view(app->usb_ccb_start));
-
-    app->view_id = UsbCcbViewSubmenu;
-    view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id);
-
-    return app;
-}
-
-void usb_ccb_app_free(UsbCcb* app) {
-    furi_assert(app);
-
-    // Reset notification
-    notification_internal_message(app->notifications, &sequence_reset_blue);
-
-    // Free views
-    view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewSubmenu);
-    submenu_free(app->submenu);
-    view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewExitConfirm);
-    dialog_ex_free(app->dialog);
-    view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewAbout);
-    usb_ccb_about_free(app->usb_ccb_about);
-    view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewHelp);
-    usb_ccb_help_free(app->usb_ccb_help);
-    view_dispatcher_remove_view(app->view_dispatcher, UsbCcbViewStart);
-    usb_ccb_start_free(app->usb_ccb_start);
-    view_dispatcher_free(app->view_dispatcher);
-    // Close records
-    furi_record_close(RECORD_GUI);
-    app->gui = NULL;
-    furi_record_close(RECORD_NOTIFICATION);
-    app->notifications = NULL;
-
-    // Free rest
-    free(app);
-}
-
-int32_t usb_ccb_app(void* p) {
-    UNUSED(p);
-    // Switch profile to Hid
-    UsbCcb* app = usb_ccb_app_alloc();
-
-    FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
-    furi_hal_usb_unlock();
-    furi_check(furi_hal_usb_set_config(&usb_hid, NULL) == true);
-
-    view_dispatcher_run(app->view_dispatcher);
-
-    // Change back profile
-    furi_hal_usb_set_config(usb_mode_prev, NULL);
-    usb_ccb_app_free(app);
-
-    return 0;
-}

+ 0 - 33
usb_consumer_control/usb_ccb.h

@@ -1,33 +0,0 @@
-#pragma once
-
-#include <furi.h>
-#include <gui/gui.h>
-#include <gui/view.h>
-#include <gui/view_dispatcher.h>
-#include <notification/notification.h>
-
-#include <gui/modules/submenu.h>
-#include <gui/modules/dialog_ex.h>
-#include "views/usb_ccb_about.h"
-#include "views/usb_ccb_help.h"
-#include "views/usb_ccb_start.h"
-
-typedef struct {
-    Gui* gui;
-    NotificationApp* notifications;
-    ViewDispatcher* view_dispatcher;
-    Submenu* submenu;
-    DialogEx* dialog;
-    UsbCcbAbout* usb_ccb_about;
-    UsbCcbHelp* usb_ccb_help;
-    UsbCcbStart* usb_ccb_start;
-    uint32_t view_id;
-} UsbCcb;
-
-typedef enum {
-    UsbCcbViewSubmenu,
-    UsbCcbViewAbout,
-    UsbCcbViewHelp,
-    UsbCcbViewStart,
-    UsbCcbViewExitConfirm,
-} UsbCcbView;

BIN
usb_consumer_control/usb_ccb_10px.png


+ 0 - 68
usb_consumer_control/views/usb_ccb_about.c

@@ -1,68 +0,0 @@
-#include "usb_ccb_about.h"
-#include <furi.h>
-#include <furi_hal_usb_hid.h>
-#include <gui/elements.h>
-
-struct UsbCcbAbout {
-    View* view;
-};
-
-typedef struct {
-    bool left_pressed;
-    bool up_pressed;
-    bool right_pressed;
-    bool down_pressed;
-    bool ok_pressed;
-    bool back_pressed;
-    bool connected;
-} UsbCcbAboutModel;
-
-static void usb_ccb_about_draw_callback(Canvas* canvas, void* context) {
-    furi_assert(context);
-
-    canvas_set_font(canvas, FontSecondary);
-    canvas_draw_str(canvas, 0, 7, "A tool to send USB CCBs,");
-    canvas_draw_str(canvas, 0, 16, "to launch & control apps.");
-    canvas_draw_str(canvas, 0, 28, "For security research.");
-    canvas_draw_str(canvas, 0, 37, "Only use with permission.");
-    canvas_draw_str(canvas, 0, 49, "More info at: github.com");
-    canvas_draw_str(canvas, 0, 58, "/piraija/usb-hid-and-run");
-}
-
-static bool usb_ccb_about_input_callback(InputEvent* event, void* context) {
-    furi_assert(context);
-    bool consumed = false;
-
-    if(event->type == InputTypeLong && event->key == InputKeyBack) {
-        furi_hal_hid_kb_release_all();
-    } 
-
-    return consumed;
-}
-
-UsbCcbAbout* usb_ccb_about_alloc() {
-    UsbCcbAbout* usb_ccb_about = malloc(sizeof(UsbCcbAbout));
-    usb_ccb_about->view = view_alloc();
-    view_set_context(usb_ccb_about->view, usb_ccb_about);
-    view_allocate_model(usb_ccb_about->view, ViewModelTypeLocking, sizeof(UsbCcbAboutModel));
-    view_set_draw_callback(usb_ccb_about->view, usb_ccb_about_draw_callback);
-    view_set_input_callback(usb_ccb_about->view, usb_ccb_about_input_callback);
-
-    return usb_ccb_about;
-}
-
-void usb_ccb_about_free(UsbCcbAbout* usb_ccb_about) {
-    furi_assert(usb_ccb_about);
-    view_free(usb_ccb_about->view);
-    free(usb_ccb_about);
-}
-
-View* usb_ccb_about_get_view(UsbCcbAbout* usb_ccb_about) {
-    furi_assert(usb_ccb_about);
-    return usb_ccb_about->view;
-}
-
-void usb_ccb_about_set_connected_status(UsbCcbAbout* usb_ccb_about, bool connected) {
-    furi_assert(usb_ccb_about);
-    with_view_model(usb_ccb_about->view, UsbCcbAboutModel * model, { model->connected = connected; }, true);
-}

+ 0 - 13
usb_consumer_control/views/usb_ccb_about.h

@@ -1,13 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-
-typedef struct UsbCcbAbout UsbCcbAbout;
-
-UsbCcbAbout* usb_ccb_about_alloc();
-
-void usb_ccb_about_free(UsbCcbAbout* usb_ccb_about);
-
-View* usb_ccb_about_get_view(UsbCcbAbout* usb_ccb_about);
-
-void usb_ccb_about_set_connected_status(UsbCcbAbout* usb_ccb_about, bool connected);

+ 0 - 69
usb_consumer_control/views/usb_ccb_help.c

@@ -1,69 +0,0 @@
-#include "usb_ccb_help.h"
-#include <furi.h>
-#include <furi_hal_usb_hid.h>
-#include <gui/elements.h>
-
-struct UsbCcbHelp {
-    View* view;
-};
-
-typedef struct {
-    bool left_pressed;
-    bool up_pressed;
-    bool right_pressed;
-    bool down_pressed;
-    bool ok_pressed;
-    bool back_pressed;
-    bool connected;
-} UsbCcbHelpModel;
-
-static void usb_ccb_help_draw_callback(Canvas* canvas, void* context) {
-    furi_assert(context);
-
-    canvas_set_font(canvas, FontSecondary);
-    canvas_draw_str(canvas, 0, 8, "Exit to menu: hold [back].");
-    canvas_draw_str(canvas, 0, 18, "Adjust delay between keys:");
-    canvas_draw_str(canvas, 0, 26, "push [up] or [down].");
-    canvas_draw_str(canvas, 0, 36, "Cycle between keys:");
-    canvas_draw_str(canvas, 0, 44, "push/hold [left] or [right].");
-    canvas_draw_str(canvas, 0, 54, "Toggle sending keys: push [ok].");
-    canvas_draw_str(canvas, 0, 62, "Send one key: double click [ok].");
-}
-
-static bool usb_ccb_help_input_callback(InputEvent* event, void* context) {
-    furi_assert(context);
-    bool consumed = false;
-
-    if(event->type == InputTypeLong && event->key == InputKeyBack) {
-        furi_hal_hid_kb_release_all();
-    } 
-
-    return consumed;
-}
-
-UsbCcbHelp* usb_ccb_help_alloc() {
-    UsbCcbHelp* usb_ccb_help = malloc(sizeof(UsbCcbHelp));
-    usb_ccb_help->view = view_alloc();
-    view_set_context(usb_ccb_help->view, usb_ccb_help);
-    view_allocate_model(usb_ccb_help->view, ViewModelTypeLocking, sizeof(UsbCcbHelpModel));
-    view_set_draw_callback(usb_ccb_help->view, usb_ccb_help_draw_callback);
-    view_set_input_callback(usb_ccb_help->view, usb_ccb_help_input_callback);
-
-    return usb_ccb_help;
-}
-
-void usb_ccb_help_free(UsbCcbHelp* usb_ccb_help) {
-    furi_assert(usb_ccb_help);
-    view_free(usb_ccb_help->view);
-    free(usb_ccb_help);
-}
-
-View* usb_ccb_help_get_view(UsbCcbHelp* usb_ccb_help) {
-    furi_assert(usb_ccb_help);
-    return usb_ccb_help->view;
-}
-
-void usb_ccb_help_set_connected_status(UsbCcbHelp* usb_ccb_help, bool connected) {
-    furi_assert(usb_ccb_help);
-    with_view_model(usb_ccb_help->view, UsbCcbHelpModel * model, { model->connected = connected; }, true);
-}

+ 0 - 13
usb_consumer_control/views/usb_ccb_help.h

@@ -1,13 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-
-typedef struct UsbCcbHelp UsbCcbHelp;
-
-UsbCcbHelp* usb_ccb_help_alloc();
-
-void usb_ccb_help_free(UsbCcbHelp* usb_ccb_help);
-
-View* usb_ccb_help_get_view(UsbCcbHelp* usb_ccb_help);
-
-void usb_ccb_help_set_connected_status(UsbCcbHelp* usb_ccb_help, bool connected);

+ 0 - 686
usb_consumer_control/views/usb_ccb_start.c

@@ -1,686 +0,0 @@
-#include "usb_ccb_start.h"
-#include <furi.h>
-#include <furi_hal_usb_hid.h>
-#include <gui/elements.h>
-
-struct UsbCcbStart {
-    View* view;
-};
-
-typedef struct {
-    bool left_pressed;
-    bool up_pressed;
-    bool right_pressed;
-    bool down_pressed;
-    bool ok_pressed;
-    bool back_pressed;
-    bool connected;
-} UsbCcbStartModel;
-
-typedef struct {
-    uint16_t value;
-    const char* name;
-} HID_CONSUMER;
-
-// All of the strings are prefixed with "HID_CONSUMER_", which has been removed to save some space.
-HID_CONSUMER hidConsumerArray[] = {
-    {0x00, "UNASSIGNED"}, // Generic Consumer Control Device
-    {0x01, "CONTROL"},
-    {0x02, "NUMERIC_KEY_PAD"},
-    {0x03, "PROGRAMMABLE_BUTTONS"},
-    {0x04, "MICROPHONE"},
-    {0x05, "HEADPHONE"},
-    {0x06, "GRAPHIC_EQUALIZER"},
-    {0x20, "PLUS_10"}, // Numeric Key Pad
-    {0x21, "PLUS_100"},
-    {0x22, "AM_PM"},
-    {0x30, "POWER"}, // General Controls
-    {0x31, "RESET"},
-    {0x32, "SLEEP"},
-    {0x33, "SLEEP_AFTER"},
-    {0x34, "SLEEP_MODE"},
-    {0x35, "ILLUMINATION"},
-    {0x36, "FUNCTION_BUTTONS"},
-    {0x40, "MENU"}, // Menu Controls
-    {0x41, "MENU_PICK"},
-    {0x42, "MENU_UP"},
-    {0x43, "MENU_DOWN"},
-    {0x44, "MENU_LEFT"},
-    {0x45, "MENU_RIGHT"},
-    {0x46, "MENU_ESCAPE"},
-    {0x47, "MENU_VALUE_INCREASE"},
-    {0x48, "MENU_VALUE_DECREASE"},
-    {0x60, "DATA_ON_SCREEN"}, // Display Controls
-    {0x61, "CLOSED_CAPTION"},
-    {0x62, "CLOSED_CAPTION_SELECT"},
-    {0x63, "VCR_TV"},
-    {0x64, "BROADCAST_MODE"},
-    {0x65, "SNAPSHOT"},
-    {0x66, "STILL"},
-    {0x80, "SELECTION"}, // Selection Controls
-    {0x81, "ASSIGN_SELECTION"},
-    {0x82, "MODE_STEP"},
-    {0x83, "RECALL_LAST"},
-    {0x84, "ENTER_CHANNEL"},
-    {0x85, "ORDER_MOVIE"},
-    {0x86, "CHANNEL"},
-    {0x87, "MEDIA_SELECTION"},
-    {0x88, "MEDIA_SELECT_COMPUTER"},
-    {0x89, "MEDIA_SELECT_TV"},
-    {0x8A, "MEDIA_SELECT_WWW"},
-    {0x8B, "MEDIA_SELECT_DVD"},
-    {0x8C, "MEDIA_SELECT_TELEPHONE"},
-    {0x8D, "MEDIA_SELECT_PROGRAM_GUIDE"},
-    {0x8E, "MEDIA_SELECT_VIDEO_PHONE"},
-    {0x8F, "MEDIA_SELECT_GAMES"},
-    {0x90, "MEDIA_SELECT_MESSAGES"},
-    {0x91, "MEDIA_SELECT_CD"},
-    {0x92, "MEDIA_SELECT_VCR"},
-    {0x93, "MEDIA_SELECT_TUNER"},
-    {0x94, "QUIT"},
-    {0x95, "HELP"},
-    {0x96, "MEDIA_SELECT_TAPE"},
-    {0x97, "MEDIA_SELECT_CABLE"},
-    {0x98, "MEDIA_SELECT_SATELLITE"},
-    {0x99, "MEDIA_SELECT_SECURITY"},
-    {0x9A, "MEDIA_SELECT_HOME"},
-    {0x9B, "MEDIA_SELECT_CALL"},
-    {0x9C, "CHANNEL_INCREMENT"},
-    {0x9D, "CHANNEL_DECREMENT"},
-    {0x9E, "MEDIA_SELECT_SAP"},
-    {0xA0, "VCR_PLUS"},
-    {0xA1, "ONCE"},
-    {0xA2, "DAILY"},
-    {0xA3, "WEEKLY"},
-    {0xA4, "MONTHLY"},
-    {0xB0, "PLAY"}, // Transport Controls
-    {0xB1, "PAUSE"},
-    {0xB2, "RECORD"},
-    {0xB3, "FAST_FORWARD"},
-    {0xB4, "REWIND"},
-    {0xB5, "SCAN_NEXT_TRACK"},
-    {0xB6, "SCAN_PREVIOUS_TRACK"},
-    {0xB7, "STOP"},
-    {0xB8, "EJECT"},
-    {0xB9, "RANDOM_PLAY"},
-    {0xBA, "SELECT_DISC"},
-    {0xBB, "ENTER_DISC"},
-    {0xBC, "REPEAT"},
-    {0xBD, "TRACKING"},
-    {0xBE, "TRACK_NORMAL"},
-    {0xBF, "SLOW_TRACKING"},
-    {0xC0, "FRAME_FORWARD"},
-    {0xC1, "FRAME_BACK"},
-    {0xC2, "MARK"}, // Search Controls
-    {0xC3, "CLEAR_MARK"},
-    {0xC4, "REPEAT_FROM_MARK"},
-    {0xC5, "RETURN_TO_MARK"},
-    {0xC6, "SEARCH_MARK_FORWARD"},
-    {0xC7, "SEARCH_MARK_BACKWARDS"},
-    {0xC8, "COUNTER_RESET"},
-    {0xC9, "SHOW_COUNTER"},
-    {0xCA, "TRACKING_INCREMENT"},
-    {0xCB, "TRACKING_DECREMENT"},
-    {0xCC, "STOP_EJECT"},
-    {0xCD, "PLAY_PAUSE"},
-    {0xCE, "PLAY_SKIP"},
-    {0xE0, "VOLUME"}, // Audio Controls
-    {0xE1, "BALANCE"},
-    {0xE2, "MUTE"},
-    {0xE3, "BASS"},
-    {0xE4, "TREBLE"},
-    {0xE5, "BASS_BOOST"},
-    {0xE6, "SURROUND_MODE"},
-    {0xE7, "LOUDNESS"},
-    {0xE8, "MPX"},
-    {0xE9, "VOLUME_INCREMENT"},
-    {0xEA, "VOLUME_DECREMENT"},
-    {0xF0, "SPEED_SELECT"}, // Speed Controls
-    {0xF1, "PLAYBACK_SPEED"},
-    {0xF2, "STANDARD_PLAY"},
-    {0xF3, "LONG_PLAY"},
-    {0xF4, "EXTENDED_PLAY"},
-    {0xF5, "SLOW"},
-    {0x100, "FAN_ENABLE"}, // Home and Security Controls
-    {0x101, "FAN_SPEED"},
-    {0x102, "LIGHT_ENABLE"},
-    {0x103, "LIGHT_ILLUMINATION_LEVEL"},
-    {0x104, "CLIMATE_CONTROL_ENABLE"},
-    {0x105, "ROOM_TEMPERATURE"},
-    {0x106, "SECURITY_ENABLE"},
-    {0x107, "FIRE_ALARM"},
-    {0x108, "POLICE_ALARM"},
-    {0x109, "PROXIMITY"},
-    {0x10A, "MOTION"},
-    {0x10B, "DURESS_ALARM"},
-    {0x10C, "HOLDUP_ALARM"},
-    {0x10D, "MEDICAL_ALARM"},
-    {0x150, "BALANCE_RIGHT"}, // Speaker Channels
-    {0x151, "BALANCE_LEFT"},
-    {0x152, "BASS_INCREMENT"},
-    {0x153, "BASS_DECREMENT"},
-    {0x154, "TREBLE_INCREMENT"},
-    {0x155, "TREBLE_DECREMENT"},
-    {0x160, "SPEAKER_SYSTEM"},
-    {0x161, "CHANNEL_LEFT"},
-    {0x162, "CHANNEL_RIGHT"},
-    {0x163, "CHANNEL_CENTER"},
-    {0x164, "CHANNEL_FRONT"},
-    {0x165, "CHANNEL_CENTER_FRONT"},
-    {0x166, "CHANNEL_SIDE"},
-    {0x167, "CHANNEL_SURROUND"},
-    {0x168, "CHANNEL_LOW_FREQUENCY_ENHANCEMENT"},
-    {0x169, "CHANNEL_TOP"},
-    {0x16A, "CHANNEL_UNKNOWN"},
-    {0x170, "SUB_CHANNEL"}, // PC Theatre
-    {0x171, "SUB_CHANNEL_INCREMENT"},
-    {0x172, "SUB_CHANNEL_DECREMENT"},
-    {0x173, "ALTERNATE_AUDIO_INCREMENT"},
-    {0x174, "ALTERNATE_AUDIO_DECREMENT"},
-    {0x180, "APPLICATION_LAUNCH_BUTTONS"}, // Application Launch Buttons
-    {0x181, "AL_LAUNCH_BUTTON_CONFIGURATION_TOOL"},
-    {0x182, "AL_PROGRAMMABLE_BUTTON_CONFIGURATION"},
-    {0x183, "AL_CONSUMER_CONTROL_CONFIGURATION"},
-    {0x184, "AL_WORD_PROCESSOR"},
-    {0x185, "AL_TEXT_EDITOR"},
-    {0x186, "AL_SPREADSHEET"},
-    {0x187, "AL_GRAPHICS_EDITOR"},
-    {0x188, "AL_PRESENTATION_APP"},
-    {0x189, "AL_DATABASE_APP"},
-    {0x18A, "AL_EMAIL_READER"},
-    {0x18B, "AL_NEWSREADER"},
-    {0x18C, "AL_VOICEMAIL"},
-    {0x18D, "AL_CONTACTS_ADDRESS_BOOK"},
-    {0x18E, "AL_CALENDAR_SCHEDULE"},
-    {0x18F, "AL_TASK_PROJECT_MANAGER"},
-    {0x190, "AL_LOG_JOURNAL_TIMECARD"},
-    {0x191, "AL_CHECKBOOK_FINANCE"},
-    {0x192, "AL_CALCULATOR"},
-    {0x193, "AL_A_V_CAPTURE_PLAYBACK"},
-    {0x194, "AL_LOCAL_MACHINE_BROWSER"},
-    {0x195, "AL_LAN_WAN_BROWSER"},
-    {0x196, "AL_INTERNET_BROWSER"},
-    {0x197, "AL_REMOTE_NETWORKING_ISP_CONNECT"},
-    {0x198, "AL_NETWORK_CONFERENCE"},
-    {0x199, "AL_NETWORK_CHAT"},
-    {0x19A, "AL_TELEPHONY_DIALER"},
-    {0x19B, "AL_LOGON"},
-    {0x19C, "AL_LOGOFF"},
-    {0x19D, "AL_LOGON_LOGOFF"},
-    {0x19E, "AL_TERMINAL_LOCK_SCREENSAVER"},
-    {0x19F, "AL_CONTROL_PANEL"},
-    {0x1A0, "AL_COMMAND_LINE_PROCESSOR_RUN"},
-    {0x1A1, "AL_PROCESS_TASK_MANAGER"},
-    {0x1A2, "AL_SELECT_TASK_APPLICATION"},
-    {0x1A3, "AL_NEXT_TASK_APPLICATION"},
-    {0x1A4, "AL_PREVIOUS_TASK_APPLICATION"},
-    {0x1A5, "AL_PREEMPTIVE_HALT_TASK_APPLICATION"},
-    {0x1A6, "AL_INTEGRATED_HELP_CENTER"},
-    {0x1A7, "AL_DOCUMENTS"},
-    {0x1A8, "AL_THESAURUS"},
-    {0x1A9, "AL_DICTIONARY"},
-    {0x1AA, "AL_DESKTOP"},
-    {0x1AB, "AL_SPELL_CHECK"},
-    {0x1AC, "AL_GRAMMAR_CHECK"},
-    {0x1AD, "AL_WIRELESS_STATUS"},
-    {0x1AE, "AL_KEYBOARD_LAYOUT"},
-    {0x1AF, "AL_VIRUS_PROTECTION"},
-    {0x1B0, "AL_ENCRYPTION"},
-    {0x1B1, "AL_SCREEN_SAVER"},
-    {0x1B2, "AL_ALARMS"},
-    {0x1B3, "AL_CLOCK"},
-    {0x1B4, "AL_FILE_BROWSER"},
-    {0x1B5, "AL_POWER_STATUS"},
-    {0x1B6, "AL_IMAGE_BROWSER"},
-    {0x1B7, "AL_AUDIO_BROWSER"},
-    {0x1B8, "AL_MOVIE_BROWSER"},
-    {0x1B9, "AL_DIGITAL_RIGHTS_MANAGER"},
-    {0x1BA, "AL_DIGITAL_WALLET"},
-    {0x1BC, "AL_INSTANT_MESSAGING"},
-    {0x1BD, "AL_OEM_FEATURES_TIPS_TUTORIAL_BROWSER"},
-    {0x1BE, "AL_OEM_HELP"},
-    {0x1BF, "AL_ONLINE_COMMUNITY"},
-    {0x1C0, "AL_ENTERTAINMENT_CONTENT_BROWSER"},
-    {0x1C1, "AL_ONLINE_SHOPPING_BROWSER"},
-    {0x1C2, "AL_SMARTCARD_INFORMATION_HELP"},
-    {0x1C3, "AL_MARKET_MONITOR_FINANCE_BROWSER"},
-    {0x1C4, "AL_CUSTOMIZED_CORPORATE_NEWS_BROWSER"},
-    {0x1C5, "AL_ONLINE_ACTIVITY_BROWSER"},
-    {0x1C6, "AL_RESEARCH_SEARCH_BROWSER"},
-    {0x1C7, "AL_AUDIO_PLAYER"},
-    {0x200, "GENERIC_GUI_APPLICATION_CONTROLS"}, // Generic GUI Application Controls
-    {0x201, "AC_NEW"},
-    {0x202, "AC_OPEN"},
-    {0x203, "AC_CLOSE"},
-    {0x204, "AC_EXIT"},
-    {0x205, "AC_MAXIMIZE"},
-    {0x206, "AC_MINIMIZE"},
-    {0x207, "AC_SAVE"},
-    {0x208, "AC_PRINT"},
-    {0x209, "AC_PROPERTIES"},
-    {0x21A, "AC_UNDO"},
-    {0x21B, "AC_COPY"},
-    {0x21C, "AC_CUT"},
-    {0x21D, "AC_PASTE"},
-    {0x21E, "AC_SELECT_ALL"},
-    {0x21F, "AC_FIND"},
-    {0x220, "AC_FIND_AND_REPLACE"},
-    {0x221, "AC_SEARCH"},
-    {0x222, "AC_GO_TO"},
-    {0x223, "AC_HOME"},
-    {0x224, "AC_BACK"},
-    {0x225, "AC_FORWARD"},
-    {0x226, "AC_STOP"},
-    {0x227, "AC_REFRESH"},
-    {0x228, "AC_PREVIOUS_LINK"},
-    {0x229, "AC_NEXT_LINK"},
-    {0x22A, "AC_BOOKMARKS"},
-    {0x22B, "AC_HISTORY"},
-    {0x22C, "AC_SUBSCRIPTIONS"},
-    {0x22D, "AC_ZOOM_IN"},
-    {0x22E, "AC_ZOOM_OUT"},
-    {0x22F, "AC_ZOOM"},
-    {0x230, "AC_FULL_SCREEN_VIEW"},
-    {0x231, "AC_NORMAL_VIEW"},
-    {0x232, "AC_VIEW_TOGGLE"},
-    {0x233, "AC_SCROLL_UP"},
-    {0x234, "AC_SCROLL_DOWN"},
-    {0x235, "AC_SCROLL"},
-    {0x236, "AC_PAN_LEFT"},
-    {0x237, "AC_PAN_RIGHT"},
-    {0x238, "AC_PAN"},
-    {0x239, "AC_NEW_WINDOW"},
-    {0x23A, "AC_TILE_HORIZONTALLY"},
-    {0x23B, "AC_TILE_VERTICALLY"},
-    {0x23C, "AC_FORMAT"},
-    {0x23D, "AC_EDIT"},
-    {0x23E, "AC_BOLD"},
-    {0x23F, "AC_ITALICS"},
-    {0x240, "AC_UNDERLINE"},
-    {0x241, "AC_STRIKETHROUGH"},
-    {0x242, "AC_SUBSCRIPT"},
-    {0x243, "AC_SUPERSCRIPT"},
-    {0x244, "AC_ALL_CAPS"},
-    {0x245, "AC_ROTATE"},
-    {0x246, "AC_RESIZE"},
-    {0x247, "AC_FLIP_HORIZONTAL"},
-    {0x248, "AC_FLIP_VERTICAL"},
-    {0x249, "AC_MIRROR_HORIZONTAL"},
-    {0x24A, "AC_MIRROR_VERTICAL"},
-    {0x24B, "AC_FONT_SELECT"},
-    {0x24C, "AC_FONT_COLOR"},
-    {0x24D, "AC_FONT_SIZE"},
-    {0x24E, "AC_JUSTIFY_LEFT"},
-    {0x24F, "AC_JUSTIFY_CENTER_H"},
-    {0x250, "AC_JUSTIFY_RIGHT"},
-    {0x251, "AC_JUSTIFY_BLOCK_H"},
-    {0x252, "AC_JUSTIFY_TOP"},
-    {0x253, "AC_JUSTIFY_CENTER_V"},
-    {0x254, "AC_JUSTIFY_BOTTOM"},
-    {0x255, "AC_JUSTIFY_BLOCK_V"},
-    {0x256, "AC_INDENT_DECREASE"},
-    {0x257, "AC_INDENT_INCREASE"},
-    {0x258, "AC_NUMBERED_LIST"},
-    {0x259, "AC_RESTART_NUMBERING"},
-    {0x25A, "AC_BULLETED_LIST"},
-    {0x25B, "AC_PROMOTE"},
-    {0x25C, "AC_DEMOTE"},
-    {0x25D, "AC_YES"},
-    {0x25E, "AC_NO"},
-    {0x25F, "AC_CANCEL"},
-    {0x260, "AC_CATALOG"},
-    {0x261, "AC_BUY_CHECKOUT"},
-    {0x262, "AC_ADD_TO_CART"},
-    {0x263, "AC_EXPAND"},
-    {0x264, "AC_EXPAND_ALL"},
-    {0x265, "AC_COLLAPSE"},
-    {0x266, "AC_COLLAPSE_ALL"},
-    {0x267, "AC_PRINT_PREVIEW"},
-    {0x268, "AC_PASTE_SPECIAL"},
-    {0x269, "AC_INSERT_MODE"},
-    {0x26A, "AC_DELETE"},
-    {0x26B, "AC_LOCK"},
-    {0x26C, "AC_UNLOCK"},
-    {0x26D, "AC_PROTECT"},
-    {0x26E, "AC_UNPROTECT"},
-    {0x26F, "AC_ATTACH_COMMENT"},
-    {0x270, "AC_DELETE_COMMENT"},
-    {0x271, "AC_VIEW_COMMENT"},
-    {0x272, "AC_SELECT_WORD"},
-    {0x273, "AC_SELECT_SENTENCE"},
-    {0x274, "AC_SELECT_PARAGRAPH"},
-    {0x275, "AC_SELECT_COLUMN"},
-    {0x276, "AC_SELECT_ROW"},
-    {0x277, "AC_SELECT_TABLE"},
-    {0x278, "AC_SELECT_OBJECT"},
-    {0x279, "AC_REDO_REPEAT"},
-    {0x27A, "AC_SORT"},
-    {0x27B, "AC_SORT_ASCENDING"},
-    {0x27C, "AC_SORT_DESCENDING"},
-    {0x27D, "AC_FILTER"},
-    {0x27E, "AC_SET_CLOCK"},
-    {0x27F, "AC_VIEW_CLOCK"},
-    {0x280, "AC_SELECT_TIME_ZONE"},
-    {0x281, "AC_EDIT_TIME_ZONES"},
-    {0x282, "AC_SET_ALARM"},
-    {0x283, "AC_CLEAR_ALARM"},
-    {0x284, "AC_SNOOZE_ALARM"},
-    {0x285, "AC_RESET_ALARM"},
-    {0x286, "AC_SYNCHRONIZE"},
-    {0x287, "AC_SEND_RECEIVE"},
-    {0x288, "AC_SEND_TO"},
-    {0x289, "AC_REPLY"},
-    {0x28A, "AC_REPLY_ALL"},
-    {0x28B, "AC_FORWARD_MSG"},
-    {0x28C, "AC_SEND"},
-    {0x28D, "AC_ATTACH_FILE"},
-    {0x28E, "AC_UPLOAD"},
-    {0x28F, "AC_DOWNLOAD_SAVE_TARGET_AS"},
-    {0x290, "AC_SET_BORDERS"},
-    {0x291, "AC_INSERT_ROW"},
-    {0x292, "AC_INSERT_COLUMN"},
-    {0x293, "AC_INSERT_FILE"},
-    {0x294, "AC_INSERT_PICTURE"},
-    {0x295, "AC_INSERT_OBJECT"},
-    {0x296, "AC_INSERT_SYMBOL"},
-    {0x297, "AC_SAVE_AND_CLOSE"},
-    {0x298, "AC_RENAME"},
-    {0x299, "AC_MERGE"},
-    {0x29A, "AC_SPLIT"},
-    {0x29B, "AC_DISRIBUTE_HORIZONTALLY"},
-    {0x29C, "AC_DISTRIBUTE_VERTICALLY"}
-};
-
-const int hidConsumerArraySize = sizeof(hidConsumerArray) / sizeof(hidConsumerArray[0]);
-
-void strrev(char* arr, int start, int end) {
-    char temp;
-
-    if (start >= end)
-        return;
-
-    temp = *(arr + start);
-    *(arr + start) = *(arr + end);
-    *(arr + end) = temp;
-
-    start++;
-    end--;
-    strrev(arr, start, end);
-}
-
-char *itoa(int number, char *arr, int base){
-    int i = 0, r, negative = 0;
-
-    if (number == 0)
-    {
-        arr[i] = '0';
-        arr[i + 1] = '\0';
-        return arr;
-    }
-
-    if (number < 0 && base == 10)
-    {
-        number *= -1;
-        negative = 1;
-    }
-
-    while (number != 0)
-    {
-        r = number % base;
-        arr[i] = (r > 9) ? (r - 10) + 'a' : r + '0';
-        i++;
-        number /= base;
-    }
-
-    if (negative)
-    {
-        arr[i] = '-';
-        i++;
-    }
-
-    strrev(arr, 0, i - 1);
-
-    arr[i] = '\0';
-
-    return arr;
-}
-
-// Function to convert a single hex digit to its character representation
-char hexDigitToChar(uint8_t digit) {
-    if (digit < 10) {
-        return '0' + digit;
-    } else {
-        return 'A' + (digit - 10);
-    }
-}
-
-// Function to convert a uint16_t value to its hex string representation
-void uint16ToHexString(uint16_t value, char* hexString) {
-    hexString[0] = '0';
-    hexString[1] = 'x';
-    int startIndex = 2;
-    for (int i = 3; i >= 0; --i) {
-        uint8_t digit = (value >> (i * 4)) & 0xF;
-        if (digit != 0 || startIndex != 2) {
-            hexString[startIndex++] = hexDigitToChar(digit);
-        }
-    }
-    if (startIndex == 2) { // If there are no non-zero digits, display at least "0x0"
-        hexString[startIndex++] = '0';
-    }
-    hexString[startIndex] = '\0';
-}
-
-bool is_running = false;
-uint32_t autofire_delay = 1000;
-char autofire_delay_str[12];
-char hexString[7];
-
-// Start at the Application Launch Buttons by default, since that's the most interesting
-int i = 153;
-int currentSubsetIndex = 13;
-
-// Array to store indexes of different CCB subsets
-// The idea would be to try using these different subsets against different types of devices
-int hidConsumerSubsets[] = { 
-    0, // Generic Consumer Control Device
-    7, // Numeric Key Pad
-    10, // General Controls
-    17, // Menu Controls
-    26, // Display Controls
-    33, // Selection Controls
-    69, // Transport Controls (nice)
-    87, // Search Controls
-    100, // Audio Controls
-    111, // Speed Controls
-    117, // Home and Security Controls
-    131, // Speaker Channels
-    148, // PC Theatre
-    153, // Application Launch Buttons
-    224 // Generic GUI Application Controls
-};
-
-const int hidConsumerSubsetsSize = sizeof(hidConsumerSubsets) / sizeof(hidConsumerSubsets[0]);
-
-const char* getConsumerSubsetName(int i) {
-    if (i >= 0 && i < 7) {
-        return "Generic Consumer Control";
-    } else if (i >= 7 && i < 10) {
-        return "Numeric Key Pad";
-    } else if (i >= 10 && i < 17) {
-        return "General Controls";
-    } else if (i >= 17 && i < 26) {
-        return "Menu Controls";
-    } else if (i >= 26 && i < 33) {
-        return "Display Controls";
-    } else if (i >= 33 && i < 69) {
-        return "Selection Controls";
-    } else if (i >= 69 && i < 87) {
-        return "Transport Controls";
-    } else if (i >= 87 && i < 100) {
-        return "Search Controls";
-    } else if (i >= 100 && i < 111) {
-        return "Audio Controls";
-    } else if (i >= 111 && i < 117) {
-        return "Speed Controls";
-    } else if (i >= 117 && i < 131) {
-        return "Home and Security Controls";
-    } else if (i >= 131 && i < 148) {
-        return "Speaker Channels";
-    } else if (i >= 148 && i < 153) {
-        return "PC Theatre";
-    } else if (i >= 153 && i < 224) {
-        return "Application Launch Buttons";
-    } else if (i >= 224) {
-        return "GUI Application Controls";
-    }
-    // Won't ever happen though
-    return "Invalid Index";
-}
-
-// This is the main program loop
-static void usb_ccb_start_draw_callback(Canvas* canvas, void* context) {
-    furi_assert(context);
-    itoa(autofire_delay, autofire_delay_str, 10);
-    uint16ToHexString(hidConsumerArray[i].value, hexString);
-
-    canvas_clear(canvas);
-
-    canvas_set_font(canvas, FontPrimary);
-    canvas_draw_str(canvas, 0, 10, is_running ? "Running" : "Not running");
-
-    canvas_set_font(canvas, FontSecondary);
-    canvas_draw_str(canvas, 0, 24, "Delay [ms]: ");
-    canvas_draw_str(canvas, 50, 24, autofire_delay_str);
-
-    canvas_draw_str(canvas, 0, 38, "Current key subset:");
-    canvas_draw_str(canvas, 0, 46, getConsumerSubsetName(i));
-
-    canvas_draw_str(canvas, 0, 56, is_running ? "Sent:                HID_CONSUMER_" : "Next:                HID_CONSUMER_");
-    canvas_draw_str(canvas, 24, 56, hexString);
-    canvas_draw_str(canvas, 0, 64, hidConsumerArray[i].name);
-
-    if(is_running) {
-        uint16_t consumer_key = hidConsumerArray[i].value;
-        // Sending the consumer control button
-        furi_delay_us(autofire_delay * 500);
-        furi_hal_hid_consumer_key_press(consumer_key);
-        furi_delay_us(2000); // Hold the key pressed for a short amount of time
-        
-        // Stop sending the consumer control button
-        furi_hal_hid_consumer_key_release(consumer_key);
-        furi_delay_us(autofire_delay * 500);
-
-        // Cycle onto next consumer control button
-        i += 1;
-
-        // Stop once we've cycled all consumer control buttons
-        if(i == hidConsumerArraySize){
-            i = 0; 
-            is_running = false;
-        }
-    }
-}
-
-// This function is the controller
-static void usb_ccb_start_process(UsbCcbStart* usb_ccb_start, InputEvent* event) {
-    with_view_model(
-        usb_ccb_start->view,
-        UsbCcbStartModel * model,
-        {
-            if (event->type == InputTypeLong) {
-                if (event->key == InputKeyRight) {
-                    model->right_pressed = true;
-                    currentSubsetIndex = (currentSubsetIndex + 1) % hidConsumerSubsetsSize;
-                    i = hidConsumerSubsets[currentSubsetIndex];
-                } else if (event->key == InputKeyLeft) {
-                    model->left_pressed = true;
-                    currentSubsetIndex = (currentSubsetIndex - 1 + hidConsumerSubsetsSize) % hidConsumerSubsetsSize;
-                    i = hidConsumerSubsets[currentSubsetIndex];
-                }
-            } else if(event->type == InputTypePress) {
-                if(event->key == InputKeyRight) {
-                    model->right_pressed = true;
-                    i = (i + 1) % hidConsumerArraySize;
-                } else if(event->key == InputKeyLeft) {
-                    model->left_pressed = true;
-                    i = (i - 1 + hidConsumerArraySize) % hidConsumerArraySize;
-                } else if(event->key == InputKeyDown) {
-                    model->down_pressed = true;
-                    if(autofire_delay > 0) {
-                            autofire_delay -= 100;
-                    }
-                } else if(event->key == InputKeyUp) {
-                    model->up_pressed = true;
-                    autofire_delay += 100;
-                } else if(event->key == InputKeyOk) {
-                    model->ok_pressed = true;
-                    is_running = !is_running;
-                } else if(event->key == InputKeyBack) {
-                    model->back_pressed = true;
-                }
-            } else if(event->type == InputTypeRelease) {
-                if(event->key == InputKeyUp) {
-                    model->up_pressed = false;
-                } else if(event->key == InputKeyDown) {
-                    model->down_pressed = false;
-                } else if(event->key == InputKeyLeft) {
-                    model->left_pressed = false;
-                } else if(event->key == InputKeyRight) {
-                    model->right_pressed = false;
-                } else if(event->key == InputKeyOk) {
-                    model->ok_pressed = false;
-                } else if(event->key == InputKeyBack) {
-                    model->back_pressed = false;
-                }
-            } else if(event->type == InputTypeShort) {
-                if(event->key == InputKeyBack) {
-                }
-            }
-            
-        },
-        true);
-}
-
-static bool usb_ccb_start_input_callback(InputEvent* event, void* context) {
-    furi_assert(context);
-    UsbCcbStart* usb_ccb_start = context;
-    bool consumed = false;
-
-    if(event->type == InputTypeLong && event->key == InputKeyBack) {
-        furi_hal_hid_kb_release_all();
-    } else {
-        usb_ccb_start_process(usb_ccb_start, event);
-        consumed = true;
-    }
-
-    return consumed;
-}
-
-UsbCcbStart* usb_ccb_start_alloc() {
-    UsbCcbStart* usb_ccb_start = malloc(sizeof(UsbCcbStart));
-    usb_ccb_start->view = view_alloc();
-    view_set_context(usb_ccb_start->view, usb_ccb_start);
-    view_allocate_model(usb_ccb_start->view, ViewModelTypeLocking, sizeof(UsbCcbStartModel));
-    view_set_draw_callback(usb_ccb_start->view, usb_ccb_start_draw_callback);
-    view_set_input_callback(usb_ccb_start->view, usb_ccb_start_input_callback);
-
-    return usb_ccb_start;
-}
-
-void usb_ccb_start_free(UsbCcbStart* usb_ccb_start) {
-    furi_assert(usb_ccb_start);
-    view_free(usb_ccb_start->view);
-    free(usb_ccb_start);
-    i = 0;
-}
-
-View* usb_ccb_start_get_view(UsbCcbStart* usb_ccb_start) {
-    furi_assert(usb_ccb_start);
-    return usb_ccb_start->view;
-}
-
-void usb_ccb_start_set_connected_status(UsbCcbStart* usb_ccb_start, bool connected) {
-    furi_assert(usb_ccb_start);
-    with_view_model(usb_ccb_start->view, UsbCcbStartModel * model, { model->connected = connected; }, true);
-}

+ 0 - 13
usb_consumer_control/views/usb_ccb_start.h

@@ -1,13 +0,0 @@
-#pragma once
-
-#include <gui/view.h>
-
-typedef struct UsbCcbStart UsbCcbStart;
-
-UsbCcbStart* usb_ccb_start_alloc();
-
-void usb_ccb_start_free(UsbCcbStart* usb_ccb_start);
-
-View* usb_ccb_start_get_view(UsbCcbStart* usb_ccb_start);
-
-void usb_ccb_start_set_connected_status(UsbCcbStart* usb_ccb_start, bool connected);