Split keyboard module into hid, keyboard and mouse

This commit is contained in:
Spacehuhn 2022-07-15 23:43:51 +02:00
parent 56367c77e0
commit 78d5595769
10 changed files with 194 additions and 110 deletions

View File

@ -1,12 +1,8 @@
/*
* Note2: If your flash is not formatted as FAT12 previously, you could format it using
* follow sketch https://github.com/adafruit/Adafruit_SPIFlash/tree/master/examples/SdFat_format
*/
#include "config.h" #include "config.h"
#include "debug.h" #include "debug.h"
#include "src/keyboard/keyboard.h" #include "src/hid/hid.h"
#include "src/hid/keyboard.h"
#include "src/led/led.h" #include "src/led/led.h"
#include "src/msc/msc.h" #include "src/msc/msc.h"
#include "src/selector/selector.h" #include "src/selector/selector.h"
@ -14,6 +10,7 @@
#include "src/preferences/preferences.h" #include "src/preferences/preferences.h"
#include "src/duckparser/duckparser.h" #include "src/duckparser/duckparser.h"
#include "src/format/format.h" #include "src/format/format.h"
#include "src/tasks/tasks.h"
enum Mode { enum Mode {
SETUP, ATTACK SETUP, ATTACK
@ -26,6 +23,7 @@ void setup() {
debug_init(); debug_init();
selector::init(); selector::init();
led::init(); led::init();
tasks::setCallback(loop);
// Initialize memory and ceck for problems // Initialize memory and ceck for problems
if (!msc::init()) { if (!msc::init()) {
@ -49,12 +47,12 @@ void setup() {
preferences::load(); preferences::load();
led::setEnable(preferences::ledEnabled()); led::setEnable(preferences::ledEnabled());
keyboard::setLocale(locale::get(preferences::getDefaultLayout().c_str())); keyboard::setLocale(locale::get(preferences::getDefaultLayout().c_str()));
keyboard::setID(preferences::getHidVid(), preferences::getHidPid(), preferences::getHidRev()); hid::setID(preferences::getHidVid(), preferences::getHidPid(), preferences::getHidRev());
msc::setID(preferences::getMscVid().c_str(), preferences::getMscPid().c_str(), preferences::getMscRev().c_str()); msc::setID(preferences::getMscVid().c_str(), preferences::getMscPid().c_str(), preferences::getMscRev().c_str());
duckparser::setDefaultDelay(preferences::getDefaultDelay()); duckparser::setDefaultDelay(preferences::getDefaultDelay());
// Start Keyboard // Start Keyboard
keyboard::init(); hid::init();
// Start USB Drive // Start USB Drive
if (preferences::mscEnabled() || (mode == SETUP)) msc::enableDrive(); if (preferences::mscEnabled() || (mode == SETUP)) msc::enableDrive();
@ -66,7 +64,7 @@ void setup() {
if (preferences::getDisableCapslock()) { if (preferences::getDisableCapslock()) {
keyboard::disableCapslock(); keyboard::disableCapslock();
delay(10); delay(10);
keyboard::indicatorChanged(); hid::indicatorChanged();
} }
// Format Flash // Format Flash
@ -106,7 +104,7 @@ void setup() {
else if (mode == ATTACK) { else if (mode == ATTACK) {
// Run on capslock // Run on capslock
if (preferences::getRunOnIndicator()) { if (preferences::getRunOnIndicator()) {
while (!keyboard::indicatorChanged()) { while (!hid::indicatorChanged()) {
delay(100); delay(100);
} }
keyboard::disableCapslock(); keyboard::disableCapslock();
@ -135,4 +133,6 @@ void setup() {
debugln("[Finished]"); debugln("[Finished]");
} }
void loop() {} void loop() {
led::update();
}

View File

@ -4,7 +4,7 @@
#include "../../config.h" #include "../../config.h"
#include "../../debug.h" #include "../../debug.h"
#include "../keyboard/keyboard.h" #include "../hid/keyboard.h"
#include "../led/led.h" #include "../led/led.h"
#include <Arduino.h> // millis(), delay() #include <Arduino.h> // millis(), delay()

107
src/hid/hid.cpp Normal file
View File

@ -0,0 +1,107 @@
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/usbnova */
#include "hid.h"
#include <Adafruit_TinyUSB.h>
#include <Arduino.h> // delay()
#include "../tasks/tasks.h"
namespace hid {
// ====== PRIVATE ====== //
uint8_t indicator = 0; // Indicator LED state
bool indicator_changed = false; // Whether or not any indicator changed since last time
bool indicator_read = false; // If initial indicator was read
// HID report descriptor using TinyUSB's template
// Single Report (no ID) descriptor
uint8_t const desc_hid_report[] = {
// TUD_HID_REPORT_DESC_KEYBOARD()
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(RID::KEYBOARD)),
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(RID::MOUSE)),
TUD_HID_REPORT_DESC_CONSUMER(HID_REPORT_ID(RID::CONSUMER_CONTROL))
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_KEYBOARD, 2, false);
// Output report callback for LED indicator such as Caplocks
void hid_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
(void)report_id;
(void)bufsize;
// LED indicator is output report with only 1 byte length
if (report_type != HID_REPORT_TYPE_OUTPUT)
return;
// The LED bit map is as follows: (also defined by KEYBOARD_LED_* )
// Kana (4) | Compose (3) | ScrollLock (2) | CapsLock (1) | Numlock (0)
uint8_t tmp = buffer[0];
// Save caps lock state
if (tmp != indicator) {
indicator = tmp;
indicator_changed = true;
}
// Making sure that indicator_changed isn't set to true because of an initial read
if (!indicator_read) {
indicator_read = true;
indicator_changed = false;
}
// turn on LED if capslock is set
// digitalWrite(LED_BUILTIN, ledIndicator & KEYBOARD_LED_CAPSLOCK);
}
// ====== PUBLIC ====== //
void init() {
// Notes: following commented-out functions has no affect on ESP32
// usb_hid.setBootProtocol(HID_ITF_PROTOCOL_KEYBOARD);
// usb_hid.setPollInterval(2);
// usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
// usb_hid.setStringDescriptor("TinyUSB Keyboard");
// Set up output report (on control endpoint) for Capslock indicator
usb_hid.setReportCallback(NULL, hid_report_callback);
usb_hid.begin();
}
void setID(uint16_t vid, uint16_t pid, uint16_t version) {
TinyUSBDevice.setID(vid, pid);
TinyUSBDevice.setDeviceVersion(version);
}
bool mounted() {
return TinyUSBDevice.mounted();
}
void sendKeyboardReport(uint8_t modifier, uint8_t* keys) {
if (TinyUSBDevice.suspended()) {
// Wake up host if we are in suspend mode
// and REMOTE_WAKEUP feature is enabled by host
TinyUSBDevice.remoteWakeup();
}
// Wait until ready to send next report
while (!usb_hid.ready()) {
delay(1);
tasks::update();
}
usb_hid.keyboardReport(RID::KEYBOARD, modifier, keys);
}
uint8_t getIndicator() {
return indicator;
}
bool indicatorChanged() {
bool res = indicator_changed;
indicator_changed = false;
return res;
}
}

23
src/hid/hid.h Normal file
View File

@ -0,0 +1,23 @@
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/usbnova */
#pragma once
#include <cstdint> // uint8_t
namespace hid {
// Report ID
enum RID {
KEYBOARD = 1,
MOUSE = 2,
CONSUMER_CONTROL = 3, // Media, volume etc ..
};
void init();
void setID(uint16_t vid, uint16_t pid, uint16_t version);
bool mounted();
void sendKeyboardReport(uint8_t modifier, uint8_t* keys);
uint8_t getIndicator();
bool indicatorChanged();
}

View File

@ -2,33 +2,14 @@
#include "keyboard.h" #include "keyboard.h"
#include <Adafruit_TinyUSB.h> #include "hid.h"
#include <Arduino.h> // millis(), delay() #include <Arduino.h> // pgm_read_byte
#include "../led/led.h"
namespace keyboard { namespace keyboard {
// ====== PRIVATE ====== // // ====== PRIVATE ====== //
hid_locale_t* locale { locale::get_default() }; hid_locale_t* locale { locale::get_default() };
report_t prev_report = report_t{ KEY_NONE, { KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE } }; report_t prev_report = report_t{ KEY_NONE, { KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE, KEY_NONE } };
uint8_t const report_id = 0;
bool caps_lock = false; // State of capslock
uint8_t indicator = 0; // Indicator LED state
bool indicator_changed = false; // Whether or not any indicator changed since last time
bool indicator_read = false; // If initial indicator was read
// HID report descriptor using TinyUSB's template
// Single Report (no ID) descriptor
uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD()
};
// USB HID object. For ESP32 these values cannot be changed after this declaration
// desc report, desc len, protocol, interval, use out endpoint
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_KEYBOARD, 2, false);
report_t makeReport(uint8_t modifiers = 0, uint8_t key1 = 0, uint8_t key2 = 0, uint8_t key3 = 0, uint8_t key4 = 0, uint8_t key5 = 0, uint8_t key6 = 0); report_t makeReport(uint8_t modifiers = 0, uint8_t key1 = 0, uint8_t key2 = 0, uint8_t key3 = 0, uint8_t key4 = 0, uint8_t key5 = 0, uint8_t key6 = 0);
@ -47,78 +28,14 @@ namespace keyboard {
return k; return k;
} }
// Output report callback for LED indicator such as Caplocks
void hid_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
(void)report_id;
(void)bufsize;
// LED indicator is output report with only 1 byte length
if (report_type != HID_REPORT_TYPE_OUTPUT)
return;
// The LED bit map is as follows: (also defined by KEYBOARD_LED_* )
// Kana (4) | Compose (3) | ScrollLock (2) | CapsLock (1) | Numlock (0)
uint8_t tmp = buffer[0];
// Save caps lock state
if (tmp != indicator) {
indicator = tmp;
caps_lock = indicator & KEYBOARD_LED_CAPSLOCK;
indicator_changed = true;
}
// Making sure that indicator_changed isn't set to true because of an initial read
if (!indicator_read) {
indicator_read = true;
indicator_changed = false;
}
// turn on LED if capslock is set
// digitalWrite(LED_BUILTIN, ledIndicator & KEYBOARD_LED_CAPSLOCK);
}
// ====== PUBLIC ====== // // ====== PUBLIC ====== //
void init() {
// Notes: following commented-out functions has no affect on ESP32
// usb_hid.setBootProtocol(HID_ITF_PROTOCOL_KEYBOARD);
// usb_hid.setPollInterval(2);
// usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report));
// usb_hid.setStringDescriptor("TinyUSB Keyboard");
// Set up output report (on control endpoint) for Capslock indicator
usb_hid.setReportCallback(NULL, hid_report_callback);
usb_hid.begin();
}
void setID(uint16_t vid, uint16_t pid, uint16_t version) {
TinyUSBDevice.setID(vid, pid);
TinyUSBDevice.setDeviceVersion(version);
}
bool mounted() {
return TinyUSBDevice.mounted();
}
void setLocale(hid_locale_t* locale) { void setLocale(hid_locale_t* locale) {
if (locale == nullptr) return; if (locale == nullptr) return;
keyboard::locale = locale; keyboard::locale = locale;
} }
void send(report_t* k) { void send(report_t* k) {
if (TinyUSBDevice.suspended()) { hid::sendKeyboardReport(k->modifiers, k->keys);
// Wake up host if we are in suspend mode
// and REMOTE_WAKEUP feature is enabled by host
TinyUSBDevice.remoteWakeup();
}
// Wait until ready to send next report
while (!usb_hid.ready()) {
delay(1);
led::update();
}
usb_hid.keyboardReport(report_id, k->modifiers, k->keys);
} }
void release() { void release() {
@ -251,16 +168,9 @@ namespace keyboard {
} }
void disableCapslock() { void disableCapslock() {
if (caps_lock) { if (hid::getIndicator() & 2) { /*KEYBOARD_LED_CAPSLOCK*/
pressKey(KEY_CAPSLOCK); pressKey(KEY_CAPSLOCK);
release(); release();
} }
} }
bool indicatorChanged() {
bool res = indicator_changed;
indicator_changed = false;
return res;
}
} }

View File

@ -12,9 +12,6 @@ namespace keyboard {
uint8_t keys[6]; uint8_t keys[6];
} report_t; } report_t;
void init();
void setID(uint16_t vid, uint16_t pid, uint16_t version);
void setLocale(hid_locale_t* locale); void setLocale(hid_locale_t* locale);
void send(report_t* k); void send(report_t* k);

11
src/hid/mouse.cpp Normal file
View File

@ -0,0 +1,11 @@
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/usbnova */
#include "mouse.h"
namespace mouse {
// ====== PRIVATE ====== //
// ====== PUBLIC ====== //
}

7
src/hid/mouse.h Normal file
View File

@ -0,0 +1,7 @@
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/usbnova */
#pragma once
namespace mouse {
}

21
src/tasks/tasks.cpp Normal file
View File

@ -0,0 +1,21 @@
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/usbnova */
#include "tasks.h"
#include <cstddef> // NULL
namespace tasks {
// ====== PRIVATE ====== //
void (*callback)(void) = NULL;
// ====== PUBLIC ====== //
void setCallback(void (*_callback)(void)) {
callback = _callback;
}
void update() {
if (callback != NULL) {
callback();
}
}
}

8
src/tasks/tasks.h Normal file
View File

@ -0,0 +1,8 @@
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/usbnova */
#pragma once
namespace tasks {
void setCallback(void (*callback)(void));
void update();
}