diff --git a/.github/workflows/buil_parallel.yml b/.github/workflows/buil_parallel.yml index 0d63151282..08fb9432b7 100644 --- a/.github/workflows/buil_parallel.yml +++ b/.github/workflows/buil_parallel.yml @@ -17,7 +17,6 @@ jobs: fail-fast: false matrix: board: - - { env: "arduino-nesso-n1", family: "ESP32-C6",} - { env: "m5stack-cardputer", family: "ESP32-S3",} - { env: "m5stack-sticks3", family: "ESP32-S3",} - { env: "m5stack-cplus2", family: "ESP32",} @@ -27,11 +26,9 @@ jobs: - { env: "m5stack-core16mb", family: "ESP32",} - { env: "m5stack-core4mb", family: "ESP32",} - { env: "m5stack-cores3", family: "ESP32-S3",} - - { env: "m5stack-dinmeter", family: "ESP32-S3",} - { env: "esp32-s3-devkitc-1", family: "ESP32-S3",} - { env: "esp32-c5", family: "ESP32-C5",} - { env: "esp32-c5-tft", family: "ESP32-C5",} - - { env: "nm-cyd-c5", family: "ESP32-C5",} - { env: "CYD-2432S028", family: "ESP32",} - { env: "CYD-2USB", family: "ESP32",} - { env: "CYD-2432W328C", family: "ESP32",} @@ -44,7 +41,7 @@ jobs: - { env: "LAUNCHER_CYD-2USB", family: "ESP32",} - { env: "LAUNCHER_CYD-2432W328C", family: "ESP32",} - { env: "LAUNCHER_CYD-3248S035R", family: "ESP32",} - - { env: "LAUNCHER_CYD-3248S035C", family: "ESP32",} + # - { env: "LAUNCHER_CYD-3248S035C", family: "ESP32",} - { env: "lilygo-t-embed-cc1101", family: "ESP32-S3",} - { env: "lilygo-t-embed", family: "ESP32-S3",} - { env: "lilygo-t-deck", family: "ESP32-S3",} @@ -58,8 +55,6 @@ jobs: - { env: "lilygo-t-display-ttgo", family: "ESP32",} - { env: "lilygo-t-hmi", family: "ESP32-S3",} - { env: "lilygo-t-lora-pager", family: "ESP32-S3",} - - { env: "elecrow-24B", family: "ESP32",} - - { env: "elecrow-28B", family: "ESP32",} - { env: "smoochiee-board", family: "ESP32-S3",} - { env: "reaper", family: "ESP32-S3",} - { env: "Phantom_S024R", family: "ESP32",} diff --git a/.gitignore b/.gitignore index 243b5b105e..db25b5ed35 100644 --- a/.gitignore +++ b/.gitignore @@ -19,5 +19,3 @@ docker-logs lib/mquickjs_headers/mqjs_stdlib_generator lib/mquickjs_headers/mqjs_stdlib_generator.exe .github/agents/Bruce-AI.agent.md -.idea -.ai \ No newline at end of file diff --git a/README.md b/README.md index a95a00f5e6..da6d9d7d17 100644 --- a/README.md +++ b/README.md @@ -7,16 +7,12 @@ It also supports M5stack and Lilygo products and works great with Cardputer, Sti **Check our fully open-source hardware too:** https://bruce.computer/boards -**Also Check Our official Shop!! Buy here and support us** https://bruce-devices.myshopify.com/ - ## :building_construction: How to install ### The easiest way to install Bruce is using our official Web Flasher! - ### Check out: https://bruce.computer/flasher Alternatively, you can download the latest binary from releases or actions and flash locally using esptool.py - ```sh esptool.py --port /dev/ttyACM0 write_flash 0x00000 Bruce-.bin ``` @@ -27,14 +23,15 @@ If you already use M5Launcher to manage your m5stack device, you can install it Or you can burn it directly from the [m5burner tool](https://docs.m5stack.com/en/download), just search for 'Bruce' (My official builds will be uploaded by "owner" and have photos.) on the device category you want to and click on burn + ## :keyboard: Discord Server Contact us in our [Discord Server](https://discord.gg/WJ9XF9czVT)! ## :bookmark_tabs: Wiki -For more information on each function supported by Bruce, [read our wiki here](https://wiki.bruce.computer/). -Also, [read our FAQ](https://wiki.bruce.computer/faq/) +For more information on each function supported by Bruce, [read our wiki here](https://github.com/pr3y/Bruce/wiki). +Also, [read our FAQ](https://github.com/pr3y/Bruce/wiki/FAQ) ## :computer: List of Features @@ -44,25 +41,25 @@ Also, [read our FAQ](https://wiki.bruce.computer/faq/) - [x] Connect to WiFi - [x] WiFi AP - [x] Disconnect WiFi -- [x] [WiFi Atks](https://wiki.bruce.computer/features/wifi/#wifi-atks) - - [x] [Beacon Spam](https://wiki.bruce.computer/features/wifi/#beacon-spam) - - [x] [Target Atk](https://wiki.bruce.computer/features/wifi/#target-atks) +- [x] [WiFi Atks](https://github.com/pr3y/Bruce/wiki/WiFi#wifi-atks) + - [x] [Beacon Spam](https://github.com/pr3y/Bruce/wiki/WiFi#beacon-spam) + - [x] [Target Atk](https://github.com/pr3y/Bruce/wiki/WiFi#target-atk) - [x] Information - [x] Target Deauth - [x] EvilPortal + Deauth - [x] Deauth Flood (More than one target) -- [x] [Wardriving](https://wiki.bruce.computer/features/gps/#wardriving) -- [x] [TelNet](https://wiki.bruce.computer/features/wifi/#telnet) -- [x] [SSH](https://wiki.bruce.computer/features/wifi/#ssh) -- [x] [RAW Sniffer](https://wiki.bruce.computer/features/wifi/#raw-sniffer) -- [x] [TCP Client](https://wiki.bruce.computer/features/wifi/#client-tcp) -- [x] [TCP Listener](https://wiki.bruce.computer/features/wifi/#listen-tcp) -- [x] [Evil Portal](https://wiki.bruce.computer/features/wifi/#evil-portal) -- [x] [Scan Hosts](https://wiki.bruce.computer/features/wifi/#scan-hosts) (with TCP Port scanning) -- [x] [Responder](https://wiki.bruce.computer/features/wifi/#responder) -- [x] [Arp Spoofing](https://wiki.bruce.computer/features/wifi/#arp-spoofing) -- [x] [Arp Poisoning](https://wiki.bruce.computer/features/wifi/#arp-poisoning) -- [x] [Wireguard Tunneling](https://wiki.bruce.computer/features/wifi/#wireguard-tunneling) +- [x] [Wardriving](https://github.com/pr3y/Bruce/wiki/Wardriving) +- [x] [TelNet](https://github.com/pr3y/Bruce/wiki/WiFi#telnet) +- [x] [SSH](https://github.com/pr3y/Bruce/wiki/WiFi#ssh) +- [x] [RAW Sniffer](https://github.com/pr3y/Bruce/wiki/WiFi#raw-sniffer) +- [x] [TCP Client](https://github.com/pr3y/Bruce/wiki/WiFi#tcp-client) +- [x] [TCP Listener](https://github.com/pr3y/Bruce/wiki/WiFi#tcp-listener) +- [x] [Evil Portal](https://github.com/pr3y/Bruce/wiki/WiFi#evil-portal) +- [x] [Scan Hosts](https://github.com/pr3y/Bruce/wiki/WiFi#evil-portal) (with TCP Port scanning) +- [x] [Responder](https://github.com/BruceDevices/firmware/wiki/WiFi#responder) +- [x] [Arp Spoofing](https://github.com/BruceDevices/firmware/wiki/WiFi#arp-spoofing) +- [x] [Arp Poisoning](https://github.com/BruceDevices/firmware/wiki/WiFi#arp-poisoning) +- [x] [Wireguard Tunneling](https://github.com/pr3y/Bruce/wiki/WiFi#wireguard-tunneling) - [x] Brucegotchi - [x] Pwnagotchi friend - [x] Pwngrid spam faces & names @@ -74,31 +71,32 @@ Also, [read our FAQ](https://wiki.bruce.computer/faq/)

BLE

