From 7898840efb037cae3723f4d44c81823122690f7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20SAILLANT?= Date: Thu, 27 Mar 2025 19:51:27 +0100 Subject: [PATCH] ESP_Bluetooth keyboard ok --- lib/ADB-pour-Framework-Arduino | 2 +- platformio.ini | 16 +- src/hid_keyboard.cpp | 276 ++++++++++++++++++++------------- src/hid_mouse.cpp | 62 ++++++-- src/hid_mouse.h | 2 +- src/main.cpp | 235 +++++++++++++++++++++++++--- 6 files changed, 449 insertions(+), 144 deletions(-) diff --git a/lib/ADB-pour-Framework-Arduino b/lib/ADB-pour-Framework-Arduino index 1b35d9e..d3f1bfa 160000 --- a/lib/ADB-pour-Framework-Arduino +++ b/lib/ADB-pour-Framework-Arduino @@ -1 +1 @@ -Subproject commit 1b35d9ea54fb16d78dac35bbb76974bc1840c6bc +Subproject commit d3f1bfa9bab8d96efed44558ae0b5402d039bfd9 diff --git a/platformio.ini b/platformio.ini index 97dde9f..82f0126 100644 --- a/platformio.ini +++ b/platformio.ini @@ -52,10 +52,24 @@ monitor_speed = 115200 lib_deps = ; je voudrais ; electronrare/ADB @ ^1.0.0 + [env:native] platform = native build_flags = -D USBCON -D USBD_USE_HID_COMPOSITE -D PIO_FRAMEWORK_ARDUINO_ENABLE_HID -test_build_src = true \ No newline at end of file +test_build_src = true + +[env:esp32dev] +platform = espressif32 +board = esp32dev +framework = arduino +build_flags = + -D USBCON + -D USBD_USE_HID_COMPOSITE + -D PIO_FRAMEWORK_ARDUINO_ENABLE_HID + -D BLUETOOTH_ENABLED +monitor_speed = 115200 +lib_deps = +; electronrare/ADB @ ^1.0.0 \ No newline at end of file diff --git a/src/hid_keyboard.cpp b/src/hid_keyboard.cpp index c6ce3ab..86d7b50 100644 --- a/src/hid_keyboard.cpp +++ b/src/hid_keyboard.cpp @@ -2,9 +2,10 @@ * @file hid_keyboard.cpp * @brief Implémentation des fonctionnalités HID pour les claviers. * @part of Apple-ADB-Ressurector - * Inspiré et basé sur le travail initial de Szymon Łopaciuk https://github.com/szymonlopaciuk/stm32-adb2usb - * - * + * Inspiré et basé sur le travail initial de Szymon Łopaciuk + * https://github.com/szymonlopaciuk/stm32-adb2usb + * + * * @date 2025 * @author Clément SAILLANT * Dépôt actuel : https://github.com/electron-rare/Apple-ADB-Ressurector @@ -12,17 +13,31 @@ */ #include "hid_keyboard.h" +#ifdef ARDUINO_ARCH_STM32 #include "usbd_hid_composite_if.h" +#endif +#ifdef ARDUINO_ARCH_ESP32 +#include // Ajout de l'inclusion manquante pour BLECharacteristic +extern bool isBleConnected; // Déclaration externe pour isBleConnected +extern BLECharacteristic* input_keyboard; // Déclaration externe pour input_keyboard +#endif #include /** * @brief Initialise le clavier HID. */ void hid_keyboard_init() { -#ifdef PIO_FRAMEWORK_ARDUINO_ENABLE_HID - Serial.println("Initialisation du clavier HID..."); - HID_Composite_Init(HID_KEYBOARD); - Serial.println("Clavier HID initialisé."); +#ifdef ARDUINO_ARCH_STM32 + Serial.println("Initialisation du clavier HID USB..."); + HID_Composite_Init(HID_KEYBOARD); + Serial.println("Clavier HID USB initialisé."); +#endif + +#ifdef ARDUINO_ARCH_ESP32 + Serial.println("Initialisation du clavier HID Bluetooth..."); + // L'initialisation Bluetooth HID est déjà gérée dans `setupBluetoothHID` dans + // main.cpp + Serial.println("Clavier HID Bluetooth initialisé."); #endif } @@ -30,176 +45,217 @@ void hid_keyboard_init() { * @brief Ferme le clavier HID. */ void hid_keyboard_close() { -#ifdef PIO_FRAMEWORK_ARDUINO_ENABLE_HID - Serial.println("Fermeture du clavier HID..."); - HID_Composite_DeInit(HID_KEYBOARD); - Serial.println("Clavier HID fermé."); +#ifdef ARDUINO_ARCH_STM32 + Serial.println("Fermeture du clavier HID USB..."); + HID_Composite_DeInit(HID_KEYBOARD); + Serial.println("Clavier HID USB fermé."); +#endif +#ifdef ARDUINO_ARCH_ESP32 + Serial.println("Fermeture du clavier HID Bluetooth..."); + // Aucune action spécifique nécessaire pour ESP32, car Bluetooth HID est géré + // globalement. + Serial.println("Clavier HID Bluetooth fermé."); #endif } /** * @brief Envoie un rapport HID pour le clavier. - * + * * @param report Pointeur vers le rapport HID à envoyer. */ -void hid_keyboard_send_report(hid_key_report* report) { - uint8_t buf[8] = {report->modifiers, 0, report->keys[0], - report->keys[1], report->keys[2], report->keys[3], - report->keys[4], report->keys[5]}; +void hid_keyboard_send_report(hid_key_report *report) { + uint8_t buf[8] = {report->modifiers, 0, + report->keys[0], report->keys[1], + report->keys[2], report->keys[3], + report->keys[4], report->keys[5]}; - Serial.print("Envoi du rapport HID clavier - Modificateurs: "); - Serial.print(report->modifiers, HEX); - Serial.print(", Touches: "); - for (int i = 0; i < KEY_REPORT_KEYS_COUNT; i++) { - Serial.print(report->keys[i], HEX); - if (i < KEY_REPORT_KEYS_COUNT - 1) Serial.print(", "); - } - Serial.println(); + Serial.print("Envoi du rapport HID clavier - Modificateurs: "); + Serial.print(report->modifiers, HEX); + Serial.print(", Touches: "); + for (int i = 0; i < KEY_REPORT_KEYS_COUNT; i++) { + Serial.print(report->keys[i], HEX); + if (i < KEY_REPORT_KEYS_COUNT - 1) + Serial.print(", "); + } + Serial.println(); -#ifdef PIO_FRAMEWORK_ARDUINO_ENABLE_HID - HID_Composite_keyboard_sendReport(buf, 8); +#ifdef ARDUINO_ARCH_STM32 + HID_Composite_keyboard_sendReport(buf, 8); +#endif + +#ifdef ARDUINO_ARCH_ESP32 + if (isBleConnected) { + input_keyboard->setValue(buf, sizeof(buf)); + input_keyboard->notify(); + } #endif } /** * @brief Met à jour les touches du rapport HID à partir d'un registre ADB. - * + * * @param report Pointeur vers le rapport HID. * @param key_press Données du registre ADB. * @return true si le rapport a été modifié, false sinon. */ -bool hid_keyboard_set_keys_from_adb_register(hid_key_report* report, adb_data key_press) { - Serial.print("Mise à jour des touches HID depuis le registre ADB - Raw: "); - Serial.println(key_press.raw, HEX); +bool hid_keyboard_set_keys_from_adb_register( + hid_key_report *report, adb_data key_press) { + Serial.print("Mise à jour des touches HID depuis le registre ADB - Raw: "); + Serial.println(key_press.raw, HEX); - if (key_press.raw == ADBKey::KeyCode::POWER_DOWN) - return hid_keyboard_update_key_in_report(report, KEY_POWER, false); - else if (key_press.raw == ADBKey::KeyCode::POWER_UP) - return hid_keyboard_update_key_in_report(report, KEY_POWER, true); + if (key_press.raw == ADBKey::KeyCode::POWER_DOWN) + return hid_keyboard_update_key_in_report(report, ADB_KEY_POWER, false); + else if (key_press.raw == ADBKey::KeyCode::POWER_UP) + return hid_keyboard_update_key_in_report(report, ADB_KEY_POWER, true); - bool report_changed = false; + bool report_changed = false; - uint8_t key0 = key_press.data.key0; - if (ADBKeymap::isModifier(key0)) - report_changed = hid_keyboard_update_modifier_in_report(report, key0, key_press.data.released0); - else - report_changed = hid_keyboard_update_key_in_report(report, ADBKeymap::toHID(key0), key_press.data.released0); + uint8_t key0 = key_press.data.key0; + if (ADBKeymap::isModifier(key0)) + report_changed = hid_keyboard_update_modifier_in_report( + report, key0, key_press.data.released0); + else + report_changed = hid_keyboard_update_key_in_report( + report, ADBKeymap::toHID(key0), key_press.data.released0); - uint8_t key1 = key_press.data.key1; - if (ADBKeymap::isModifier(key1)) - report_changed = hid_keyboard_update_modifier_in_report(report, key1, key_press.data.released1) || report_changed; - else - report_changed = hid_keyboard_update_key_in_report(report, ADBKeymap::toHID(key1), key_press.data.released1) || report_changed; + uint8_t key1 = key_press.data.key1; + if (ADBKeymap::isModifier(key1)) + report_changed = hid_keyboard_update_modifier_in_report( + report, key1, key_press.data.released1) || + report_changed; + else + report_changed = + hid_keyboard_update_key_in_report(report, ADBKeymap::toHID(key1), + key_press.data.released1) || + report_changed; - return report_changed; + return report_changed; } /** * @brief Met à jour une touche spécifique dans le rapport HID. - * + * * @param report Pointeur vers le rapport HID. * @param hid_keycode Code HID de la touche. * @param released Indique si la touche est relâchée. * @return true si le rapport a été modifié, false sinon. */ -bool hid_keyboard_update_key_in_report(hid_key_report* report, uint8_t hid_keycode, bool released) { - Serial.print("Mise à jour d'une touche HID - Code: "); - Serial.print(hid_keycode, HEX); - Serial.print(", Relâché: "); - Serial.println(released); +bool hid_keyboard_update_key_in_report(hid_key_report *report, + uint8_t hid_keycode, bool released) { + Serial.print("Mise à jour d'une touche HID - Code: "); + Serial.print(hid_keycode, HEX); + Serial.print(", Relâché: "); + Serial.println(released); - if (hid_keycode == KEY_NONE) return false; + if (hid_keycode == ADB_KEY_NONE) + return false; - if (released) - return hid_keyboard_remove_key_from_report(report, hid_keycode); - else - return hid_keyboard_add_key_to_report(report, hid_keycode); + if (released) + return hid_keyboard_remove_key_from_report(report, hid_keycode); + else + return hid_keyboard_add_key_to_report(report, hid_keycode); } /** * @brief Ajoute une touche au rapport HID. - * + * * @param report Pointeur vers le rapport HID. * @param hid_keycode Code HID de la touche. * @return true si la touche a été ajoutée, false sinon. */ -bool hid_keyboard_add_key_to_report(hid_key_report* report, uint8_t hid_keycode) { - Serial.print("Ajout d'une touche HID - Code: "); - Serial.println(hid_keycode, HEX); +bool hid_keyboard_add_key_to_report(hid_key_report *report, + uint8_t hid_keycode) { + Serial.print("Ajout d'une touche HID - Code: "); + Serial.println(hid_keycode, HEX); - int8_t free_slot = -1; + int8_t free_slot = -1; - for (uint8_t i = 0; i < KEY_REPORT_KEYS_COUNT; i++) { - if (report->keys[i] == hid_keycode) - return true; + for (uint8_t i = 0; i < KEY_REPORT_KEYS_COUNT; i++) { + if (report->keys[i] == hid_keycode) + return true; - if (report->keys[i] == 0 && free_slot == -1) - free_slot = i; - } + if (report->keys[i] == 0 && free_slot == -1) + free_slot = i; + } - if (free_slot == -1) - return false; + if (free_slot == -1) + return false; - report->keys[free_slot] = hid_keycode; - return true; + report->keys[free_slot] = hid_keycode; + return true; } /** * @brief Supprime une touche du rapport HID. - * + * * @param report Pointeur vers le rapport HID. * @param hid_keycode Code HID de la touche. * @return true si la touche a été supprimée, false sinon. */ -bool hid_keyboard_remove_key_from_report(hid_key_report* report, uint8_t hid_keycode) { - Serial.print("Suppression d'une touche HID - Code: "); - Serial.println(hid_keycode, HEX); +bool hid_keyboard_remove_key_from_report(hid_key_report *report, + uint8_t hid_keycode) { + Serial.print("Suppression d'une touche HID - Code: "); + Serial.println(hid_keycode, HEX); - bool report_changed = false; - for (uint8_t i = 0; i < KEY_REPORT_KEYS_COUNT; i++) { - if (report->keys[i] == hid_keycode) { - report->keys[i] = 0; - report_changed = true; - } + bool report_changed = false; + for (uint8_t i = 0; i < KEY_REPORT_KEYS_COUNT; i++) { + if (report->keys[i] == hid_keycode) { + report->keys[i] = 0; + report_changed = true; } - return report_changed; + } + return report_changed; } /** * @brief Met à jour les modificateurs dans le rapport HID. - * + * * @param report Pointeur vers le rapport HID. * @param modifier Code du modificateur (ex. Shift, Ctrl). - * @param pressed Indique si le modificateur est pressé (true) ou relâché (false). + * @param pressed Indique si le modificateur est pressé (true) ou relâché + * (false). * @return true si le rapport a été modifié, false sinon. */ -bool hid_keyboard_update_modifier_in_report(hid_key_report* report, uint8_t adb_keycode, bool released) { - Serial.print("Mise à jour d'un modificateur HID - ADB Keycode: "); - Serial.print(adb_keycode, HEX); - Serial.print(", Relâché: "); - Serial.println(released); +bool hid_keyboard_update_modifier_in_report(hid_key_report *report, + uint8_t adb_keycode, + bool released) { + Serial.print("Mise à jour d'un modificateur HID - ADB Keycode: "); + Serial.print(adb_keycode, HEX); + Serial.print(", Relâché: "); + Serial.println(released); - auto update_modifier = [released, report](uint8_t mask) { - // Vérifie si le modificateur est déjà dans l'état souhaité - if (released == !(report->modifiers & mask)) return false; + auto update_modifier = [released, report](uint8_t mask) { + // Vérifie si le modificateur est déjà dans l'état souhaité + if (released == !(report->modifiers & mask)) + return false; - // Met à jour le modificateur - if (!released) report->modifiers |= mask; // Active le modificateur - else report->modifiers &= ~mask; // Désactive le modificateur + // Met à jour le modificateur + if (!released) + report->modifiers |= mask; // Active le modificateur + else + report->modifiers &= ~mask; // Désactive le modificateur - return true; - }; + return true; + }; - // Correspondance des codes ADB avec les modificateurs HID - if (adb_keycode == ADBKey::KeyCode::LEFT_SHIFT) return update_modifier(KEY_MOD_LSHIFT); - if (adb_keycode == ADBKey::KeyCode::RIGHT_SHIFT) return update_modifier(KEY_MOD_RSHIFT); - if (adb_keycode == ADBKey::KeyCode::LEFT_CONTROL) return update_modifier(KEY_MOD_LCTRL); - if (adb_keycode == ADBKey::KeyCode::RIGHT_CONTROL) return update_modifier(KEY_MOD_RCTRL); - if (adb_keycode == ADBKey::KeyCode::LEFT_OPTION) return update_modifier(KEY_MOD_LALT); - if (adb_keycode == ADBKey::KeyCode::RIGHT_OPTION) return update_modifier(KEY_MOD_RALT); - if (adb_keycode == ADBKey::KeyCode::LEFT_COMMAND) return update_modifier(KEY_MOD_LMETA); - if (adb_keycode == ADBKey::KeyCode::RIGHT_COMMAND) return update_modifier(KEY_MOD_RMETA); + // Correspondance des codes ADB avec les modificateurs HID + if (adb_keycode == ADBKey::KeyCode::LEFT_SHIFT) + return update_modifier(KEY_MOD_LSHIFT); + if (adb_keycode == ADBKey::KeyCode::RIGHT_SHIFT) + return update_modifier(KEY_MOD_RSHIFT); + if (adb_keycode == ADBKey::KeyCode::LEFT_CONTROL) + return update_modifier(KEY_MOD_LCTRL); + if (adb_keycode == ADBKey::KeyCode::RIGHT_CONTROL) + return update_modifier(KEY_MOD_RCTRL); + if (adb_keycode == ADBKey::KeyCode::LEFT_OPTION) + return update_modifier(KEY_MOD_LALT); + if (adb_keycode == ADBKey::KeyCode::RIGHT_OPTION) + return update_modifier(KEY_MOD_RALT); + if (adb_keycode == ADBKey::KeyCode::LEFT_COMMAND) + return update_modifier(KEY_MOD_LMETA); + if (adb_keycode == ADBKey::KeyCode::RIGHT_COMMAND) + return update_modifier(KEY_MOD_RMETA); - Serial.println("Modificateur inconnu."); - return false; // Aucun changement -} + Serial.println("Modificateur inconnu."); + return false; // Aucun changement +} \ No newline at end of file diff --git a/src/hid_mouse.cpp b/src/hid_mouse.cpp index d7008d9..8ec82ab 100644 --- a/src/hid_mouse.cpp +++ b/src/hid_mouse.cpp @@ -12,17 +12,34 @@ */ #include "hid_mouse.h" + +#ifdef ARDUINO_ARCH_STM32 #include "usbd_hid_composite_if.h" +#endif + #include +#ifdef ARDUINO_ARCH_ESP32 +#include // Ajout de l'inclusion manquante pour BLECharacteristic +#include "ADBKeymap.h" // Assurez-vous que la conversion ADB vers HID est incluse +extern BLECharacteristic* input_mouse; // Déclaration externe pour input_mouse +extern bool isBleConnected; // Déclaration externe pour isBleConnected +#endif + /** * @brief Initialise la souris HID. */ void hid_mouse_init() { -#ifdef PIO_FRAMEWORK_ARDUINO_ENABLE_HID - Serial.println("Initialisation de la souris HID..."); +#ifdef ARDUINO_ARCH_STM32 + Serial.println("Initialisation de la souris HID USB..."); HID_Composite_Init(HID_MOUSE); - Serial.println("Souris HID initialisée."); + Serial.println("Souris HID USB initialisée."); +#endif + +#ifdef ARDUINO_ARCH_ESP32 + Serial.println("Initialisation de la souris HID Bluetooth..."); + // L'initialisation Bluetooth HID est déjà gérée dans `setupBluetoothHID` dans main.cpp + Serial.println("Souris HID Bluetooth initialisée."); #endif } @@ -30,10 +47,16 @@ void hid_mouse_init() { * @brief Ferme la souris HID. */ void hid_mouse_close() { -#ifdef PIO_FRAMEWORK_ARDUINO_ENABLE_HID - Serial.println("Fermeture de la souris HID..."); +#ifdef ARDUINO_ARCH_STM32 + Serial.println("Fermeture de la souris HID USB..."); HID_Composite_DeInit(HID_MOUSE); - Serial.println("Souris HID fermée."); + Serial.println("Souris HID USB fermée."); +#endif + +#ifdef ARDUINO_ARCH_ESP32 + Serial.println("Fermeture de la souris HID Bluetooth..."); + // Aucune action spécifique nécessaire pour ESP32, car Bluetooth HID est géré globalement. + Serial.println("Souris HID Bluetooth fermée."); #endif } @@ -46,10 +69,10 @@ void hid_mouse_close() { */ void hid_mouse_send_report(bool button, int8_t offset_x, int8_t offset_y) { uint8_t m[4]; - m[0] = button; - m[1] = offset_x; - m[2] = offset_y; - m[3] = 0; + m[0] = button; // Bouton de la souris (0 = relâché, 1 = appuyé) + m[1] = offset_x; // Déplacement horizontal + m[2] = offset_y; // Déplacement vertical + m[3] = 0; // Réservé Serial.print("Envoi du rapport HID souris - Bouton: "); Serial.print(button); @@ -58,7 +81,24 @@ void hid_mouse_send_report(bool button, int8_t offset_x, int8_t offset_y) { Serial.print(", Y: "); Serial.println(offset_y); -#ifdef PIO_FRAMEWORK_ARDUINO_ENABLE_HID +#ifdef ARDUINO_ARCH_STM32 HID_Composite_mouse_sendReport(m, 4); #endif + +#ifdef ARDUINO_ARCH_ESP32 + if (isBleConnected) { + // Traduction des données ADB en HID Bluetooth + uint8_t bt_report[4] = {m[0], m[1], m[2], m[3]}; + + // Envoi du rapport via Bluetooth + input_mouse->setValue(bt_report, sizeof(bt_report)); + input_mouse->notify(); + + // Libération des boutons entre deux actions pour éviter les répétitions + delay(5); + bt_report[0] = 0; // Aucun bouton appuyé + input_mouse->setValue(bt_report, sizeof(bt_report)); + input_mouse->notify(); + } +#endif } \ No newline at end of file diff --git a/src/hid_mouse.h b/src/hid_mouse.h index 7b1451d..42240a1 100644 --- a/src/hid_mouse.h +++ b/src/hid_mouse.h @@ -3,7 +3,7 @@ * @brief Gestion des fonctionnalités HID pour les souris. * @part of Apple-ADB-Ressurector * Inspiré et basé sur le travail initial de Szymon Łopaciuk https://github.com/szymonlopaciuk/stm32-adb2usb - * + * AaaaAaAa * * @date 2025 * @author Clément SAILLANT diff --git a/src/main.cpp b/src/main.cpp index 0dec9f5..91ce9e3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,6 +17,21 @@ #include "hid_mouse.h" #define POLL_DELAY 5 +// Définition de la pin ADB selon la plateforme +#ifdef ARDUINO_ARCH_ESP32 +#define ADB_PIN 2 +#endif +#ifdef ARDUINO_ARCH_STM32 +#define ADB_PIN PB4 +#endif + +// Définition de la pin LED selon la plateforme +#ifdef ARDUINO_ARCH_ESP32 +#define LED_PIN 4 // Pin pour ESP32 (Devkit Wemos) +#endif +#ifdef ARDUINO_ARCH_STM32 +#define LED_PIN PC13 // Pin pour STM32 +#endif /** * @struct DeviceState @@ -26,14 +41,170 @@ struct DeviceState { bool apple_extended_detected = false; /**< Détection du clavier Apple étendu. */ bool keyboard_present = false; /**< Présence d'un clavier. */ bool mouse_present = false; /**< Présence d'une souris. */ - bool led_caps = false; /**< État de la LED Caps Lock. */ bool led_num = true; /**< État de la LED Num Lock (actif par défaut). */ + bool led_caps = false; /**< État de la LED Caps Lock. */ + bool led_scroll = false; /**< État de la LED Scroll Lock. */ + bool led_power = false; /**< État de la LED Power. */ }; // Instances globales -ADB adb(PB4); /**< Instance du bus ADB. */ +ADB adb(ADB_PIN); /**< Instance du bus ADB. */ ADBDevices adbDevices(adb); /**< Gestionnaire des périphériques ADB. */ DeviceState deviceState; /**< État des périphériques. */ +static bool caps_lock_mechanical_state = false; /**< État mécanique de la touche Caps Lock. */ + +#ifdef ARDUINO_ARCH_ESP32 +#include +#include +#include +#include + +// Déclaration de la structure InputReport +struct InputReport { + uint8_t modifiers; // bitmask: CTRL = 1, SHIFT = 2, ALT = 4 + uint8_t reserved; // doit être 0 + uint8_t pressedKeys[6]; // jusqu'à six touches pressées simultanément +}; + +// The report map describes the HID device (a keyboard in this case) and +// the messages (reports in HID terms) sent and received. +static const uint8_t REPORT_MAP[] = { + USAGE_PAGE(1), 0x01, // Generic Desktop Controls + USAGE(1), 0x06, // Keyboard + COLLECTION(1), 0x01, // Application + REPORT_ID(1), 0x01, // Report ID (1) + USAGE_PAGE(1), 0x07, // Keyboard/Keypad + USAGE_MINIMUM(1), 0xE0, // Keyboard Left Control + USAGE_MAXIMUM(1), 0xE7, // Keyboard Right Control + LOGICAL_MINIMUM(1), 0x00, // Each bit is either 0 or 1 + LOGICAL_MAXIMUM(1), 0x01, + REPORT_COUNT(1), 0x08, // 8 bits for the modifier keys + REPORT_SIZE(1), 0x01, + HIDINPUT(1), 0x02, // Data, Var, Abs + REPORT_COUNT(1), 0x01, // 1 byte (unused) + REPORT_SIZE(1), 0x08, + HIDINPUT(1), 0x01, // Const, Array, Abs + REPORT_COUNT(1), 0x06, // 6 bytes (for up to 6 concurrently pressed keys) + REPORT_SIZE(1), 0x08, + LOGICAL_MINIMUM(1), 0x00, + LOGICAL_MAXIMUM(1), 0x65, // 101 keys + USAGE_MINIMUM(1), 0x00, + USAGE_MAXIMUM(1), 0x65, + HIDINPUT(1), 0x00, // Data, Array, Abs + REPORT_COUNT(1), 0x05, // 5 bits (Num lock, Caps lock, Scroll lock, Compose, Kana) + REPORT_SIZE(1), 0x01, + USAGE_PAGE(1), 0x08, // LEDs + USAGE_MINIMUM(1), 0x01, // Num Lock + USAGE_MAXIMUM(1), 0x05, // Kana + LOGICAL_MINIMUM(1), 0x00, + LOGICAL_MAXIMUM(1), 0x01, + HIDOUTPUT(1), 0x02, // Data, Var, Abs + REPORT_COUNT(1), 0x01, // 3 bits (Padding) + REPORT_SIZE(1), 0x03, + HIDOUTPUT(1), 0x01, // Const, Array, Abs + END_COLLECTION(0) // End application collection +}; + +// Déclarations HID Bluetooth +BLEHIDDevice* hid; +BLECharacteristic* input_keyboard; +BLECharacteristic* input_mouse; +BLECharacteristic* output_keyboard; +bool isBleConnected = false; + +const InputReport NO_KEY_PRESSED = { }; + +// Callbacks pour la connexion BLE +class BleHIDCallbacks : public BLEServerCallbacks { + void onConnect(BLEServer* server) { + isBleConnected = true; + + BLE2902* cccDescKeyboard = (BLE2902*)input_keyboard->getDescriptorByUUID(BLEUUID((uint16_t)0x2902)); + cccDescKeyboard->setNotifications(true); + + BLE2902* cccDescMouse = (BLE2902*)input_mouse->getDescriptorByUUID(BLEUUID((uint16_t)0x2902)); + cccDescMouse->setNotifications(true); + + Serial.println("Client connecté au clavier et souris HID Bluetooth."); + } + + void onDisconnect(BLEServer* server) { + isBleConnected = false; + + BLE2902* cccDescKeyboard = (BLE2902*)input_keyboard->getDescriptorByUUID(BLEUUID((uint16_t)0x2902)); + cccDescKeyboard->setNotifications(false); + + BLE2902* cccDescMouse = (BLE2902*)input_mouse->getDescriptorByUUID(BLEUUID((uint16_t)0x2902)); + cccDescMouse->setNotifications(false); + + Serial.println("Client déconnecté du clavier et souris HID Bluetooth."); + } +}; + +// Callbacks pour les LEDs (Num Lock, Caps Lock, etc.) +class OutputCallbacks : public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic* characteristic) { + uint8_t* data = characteristic->getData(); + Serial.print("LED state (Bluetooth): "); + Serial.println(*data, HEX); + + // Synchronisation des états des LEDs + deviceState.led_num = (*data & 0x01) != 0; // Num Lock + deviceState.led_caps = (*data & 0x02) != 0; // Caps Lock + + // Si la touche Caps Lock du clavier ADB est mécaniquement active, réactivez le verrouillage + if (caps_lock_mechanical_state && !deviceState.led_caps) { + deviceState.led_caps = true; + adbDevices.keyboardWriteLEDs(deviceState.led_num, deviceState.led_caps, deviceState.led_scroll); + Serial.println("Réactivation de Caps Lock en raison de l'état mécanique du clavier ADB."); + } + + // Mise à jour des LEDs sur le clavier ADB + adbDevices.keyboardWriteLEDs(deviceState.led_num, deviceState.led_caps, deviceState.led_scroll); + + Serial.print("LED Num Lock : "); + Serial.println(deviceState.led_num ? "Allumée" : "Éteinte"); + Serial.print("LED Caps Lock : "); + Serial.println(deviceState.led_caps ? "Allumée" : "Éteinte"); + } +}; + +void bluetoothTask(void*) { + BLEDevice::init("ESP32 HID Device"); + BLEServer* server = BLEDevice::createServer(); + server->setCallbacks(new BleHIDCallbacks()); + + hid = new BLEHIDDevice(server); + input_keyboard = hid->inputReport(1); // Report ID 1 pour le clavier + input_mouse = hid->inputReport(2); // Report ID 2 pour la souris + output_keyboard = hid->outputReport(1); // Report ID 1 pour les LEDs clavier + output_keyboard->setCallbacks(new OutputCallbacks()); + + hid->manufacturer()->setValue("Maker Community"); + hid->pnp(0x02, 0xe502, 0xa111, 0x0210); + hid->hidInfo(0x00, 0x02); + + BLESecurity* security = new BLESecurity(); + security->setAuthenticationMode(ESP_LE_AUTH_BOND); + + // Rapport HID pour clavier et souris + hid->reportMap((uint8_t*)REPORT_MAP, sizeof(REPORT_MAP)); + hid->startServices(); + + BLEAdvertising* advertising = server->getAdvertising(); + advertising->setAppearance(HID_KEYBOARD); + advertising->addServiceUUID(hid->hidService()->getUUID()); + advertising->start(); + + Serial.println("Bluetooth HID prêt."); + delay(portMAX_DELAY); +} + +void setupBluetoothTask() { + xTaskCreate(bluetoothTask, "bluetooth", 20000, NULL, 5, NULL); +} + +#endif /** * @brief Initialise un périphérique ADB. @@ -54,18 +225,21 @@ bool initializeDevice(uint8_t addr, uint8_t handler_id) { * @brief Fonction d'initialisation du programme. */ void setup() { - pinMode(PC13, OUTPUT); - digitalWrite(PC13, LOW); + pinMode(LED_PIN, OUTPUT); // Configuration de la pin LED + digitalWrite(LED_PIN, LOW); // État initial de la LED Serial.begin(115200); Serial.println("Initialisation du programme..."); - // Set up HID + #ifdef ARDUINO_ARCH_ESP32 + setupBluetoothTask(); // Lancer la tâche Bluetooth + #endif + hid_keyboard_init(); hid_mouse_init(); - Serial.println("HID initialisé."); - - adb.init(PB4, true); + Serial.println("HID initialisé."); + + adb.init(ADB_PIN, true); Serial.println("Bus ADB initialisé."); delay(1000); @@ -78,9 +252,9 @@ void setup() { Serial.print("Souris détectée : "); Serial.println(deviceState.mouse_present ? "Oui" : "Non"); - digitalWrite(PC13, HIGH); + digitalWrite(LED_PIN, HIGH); // Allumer la LED après l'initialisation - adbDevices.keyboardWriteLEDs(false, deviceState.led_caps, deviceState.led_num); + adbDevices.keyboardWriteLEDs(deviceState.led_num, deviceState.led_caps, deviceState.led_scroll); Serial.println("LEDs initialisées."); } @@ -93,26 +267,39 @@ void handleKeyboard() { auto key_press = adbDevices.keyboardReadKeyPress(&error); if (error) { - // Serial.println("Erreur lors de la lecture des touches du clavier."); + // Serial.println("Erreur lors de la lecture des touches du clavier."); return; } bool report_changed = hid_keyboard_set_keys_from_adb_register(&key_report, key_press); - if ((key_press.data.key0 == ADBKey::KeyCode::CAPS_LOCK && !key_press.data.released0) || - (key_press.data.key1 == ADBKey::KeyCode::CAPS_LOCK && !key_press.data.released1)) { - deviceState.led_caps = !deviceState.led_caps; - adbDevices.keyboardWriteLEDs(false, deviceState.led_caps, deviceState.led_num); - Serial.print("Caps Lock LED : "); - Serial.println(deviceState.led_caps ? "Allumée" : "Éteinte"); - report_changed = true; + // Gestion de Caps Lock + if (key_press.data.key0 == ADBKey::KeyCode::CAPS_LOCK || key_press.data.key1 == ADBKey::KeyCode::CAPS_LOCK) { + if (!key_press.data.released0 || !key_press.data.released1) { + // Si la touche est pressée, activez le verrouillage + if (!deviceState.led_caps) { + deviceState.led_caps = true; + adbDevices.keyboardWriteLEDs(deviceState.led_num, deviceState.led_caps, deviceState.led_scroll); + Serial.println("Caps Lock activé."); + report_changed = true; + } + } else { + // Si la touche est relâchée, désactivez le verrouillage + if (deviceState.led_caps) { + deviceState.led_caps = false; + adbDevices.keyboardWriteLEDs(deviceState.led_num, deviceState.led_caps, deviceState.led_scroll); + Serial.println("Caps Lock désactivé."); + report_changed = true; + } + } } + // Gestion de Num Lock if ((key_press.data.key0 == ADBKey::KeyCode::NUM_LOCK && !key_press.data.released0) || (key_press.data.key1 == ADBKey::KeyCode::NUM_LOCK && !key_press.data.released1)) { deviceState.led_num = !deviceState.led_num; - adbDevices.keyboardWriteLEDs(false, deviceState.led_caps, deviceState.led_num); - Serial.print("Num Lock LED : "); + adbDevices.keyboardWriteLEDs(deviceState.led_num, deviceState.led_caps, deviceState.led_scroll); + Serial.print("Num Lock LED (ADB) : "); Serial.println(deviceState.led_num ? "Allumée" : "Éteinte"); report_changed = true; } @@ -144,6 +331,14 @@ void handleMouse() { Serial.println(mouse_y); hid_mouse_send_report(mouse_data.data.button ? 0 : 1, mouse_x, mouse_y); + + #ifdef ARDUINO_ARCH_ESP32 + if (isBleConnected) { + uint8_t buf[4] = {mouse_data.data.button ? 0 : 1, (uint8_t)mouse_x, (uint8_t)mouse_y, 0}; + input_mouse->setValue(buf, sizeof(buf)); + input_mouse->notify(); + } + #endif } /**