-- [x] [BLE Scan](https://wiki.bruce.computer/features/ble/#ble-scan) -- [x] Bad BLE - Run Ducky scripts, similar to [BadUsb](https://wiki.bruce.computer/features/ble/#badble) -- [x] BLE Keyboard - Cardputer and T-Deck Only -- [x] iOS Spam -- [x] Windows Spam -- [x] Samsung Spam -- [x] Android Spam -- [x] Spam All +- [X] [BLE Scan](https://github.com/pr3y/Bruce/wiki/BLE#ble-scan) +- [X] Bad BLE - Run Ducky scripts, similar to [BadUsb](https://github.com/pr3y/Bruce/wiki/Others#badusb) +- [X] BLE Keyboard - Cardputer and T-Deck Only +- [X] iOS Spam +- [X] Windows Spam +- [X] Samsung Spam +- [X] Android Spam +- [X] Spam All
+

RF

- [x] Scan/Copy -- [x] [Custom SubGhz](https://wiki.bruce.computer/features/rf/#replay-payloads-like-flipper) +- [x] [Custom SubGhz](https://github.com/pr3y/Bruce/wiki/RF#replay-payloads-like-flipper) - [x] Spectrum - [x] Jammer Full (sends a full squared wave into output) - [x] Jammer Intermittent (sends PWM signal into output) - [x] Config - - [x] RF TX Pin - - [x] RF RX Pin - - [x] RF Module - - [x] RF433 T/R M5Stack - - [x] [CC1101 (Sub-Ghz)](https://wiki.bruce.computer/features/rf/#cc1101) - - [x] RF Frequency + - [X] RF TX Pin + - [X] RF RX Pin + - [X] RF Module + - [x] RF433 T/R M5Stack + - [x] [CC1101 (Sub-Ghz)](https://github.com/pr3y/Bruce/wiki/CC1101) + - [X] RF Frequency - [x] Replay
@@ -116,9 +114,9 @@ Also, [read our FAQ](https://wiki.bruce.computer/faq/) - [x] Save file - [x] Load file - [x] Config - - [x] [RFID Module](https://wiki.bruce.computer/features/rfid/#supported-modules) - - [x] PN532 - - [x] PN532Killer + - [X] [RFID Module](https://github.com/pr3y/Bruce/wiki/RFID#supported-modules) + - [x] PN532 + - [x] PN532Killer - [ ] Emulate tag @@ -127,76 +125,78 @@ Also, [read our FAQ](https://wiki.bruce.computer/faq/) - [x] TV-B-Gone - [x] IR Receiver -- [x] [Custom IR (NEC, NECext, SIRC, SIRC15, SIRC20, Samsung32, RC5, RC5X, RC6)](https://wiki.bruce.computer/features/ir/#replay-payloads-like-flipper) -- [x] Config - [X] Ir TX Pin - [X] Ir RX Pin +- [x] [Custom IR (NEC, NECext, SIRC, SIRC15, SIRC20, Samsung32, RC5, RC5X, RC6)](https://github.com/pr3y/Bruce/wiki/IR#replay-payloads-like-flipper) +- [x] Config + - [X] Ir TX Pin + - [X] Ir RX Pin

FM

-- [x] [Broadcast standard](https://wiki.bruce.computer/features/fm/#broadcast-standard) -- [x] [Broadcast reserved](https://wiki.bruce.computer/features/fm/#broadcast-standard) -- [x] [Broadcast stop](https://wiki.bruce.computer/features/fm/#broadcast-stop) -- [ ] [FM Spectrum](https://wiki.bruce.computer/features/fm/#fm-spectrum) -- [ ] [Hijack Traffic Announcements](https://wiki.bruce.computer/features/fm/#hijack-ta) -- [ ] [Config](https://wiki.bruce.computer/features/fm/#bookmark_tabs-config) +- [x] [Broadcast standard](https://github.com/pr3y/Bruce/wiki/FM#play_or_pause_button-broadcast-standard) +- [x] [Broadcast reserved](https://github.com/pr3y/Bruce/wiki/FM#no_entry_sign-broadcast-rerserved) +- [x] [Broadcast stop](https://github.com/pr3y/Bruce/wiki/FM#stop_button-broadcast-stop) +- [ ] [FM Spectrum](https://github.com/pr3y/Bruce/wiki/FM#ocean-fm-spectrum) +- [ ] [Hijack Traffic Announcements](https://github.com/pr3y/Bruce/wiki/FM#car-hijack-ta) +- [ ] [Config](https://github.com/pr3y/Bruce/wiki/FM#bookmark_tabs-config)

NRF24

-- [x] [NRF24 Jammer](https://wiki.bruce.computer/features/nrf24/) -- [x] 2.4G Spectrum +- [X] [NRF24 Jammer](https://github.com/pr3y/Bruce/wiki/BLE#nrf24-jammer) +- [X] 2.4G Spectrum - [ ] Mousejack

Scripts

-- [x] [JavaScript Interpreter](https://wiki.bruce.computer/features/js-interpreter/) [Credits to justinknight93](https://github.com/justinknight93/Doolittle) +- [X] [JavaScript Interpreter](https://github.com/pr3y/Bruce/wiki/Interpreter) [Credits to justinknight93](https://github.com/justinknight93/Doolittle)

Others

-- [x] Mic Spectrum -- [x] [QRCodes](https://wiki.bruce.computer/features/others/#qrcodes) - - [x] Custom - - [x] PIX (Brazil bank transfer system) +- [X] Mic Spectrum +- [X] QRCodes + - [x] Custom + - [x] PIX (Brazil bank transfer system) - [x] [SD Card Mngr](https://github.com/pr3y/Bruce/wiki/Others#sd-card-mngr) - - [x] View image (jpg) - - [x] File Info - - [x] [Wigle Upload](https://wiki.bruce.computer/features/gps/#how-to-use-wigle) - - [x] Play Audio - - [x] View File -- [x] LittleFS Mngr -- [x] [WebUI](https://wiki.bruce.computer/controlling-device/webui/) - - [x] Server Structure - - [x] Html - - [x] SDCard Mngr - - [x] Spiffs Mngr + - [x] View image (jpg) + - [x] File Info + - [x] [Wigle Upload](https://github.com/pr3y/Bruce/wiki/Wardriving#how-to-upload) + - [x] Play Audio + - [x] View File +- [x] [LittleFS Mngr](https://github.com/pr3y/Bruce/wiki/Others#littlefs-mngr) +- [x] [WebUI](https://github.com/pr3y/Bruce/wiki/Others#webui) + - [x] Server Structure + - [x] Html + - [x] SDCard Mngr + - [x] Spiffs Mngr - [x] Megalodon -- [x] [BADUsb (New features, LittleFS and SDCard)](https://wiki.bruce.computer/features/others/#badusb) +- [x] [BADUsb (New features, LittleFS and SDCard)](https://github.com/pr3y/Bruce/wiki/Others#badusb) - [x] USB Keyboard - Cardputer and T-Deck Only -- [x] [iButton](https://wiki.bruce.computer/features/others/#ibutton) -- [x] LED Control +- [x] [iButton](https://github.com/pr3y/Bruce/wiki/Others#ibutton) +- [x] [LED Control](https://github.com/pr3y/Bruce/wiki/Others#led-control)

Clock

-- [x] RTC Support -- [x] NTP time adjust -- [x] Manual adjust +- [X] RTC Support +- [X] NTP time adjust +- [X] Manual adjust

Connect (ESPNOW)

-- [x] Send File -- [x] Receive File -- [x] Send Commands -- [x] Receive Commands +- [X] Send File +- [X] Receive File +- [X] Send Commands +- [X] Receive Commands
@@ -205,7 +205,7 @@ Also, [read our FAQ](https://wiki.bruce.computer/faq/) - [x] Brightness - [x] Dim Time - [x] Orientation -- [x] UI Color +- [X] UI Color - [x] Boot Sound on/off - [x] Clock - [x] Sleep @@ -213,30 +213,30 @@ Also, [read our FAQ](https://wiki.bruce.computer/faq/)
## Specific functions per Device, the ones not mentioned here are available to all. +| Device | CC1101 | NRF24 | FM Radio | PN532 | Mic | BadUSB | RGB Led | Speaker | Fuel Guage | LITE_VERSION | +| --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| [M5Stack Cardputer](https://shop.m5stack.com/products/m5stack-cardputer-kit-w-m5stamps) (and ADV) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | NS4168 | :x: | :x: | +| [M5Stack M5StickC PLUS2](https://shop.m5stack.com/products/m5stickc-plus2-esp32-mini-iot-development-kit) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | Tone | :x: | :x: | +| [M5Stack M5StickC PLUS](https://shop.m5stack.com/products/m5stickc-plus-esp32-pico-mini-iot-development-kit) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | Tone | :x: | :x:² | +| [M5Stack M5Core BASIC](https://shop.m5stack.com/products/basic-core-iot-development-kit) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | Tone | :x: | :x: | +| [M5Stack M5Core2](https://shop.m5stack.com/products/m5stack-core2-esp32-iot-development-kit-v1-1) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | :x: | :x: | :x: | +| [M5Stack M5CoreS3](https://shop.m5stack.com/products/m5stack-cores3-esp32s3-lotdevelopment-kit)/[SE](https://shop.m5stack.com/products/m5stack-cores3-se-iot-controller-w-o-battery-bottom) | :ok: | :ok: | :ok: | :ok: | :x: | :ok: | :x: | :x: | :x: | :x: | +| [JCZN CYD‑2432S028](https://www.aliexpress.us/item/3256804774970998.html) | :ok: | :ok: | :ok: | :ok: | :x: | :ok:¹ | :x: | :x: | :x: | :x:² | +| [Lilygo T‑Embed CC1101](https://lilygo.cc/products/t-embed-cc1101) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :x: | +| [Lilygo T‑Embed](https://lilygo.cc/products/t-embed) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :x: | :x: | +| [Lilygo T-Display-S3](https://lilygo.cc/products/t-display-s3) | :ok: | :ok: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | +| [Lilygo T‑Deck](https://lilygo.cc/products/t-deck) ([and pro](https://lilygo.cc/products/t-deck-plus-1)) | :ok: | :x: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | +| [Lilygo T-Watch-S3](https://lilygo.cc/products/t-watch-s3) | :x: | :x: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | +| [Lilygo T-LoRa Pager](https://lilygo.cc/products/t-lora-pager) | :x: | :x: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | +| [Smoochiee V2](https://www.pcbway.com/project/shareproject/Bruce_PCB_Smoochiee_d6a0284b.html) | :ok: | :ok: | :x: | :ok: | :x: | :ok: | :x: | :x: | :x: | :x: | +| [ESP32-C5](https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32c5/esp32-c5-devkitc-1/user_guide.html) | :ok: | :ok: | :x: | :ok: | :x: | :x: | :x: | :x: | :x: | :x: | +| [Bruce RF Reaper](https://www.elecrow.com/bruce-pcb-rf-reaper.html) | :ok: | :ok: | :x: | :x: but w/ ST25R3916 | :x: | :ok: | :ok: | :x: | :ok: | :x: | -| Device | CC1101 | NRF24 | FM Radio | PN532 | Mic | BadUSB | RGB Led | Speaker | Fuel Guage | LITE_VERSION | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----: | :---: | :------: | :------------------: | :--: | :----: | :-----: | :-----: | :--------: | :----------: | -| [M5Stack Cardputer](https://shop.m5stack.com/products/m5stack-cardputer-kit-w-m5stamps) (and ADV) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | NS4168 | :x: | :x: | -| [M5Stack M5StickC PLUS2](https://shop.m5stack.com/products/m5stickc-plus2-esp32-mini-iot-development-kit) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | Tone | :x: | :x: | -| [M5Stack M5StickC PLUS](https://shop.m5stack.com/products/m5stickc-plus-esp32-pico-mini-iot-development-kit) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | Tone | :x: | :x:² | -| [M5Stack M5Core BASIC](https://shop.m5stack.com/products/basic-core-iot-development-kit) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | Tone | :x: | :x: | -| [M5Stack M5Core2](https://shop.m5stack.com/products/m5stack-core2-esp32-iot-development-kit-v1-1) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok:¹ | :x: | :x: | :x: | :x: | -| [M5Stack M5CoreS3](https://shop.m5stack.com/products/m5stack-cores3-esp32s3-lotdevelopment-kit)/[SE](https://shop.m5stack.com/products/m5stack-cores3-se-iot-controller-w-o-battery-bottom) | :ok: | :ok: | :ok: | :ok: | :x: | :ok: | :x: | :x: | :x: | :x: | -| [JCZN CYD‑2432S028](https://www.aliexpress.us/item/3256804774970998.html) | :ok: | :ok: | :ok: | :ok: | :x: | :ok:¹ | :x: | :x: | :x: | :x:² | -| [Lilygo T‑Embed CC1101](https://lilygo.cc/products/t-embed-cc1101) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :x: | -| [Lilygo T‑Embed](https://lilygo.cc/products/t-embed) | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :ok: | :x: | :x: | -| [Lilygo T-Display-S3](https://lilygo.cc/products/t-display-s3) | :ok: | :ok: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | -| [Lilygo T‑Deck](https://lilygo.cc/products/t-deck) ([and pro](https://lilygo.cc/products/t-deck-plus-1)) | :ok: | :x: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | -| [Lilygo T-Watch-S3](https://lilygo.cc/products/t-watch-s3) | :x: | :x: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | -| [Lilygo T-LoRa Pager](https://lilygo.cc/products/t-lora-pager) | :x: | :x: | :x: | :x: | :x: | :ok: | :x: | :x: | :x: | :x: | -| [Smoochiee V2](https://www.pcbway.com/project/shareproject/Bruce_PCB_Smoochiee_d6a0284b.html) | :ok: | :ok: | :x: | :ok: | :x: | :ok: | :x: | :x: | :x: | :x: | -| [ESP32-C5](https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32c5/esp32-c5-devkitc-1/user_guide.html) | :ok: | :ok: | :x: | :ok: | :x: | :x: | :x: | :x: | :x: | :x: | -| [Bruce RF Reaper](https://www.elecrow.com/bruce-pcb-rf-reaper.html) | :ok: | :ok: | :x: | :x: but w/ ST25R3916 | :x: | :ok: | :ok: | :x: | :ok: | :x: | -| [Elecrow 24B](https://www.elecrow.com/2-4inch-esp32-miner-lcd-display-2pcs-cryptocurrency-solo-miner-with-1000kh-s-hashrate.html) | :ok: | :ok: | :x: | :x: but w/ ST25R3916 | :x: | :ok: | :ok: | :x: | :ok: | :x: | ² CYD have a LITE_VERSION version for Launcher Compatibility -¹ Core, CYD and StickCs Bad-USB: [here](https://wiki.bruce.computer/features/others/#badusb) +¹ Core, CYD and StickCs Bad-USB: [here](https://github.com/pr3y/Bruce/wiki/Others#badusb) + +*LITE_VERSION*: TelNet, SSH, WireGuard, ScanHosts, RawSniffer, Brucegotchi, BLEBacon, BLEScan and Interpreter are NOT available for M5Launcher Compatibility -_LITE_VERSION_: TelNet, SSH, WireGuard, ScanHosts, RawSniffer, Brucegotchi, BLEBacon, BLEScan and Interpreter are NOT available for M5Launcher Compatibility ## :sparkles: Why and how does it look? @@ -251,18 +251,19 @@ Other media can be [found here](./media/). ## :clap: Acknowledgements -- [@bmorcelli](https://github.com/bmorcelli) for new core and a bunch of new features, also porting to many devices! -- [@IncursioHack](https://github.com/IncursioHack) for adding RF and RFID modules features. -- [@Luidiblu](https://github.com/Luidiblu) for logo and UI design assistance. -- [@eadmaster](https://github.com/eadmaster) for adding a lot of features. -- [@rennancockles](https://github.com/rennancockles) for a lot of RFID code, refactoring and others features. -- [@7h30th3r0n3](https://github.com/7h30th3r0n3) refactoring and a lot of help with WiFi attacks. -- [@Tawank](https://github.com/Tawank) refactoring interpreter among many other things -- [@pablonymous]() new RF functions to read RAW Data -- [Smoochiee]() for Bruce PCB design. -- [TH3_KR4K3N]() for Stick cplus extender PCB design. -- Everyone who contributed in some way to the project, thanks :heart: ++ [@bmorcelli](https://github.com/bmorcelli) for new core and a bunch of new features, also porting to many devices! ++ [@IncursioHack](https://github.com/IncursioHack) for adding RF and RFID modules features. ++ [@Luidiblu](https://github.com/Luidiblu) for logo and UI design assistance. ++ [@eadmaster](https://github.com/eadmaster) for adding a lot of features. ++ [@rennancockles](https://github.com/rennancockles) for a lot of RFID code, refactoring and others features. ++ [@7h30th3r0n3](https://github.com/7h30th3r0n3) refactoring and a lot of help with WiFi attacks. ++ [@Tawank](https://github.com/Tawank) refactoring interpreter among many other things ++ [@pablonymous]() new RF functions to read RAW Data ++ [Smoochiee]() for Bruce PCB design. ++ [TH3_KR4K3N]() for Stick cplus extender PCB design. ++ Everyone who contributed in some way to the project, thanks :heart: ## :construction: Disclaimer Bruce is a tool for cyber offensive and red team operations, distributed under the terms of the Affero General Public License (AGPL). It is intended for legal and authorized security testing purposes only. Use of this software for any malicious or unauthorized activities is strictly prohibited. By downloading, installing, or using Bruce, you agree to comply with all applicable laws and regulations. This software is provided free of charge, and we do not accept payments for copies or modifications. The developers of Bruce assume no liability for any misuse of the software. Use at your own risk. + diff --git a/boards/_boards_json/m5stack-sticks3.json b/boards/_boards_json/m5stack-sticks3.json index 6d159957c3..0d39c99d7e 100644 --- a/boards/_boards_json/m5stack-sticks3.json +++ b/boards/_boards_json/m5stack-sticks3.json @@ -2,8 +2,7 @@ "build": { "arduino": { "ldscript": "esp32s3_out.ld", - "partitions": "default_8MB.csv", - "memory_type": "qio_opi" + "partitions": "default_8MB.csv" }, "core": "esp32", "extra_flags": [ diff --git a/boards/_boards_json/smoochiee-s3-2.8inch-ili9341.json b/boards/_boards_json/smoochiee-s3-2.8inch-ili9341.json new file mode 100644 index 0000000000..2bcb68adbc --- /dev/null +++ b/boards/_boards_json/smoochiee-s3-2.8inch-ili9341.json @@ -0,0 +1,49 @@ +{ + "build": { + "arduino": { + "ldscript": "esp32s3_out.ld", + "partitions": "default_16MB.csv" + }, + "core": "esp32", + "extra_flags": [ + "-DSMOOCHIEE_S3_2_8INCH_ILI9341", + "-DARDUINO_RUNNING_CORE=1", + "-DARDUINO_EVENT_RUNNING_CORE=1", + "-DARDUINO_USB_CDC_ON_BOOT", + "-DARDUINO_USB_MODE=1", + "-DBOARD_HAS_PSRAM" + ], + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "qio", + "hwids": [ + [ + "0x303A", + "0x1001" + ] + ], + "mcu": "esp32s3", + "variant": "pinouts" + }, + "connectivity": [ + "bluetooth", + "wifi" + ], + "debug": { + "openocd_target": "esp32s3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Smoochiee S3 2.8\" ILI9341", + "upload": { + "flash_size": "16MB", + "maximum_ram_size": 327680, + "maximum_size": 16777216, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://docs.m5stack.com/en/core/StampS3", + "vendor": "Smoochiee" + } diff --git a/boards/lilygo-t-embed-cc1101/interface.cpp b/boards/lilygo-t-embed-cc1101/interface.cpp index 8d41a2bb92..4099fa0b69 100644 --- a/boards/lilygo-t-embed-cc1101/interface.cpp +++ b/boards/lilygo-t-embed-cc1101/interface.cpp @@ -140,7 +140,6 @@ void _setBrightness(uint8_t brightval) { void InputHandler(void) { static unsigned long tm = millis(); // debounce for buttons static unsigned long tm2 = millis(); // delay between Select and encoder (avoid missclick) - static unsigned long lastEncoderMoveMs = 0; static int posDifference = 0; static int lastPos = 0; bool sel = !BTN_ACT; @@ -150,10 +149,6 @@ void InputHandler(void) { if (newPos != lastPos) { posDifference += (newPos - lastPos); lastPos = newPos; - lastEncoderMoveMs = millis(); - } else if (posDifference != 0 && millis() - lastEncoderMoveMs > 30) { - // Drop any stale queued steps once the encoder has stopped moving. - posDifference = 0; } if (millis() - tm > 200 || LongPress) { diff --git a/boards/lilygo-t-lora-pager/interface.cpp b/boards/lilygo-t-lora-pager/interface.cpp index fcbe41171b..2e11c6525a 100644 --- a/boards/lilygo-t-lora-pager/interface.cpp +++ b/boards/lilygo-t-lora-pager/interface.cpp @@ -94,7 +94,7 @@ const KeyValue_t _key_value_map[KB_ROWS][KB_COLS] = { {KEY_SHIFT, KEY_SHIFT, CAPS_LOCK}, {KEY_BACKSPACE, KEY_BACKSPACE, '#'}}, - {{' ', ' ', KEY_TAB}} + {{' ', ' ', ' '}} }; char getKeyChar(uint8_t k) { @@ -303,7 +303,6 @@ void _setBrightness(uint8_t brightval) { **********************************************************************/ void InputHandler(void) { static unsigned long tm = millis(); - static unsigned long lastEncoderMoveMs = 0; static int posDifference = 0; static int lastPos = 0; bool sel = !BTN_ACT; @@ -318,60 +317,39 @@ void InputHandler(void) { if (newPos != lastPos) { posDifference += (newPos - lastPos); lastPos = newPos; - lastEncoderMoveMs = millis(); - } else if (posDifference != 0 && millis() - lastEncoderMoveMs > 30) { - // Drop any stale queued steps once the encoder has stopped moving. - posDifference = 0; } sel = digitalRead(SEL_BTN); esc = digitalRead(BK_BTN); if (keyboard->available() > 0) { - keyStroke pendingKey; - bool keyPulse = false; - bool hapticPulse = false; - - // Drain the full TCA8418 FIFO so quick taps are handled immediately. - while (keyboard->available() > 0) { - int keyValue = keyboard->getEvent(); - bool pressed = keyValue & 0x80; - keyValue &= 0x7F; - keyValue--; - - if (keyValue / 10 >= 4) continue; - if (handleSpecialKeys(keyValue, pressed) > 0) continue; - + int keyValue = keyboard->getEvent(); + bool pressed = keyValue & 0x80; + keyValue &= 0x7F; + keyValue--; + if (keyValue / 10 < 4) { + if (handleSpecialKeys(keyValue, pressed) > 0) goto END; keyVal = getKeyChar(keyValue); - if (!pressed || keyVal == '\0') continue; - if (wakeUpScreen()) continue; - - pendingKey.hid_keys.push_back(keyVal); + } + if (pressed && !wakeUpScreen() && keyVal != '\0') { + KeyStroke.Clear(); + KeyStroke.hid_keys.push_back(keyVal); if (keyVal == KEY_BACKSPACE) { - pendingKey.del = true; + KeyStroke.del = true; EscPress = true; } if (keyVal == KEY_ENTER) { - pendingKey.enter = true; + KeyStroke.enter = true; SelPress = true; } - if (keyVal == KEY_FN) pendingKey.fn = true; - pendingKey.word.push_back(keyVal); - keyPulse = true; - hapticPulse = true; - } + if (keyVal == KEY_FN) KeyStroke.fn = true; + KeyStroke.word.push_back(keyVal); + KeyStroke.pressed = true; - if (keyPulse) { - pendingKey.pressed = true; - KeyStroke = pendingKey; - - if (hapticPulse) { - drv.setWaveform(0, 81); - drv.setWaveform(1, 0); - drv.run(); - } - } else { - KeyStroke.Clear(); + // Haptic feedback + drv.setWaveform(0, 81); + drv.setWaveform(1, 0); + drv.run(); } } else KeyStroke.Clear(); diff --git a/boards/lilygo-t-lora-pager/pins_arduino.h b/boards/lilygo-t-lora-pager/pins_arduino.h index 6442eee968..698e0ed057 100644 --- a/boards/lilygo-t-lora-pager/pins_arduino.h +++ b/boards/lilygo-t-lora-pager/pins_arduino.h @@ -190,7 +190,6 @@ static const uint8_t RX = SERIAL_RX; #define KEY_FN 0x14 #define KEY_BACKSPACE 0x08 #define KEY_ENTER 0x0D -#define KEY_TAB 0x2b // Interrupt IO #define RTC_INT 1 diff --git a/boards/m5stack-cardputer/interface.cpp b/boards/m5stack-cardputer/interface.cpp index 07c734aafc..04ffb64da0 100644 --- a/boards/m5stack-cardputer/interface.cpp +++ b/boards/m5stack-cardputer/interface.cpp @@ -16,9 +16,6 @@ bool fn_key_pressed = false; bool shift_key_pressed = false; bool caps_lock = false; -constexpr unsigned long TCA8418_REPEAT_START_MS = 350; -constexpr unsigned long TCA8418_REPEAT_MS = 150; - int handleSpecialKeys(uint8_t row, uint8_t col, bool pressed); void mapRawKeyToPhysical(uint8_t rawValue, uint8_t &row, uint8_t &col); @@ -88,7 +85,7 @@ void _setup_gpio() { // Set GPIO5 HIGH for SD card compatibility (thx for the tip @bmorcelli & 7h30th3r0n3) digitalWrite(5, HIGH); } -volatile bool kb_interrupt = false; +bool kb_interrupt = false; void IRAM_ATTR gpio_isr_handler(void *arg) { kb_interrupt = true; // static long i = 0; @@ -133,7 +130,7 @@ void _post_setup_gpio() { tca.matrix(7, 8); tca.flush(); pinMode(11, INPUT); - attachInterruptArg(digitalPinToInterrupt(11), gpio_isr_handler, nullptr, CHANGE); + attachInterruptArg(digitalPinToInterrupt(11), gpio_isr_handler, &kb_interrupt, CHANGE); tca.enableInterrupts(); } @@ -157,10 +154,6 @@ void _setBrightness(uint8_t brightval) { **********************************************************************/ void InputHandler(void) { static unsigned long tm = 0; - static unsigned long nextRepeatTime = 0; - static unsigned long prevRepeatTime = 0; - static unsigned long upRepeatTime = 0; - static unsigned long downRepeatTime = 0; static bool sel = false; static bool prev = false; @@ -177,7 +170,7 @@ void InputHandler(void) { bool arrow_dw = false; bool arrow_ry = false; bool arrow_le = false; - if (!UseTCA8418 && millis() - tm < 200 && !LongPress) return; + if (millis() - tm < 200 && !LongPress) return; if (digitalRead(0) == LOW) { // GPIO0 button, shoulder button tm = millis(); @@ -188,201 +181,142 @@ void InputHandler(void) { } if (UseTCA8418) { - bool keyEventHandled = false; - bool nextPulse = false; - bool prevPulse = false; - bool upPulse = false; - bool downPulse = false; - bool delPulse = false; - bool keyPulse = false; - keyStroke key; - - if (kb_interrupt || digitalRead(11) == LOW) { - if (!kb_interrupt && digitalRead(11) == LOW) { + if (!kb_interrupt) { + if (digitalRead(11) == LOW) { detachInterrupt(digitalPinToInterrupt(11)); - attachInterruptArg(digitalPinToInterrupt(11), gpio_isr_handler, nullptr, CHANGE); + attachInterruptArg(digitalPinToInterrupt(11), gpio_isr_handler, &kb_interrupt, CHANGE); Serial.println("Forcing keyboard interrupt, Restoring Interruptions."); kb_interrupt = true; } + if (!LongPress) { + sel = false; // avoid multiple selections + esc = false; // avoid multiple escapes + } + NextPress = next; + PrevPress = prev; + UpPress = up; + DownPress = down; + if (!SelPress) SelPress = sel; + EscPress = esc; + if (del) { + KeyStroke.del = del; + KeyStroke.pressed = true; + } + tm = millis(); + return; + } - while (tca.available() > 0) { - int keyEvent = tca.getEvent(); - bool pressed = (keyEvent & 0x80); // Bit 7: 1 Pressed, 0 Released - uint8_t value = keyEvent & 0x7F; // Bits 0-6: key value - - uint8_t row, col; - mapRawKeyToPhysical(value, row, col); - if (row >= 4 || col >= 14) continue; - if (wakeUpScreen()) continue; - - AnyKeyPress = true; - keyEventHandled = true; - - if (handleSpecialKeys(row, col, pressed) > 0) continue; - - if (!pressed) { KeyStroke.Clear(); } - - char keyVal = getKeyChar(row, col); - - if (keyVal == KEY_BACKSPACE && col == 13) { - del = pressed; - esc = pressed; - if (pressed) delPulse = true; - } else if (keyVal == '`') { - esc = pressed; - } else if (keyVal == KEY_ENTER && col == 13) { - sel = pressed; - } else if (keyVal == ';') { - up = pressed; - arrow_up = pressed; - if (pressed) { - prev = true; - prevPulse = true; - upPulse = true; - prevRepeatTime = millis() + TCA8418_REPEAT_START_MS; - upRepeatTime = millis() + TCA8418_REPEAT_START_MS; - } else { - prev = false; - } - } else if (keyVal == ',') { - prev = pressed; - arrow_le = pressed; - if (pressed) { - prevPulse = true; - prevRepeatTime = millis() + TCA8418_REPEAT_START_MS; - } - } else if (keyVal == '.') { - down = pressed; - arrow_dw = pressed; - if (pressed) { - next = true; - nextPulse = true; - downPulse = true; - nextRepeatTime = millis() + TCA8418_REPEAT_START_MS; - downRepeatTime = millis() + TCA8418_REPEAT_START_MS; - } else { - next = false; - } - } else if (keyVal == '/') { - next = pressed; - arrow_ry = pressed; - if (pressed) { - nextPulse = true; - nextRepeatTime = millis() + TCA8418_REPEAT_START_MS; - } - } else if (keyVal == 0xFF) { - key.fn = pressed; - } else if (keyVal == KEY_LEFT_CTRL) { - ctrl = pressed; - } else if (keyVal == KEY_LEFT_ALT) { - alt = pressed; - } else if (keyVal == KEY_OPT) { - gui = pressed; - } + // try to clear the IRQ flag + // if there are pending events it is not cleared + tca.writeRegister(TCA8418_REG_INT_STAT, 1); + int intstat = tca.readRegister(TCA8418_REG_INT_STAT); + if ((intstat & 0x01) == 0) { kb_interrupt = false; } - if (!pressed) continue; + // if (tca.available() <= 0) return; + int keyEvent = tca.getEvent(); + bool pressed = (keyEvent & 0x80); // Bit 7: 1 Pressed, 0 Released + uint8_t value = keyEvent & 0x7F; // Bits 0-6: key value - if (gui) { - key.gui = true; - key.modifier_keys.emplace_back(KEY_OPT); - key.hid_keys.emplace_back(KEY_OPT); - keyPulse = true; - } - if (alt) { - key.alt = true; - key.modifier_keys.emplace_back(KEY_LEFT_ALT); - key.hid_keys.emplace_back(KEY_LEFT_ALT); - keyPulse = true; - } - if (ctrl) { - key.ctrl = true; - key.modifier_keys.emplace_back(KEY_LEFT_CTRL); - key.hid_keys.emplace_back(KEY_LEFT_CTRL); - keyPulse = true; - } - if (shift_key_pressed) { - key.modifier_keys.emplace_back(KEY_LEFT_SHIFT); - key.hid_keys.emplace_back(KEY_LEFT_SHIFT); - keyPulse = true; - } - if (sel) { - key.enter = true; - key.exit_key = true; - keyPulse = true; - } - if (fn_key_pressed) { - key.fn = true; - keyPulse = true; - } + // Map raw value to physical position + uint8_t row, col; + mapRawKeyToPhysical(value, row, col); - if (keyVal != 0xFF && !sel && !gui && !alt && !ctrl && !del && keyVal != KEY_LEFT_SHIFT) { - if (fn_key_pressed && arrow_up) key.word.emplace_back(0xDA); - else if (fn_key_pressed && arrow_dw) key.word.emplace_back(0xD9); - else if (fn_key_pressed && arrow_ry) key.word.emplace_back(0xD7); - else if (fn_key_pressed && arrow_le) key.word.emplace_back(0xD8); - else if (fn_key_pressed && keyVal == '`') key.word.emplace_back(0xB1); - else key.word.emplace_back(keyVal); - keyPulse = true; - } - } + // Serial.printf("Key event: raw=%d, pressed=%d, row=%d, col=%d\n", value, pressed, row, col); + + if (row >= 4 || col >= 14) return; - tca.writeRegister(TCA8418_REG_INT_STAT, 1); - int intstat = tca.readRegister(TCA8418_REG_INT_STAT); - if ((intstat & 0x01) == 0) { kb_interrupt = false; } + if (wakeUpScreen()) return; + + AnyKeyPress = true; + + if (handleSpecialKeys(row, col, pressed) > 0) return; + + if (!pressed) { KeyStroke.Clear(); } + + keyStroke key; + char keyVal = getKeyChar(row, col); + + // Serial.printf("Key pressed: %c (0x%02X) at row=%d, col=%d\n", keyVal, keyVal, row, col); + + if (keyVal == KEY_BACKSPACE && col == 13) { // KEY_BACKSPACE = '*' = 0x2a + del = pressed; + esc = pressed; + } else if (keyVal == '`') { + esc = pressed; + } else if (keyVal == KEY_ENTER && col == 13) { // KEY_ENTER = '(' = 0x28 + sel = pressed; + } else if (keyVal == ',' || keyVal == ';') { + prev = pressed; + if (keyVal == ',') arrow_le = pressed; + if (keyVal == ';') arrow_up = pressed; + } else if (keyVal == '/' || keyVal == '.') { + next = pressed; + if (keyVal == '/') arrow_ry = pressed; + if (keyVal == '.') arrow_dw = pressed; + } else if (keyVal == 0xFF) { + key.fn = pressed; + } else if (keyVal == KEY_LEFT_CTRL) { + ctrl = pressed; + } else if (keyVal == KEY_LEFT_ALT) { + alt = pressed; + } else if (keyVal == KEY_OPT) { + gui = pressed; } - unsigned long now = millis(); - if (next && now >= nextRepeatTime) { - nextPulse = true; - nextRepeatTime = now + TCA8418_REPEAT_MS; + if (gui) { + key.gui = true; + key.modifier_keys.emplace_back(KEY_OPT); + key.hid_keys.emplace_back(KEY_OPT); } - if (prev && now >= prevRepeatTime) { - prevPulse = true; - prevRepeatTime = now + TCA8418_REPEAT_MS; + if (alt) { + key.alt = true; + key.modifier_keys.emplace_back(KEY_LEFT_ALT); + key.hid_keys.emplace_back(KEY_LEFT_ALT); } - if (up && now >= upRepeatTime) { - upPulse = true; - upRepeatTime = now + TCA8418_REPEAT_MS; + if (ctrl) { + key.ctrl = true; + key.modifier_keys.emplace_back(KEY_LEFT_CTRL); + key.hid_keys.emplace_back(KEY_LEFT_CTRL); } - if (down && now >= downRepeatTime) { - downPulse = true; - downRepeatTime = now + TCA8418_REPEAT_MS; + if (shift_key_pressed) { + key.fn = true; + key.modifier_keys.emplace_back(KEY_LEFT_SHIFT); + key.hid_keys.emplace_back(KEY_LEFT_SHIFT); } - - if (!keyEventHandled && !nextPulse && !prevPulse && !upPulse && !downPulse && !LongPress) { - sel = false; - esc = false; + if (sel) { + key.enter = true; + key.exit_key = true; } - - if (delPulse) { - key.del = true; - key.pressed = true; - if (fn_key_pressed) { - key.word.emplace_back(0xD4); - key.del = false; - key.fn = false; - del = false; - fn_key_pressed = false; - } - keyPulse = true; + if (fn_key_pressed) key.fn = true; + + if (keyVal != 0xFF && !sel && !gui && !alt && !ctrl && !del && keyVal != KEY_LEFT_SHIFT) { + if (fn_key_pressed && arrow_up) key.word.emplace_back(0xDA); + else if (fn_key_pressed && arrow_dw) key.word.emplace_back(0xD9); + else if (fn_key_pressed && arrow_ry) key.word.emplace_back(0xD7); + else if (fn_key_pressed && arrow_le) key.word.emplace_back(0xD8); + else if (fn_key_pressed && keyVal == '`') key.word.emplace_back(0xB1); + else key.word.emplace_back(keyVal); } - - if (keyPulse) { + key.pressed = pressed; + if (del) { + key.del = del; key.pressed = true; - KeyStroke = key; - } else if (!nextPulse && !prevPulse && !upPulse && !downPulse) { - KeyStroke.Clear(); } - - if (nextPulse || prevPulse || upPulse || downPulse || keyPulse) AnyKeyPress = true; - - NextPress = nextPulse; - PrevPress = prevPulse; - UpPress = upPulse; - DownPress = downPulse; - if (!SelPress) SelPress = sel; + if (fn_key_pressed && del) { + key.word.emplace_back(0xD4); + key.del = false; + key.fn = false; + del = false; + fn_key_pressed = false; + } + KeyStroke = key; + NextPress = next; + PrevPress = prev; + UpPress = up; + DownPress = down; + SelPress = sel; EscPress = esc; - tm = now; + tm = millis(); } else { Keyboard.update(); if (Keyboard.isPressed()) { diff --git a/boards/m5stack-sticks3/interface.cpp b/boards/m5stack-sticks3/interface.cpp index c816a27547..8be8e8b631 100644 --- a/boards/m5stack-sticks3/interface.cpp +++ b/boards/m5stack-sticks3/interface.cpp @@ -221,45 +221,10 @@ bool isCharging() { ** location: modules/others/audio.cpp ** Handles audio CODEC to enable/disable speaker **********************************************************************/ -static TimerHandle_t speaker_off_timer = NULL; - -static void speaker_off_timer_cb(TimerHandle_t xTimer) { - if (!speaker_off_timer) return; - static constexpr const uint8_t disabled_bulk_data[] = {0}; - i2c_bulk_write(&Wire1, ES8311_ADDR, disabled_bulk_data); // Shutdown ES8311 - M5.In_I2C.bitOff(0x6E, 0x11, 1 << 3, 100000); // Set gpio3 output low (turn off PA) -} - void _setup_codec_speaker(bool enable) { - - static constexpr const uint8_t enabled_bulk_data[] = { - 2, 0x00, 0x80, // 0x00 RESET/ CSM POWER ON - 2, 0x01, 0xB5, // 0x01 CLOCK_MANAGER/ MCLK=BCLK - 2, 0x02, 0x18, // 0x02 CLOCK_MANAGER/ MULT_PRE=3 - 2, 0x0D, 0x01, // 0x0D SYSTEM/ Power up analog circuitry - 2, 0x12, 0x00, // 0x12 SYSTEM/ power-up DAC - NOT default - 2, 0x13, 0x10, // 0x13 SYSTEM/ Enable output to HP drive - NOT default - 2, 0x32, 0xBF, // 0x32 DAC/ DAC volume (0xBF == +-0 dB ) - 2, 0x37, 0x08, // 0x37 DAC/ Bypass DAC equalizer - NOT default - 0 - }; - - if (speaker_off_timer == NULL) { - speaker_off_timer = xTimerCreate("SpkOffTimer", pdMS_TO_TICKS(100), pdFALSE, (void *)0, speaker_off_timer_cb); - } - - if (enable) { - if (speaker_off_timer != NULL && xTimerIsTimerActive(speaker_off_timer)) { - xTimerStop(speaker_off_timer, 0); // Cancel pending shutdown - } else { - i2c_bulk_write(&Wire1, ES8311_ADDR, enabled_bulk_data); - M5.In_I2C.bitOn(0x6E, 0x11, 1 << 3, 100000); // Set gpio3 output high (turn on PA) - } - } else { - if (speaker_off_timer != NULL) { - xTimerReset(speaker_off_timer, 0); // Start/reset shutdown timeout for 100ms - } - } + M5.Speaker.setVolume(bruceConfig.soundVolume); + if (enable) M5.Speaker.begin(); + else M5.Speaker.end(); } /********************************************************************* @@ -268,32 +233,8 @@ void _setup_codec_speaker(bool enable) { ** Handles audio CODEC to enable/disable microphone **********************************************************************/ void _setup_codec_mic(bool enable) { - // Set microfone pin for ADV - mic_bclk_pin = (gpio_num_t)17; - - static constexpr const uint8_t enabled_bulk_data[] = { - 2, 0x00, 0x80, // 0x00 RESET/ CSM POWER ON - 2, 0x01, 0xBA, // 0x01 CLOCK_MANAGER/ MCLK=BCLK - 2, 0x02, 0x18, // 0x02 CLOCK_MANAGER/ MULT_PRE=3 - 2, 0x0D, 0x01, // 0x0D SYSTEM/ Power up analog circuitry - 2, 0x0E, 0x02, // 0x0E SYSTEM/ : Enable analog PGA, enable ADC modulator - 2, 0x14, 0x10, // ES8311_ADC_REG14 : select Mic1p-Mic1n / PGA GAIN (minimum) - 2, 0x17, 0xBF, // ES8311_ADC_REG17 : ADC_VOLUME 0xBF == +- 0 dB - 2, 0x1C, 0x6A, // ES8311_ADC_REG1C : ADC Equalizer bypass, cancel DC offset in digital domain - 0 - }; - static constexpr const uint8_t disabled_bulk_data[] = { - 2, - 0x0D, - 0xFC, // 0x0D SYSTEM/ Power down analog circuitry - 2, - 0x0E, - 0x6A, // 0x0E SYSTEM - 2, - 0x00, - 0x00, // 0x00 RESET/ CSM POWER DOWN - 0 - }; + if (enable) M5.Mic.begin(); + else M5.Mic.end(); - i2c_bulk_write(&Wire1, ES8311_ADDR, enable ? enabled_bulk_data : disabled_bulk_data); + mic_bclk_pin = (gpio_num_t)17; } diff --git a/boards/m5stack-sticks3/m5stack-sticks3.ini b/boards/m5stack-sticks3/m5stack-sticks3.ini index 6209bce1b5..bae2800ce6 100644 --- a/boards/m5stack-sticks3/m5stack-sticks3.ini +++ b/boards/m5stack-sticks3/m5stack-sticks3.ini @@ -10,23 +10,12 @@ [env:m5stack-sticks3] board = m5stack-sticks3 -board_build.psram = enabled -board_build.flash_mode = qio -board_build.flash_size = 8MB -board_build.psram_type = opi board_build.partitions = custom_8Mb.csv build_src_filter =${env.build_src_filter} +<../boards/m5stack-sticks3> build_flags = ${env.build_flags} - -DBOARD_HAS_PSRAM -Iboards/m5stack-sticks3 -DCORE_DEBUG_LEVEL=1 - -DCONFIG_SPIRAM=y - -DCONFIG_SPIRAM_MODE_OCT=1 - -DCONFIG_SPIRAM_TYPE_OPI=1 - -DCONFIG_SPIRAM_USE_MALLOC=1 - -DCONFIG_SPIRAM_BOOT_INIT=1 - -DCONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=1 ;Features Enabled ;-DLITE_VERSION=1 ;limits some features to save space for M5Launcher Compatibility diff --git a/boards/marauder-touch/interface.cpp b/boards/marauder-touch/interface.cpp index 66bdfa2aaf..9f23eb9742 100644 --- a/boards/marauder-touch/interface.cpp +++ b/boards/marauder-touch/interface.cpp @@ -95,7 +95,6 @@ void InputHandler(void) { } #ifdef WAVESENTRY - static unsigned long lastEncoderMoveMs = 0; static int posDifference = 0; static int lastPos = 0; bool sel = !BTN_ACT; @@ -104,10 +103,6 @@ void InputHandler(void) { if (newPos != lastPos) { posDifference += (newPos - lastPos); lastPos = newPos; - lastEncoderMoveMs = millis(); - } else if (posDifference != 0 && millis() - lastEncoderMoveMs > 30) { - // Drop any stale queued steps once the encoder has stopped moving. - posDifference = 0; } if (millis() - tm < 200 && !LongPress) return; diff --git a/boards/pinouts/pins_arduino.h b/boards/pinouts/pins_arduino.h index def219d4b0..ef9588335b 100644 --- a/boards/pinouts/pins_arduino.h +++ b/boards/pinouts/pins_arduino.h @@ -12,10 +12,6 @@ #include "../m5stack-cardputer/pins_arduino.h" #elif CYD_2432S028 #include "../CYD-2432S028/pins_arduino.h" -#elif ARDUINO_NESSO_N1 -#include "../arduino-nesso-n1/pins_arduino.h" -#elif ARDUINO_M5STACK_DINMETER -#include "../m5stack-dinmeter/pins_arduino.h" #elif ARDUINO_M5STACK_CORE #include "../m5stack-core/pins_arduino.h" #elif ARDUINO_M5STACK_CORES3 @@ -30,6 +26,8 @@ #include "../ESP-General/pins_arduino.h" #elif SMOOCHIEE_BOARD #include "../smoochiee-board/pins_arduino.h" +#elif SMOOCHIEE_S3_2_8INCH_ILI9341 +#include "../smoochiee-s3-2.8inch-ili9341/pins_arduino.h" #elif XK404 #include "../xk404/pins_arduino.h" #elif REAPER @@ -46,12 +44,8 @@ #include "../marauder-mini/pins_arduino.h" #elif LILYGO_T_HMI #include "../lilygo-t-hmi/pins_arduino.h" -#elif ELECROW -#include "../elecrow/pins_arduino.h" #elif ESP32C5_DEVKITC_1_TFT #include "../ESP32-C5-tft/pins_arduino.h" #elif ESP32C5_DEVKITC_1 #include "../ESP32-C5/pins_arduino.h" -#elif NM_CYD_ESP32C5 -#include "../nm-cyd-c5/pins_arduino.h" #endif diff --git a/boards/smoochiee-board/README.md b/boards/smoochiee-board/README.md new file mode 100644 index 0000000000..fcac6d714e --- /dev/null +++ b/boards/smoochiee-board/README.md @@ -0,0 +1,33 @@ +# Smoochiee Board Pinout + +This board targets the original Smoochiee configuration (ST7789-based display) and button-only navigation. + +## ESP32-S3 / Board Pins + +| Function | GPIO | +| --- | --- | +| USB serial TX | 1 | +| USB serial RX | 2 | +| I2C SDA | 47 | +| I2C SCL | 48 | +| Up button | 41 | +| Down button | 40 | +| Right button | 38 | +| Left button | 39 | +| Select button | 0 | +| IR TX LED | 5 | +| IR RX LED | 4 | +| CC1101 CS | 46 | +| NRF24 CE | 21 | +| NRF24 CS | 14 | +| RGB LED | 45 | + +## Display + +- Driver: `ST7789` (original configuration) +- Resolution: 170x320 +- Backlight pin: GPIO 6 + +## Notes + +- Touch support is disabled; use the hardware buttons to navigate the UI. diff --git a/boards/smoochiee-board/pins_arduino.h b/boards/smoochiee-board/pins_arduino.h index e195481c40..efba115728 100644 --- a/boards/smoochiee-board/pins_arduino.h +++ b/boards/smoochiee-board/pins_arduino.h @@ -56,7 +56,6 @@ static const uint8_t SCK = 18; #define FP 1 #define FM 2 #define FG 3 - #define HAS_SCREEN 1 #define ROTATION 1 #define MINBRIGHT (uint8_t)1 diff --git a/boards/smoochiee-s3-2.8inch-ili9341/pins_arduino.h b/boards/smoochiee-s3-2.8inch-ili9341/pins_arduino.h new file mode 100644 index 0000000000..3f77ddffc4 --- /dev/null +++ b/boards/smoochiee-s3-2.8inch-ili9341/pins_arduino.h @@ -0,0 +1,127 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include "soc/soc_caps.h" +#include + +static const uint8_t TX = 1; +static const uint8_t RX = 2; + +static const uint8_t SDA = 47; +static const uint8_t SCL = 48; + +// Modified elsewhere +static const uint8_t SS = 3; +static const uint8_t MOSI = 17; +static const uint8_t MISO = 8; +static const uint8_t SCK = 18; + +#define SERIAL_RX 2 +#define SERIAL_TX 1 +#define BAD_RX SERIAL_RX +#define BAD_TX SERIAL_TX +#define GPS_SERIAL_TX SERIAL_TX +#define GPS_SERIAL_RX SERIAL_RX +#define USB_as_HID 1 + +#define BTN_ALIAS "\"OK\"" +#define HAS_5_BUTTONS +#define SEL_BTN 0 +#define UP_BTN 41 +#define DW_BTN 40 +#define R_BTN 38 +#define L_BTN 39 +#define BTN_ACT LOW + +#define RXLED 4 +#define TXLED 5 +#define LED_ON HIGH +#define LED_OFF LOW + +#define USE_CC1101_VIA_SPI +#define CC1101_GDO0_PIN 9 +#define CC1101_GDO2_PIN 10 +#define CC1101_SS_PIN 46 +#define CC1101_MOSI_PIN SPI_MOSI_PIN +#define CC1101_SCK_PIN SPI_SCK_PIN +#define CC1101_MISO_PIN SPI_MISO_PIN + +#define USE_NRF24_VIA_SPI +#define NRF24_CE_PIN 21 +#define NRF24_SS_PIN 14 +#define NRF24_MOSI_PIN SPI_MOSI_PIN +#define NRF24_SCK_PIN SPI_SCK_PIN +#define NRF24_MISO_PIN SPI_MISO_PIN + +#define FP 1 +#define FM 2 +#define FG 3 + +// Display: 2.8" ILI9341 SPI TFT, buttons-only navigation, backlight on LED pin. +#define HAS_SCREEN 1 +#define ROTATION 1 +#define MINBRIGHT (uint8_t)1 + +#define USER_SETUP_LOADED 1 +#define ILI9341_2_DRIVER 1 +#define TFT_INVERSION_ON 1 +#define TFT_RGB_ORDER 0 +#define TFT_WIDTH 240 +#define TFT_HEIGHT 320 +#define TFT_BACKLIGHT_ON 1 +#define TFT_BL 6 +// TFT wiring +#define TFT_RST 16 +#define TFT_DC 15 +#define TFT_MISO 8 +#define TFT_MOSI 17 +#define TFT_SCLK 18 +#define TFT_CS 7 +#define SMOOTH_FONT 1 +#define SPI_FREQUENCY 20000000 +#define SPI_READ_FREQUENCY 20000000 +#define SPI_TOUCH_FREQUENCY 2500000 + +#define SDCARD_CS 3 +#define SDCARD_SCK 18 +#define SDCARD_MISO 8 +#define SDCARD_MOSI 17 + +#define GROVE_SDA 47 +#define GROVE_SCL 48 + +#define SPI_SCK_PIN 13 +#define SPI_MOSI_PIN 12 +#define SPI_MISO_PIN 11 +#define SPI_SS_PIN 43 + +// RGB LED + +#define HAS_RGB_LED 1 +#define RGB_LED 45 +#define LED_TYPE WS2812B +#define LED_ORDER GRB +#define LED_TYPE_IS_RGBW 0 +#define LED_COUNT 16 + +#define LED_COLOR_STEP 15 + +#define XPOWERS_CHIP_BQ25896 + +// USE BOOST ENABLE PMIC 5V OUTPUT +#define USE_BOOST + +// Mic# +#define PIN_CLK 1 +#define PIN_DATA 10 +#define PIN_WS 2 + +// IO EXPANDER +#define USE_IO_EXPANDER +#define IO_EXPANDER_AW9523 +#define IO_EXP_GPS 13 +#define IO_EXP_MIC 4 +#define IO_EXP_VIBRO 2 +#define IO_EXP_CC_RX 7 +#define IO_EXP_CC_TX 12 +#endif /* Pins_Arduino_h */ diff --git a/boards/smoochiee-s3-2.8inch-ili9341/smoochiee-s3-2.8inch-ili9341.ini b/boards/smoochiee-s3-2.8inch-ili9341/smoochiee-s3-2.8inch-ili9341.ini new file mode 100644 index 0000000000..c82cdb6da1 --- /dev/null +++ b/boards/smoochiee-s3-2.8inch-ili9341/smoochiee-s3-2.8inch-ili9341.ini @@ -0,0 +1,17 @@ +; PlatformIO Project Configuration File for Smoochiee S3 + 2.8" ILI9341 +[env:smoochiee-s3-2_8inch-ili9341] +board = smoochiee-s3-2.8inch-ili9341 +build_src_filter =${env.build_src_filter} +<../boards/smoochiee-s3-2.8inch-ili9341> +board_build.partitions = custom_16Mb.csv +build_flags = + ${env.build_flags} + -Iboards/smoochiee-s3-2.8inch-ili9341 + -Os + -DCORE_DEBUG_LEVEL=1 + -DSMOOCHIEE_S3_2_8INCH_ILI9341 + -DUSE_HSPI_PORT=1 + -DDEVICE_NAME='"Smoochiee S3 2.8\" ILI9341"' + +lib_deps = + ${env.lib_deps} + lewisxhe/XPowersLib @0.3.0 diff --git a/docker/run_all_envs.sh b/docker/run_all_envs.sh index 27f6a573d8..1a7f9dc3a1 100644 --- a/docker/run_all_envs.sh +++ b/docker/run_all_envs.sh @@ -42,13 +42,6 @@ DEFAULT_ENVS=( lilygo-t-display-ttgo lilygo-t-hmi lilygo-t-lora-pager - elecrow-24B - elecrow-28B - elecrow-35B - elecrow-35Bv2_2 - LAUNCHER_elecrow-24B - LAUNCHER_elecrow-28B - LAUNCHER_elecrow-35B smoochiee-board Phantom_S024R LAUNCHER_Phantom_S024R @@ -101,7 +94,7 @@ for ((i = 0; i < ${#ENVS[@]}; i += JOBS)); do done done -if ((${#failed[@]} > 0)); then +if (( ${#failed[@]} > 0 )); then echo "Build failures: ${failed[*]}" >&2 exit 1 fi diff --git a/embedded_resources/web_interface/index.css b/embedded_resources/web_interface/index.css index 853014a5d1..380fbc9c43 100644 --- a/embedded_resources/web_interface/index.css +++ b/embedded_resources/web_interface/index.css @@ -410,17 +410,8 @@ svg > path { overflow-wrap: normal; overflow: auto; } -.dialog.upload { - width: 100%; - max-width: 420px; - max-height: calc(100vh - 20px); - display: flex; - flex-direction: column; -} .dialog.upload .dialog-body { padding: 10px; - overflow-y: auto; - max-height: calc(100vh - 60px); } .dialog.upload .upload-loading { width: 350px; diff --git a/include/SerialDevice.h b/include/SerialDevice.h index 12f1ae24e5..0735abd14e 100644 --- a/include/SerialDevice.h +++ b/include/SerialDevice.h @@ -13,7 +13,6 @@ class SerialDevice { virtual size_t print(int n, int format = DEC) = 0; virtual size_t print(const String &s) = 0; virtual void vprintf(const char *fmt, va_list args) = 0; - virtual int read() = 0; virtual size_t write(uint8_t *str, size_t size) = 0; void printf(const char *fmt, ...) { va_list args; diff --git a/include/VectorDisplay.h b/include/VectorDisplay.h index d8d6ee4eb2..4a5eee472f 100644 --- a/include/VectorDisplay.h +++ b/include/VectorDisplay.h @@ -500,15 +500,15 @@ class VectorDisplayClass : public Print { void text(int x, int y, const char *str, int n) { args.xyText.x = x; args.xyText.y = y; - if (n > VECTOR_DISPLAY_MAX_STRING - 1) n = VECTOR_DISPLAY_MAX_STRING - 1; + if (n > VECTOR_DISPLAY_MAX_STRING) n = VECTOR_DISPLAY_MAX_STRING; strncpy(args.xyText.text, str, n); - args.xyText.text[n] = 0; // Explicit null termination before loop if (fixCP437) { for (int i = 0; i < n; i++) { if ((uint8_t)args.xyText.text[i] >= 176) args.xyText.text[i]++; } } + args.xyText.text[n] = 0; sendCommand('T', &args, 4 + strlen(args.xyText.text) + 1); } @@ -520,15 +520,15 @@ class VectorDisplayClass : public Print { void addButton(uint8_t command, const char *str) { args.charText.c = command; - strncpy(args.charText.text, str, VECTOR_DISPLAY_MAX_STRING - 1); - args.charText.text[VECTOR_DISPLAY_MAX_STRING - 1] = 0; + strncpy(args.charText.text, str, VECTOR_DISPLAY_MAX_STRING); + args.charText.text[VECTOR_DISPLAY_MAX_STRING] = 0; sendCommand('U', &args, 1 + strlen(args.charText.text) + 1); } void addButton(uint8_t command, String str) { addButton(command, str.c_str()); } void toast(const char *str, unsigned n) { - if (VECTOR_DISPLAY_MAX_STRING - 1 < n) n = VECTOR_DISPLAY_MAX_STRING - 1; + if (VECTOR_DISPLAY_MAX_STRING < n) n = VECTOR_DISPLAY_MAX_STRING; strncpy(args.text, str, n); args.text[n] = 0; sendCommand('M', &args, n + 1); diff --git a/include/globals.h b/include/globals.h index 348ee78e2b..1362520197 100644 --- a/include/globals.h +++ b/include/globals.h @@ -104,7 +104,6 @@ struct Option { String label; std::function operation; bool selected = false; - bool enabled = true; bool (*hover)(void *hoverPointer, bool shouldRender); void *hoverPointer; bool hovered; // return to the remote (webui or app) if it is hovered on the loopoptions @@ -113,9 +112,9 @@ struct Option { String lbl, const std::function &op, bool sel = false, bool (*hov)(void *hoverPointer, bool shouldRender) = nullptr, // hover lambda returns true if it already handled rendering - void *ptr = nullptr, bool hvrd = false, bool en = true + void *ptr = nullptr, bool hvrd = false ) - : label(lbl), operation(op), selected(sel), enabled(en), hover(hov), hoverPointer(ptr), hovered(hvrd) {} + : label(lbl), operation(op), selected(sel), hover(hov), hoverPointer(ptr), hovered(hvrd) {} }; struct keyStroke { // DO NOT CHANGE IT!!!!! diff --git a/include/precompiler_flags.h b/include/precompiler_flags.h index a8e5d0edb2..a9259e8643 100644 --- a/include/precompiler_flags.h +++ b/include/precompiler_flags.h @@ -16,7 +16,7 @@ #define INPUT_HANDLER_TASK_STACK_SIZE 4096 #endif #ifndef SSH_TASK_STACK_SIZE - #define SSH_TASK_STACK_SIZE (1024 * 16) + #define SSH_TASK_STACK_SIZE 1024*10 #endif #ifndef SAFE_STACK_BUFFER_SIZE #define SAFE_STACK_BUFFER_SIZE 4096 @@ -33,7 +33,7 @@ #define INPUT_HANDLER_TASK_STACK_SIZE 2048 #endif #ifndef SSH_TASK_STACK_SIZE - #define SSH_TASK_STACK_SIZE (1024 * 16) + #define SSH_TASK_STACK_SIZE 1024*8 #endif #ifndef SAFE_STACK_BUFFER_SIZE #define SAFE_STACK_BUFFER_SIZE 1024 diff --git a/patch.py b/patch.py index f8538e5dbe..1dac1ede92 100644 --- a/patch.py +++ b/patch.py @@ -104,7 +104,6 @@ def minify_js(js): minify_req = requests.post( 'https://www.toptal.com/developers/javascript-minifier/api/raw', {'input': js.read().decode('utf-8')}, - timeout=10 ) return js if minify_req is False else minify_req.text.encode('utf-8') @@ -113,7 +112,6 @@ def minify_html(html): minify_req = requests.post( 'https://www.toptal.com/developers/html-minifier/api/raw', {'input': html.read().decode('utf-8')}, - timeout=10 ) return html if minify_req is False else minify_req.text.encode('utf-8') diff --git a/platformio.ini b/platformio.ini index fa639618e2..22f68db6da 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,7 +10,8 @@ [platformio] default_envs = - m5stack-cardputer + smoochiee-board + ;m5stack-cardputer ;m5stack-sticks3 ;m5stack-cplus2 ;m5stack-cplus1_1 @@ -19,8 +20,6 @@ default_envs = ;m5stack-core16mb ;m5stack-core4mb ;m5stack-cores3 - ;m5stack-dinmeter - ;arduino-nesso-n1 ;esp32-s3-devkitc-1 ;CYD-2432S028 ;CYD-2USB @@ -48,9 +47,9 @@ default_envs = ;lilygo-t-display-ttgo ;lilygo-t-hmi ;lilygo-t-lora-pager - ;smoochiee-board - ;xk404 + ;xk404 ;reaper + ;smoochiee-s3-2.8inch-ili9341 ;Phantom_S024R ;LAUNCHER_Phantom_S024R ;Marauder-Mini @@ -66,14 +65,8 @@ default_envs = ;LAUNCHER_WaveSentry-R1 ;WaveSentry-R1 ;esp32-c5-tft - ;esp32-c5 - ;ES3C28P - ;nm-cyd-c5 - ;elecrow-24B - ;elecrow-28B - ;elecrow-35B - ;elecrow-35Bv2_2 - + ;esp32-c5 + ;ES3C28P ;uncomment to not use global dirs to avoid possible conflicts ;platforms_dir = .pio/platforms @@ -89,14 +82,13 @@ extra_configs = [env] platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.36/platform-espressif32.zip ; Arduino 3.3.6 ;https://github.com/pioarduino/platform-espressif32/releases/download/55.03.34/platform-espressif32.zip ; Arduino 3.3.4 - ;https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip ; Last Version + ;https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip ; Last Version platform_packages = framework-arduinoespressif32-libs @ https://github.com/bmorcelli/esp32-arduino-lib-builder/releases/download/idf-release_v5.5/bruce_esp32-arduino-libs-20260123-153546.zip ; Arduino 3.3.6 - ;framework-arduinoespressif32-libs @ https://github.com/bmorcelli/esp32-arduino-lib-builder/releases/download/idf-release_v5.5/bruce_esp32-arduino-libs-20251205-131242.zip ; Arduino 3.3.4 - ;framework-arduinoespressif32-libs @ https://github.com/bmorcelli/esp32-arduino-lib-builder/releases/download/idf-release_v5.5/esp32-arduino-libs-20250919-170356.zip ; Arduino 3.3.1 + ;framework-arduinoespressif32-libs @ https://github.com/bmorcelli/esp32-arduino-lib-builder/releases/download/idf-release_v5.5/bruce_esp32-arduino-libs-20251205-131242.zip ; Arduino 3.3.4 + ;framework-arduinoespressif32-libs @ https://github.com/bmorcelli/esp32-arduino-lib-builder/releases/download/idf-release_v5.5/esp32-arduino-libs-20250919-170356.zip ; Arduino 3.3.1 monitor_filters = esp32_exception_decoder, send_on_enter, colorize -monitor_speed = 115200 framework = arduino board_build.variants_dir = boards board_build.filesystem = littlefs @@ -132,9 +124,6 @@ build_flags = -DEEPROMSIZE=128 -DLH=8 -DLW=6 - -flto - -ffunction-sections - -fdata-sections -Os -Wl,--print-memory-usage -Wl,--gc-sections @@ -163,7 +152,6 @@ extra_scripts = pre:pre_build_current_year.py pre:gen_mqjs_headers.py pre:patch_library_conflicts.py - flto_prep.py post:build.py lib_deps = @@ -192,7 +180,7 @@ lib_deps = earlephilhower/ESP8266SAM@^1.1.0 mikalhart/TinyGPSPlus tinyu-zhao/FFT@^0.0.1 - h2zero/NimBLE-Arduino@2.5 + h2zero/NimBLE-Arduino@^2.3.9 nrf24/RF24 @ 1.4.11 Adafruit Si4713 Library@1.2.3 Bodmer/JPEGDecoder @@ -209,6 +197,10 @@ lib_deps = fastled/FastLED @^3.10.3 jgromes/RadioLib @ ^7.4.0 +monitor_speed = 115200 + + + [env_light] extends = env build_flags = @@ -258,7 +250,7 @@ lib_deps = ;earlephilhower/ESP8266SAM@^1.1.0 mikalhart/TinyGPSPlus@1.1.0 tinyu-zhao/FFT@0.0.1 - h2zero/NimBLE-Arduino@2.5 + h2zero/NimBLE-Arduino@2.3.7 nrf24/RF24 @ 1.4.11 ;Adafruit Si4713 Library@1.2.3 Bodmer/JPEGDecoder @@ -296,6 +288,7 @@ build_flags = -DSEND_PANASONIC=true -DDECODE_PANASONIC=true -DSEND_RAW=true + -include Arduino.h lib_ignore = FastLED diff --git a/src/core/USBSerial/USBSerial.h b/src/core/USBSerial/USBSerial.h index 81083aa33c..9b127a01a6 100644 --- a/src/core/USBSerial/USBSerial.h +++ b/src/core/USBSerial/USBSerial.h @@ -18,7 +18,6 @@ class USBSerial : public SerialDevice { void flush() override { out->flush(); } int available() override { return out->available(); } size_t write(uint8_t *str, size_t size) override { return out->write(str, size); } - int read() override { return out->read(); } void setSerialOutput(Stream *in) { out = in; } Stream *getSerialOutput() { return out; } USBSerial(Stream *in = &Serial) { out = in; } diff --git a/src/core/app_launcher.cpp b/src/core/app_launcher.cpp new file mode 100644 index 0000000000..355a39caf3 --- /dev/null +++ b/src/core/app_launcher.cpp @@ -0,0 +1,88 @@ +#if !defined(LITE_VERSION) && !defined(DISABLE_INTERPRETER) +#include "app_launcher.h" +#include "sd_functions.h" +#include "modules/bjs_interpreter/interpreter.h" +#include +#include +#include + +static bool parseManifest(FS &fs, const String &dirPath, AppManifest &out) { + String manifestPath = dirPath + "/manifest.json"; + if (!fs.exists(manifestPath)) return false; + + File f = fs.open(manifestPath, "r"); + if (!f) return false; + + JsonDocument doc; + DeserializationError err = deserializeJson(doc, f); + f.close(); + if (err) return false; + + out.name = doc["name"] | dirPath.substring(dirPath.lastIndexOf('/') + 1); + out.description = doc["description"] | ""; + out.entryPoint = doc["entry"] | "main.js"; + out.category = doc["category"] | "Other"; + out.version = doc["version"] | "1.0"; + out.basePath = dirPath; + out.fs = &fs; + return true; +} + +static void scanDirectory(FS &fs, const String &root, std::vector &apps) { + File dir = fs.open(root); + if (!dir || !dir.isDirectory()) return; + + while (true) { + bool isDir; + String path = dir.getNextFileName(&isDir); + if (path.isEmpty()) break; + if (!isDir) continue; + // Skip hidden directories + String name = path.substring(path.lastIndexOf('/') + 1); + if (name.startsWith(".")) continue; + + AppManifest app; + if (parseManifest(fs, path, app)) { + apps.push_back(app); + } + } + dir.close(); +} + +std::vector discoverApps() { + std::vector apps; + + // Scan SD card first + setupSdCard(); + if (sdcardMounted) { + if (SD.exists("/apps")) scanDirectory(SD, "/apps", apps); + } + + // Then LittleFS + if (LittleFS.exists("/apps")) { + scanDirectory(LittleFS, "/apps", apps); + } + + return apps; +} + +bool launchApp(const AppManifest &app) { + String scriptPath = app.basePath + "/" + app.entryPoint; + if (!app.fs->exists(scriptPath)) { + log_e("App entry point not found: %s", scriptPath.c_str()); + return false; + } + return run_bjs_script_headless(*app.fs, scriptPath); +} + +std::vector filterAppsByCategory(const std::vector &apps, const String &category) { + std::vector filtered; + for (const auto &app : apps) { + if (app.category.equalsIgnoreCase(category)) { + filtered.push_back(app); + } + } + return filtered; +} + +#endif diff --git a/src/core/app_launcher.h b/src/core/app_launcher.h new file mode 100644 index 0000000000..1d8dfbff5b --- /dev/null +++ b/src/core/app_launcher.h @@ -0,0 +1,29 @@ +#ifndef __APP_LAUNCHER_H__ +#define __APP_LAUNCHER_H__ +#if !defined(LITE_VERSION) && !defined(DISABLE_INTERPRETER) + +#include +#include +#include + +struct AppManifest { + String name; + String description; + String entryPoint; // e.g. "main.js" + String category; // e.g. "RF", "BLE", "Tools" + String version; + String basePath; // absolute path to app directory + FS *fs; // SD or LittleFS +}; + +// Scan /apps/ on SD and LittleFS for apps with manifest.json +std::vector discoverApps(); + +// Launch an app by running its entry point script +bool launchApp(const AppManifest &app); + +// Filter apps by category +std::vector filterAppsByCategory(const std::vector &apps, const String &category); + +#endif +#endif diff --git a/src/core/config.cpp b/src/core/config.cpp index 3a0b4b132f..a275e583d4 100644 --- a/src/core/config.cpp +++ b/src/core/config.cpp @@ -43,7 +43,6 @@ JsonDocument BruceConfig::toJson() const { _wifiAp["ssid"] = wifiAp.ssid; _wifiAp["pwd"] = wifiAp.pwd; setting["wifiMAC"] = wifiMAC; //@IncursioHack - setting["TerminalLog"] = TerminalLog; JsonArray _evilWifiNames = setting["evilWifiNames"].to(); for (auto key : evilWifiNames) _evilWifiNames.add(key); @@ -54,7 +53,6 @@ JsonDocument BruceConfig::toJson() const { _evilWifiEndpoints["showEndpoints"] = evilPortalEndpoints.showEndpoints; _evilWifiEndpoints["allowSetSsid"] = evilPortalEndpoints.allowSetSsid; _evilWifiEndpoints["allowGetCreds"] = evilPortalEndpoints.allowGetCreds; - _evilWifiEndpoints["gatewayIp"] = evilPortalGatewayIp; setting["evilWifiPasswordMode"] = evilPortalPasswordMode; @@ -64,7 +62,6 @@ JsonDocument BruceConfig::toJson() const { setting["startupApp"] = startupApp; setting["startupAppJSInterpreterFile"] = startupAppJSInterpreterFile; setting["wigleBasicToken"] = wigleBasicToken; - setting["wdgwarsApiKey"] = wdgwarsApiKey; setting["devMode"] = devMode; setting["colorInverted"] = colorInverted; @@ -292,12 +289,6 @@ void BruceConfig::fromFile(bool checkFS) { count++; log_e("wifiMAC not found, using default"); } - if (!setting["TerminalLog"].isNull()) { - TerminalLog = setting["TerminalLog"].as(); - } else { - count++; - log_e("TerminalLog not found, using default"); - } // Wifi List if (!setting["wifi"].isNull()) { @@ -325,11 +316,6 @@ void BruceConfig::fromFile(bool checkFS) { evilPortalEndpoints.showEndpoints = evilPortalEndpointsObj["showEndpoints"].as(); evilPortalEndpoints.allowSetSsid = evilPortalEndpointsObj["allowSetSsid"].as(); evilPortalEndpoints.allowGetCreds = evilPortalEndpointsObj["allowGetCreds"].as(); - if (!evilPortalEndpointsObj["gatewayIp"].isNull()) { - evilPortalGatewayIp = evilPortalEndpointsObj["gatewayIp"].as(); - } else { - evilPortalGatewayIp = "172.0.0.1"; - } } else { count++; log_e("Fail"); @@ -367,12 +353,6 @@ void BruceConfig::fromFile(bool checkFS) { count++; log_e("Fail"); } - if (!setting["wdgwarsApiKey"].isNull()) { - wdgwarsApiKey = setting["wdgwarsApiKey"].as(); - } else { - count++; - log_e("Fail"); - } if (!setting["devMode"].isNull()) { devMode = setting["devMode"].as(); } else { @@ -490,7 +470,6 @@ void BruceConfig::validateConfig() { validateEvilEndpointCreds(); validateEvilEndpointSsid(); validateEvilPasswordMode(); - validateEvilGatewayIp(); } void BruceConfig::setUiColor(uint16_t primary, uint16_t *secondary, uint16_t *background) { @@ -652,11 +631,6 @@ void BruceConfig::setWifiApCreds(const String &ssid, const String &pwd) { saveFile(); } -void BruceConfig::setTerminalLog(bool value) { - TerminalLog = value; - saveFile(); -} - void BruceConfig::addWifiCredential(const String &ssid, const String &pwd) { wifi[ssid] = pwd; saveFile(); @@ -734,17 +708,6 @@ void BruceConfig::validateEvilPasswordMode() { if (evilPortalPasswordMode < 0 || evilPortalPasswordMode > 2) evilPortalPasswordMode = FULL_PASSWORD; } -void BruceConfig::setEvilGatewayIp(String value) { - evilPortalGatewayIp = value; - validateEvilGatewayIp(); - saveFile(); -} - -void BruceConfig::validateEvilGatewayIp() { - IPAddress gatewayIp; - if (!gatewayIp.fromString(evilPortalGatewayIp)) evilPortalGatewayIp = "172.0.0.1"; -} - void BruceConfig::setStartupApp(String value) { startupApp = value; saveFile(); @@ -760,11 +723,6 @@ void BruceConfig::setWigleBasicToken(String value) { saveFile(); } -void BruceConfig::setWdgwarsApiKey(String value) { - wdgwarsApiKey = value; - saveFile(); -} - void BruceConfig::setDevMode(int value) { devMode = value; validateDevModeValue(); diff --git a/src/core/config.h b/src/core/config.h index 786c088d3f..1aeea72ceb 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -36,7 +36,7 @@ class BruceConfig : public BruceTheme { const char *filepath = "/bruce.conf"; // Settings - int dimmerSet = 60; + int dimmerSet = 10; int bright = 100; bool automaticTimeUpdateViaNTP = true; float tmz = 0; @@ -65,12 +65,10 @@ class BruceConfig : public BruceTheme { std::map wifi = {}; std::set evilWifiNames = {}; String wifiMAC = ""; //@IncursioHack - bool TerminalLog = true; // EvilPortal EvilPortalEndpoints evilPortalEndpoints = {"/creds", "/ssid", true, true, true}; EvilPortalPasswordMode evilPortalPasswordMode = FULL_PASSWORD; - String evilPortalGatewayIp = "172.0.0.1"; void setWifiMAC(const String &mac) { wifiMAC = mac; @@ -84,7 +82,6 @@ class BruceConfig : public BruceTheme { String startupApp = ""; String startupAppJSInterpreterFile = ""; String wigleBasicToken = ""; - String wdgwarsApiKey = "your 64-char hex key from wdgwars.pl/profile"; int devMode = 0; int colorInverted = 1; int badUSBBLEKeyboardLayout = 0; @@ -154,7 +151,6 @@ class BruceConfig : public BruceTheme { // Wifi void setWebUICreds(const String &usr, const String &pwd); void setWifiApCreds(const String &ssid, const String &pwd); - void setTerminalLog(bool value); void addWifiCredential(const String &ssid, const String &pwd); void addQrCodeEntry(const String &menuName, const String &content); void removeQrCodeEntry(const String &menuName); @@ -167,11 +163,9 @@ class BruceConfig : public BruceTheme { void setEvilAllowGetCreds(bool value); void setEvilAllowSetSsid(bool value); void setEvilPasswordMode(EvilPortalPasswordMode value); - void setEvilGatewayIp(String value); void validateEvilEndpointCreds(); void validateEvilEndpointSsid(); void validateEvilPasswordMode(); - void validateEvilGatewayIp(); // RFID void addMifareKey(String value); @@ -181,7 +175,6 @@ class BruceConfig : public BruceTheme { void setStartupApp(String value); void setStartupAppJSInterpreterFile(String value); void setWigleBasicToken(String value); - void setWdgwarsApiKey(String value); void setDevMode(int value); void validateDevModeValue(); void setColorInverted(int value); diff --git a/src/core/configPins.cpp b/src/core/configPins.cpp index d390821cb9..af01396521 100644 --- a/src/core/configPins.cpp +++ b/src/core/configPins.cpp @@ -7,17 +7,7 @@ String getMacAddress() { esp_read_mac(mac, ESP_MAC_WIFI_STA); char macStr[18]; - snprintf( - macStr, - sizeof(macStr), - "%02X:%02X:%02X:%02X:%02X:%02X", - mac[0], - mac[1], - mac[2], - mac[3], - mac[4], - mac[5] - ); + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); return String(macStr); } @@ -146,17 +136,6 @@ void BruceConfigPins::fromJson(JsonObject obj) { count++; log_e("Fail"); } - if (!root["PN532_Pins"].isNull()) { - SPIPins def = PN532_bus; - PN532_bus.fromJson(root["PN532_Pins"].as()); - if (PN532_bus.sck == GPIO_NUM_NC && def.sck != GPIO_NUM_NC) { - PN532_bus = def; - count++; - } - } else { - count++; - log_e("Fail"); - } if (!root["SDCard_Pins"].isNull()) { SPIPins def = SDCARD_bus; @@ -241,9 +220,6 @@ void BruceConfigPins::toJson(JsonObject obj) const { JsonObject _NRF = root["NRF24_Pins"].to(); NRF24_bus.toJson(_NRF); - JsonObject _PN532 = root["PN532_Pins"].to(); - PN532_bus.toJson(_PN532); - JsonObject _SD = root["SDCard_Pins"].to(); SDCARD_bus.toJson(_SD); @@ -370,7 +346,6 @@ void BruceConfigPins::validateConfig() { #endif validateSpiPins(CC1101_bus); validateSpiPins(NRF24_bus); - validateSpiPins(PN532_bus); validateSpiPins(SDCARD_bus); validateI2CPins(i2c_bus); validateUARTPins(uart_bus); @@ -400,12 +375,6 @@ void BruceConfigPins::setNrf24Pins(SPIPins value) { saveFile(); } -void BruceConfigPins::setPn532Pins(SPIPins value) { - PN532_bus = value; - validateSpiPins(PN532_bus); - saveFile(); -} - void BruceConfigPins::setSDCardPins(SPIPins value) { SDCARD_bus = value; validateSpiPins(SDCARD_bus); diff --git a/src/core/configPins.h b/src/core/configPins.h index d7ebd4b1e5..ed4c31678b 100644 --- a/src/core/configPins.h +++ b/src/core/configPins.h @@ -135,18 +135,6 @@ class BruceConfigPins { SPIPins NRF24_bus; #endif -#ifdef PN532_SCK_PIN - SPIPins PN532_bus = { - (gpio_num_t)PN532_SCK_PIN, - (gpio_num_t)PN532_MISO_PIN, - (gpio_num_t)PN532_MOSI_PIN, - (gpio_num_t)PN532_SS_PIN, - (gpio_num_t)PN532_CE_PIN - }; -#else - SPIPins PN532_bus; -#endif - #ifdef SDCARD_SCK SPIPins SDCARD_bus = { (gpio_num_t)SDCARD_SCK, (gpio_num_t)SDCARD_MISO, (gpio_num_t)SDCARD_MOSI, (gpio_num_t)SDCARD_CS @@ -234,7 +222,6 @@ class BruceConfigPins { void setCC1101Pins(SPIPins value); void setNrf24Pins(SPIPins value); - void setPn532Pins(SPIPins value); void setSDCardPins(SPIPins value); #if !defined(LITE_VERSION) void setLoRaPins(SPIPins value); diff --git a/src/core/connect/esp_connection.cpp b/src/core/connect/esp_connection.cpp index 646fb433f6..558bdc4831 100644 --- a/src/core/connect/esp_connection.cpp +++ b/src/core/connect/esp_connection.cpp @@ -170,9 +170,7 @@ void EspConnection::printMessage(Message message) { String EspConnection::macToString(const uint8_t *mac) { char macStr[18]; - snprintf( - macStr, sizeof(macStr), "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] - ); + sprintf(macStr, "%02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); return macStr; } diff --git a/src/core/connect/serial_commands.cpp b/src/core/connect/serial_commands.cpp index 9ab067692f..26f31c254b 100644 --- a/src/core/connect/serial_commands.cpp +++ b/src/core/connect/serial_commands.cpp @@ -111,7 +111,6 @@ EspSerialCmd::Message EspSerialCmd::createCmdMessage() { delay(500); String command = keyboard("", ESP_DATA_SIZE, "Serial Command"); - if (command == "\x1B") command = ""; Message msg = createMessage(command); printMessage(msg); diff --git a/src/core/display.cpp b/src/core/display.cpp index aebbf901a2..341234ee95 100644 --- a/src/core/display.cpp +++ b/src/core/display.cpp @@ -468,33 +468,6 @@ void padprintln(double n, int digits, int16_t padx) { int loopOptions( std::vector