initial commit
This commit is contained in:
commit
0a40daf4fa
|
|
@ -0,0 +1,5 @@
|
|||
schmatics
|
||||
documentation
|
||||
|
||||
# Clangd cache
|
||||
.cache
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 199 KiB |
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
ELECHOUSE_CC1101.cpp - CC1101 module library
|
||||
Copyright (c) 2010 Michael.
|
||||
Author: Michael, <www.elechouse.com>
|
||||
Version: November 12, 2010
|
||||
|
||||
This library is designed to use CC1101/CC1100 module on Arduino platform.
|
||||
CC1101/CC1100 module is an useful wireless module.Using the functions of the
|
||||
library, you can easily send and receive data by the CC1101/CC1100 module.
|
||||
Just have fun!
|
||||
For the details, please refer to the datasheet of CC1100/CC1101.
|
||||
----------------------------------------------------------------------------------------------------------------
|
||||
cc1101 Driver for RC Switch. Mod by Little Satan. With permission to modify and publish Wilson Shen (ELECHOUSE).
|
||||
----------------------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef ELECHOUSE_CC1101_SRC_DRV_h
|
||||
#define ELECHOUSE_CC1101_SRC_DRV_h
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
//***************************************CC1101 define**************************************************//
|
||||
// CC1101 CONFIG REGSITER
|
||||
#define CC1101_IOCFG2 0x00 // GDO2 output pin configuration
|
||||
#define CC1101_IOCFG1 0x01 // GDO1 output pin configuration
|
||||
#define CC1101_IOCFG0 0x02 // GDO0 output pin configuration
|
||||
#define CC1101_FIFOTHR 0x03 // RX FIFO and TX FIFO thresholds
|
||||
#define CC1101_SYNC1 0x04 // Sync word, high INT8U
|
||||
#define CC1101_SYNC0 0x05 // Sync word, low INT8U
|
||||
#define CC1101_PKTLEN 0x06 // Packet length
|
||||
#define CC1101_PKTCTRL1 0x07 // Packet automation control
|
||||
#define CC1101_PKTCTRL0 0x08 // Packet automation control
|
||||
#define CC1101_ADDR 0x09 // Device address
|
||||
#define CC1101_CHANNR 0x0A // Channel number
|
||||
#define CC1101_FSCTRL1 0x0B // Frequency synthesizer control
|
||||
#define CC1101_FSCTRL0 0x0C // Frequency synthesizer control
|
||||
#define CC1101_FREQ2 0x0D // Frequency control word, high INT8U
|
||||
#define CC1101_FREQ1 0x0E // Frequency control word, middle INT8U
|
||||
#define CC1101_FREQ0 0x0F // Frequency control word, low INT8U
|
||||
#define CC1101_MDMCFG4 0x10 // Modem configuration
|
||||
#define CC1101_MDMCFG3 0x11 // Modem configuration
|
||||
#define CC1101_MDMCFG2 0x12 // Modem configuration
|
||||
#define CC1101_MDMCFG1 0x13 // Modem configuration
|
||||
#define CC1101_MDMCFG0 0x14 // Modem configuration
|
||||
#define CC1101_DEVIATN 0x15 // Modem deviation setting
|
||||
#define CC1101_MCSM2 0x16 // Main Radio Control State Machine configuration
|
||||
#define CC1101_MCSM1 0x17 // Main Radio Control State Machine configuration
|
||||
#define CC1101_MCSM0 0x18 // Main Radio Control State Machine configuration
|
||||
#define CC1101_FOCCFG 0x19 // Frequency Offset Compensation configuration
|
||||
#define CC1101_BSCFG 0x1A // Bit Synchronization configuration
|
||||
#define CC1101_AGCCTRL2 0x1B // AGC control
|
||||
#define CC1101_AGCCTRL1 0x1C // AGC control
|
||||
#define CC1101_AGCCTRL0 0x1D // AGC control
|
||||
#define CC1101_WOREVT1 0x1E // High INT8U Event 0 timeout
|
||||
#define CC1101_WOREVT0 0x1F // Low INT8U Event 0 timeout
|
||||
#define CC1101_WORCTRL 0x20 // Wake On Radio control
|
||||
#define CC1101_FREND1 0x21 // Front end RX configuration
|
||||
#define CC1101_FREND0 0x22 // Front end TX configuration
|
||||
#define CC1101_FSCAL3 0x23 // Frequency synthesizer calibration
|
||||
#define CC1101_FSCAL2 0x24 // Frequency synthesizer calibration
|
||||
#define CC1101_FSCAL1 0x25 // Frequency synthesizer calibration
|
||||
#define CC1101_FSCAL0 0x26 // Frequency synthesizer calibration
|
||||
#define CC1101_RCCTRL1 0x27 // RC oscillator configuration
|
||||
#define CC1101_RCCTRL0 0x28 // RC oscillator configuration
|
||||
#define CC1101_FSTEST 0x29 // Frequency synthesizer calibration control
|
||||
#define CC1101_PTEST 0x2A // Production test
|
||||
#define CC1101_AGCTEST 0x2B // AGC test
|
||||
#define CC1101_TEST2 0x2C // Various test settings
|
||||
#define CC1101_TEST1 0x2D // Various test settings
|
||||
#define CC1101_TEST0 0x2E // Various test settings
|
||||
|
||||
//CC1101 Strobe commands
|
||||
#define CC1101_SRES 0x30 // Reset chip.
|
||||
#define CC1101_SFSTXON 0x31 // Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).
|
||||
// If in RX/TX: Go to a wait state where only the synthesizer is
|
||||
// running (for quick RX / TX turnaround).
|
||||
#define CC1101_SXOFF 0x32 // Turn off crystal oscillator.
|
||||
#define CC1101_SCAL 0x33 // Calibrate frequency synthesizer and turn it off
|
||||
// (enables quick start).
|
||||
#define CC1101_SRX 0x34 // Enable RX. Perform calibration first if coming from IDLE and
|
||||
// MCSM0.FS_AUTOCAL=1.
|
||||
#define CC1101_STX 0x35 // In IDLE state: Enable TX. Perform calibration first if
|
||||
// MCSM0.FS_AUTOCAL=1. If in RX state and CCA is enabled:
|
||||
// Only go to TX if channel is clear.
|
||||
#define CC1101_SIDLE 0x36 // Exit RX / TX, turn off frequency synthesizer and exit
|
||||
// Wake-On-Radio mode if applicable.
|
||||
#define CC1101_SAFC 0x37 // Perform AFC adjustment of the frequency synthesizer
|
||||
#define CC1101_SWOR 0x38 // Start automatic RX polling sequence (Wake-on-Radio)
|
||||
#define CC1101_SPWD 0x39 // Enter power down mode when CSn goes high.
|
||||
#define CC1101_SFRX 0x3A // Flush the RX FIFO buffer.
|
||||
#define CC1101_SFTX 0x3B // Flush the TX FIFO buffer.
|
||||
#define CC1101_SWORRST 0x3C // Reset real time clock.
|
||||
#define CC1101_SNOP 0x3D // No operation. May be used to pad strobe commands to two
|
||||
// INT8Us for simpler software.
|
||||
//CC1101 STATUS REGSITER
|
||||
#define CC1101_PARTNUM 0x30
|
||||
#define CC1101_VERSION 0x31
|
||||
#define CC1101_FREQEST 0x32
|
||||
#define CC1101_LQI 0x33
|
||||
#define CC1101_RSSI 0x34
|
||||
#define CC1101_MARCSTATE 0x35
|
||||
#define CC1101_WORTIME1 0x36
|
||||
#define CC1101_WORTIME0 0x37
|
||||
#define CC1101_PKTSTATUS 0x38
|
||||
#define CC1101_VCO_VC_DAC 0x39
|
||||
#define CC1101_TXBYTES 0x3A
|
||||
#define CC1101_RXBYTES 0x3B
|
||||
|
||||
//CC1101 PATABLE,TXFIFO,RXFIFO
|
||||
#define CC1101_PATABLE 0x3E
|
||||
#define CC1101_TXFIFO 0x3F
|
||||
#define CC1101_RXFIFO 0x3F
|
||||
|
||||
//************************************* class **************************************************//
|
||||
class ELECHOUSE_CC1101
|
||||
{
|
||||
private:
|
||||
void SpiStart(void);
|
||||
void SpiEnd(void);
|
||||
void GDO_Set (void);
|
||||
void GDO0_Set (void);
|
||||
void Reset (void);
|
||||
void setSpi(void);
|
||||
void RegConfigSettings(void);
|
||||
void Calibrate(void);
|
||||
void Split_PKTCTRL0(void);
|
||||
void Split_PKTCTRL1(void);
|
||||
void Split_MDMCFG1(void);
|
||||
void Split_MDMCFG2(void);
|
||||
void Split_MDMCFG4(void);
|
||||
public:
|
||||
void Init(void);
|
||||
byte SpiReadStatus(byte addr);
|
||||
void setSpiPin(byte sck, byte miso, byte mosi, byte ss);
|
||||
void addSpiPin(byte sck, byte miso, byte mosi, byte ss, byte modul);
|
||||
void setGDO(byte gdo0, byte gdo2);
|
||||
void setGDO0(byte gdo0);
|
||||
void addGDO(byte gdo0, byte gdo2, byte modul);
|
||||
void addGDO0(byte gdo0, byte modul);
|
||||
void setModul(byte modul);
|
||||
void setCCMode(bool s);
|
||||
void setModulation(byte m);
|
||||
void setPA(int p);
|
||||
void setMHZ(float mhz);
|
||||
void setChannel(byte chnl);
|
||||
void setChsp(float f);
|
||||
void setRxBW(float f);
|
||||
void setDRate(float d);
|
||||
void setDeviation(float d);
|
||||
void SetTx(void);
|
||||
void SetRx(void);
|
||||
void SetTx(float mhz);
|
||||
void SetRx(float mhz);
|
||||
int getRssi(void);
|
||||
byte getLqi(void);
|
||||
void setSres(void);
|
||||
void setSidle(void);
|
||||
void goSleep(void);
|
||||
void SendData(byte *txBuffer, byte size);
|
||||
void SendData(char *txchar);
|
||||
void SendData(byte *txBuffer, byte size, int t);
|
||||
void SendData(char *txchar, int t);
|
||||
byte CheckReceiveFlag(void);
|
||||
byte ReceiveData(byte *rxBuffer);
|
||||
bool CheckCRC(void);
|
||||
void SpiStrobe(byte strobe);
|
||||
void SpiWriteReg(byte addr, byte value);
|
||||
void SpiWriteBurstReg(byte addr, byte *buffer, byte num);
|
||||
byte SpiReadReg(byte addr);
|
||||
void SpiReadBurstReg(byte addr, byte *buffer, byte num);
|
||||
void setClb(byte b, byte s, byte e);
|
||||
bool getCC1101(void);
|
||||
byte getMode(void);
|
||||
void setSyncWord(byte sh, byte sl);
|
||||
void setAddr(byte v);
|
||||
void setWhiteData(bool v);
|
||||
void setPktFormat(byte v);
|
||||
void setCrc(bool v);
|
||||
void setLengthConfig(byte v);
|
||||
void setPacketLength(byte v);
|
||||
void setDcFilterOff(bool v);
|
||||
void setManchester(bool v);
|
||||
void setSyncMode(byte v);
|
||||
void setFEC(bool v);
|
||||
void setPRE(byte v);
|
||||
void setPQT(byte v);
|
||||
void setCRC_AF(bool v);
|
||||
void setAppendStatus(bool v);
|
||||
void setAdrChk(byte v);
|
||||
bool CheckRxFifo(int t);
|
||||
};
|
||||
|
||||
extern ELECHOUSE_CC1101 ELECHOUSE_cc1101;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#include <Arduino.h>
|
||||
#include <USBHIDKeyboard.h>
|
||||
|
||||
extern USBHIDKeyboard Keyboard;
|
||||
|
||||
void runBadUSBDemo()
|
||||
{
|
||||
delay(2000);
|
||||
Keyboard.println("");
|
||||
Keyboard.println("#-FEATURES:");
|
||||
Keyboard.println("1- WIFI ATTACKS");
|
||||
Keyboard.println("2- BLE ATTACKS");
|
||||
Keyboard.println("3- BAD USB");
|
||||
Keyboard.println("4- NFC");
|
||||
Keyboard.println("5- INFRARED");
|
||||
Keyboard.println("6- SUB-GHZ");
|
||||
Keyboard.println("7- GPIO");
|
||||
Keyboard.println("8- APPS");
|
||||
Keyboard.println("9- SETTINGS");
|
||||
Keyboard.println("10- FILES");
|
||||
|
||||
}
|
||||
|
||||
void runBadUSBOpenCMD()
|
||||
{
|
||||
delay(2000);
|
||||
Keyboard.println("");
|
||||
Keyboard.println("#-FEATURES:");
|
||||
Keyboard.println("1- WIFI ATTACKS");
|
||||
Keyboard.println("2- BLE ATTACKS");
|
||||
Keyboard.println("3- BAD USB");
|
||||
Keyboard.println("4- NFC");
|
||||
Keyboard.println("5- INFRARED");
|
||||
Keyboard.println("6- SUB-GHZ");
|
||||
Keyboard.println("7- GPIO");
|
||||
Keyboard.println("8- APPS");
|
||||
Keyboard.println("9- SETTINGS");
|
||||
Keyboard.println("10- FILES");
|
||||
}
|
||||
|
||||
void runBadUSBRickroll()
|
||||
{
|
||||
delay(2000);
|
||||
Keyboard.println("");
|
||||
Keyboard.println("#-FEATURES:");
|
||||
Keyboard.println("1- WIFI ATTACKS");
|
||||
Keyboard.println("2- BLE ATTACKS");
|
||||
Keyboard.println("3- BAD USB");
|
||||
Keyboard.println("4- NFC");
|
||||
Keyboard.println("5- INFRARED");
|
||||
Keyboard.println("6- SUB-GHZ");
|
||||
Keyboard.println("7- GPIO");
|
||||
Keyboard.println("8- APPS");
|
||||
Keyboard.println("9- SETTINGS");
|
||||
Keyboard.println("10- FILES");
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
void runBadUSBDemo();
|
||||
void runBadUSBOpenCMD();
|
||||
void runBadUSBRickroll();
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
#include <Arduino.h>
|
||||
#include <BLEDevice.h>
|
||||
#include <BLEScan.h>
|
||||
#include <BLEAdvertisedDevice.h>
|
||||
#include <vector>
|
||||
|
||||
#include "display.h"
|
||||
#include "buttons.h"
|
||||
#include "config.h"
|
||||
|
||||
// ===== DEVICE STRUCT =====
|
||||
struct BLEDeviceInfo {
|
||||
String name;
|
||||
String address;
|
||||
int rssi;
|
||||
String manufacturer;
|
||||
String deviceType;
|
||||
};
|
||||
|
||||
static std::vector<BLEDeviceInfo> devices;
|
||||
static BLEScan *pBLEScan;
|
||||
static int selectedIndex = 0;
|
||||
|
||||
// ===== CALLBACK =====
|
||||
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
|
||||
void onResult(BLEAdvertisedDevice advertisedDevice) override {
|
||||
BLEDeviceInfo dev;
|
||||
|
||||
String tempName = advertisedDevice.getName();
|
||||
|
||||
if (tempName.length() == 0 && advertisedDevice.haveServiceData()) {
|
||||
tempName = advertisedDevice.getServiceData().c_str();
|
||||
}
|
||||
|
||||
if (tempName.length() == 0) {
|
||||
String addr = advertisedDevice.getAddress().toString().c_str();
|
||||
tempName = "BLE_" + addr.substring(addr.length() - 5);
|
||||
}
|
||||
|
||||
dev.name = tempName;
|
||||
dev.address = advertisedDevice.getAddress().toString().c_str();
|
||||
dev.rssi = advertisedDevice.getRSSI();
|
||||
|
||||
if (advertisedDevice.haveManufacturerData()) {
|
||||
String mData = advertisedDevice.getManufacturerData().c_str();
|
||||
|
||||
if (mData.length() >= 2) {
|
||||
char buffer[10];
|
||||
sprintf(buffer, "0x%02X%02X",
|
||||
(uint8_t)mData[1],
|
||||
(uint8_t)mData[0]);
|
||||
dev.manufacturer = String(buffer);
|
||||
} else {
|
||||
dev.manufacturer = "unknown";
|
||||
}
|
||||
} else {
|
||||
dev.manufacturer = "unknown";
|
||||
}
|
||||
|
||||
if (advertisedDevice.haveServiceUUID()) {
|
||||
dev.deviceType =
|
||||
advertisedDevice.getServiceUUID().toString().c_str();
|
||||
} else {
|
||||
dev.deviceType = "unknown";
|
||||
}
|
||||
|
||||
devices.push_back(dev);
|
||||
}
|
||||
};
|
||||
|
||||
// ===== DRAW MENU =====
|
||||
void ble_drawMenu()
|
||||
{
|
||||
u8g2.clearBuffer();
|
||||
|
||||
if (devices.empty())
|
||||
{
|
||||
u8g2.setFont(u8g2_font_6x12_tr);
|
||||
u8g2.drawStr(0, 30, "No devices");
|
||||
u8g2.drawStr(0, 45, "Press BACK");
|
||||
}
|
||||
else
|
||||
{
|
||||
u8g2.setFont(u8g2_font_5x8_tr);
|
||||
|
||||
char counter[20];
|
||||
sprintf(counter, "%d/%d", selectedIndex + 1, (int)devices.size());
|
||||
u8g2.drawStr(0, 8, counter);
|
||||
|
||||
u8g2.setFont(u8g2_font_6x10_tr);
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
int idx = selectedIndex + i;
|
||||
if (idx >= devices.size()) break;
|
||||
|
||||
int y = 22 + i * 14;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
u8g2.drawBox(0, y - 10, 128, 12);
|
||||
u8g2.setDrawColor(0);
|
||||
}
|
||||
|
||||
String text = devices[idx].name;
|
||||
if (text.length() > 12)
|
||||
text = text.substring(0, 12) + "..";
|
||||
|
||||
text += " (" + String(devices[idx].rssi) + ")";
|
||||
|
||||
u8g2.drawStr(2, y, text.c_str());
|
||||
|
||||
if (i == 0)
|
||||
u8g2.setDrawColor(1);
|
||||
}
|
||||
}
|
||||
|
||||
u8g2.sendBuffer();
|
||||
}
|
||||
|
||||
// ===== DEVICE DETAILS =====
|
||||
void ble_drawDetails(const BLEDeviceInfo &dev)
|
||||
{
|
||||
u8g2.clearBuffer();
|
||||
u8g2.setFont(u8g2_font_5x8_tr);
|
||||
|
||||
u8g2.drawStr(0, 10, dev.name.c_str());
|
||||
u8g2.drawStr(0, 20, dev.address.c_str());
|
||||
|
||||
char rssiStr[20];
|
||||
sprintf(rssiStr, "RSSI: %d", dev.rssi);
|
||||
u8g2.drawStr(0, 30, rssiStr);
|
||||
|
||||
u8g2.drawStr(0, 40, dev.manufacturer.c_str());
|
||||
|
||||
u8g2.sendBuffer();
|
||||
}
|
||||
|
||||
// ===== SCAN =====
|
||||
void ble_scan()
|
||||
{
|
||||
devices.clear();
|
||||
|
||||
u8g2.clearBuffer();
|
||||
u8g2.drawStr(10, 30, "Scanning...");
|
||||
u8g2.sendBuffer();
|
||||
|
||||
BLEDevice::init("");
|
||||
|
||||
pBLEScan = BLEDevice::getScan();
|
||||
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), false);
|
||||
pBLEScan->setActiveScan(true);
|
||||
pBLEScan->setInterval(100);
|
||||
pBLEScan->setWindow(99);
|
||||
|
||||
pBLEScan->start(5, false);
|
||||
|
||||
// remove duplicates
|
||||
std::vector<BLEDeviceInfo> unique;
|
||||
for (auto &d : devices)
|
||||
{
|
||||
bool exists = false;
|
||||
for (auto &u : unique)
|
||||
{
|
||||
if (u.address == d.address)
|
||||
{
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!exists) unique.push_back(d);
|
||||
}
|
||||
|
||||
devices = unique;
|
||||
}
|
||||
|
||||
// ===== MAIN LOOP =====
|
||||
void ble_loop()
|
||||
{
|
||||
static uint32_t lastPress = 0;
|
||||
|
||||
if (millis() - lastPress < 200)
|
||||
return;
|
||||
|
||||
if (btnDown() && selectedIndex < (int)devices.size() - 1)
|
||||
{
|
||||
selectedIndex++;
|
||||
ble_drawMenu();
|
||||
lastPress = millis();
|
||||
}
|
||||
else if (btnUp() && selectedIndex > 0)
|
||||
{
|
||||
selectedIndex--;
|
||||
ble_drawMenu();
|
||||
lastPress = millis();
|
||||
}
|
||||
else if (btnSelect() && !devices.empty())
|
||||
{
|
||||
ble_drawDetails(devices[selectedIndex]);
|
||||
delay(3000);
|
||||
ble_drawMenu();
|
||||
lastPress = millis();
|
||||
}
|
||||
else if (btnBack())
|
||||
{
|
||||
ble_scan();
|
||||
selectedIndex = 0;
|
||||
ble_drawMenu();
|
||||
lastPress = millis();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
void ble_scan();
|
||||
void ble_loop();
|
||||
void ble_drawMenu();
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#include "buttons.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
#define BTN_UP 4
|
||||
#define BTN_DOWN 5
|
||||
#define BTN_SELECT 6
|
||||
#define BTN_BACK 7
|
||||
|
||||
void buttonsInit()
|
||||
{
|
||||
pinMode(BTN_UP, INPUT_PULLUP);
|
||||
pinMode(BTN_DOWN, INPUT_PULLUP);
|
||||
pinMode(BTN_SELECT, INPUT_PULLUP);
|
||||
pinMode(BTN_BACK, INPUT_PULLUP);
|
||||
}
|
||||
|
||||
bool btnUp() { return !digitalRead(BTN_UP); }
|
||||
bool btnDown() { return !digitalRead(BTN_DOWN); }
|
||||
bool btnSelect() { return !digitalRead(BTN_SELECT); }
|
||||
bool btnBack() { return !digitalRead(BTN_BACK); }
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
void buttonsInit();
|
||||
|
||||
bool btnUp();
|
||||
bool btnDown();
|
||||
bool btnSelect();
|
||||
bool btnBack();
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
#include <Arduino.h>
|
||||
#include "ELECHOUSE_CC1101_SRC_DRV.h"
|
||||
#include "cc1101.h"
|
||||
#include "config.h"
|
||||
|
||||
// ===== CONFIG =====
|
||||
#define RAW_BUF_MAX 512
|
||||
|
||||
// ===== STATE =====
|
||||
static bool cc1101Inited = false;
|
||||
|
||||
// ===== CAPTURE STATE =====
|
||||
volatile unsigned long captureBuffer[RAW_BUF_MAX];
|
||||
volatile int pulseIndex = 0;
|
||||
volatile unsigned long lastEdgeTime = 0;
|
||||
volatile bool capturing = false;
|
||||
|
||||
// ===== RF SETTINGS =====
|
||||
float currentFreq = 433.92;
|
||||
float dataRate = 3.79372;
|
||||
float deviation = 0.0;
|
||||
float rxBW = 325.0;
|
||||
int powerLevel = 10;
|
||||
|
||||
// ===== ISR =====
|
||||
void IRAM_ATTR pulseISR()
|
||||
{
|
||||
unsigned long now = micros();
|
||||
|
||||
if (!capturing) return;
|
||||
if (pulseIndex >= RAW_BUF_MAX) return;
|
||||
|
||||
unsigned long duration = now - lastEdgeTime;
|
||||
|
||||
if (duration < 50) return;
|
||||
|
||||
captureBuffer[pulseIndex++] = duration;
|
||||
lastEdgeTime = now;
|
||||
}
|
||||
|
||||
// ===== OOK SETUP =====
|
||||
void setupOOKMode()
|
||||
{
|
||||
ELECHOUSE_cc1101.SetRx();
|
||||
ELECHOUSE_cc1101.setMHZ(currentFreq);
|
||||
|
||||
ELECHOUSE_cc1101.setModulation(0); // ASK/OOK
|
||||
ELECHOUSE_cc1101.setDRate(dataRate);
|
||||
ELECHOUSE_cc1101.setDeviation(0);
|
||||
ELECHOUSE_cc1101.setRxBW(rxBW);
|
||||
ELECHOUSE_cc1101.setSyncMode(0);
|
||||
ELECHOUSE_cc1101.setPA(powerLevel);
|
||||
}
|
||||
|
||||
// ===== INIT (LAZY, SAFE) =====
|
||||
bool initCC1101()
|
||||
{
|
||||
if (cc1101Inited)
|
||||
return true;
|
||||
|
||||
Serial.println("Initializing CC1101...");
|
||||
|
||||
// IMPORTANT: no detachInterrupt here (causes crash if not installed)
|
||||
|
||||
ELECHOUSE_cc1101.setSpiPin(
|
||||
cc1101_SCK,
|
||||
cc1101_MISO,
|
||||
cc1101_MOSI,
|
||||
CC1101_CS
|
||||
);
|
||||
|
||||
ELECHOUSE_cc1101.setGDO(CC1101_GDO0, CC1101_GDO2);
|
||||
|
||||
if (!ELECHOUSE_cc1101.getCC1101())
|
||||
{
|
||||
Serial.println("❌ CC1101 NOT FOUND");
|
||||
return false;
|
||||
}
|
||||
|
||||
delay(10); // let SPI settle
|
||||
|
||||
ELECHOUSE_cc1101.Init(); // THIS WAS YOUR FREEZE POINT
|
||||
setupOOKMode();
|
||||
|
||||
pinMode(CC1101_GDO0, INPUT);
|
||||
|
||||
Serial.println("✅ CC1101 READY");
|
||||
|
||||
cc1101Inited = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ===== CAPTURE CONTROL =====
|
||||
void startCapture()
|
||||
{
|
||||
pulseIndex = 0;
|
||||
capturing = true;
|
||||
lastEdgeTime = micros();
|
||||
|
||||
attachInterrupt(
|
||||
digitalPinToInterrupt(CC1101_GDO0),
|
||||
pulseISR,
|
||||
CHANGE
|
||||
);
|
||||
|
||||
Serial.println("Capture started");
|
||||
}
|
||||
|
||||
bool isCC1101Ready() {
|
||||
return cc1101Inited;
|
||||
}
|
||||
|
||||
void stopCapture()
|
||||
{
|
||||
capturing = false;
|
||||
|
||||
detachInterrupt(digitalPinToInterrupt(CC1101_GDO0));
|
||||
|
||||
Serial.println("Capture stopped");
|
||||
}
|
||||
|
||||
// ===== DEBUG PRINT =====
|
||||
void printCapture()
|
||||
{
|
||||
Serial.println("Captured pulses:");
|
||||
|
||||
for (int i = 0; i < pulseIndex; i++)
|
||||
{
|
||||
Serial.println(captureBuffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ===== REPLAY =====
|
||||
void replaySignal()
|
||||
{
|
||||
Serial.println("Replaying...");
|
||||
|
||||
ELECHOUSE_cc1101.SetTx();
|
||||
pinMode(CC1101_GDO0, OUTPUT);
|
||||
|
||||
for (int i = 0; i < pulseIndex; i++)
|
||||
{
|
||||
digitalWrite(CC1101_GDO0, (i % 2 == 0) ? HIGH : LOW);
|
||||
delayMicroseconds(captureBuffer[i]);
|
||||
}
|
||||
|
||||
digitalWrite(CC1101_GDO0, LOW);
|
||||
ELECHOUSE_cc1101.SetRx();
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
bool initCC1101();
|
||||
bool isCC1101Ready();
|
||||
|
||||
void startCapture();
|
||||
void stopCapture();
|
||||
void printCapture();
|
||||
void replaySignal();
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
|
||||
// ================= NRF24 =================
|
||||
#define CE1_PIN 10
|
||||
#define CSN1_PIN 11
|
||||
|
||||
#define CE2_PIN 12
|
||||
#define CSN2_PIN 13
|
||||
|
||||
#define NRF_SCK 18
|
||||
#define NRF_MISO 16
|
||||
#define NRF_MOSI 17
|
||||
|
||||
// ================== OLED ===================
|
||||
#define OLED_SDA_PIN 8
|
||||
#define OLED_SCL_PIN 9
|
||||
|
||||
/////////////////cc1101 vars//////////////
|
||||
// CC1101 via FSPI
|
||||
#define cc1101_SCK 15
|
||||
#define cc1101_MISO 3
|
||||
#define cc1101_MOSI 46
|
||||
|
||||
//////////////cc1101(1)//////////
|
||||
#define CC1101_CS 45
|
||||
#define CC1101_GDO0 21
|
||||
#define CC1101_GDO2 47
|
||||
|
||||
/////////////cc1101(2)//////////
|
||||
#define CC1101_2_CS 40
|
||||
#define CC1101_2_GDO0 41
|
||||
#define CC1101_2_GDO2 42
|
||||
|
||||
// SD Card via HSPI
|
||||
#define SD_SCK 14
|
||||
#define SD_MISO 39
|
||||
#define SD_MOSI 38
|
||||
#define SD_CS 37
|
||||
|
||||
|
||||
// =================== Buttons ====================
|
||||
#define BTN_UP 4
|
||||
#define BTN_DOWN 5
|
||||
#define BTN_SELECT 6
|
||||
#define BTN_BACK 7
|
||||
#define BTN_LEFT 1
|
||||
#define BTN_RIGHT 2
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,242 @@
|
|||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
#include <Wire.h>
|
||||
#include <RF24.h>
|
||||
#include "ELECHOUSE_CC1101_SRC_DRV.h"
|
||||
|
||||
#include "display.h"
|
||||
#include "buttons.h"
|
||||
#include "config.h"
|
||||
|
||||
// ===== EXTERNALS =====
|
||||
extern RF24 radio1;
|
||||
extern RF24 radio2;
|
||||
extern SPIClass *RADIO_SPI;
|
||||
extern U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2;
|
||||
|
||||
// ===== RESULTS =====
|
||||
struct DeviceStatus {
|
||||
bool nrf_link = false;
|
||||
bool nrf1 = false;
|
||||
bool nrf2 = false;
|
||||
bool cc1101 = false;
|
||||
bool oled = true;
|
||||
bool buttons = false;
|
||||
};
|
||||
|
||||
// ===== NRF CHECK =====
|
||||
bool checkNRF(RF24 &radio)
|
||||
{
|
||||
// safer: only init if needed
|
||||
if (!radio.isChipConnected()) {
|
||||
if (!radio.begin(RADIO_SPI))
|
||||
return false;
|
||||
}
|
||||
|
||||
return radio.isChipConnected();
|
||||
}
|
||||
|
||||
// ===== CC1101 CHECK =====
|
||||
bool checkCC1101()
|
||||
{
|
||||
ELECHOUSE_cc1101.setSpiPin(
|
||||
cc1101_SCK,
|
||||
cc1101_MISO,
|
||||
cc1101_MOSI,
|
||||
CC1101_CS
|
||||
);
|
||||
|
||||
delay(5); // important stabilization
|
||||
|
||||
return ELECHOUSE_cc1101.getCC1101();
|
||||
}
|
||||
|
||||
// ===== BUTTON CHECK =====
|
||||
bool checkButtons()
|
||||
{
|
||||
u8g2.clearBuffer();
|
||||
u8g2.setFont(u8g2_font_6x10_tr);
|
||||
u8g2.drawStr(0, 20, "Press any button...");
|
||||
u8g2.sendBuffer();
|
||||
|
||||
unsigned long start = millis();
|
||||
|
||||
while (millis() - start < 2000)
|
||||
{
|
||||
if (!digitalRead(BTN_UP) ||
|
||||
!digitalRead(BTN_DOWN) ||
|
||||
!digitalRead(BTN_SELECT) ||
|
||||
!digitalRead(BTN_BACK))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ===== DRAW =====
|
||||
#define MAX_ITEMS 6
|
||||
#define VISIBLE_ROWS 5
|
||||
|
||||
const char* labels[MAX_ITEMS] = {
|
||||
"NRF1",
|
||||
"NRF2",
|
||||
"LINK",
|
||||
"CC1101",
|
||||
"BUTTONS",
|
||||
"OLED"
|
||||
};
|
||||
|
||||
bool values[MAX_ITEMS];
|
||||
|
||||
int selectedIndex = 0;
|
||||
int offset = 0;
|
||||
|
||||
void drawStatus(DeviceStatus &s)
|
||||
{
|
||||
values[0] = s.nrf1;
|
||||
values[1] = s.nrf2;
|
||||
values[2] = s.nrf_link;
|
||||
values[3] = s.cc1101;
|
||||
values[4] = s.buttons;
|
||||
values[5] = s.oled;
|
||||
|
||||
u8g2.clearBuffer();
|
||||
u8g2.setFont(u8g2_font_6x10_tr);
|
||||
|
||||
// scrolling logic
|
||||
if (selectedIndex < offset)
|
||||
offset = selectedIndex;
|
||||
|
||||
if (selectedIndex >= offset + VISIBLE_ROWS)
|
||||
offset = selectedIndex - VISIBLE_ROWS + 1;
|
||||
|
||||
for (int i = 0; i < VISIBLE_ROWS; i++)
|
||||
{
|
||||
int item = offset + i;
|
||||
if (item >= MAX_ITEMS) break;
|
||||
|
||||
int y = 12 + i * 10;
|
||||
|
||||
if (item == selectedIndex)
|
||||
{
|
||||
u8g2.drawBox(0, y - 9, 128, 10);
|
||||
u8g2.setDrawColor(0);
|
||||
}
|
||||
|
||||
u8g2.drawStr(2, y, labels[item]);
|
||||
|
||||
if (values[item])
|
||||
u8g2.drawStr(80, y, "OK");
|
||||
else
|
||||
u8g2.drawStr(80, y, "FAIL");
|
||||
|
||||
if (item == selectedIndex)
|
||||
u8g2.setDrawColor(1);
|
||||
}
|
||||
|
||||
u8g2.sendBuffer();
|
||||
}
|
||||
|
||||
bool testNRFLink()
|
||||
{
|
||||
const byte address[6] = "00001";
|
||||
uint8_t payload = 0xAB;
|
||||
uint8_t received = 0;
|
||||
|
||||
// --- init radios ---
|
||||
if (!radio1.begin(RADIO_SPI)) return false;
|
||||
if (!radio2.begin(RADIO_SPI)) return false;
|
||||
|
||||
radio1.setPALevel(RF24_PA_LOW);
|
||||
radio2.setPALevel(RF24_PA_LOW);
|
||||
|
||||
radio1.setDataRate(RF24_1MBPS);
|
||||
radio2.setDataRate(RF24_1MBPS);
|
||||
|
||||
radio1.setChannel(100);
|
||||
radio2.setChannel(100);
|
||||
|
||||
radio1.setAutoAck(false);
|
||||
radio2.setAutoAck(false);
|
||||
|
||||
// --- configure pipes ---
|
||||
radio1.openWritingPipe(address);
|
||||
radio2.openReadingPipe(0, address);
|
||||
|
||||
radio2.startListening();
|
||||
|
||||
delay(50);
|
||||
|
||||
// --- send ---
|
||||
radio1.stopListening();
|
||||
bool sent = radio1.write(&payload, sizeof(payload));
|
||||
|
||||
if (!sent) return false;
|
||||
|
||||
// --- receive ---
|
||||
unsigned long start = millis();
|
||||
|
||||
while (millis() - start < 200)
|
||||
{
|
||||
if (radio2.available())
|
||||
{
|
||||
radio2.read(&received, sizeof(received));
|
||||
return (received == payload);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ===== MAIN =====
|
||||
void device_check_run()
|
||||
{
|
||||
DeviceStatus status;
|
||||
|
||||
Serial.println("Running device diagnostics...");
|
||||
|
||||
// NRF
|
||||
// NRF link test
|
||||
status.nrf_link = testNRFLink();
|
||||
status.nrf1 = checkNRF(radio1);
|
||||
status.nrf2 = checkNRF(radio2);
|
||||
|
||||
// CC1101
|
||||
status.cc1101 = checkCC1101();
|
||||
|
||||
// Buttons
|
||||
status.buttons = checkButtons();
|
||||
|
||||
drawStatus(status);
|
||||
|
||||
Serial.println("Diagnostics complete");
|
||||
|
||||
while (1)
|
||||
{
|
||||
drawStatus(status);
|
||||
|
||||
if (btnUp())
|
||||
{
|
||||
selectedIndex--;
|
||||
if (selectedIndex < 0) selectedIndex = MAX_ITEMS - 1;
|
||||
delay(150);
|
||||
}
|
||||
|
||||
if (btnDown())
|
||||
{
|
||||
selectedIndex++;
|
||||
if (selectedIndex >= MAX_ITEMS) selectedIndex = 0;
|
||||
delay(150);
|
||||
}
|
||||
|
||||
if (btnBack())
|
||||
{
|
||||
delay(150);
|
||||
break;
|
||||
}
|
||||
}}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
void device_check_run();
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#include "display.h"
|
||||
#include <Wire.h>
|
||||
#include "config.h"
|
||||
|
||||
|
||||
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(
|
||||
U8G2_R0,
|
||||
U8X8_PIN_NONE
|
||||
);
|
||||
|
||||
void displayInit()
|
||||
{
|
||||
Wire.begin(OLED_SDA_PIN, OLED_SCL_PIN);
|
||||
u8g2.begin();
|
||||
u8g2.setFont(u8g2_font_6x12_tr);
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <U8g2lib.h>
|
||||
|
||||
extern U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2;
|
||||
|
||||
void displayInit();
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
#include <Arduino.h>
|
||||
#include <USB.h>
|
||||
#include <USBHIDKeyboard.h>
|
||||
|
||||
#include <BLEDevice.h>
|
||||
#include <BLEScan.h>
|
||||
|
||||
#include <RF24.h>
|
||||
#include <nRF24L01.h>
|
||||
|
||||
#include "ELECHOUSE_CC1101_SRC_DRV.h"
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <esp_wifi.h>
|
||||
|
||||
#include <esp_chip_info.h>
|
||||
#include <esp_heap_caps.h>
|
||||
#include <esp_system.h>
|
||||
#include <SPI.h>
|
||||
|
||||
|
||||
#include "display.h"
|
||||
#include "buttons.h"
|
||||
#include "menu.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "cc1101.h"
|
||||
|
||||
// ================= USB HID =================
|
||||
USBHIDKeyboard Keyboard;
|
||||
|
||||
|
||||
RF24 radio1(CE1_PIN, CSN1_PIN);
|
||||
RF24 radio2(CE2_PIN, CSN2_PIN);
|
||||
SPIClass *RADIO_SPI;
|
||||
|
||||
|
||||
|
||||
|
||||
// ================= BLE SCAN =================
|
||||
BLEScan *pBLEScan;
|
||||
|
||||
|
||||
void startBLEScan()
|
||||
{
|
||||
BLEDevice::init("");
|
||||
|
||||
pBLEScan = BLEDevice::getScan();
|
||||
|
||||
pBLEScan->setActiveScan(true);
|
||||
|
||||
pBLEScan->start(5);
|
||||
|
||||
Serial.println("BLE scan complete");
|
||||
}
|
||||
|
||||
// ================= SYSTEM INFO =================
|
||||
void printSystemUsage()
|
||||
{
|
||||
esp_chip_info_t chip_info;
|
||||
|
||||
esp_chip_info(&chip_info);
|
||||
|
||||
Serial.printf("CPU cores: %d\n", chip_info.cores);
|
||||
|
||||
Serial.printf(
|
||||
"Free heap: %d bytes\n",
|
||||
heap_caps_get_free_size(MALLOC_CAP_DEFAULT)
|
||||
);
|
||||
|
||||
Serial.printf(
|
||||
"PSRAM free: %d bytes\n",
|
||||
heap_caps_get_free_size(MALLOC_CAP_SPIRAM)
|
||||
);
|
||||
}
|
||||
|
||||
void showSplash()
|
||||
{
|
||||
u8g2.clearBuffer();
|
||||
|
||||
u8g2.setFont(u8g2_font_logisoso20_tr); // big font
|
||||
u8g2.drawStr(10, 40, "Orion-RF");
|
||||
|
||||
u8g2.setFont(u8g2_font_5x8_tr); // small subtitle
|
||||
u8g2.drawStr(25, 58, "Initializing...");
|
||||
|
||||
u8g2.sendBuffer();
|
||||
|
||||
delay(1500); // 1.5 sec
|
||||
}
|
||||
|
||||
|
||||
// ================= SETUP =================
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
displayInit();
|
||||
showSplash();
|
||||
|
||||
buttonsInit();
|
||||
menuInit();
|
||||
|
||||
delay(1500);
|
||||
|
||||
USB.begin();
|
||||
Keyboard.begin();
|
||||
|
||||
// NRF SPI safety
|
||||
pinMode(CSN1_PIN, OUTPUT);
|
||||
digitalWrite(CSN1_PIN, HIGH);
|
||||
|
||||
pinMode(CSN2_PIN, OUTPUT);
|
||||
digitalWrite(CSN2_PIN, HIGH);
|
||||
|
||||
RADIO_SPI = new SPIClass(FSPI);
|
||||
RADIO_SPI->begin(NRF_SCK, NRF_MISO, NRF_MOSI);
|
||||
|
||||
printSystemUsage();
|
||||
|
||||
Serial.println("SYSTEM READY");
|
||||
}
|
||||
|
||||
// ================= LOOP =================
|
||||
void loop()
|
||||
{
|
||||
menuLoop();
|
||||
}
|
||||
|
|
@ -0,0 +1,278 @@
|
|||
#include <Arduino.h>
|
||||
#include "menu.h"
|
||||
#include "display.h"
|
||||
#include "buttons.h"
|
||||
#include "badusb.h"
|
||||
#include "nrf24.h"
|
||||
#include "cc1101.h"
|
||||
#include "blescanner.h"
|
||||
#include "wifi_scan.h"
|
||||
#include "wifi_analyzer.h"
|
||||
#include "device_check.h"
|
||||
|
||||
// ================= FEATURE HANDLERS =================
|
||||
void runSystemInfoFeature();
|
||||
void runRFCaptureFeature();
|
||||
void runBLEScanFeature();
|
||||
|
||||
|
||||
|
||||
// ================= MENU DATA =================
|
||||
|
||||
// Root menu
|
||||
const char *mainMenuItems[] = {
|
||||
"BadUSB",
|
||||
"RF Capture",
|
||||
"NRF Jammer",
|
||||
"BLE Scan",
|
||||
"Wifi Scan",
|
||||
"Wifi Analyzer",
|
||||
"System Info",
|
||||
"Device Check",
|
||||
"Restart"
|
||||
};
|
||||
|
||||
Menu mainMenu = {mainMenuItems, sizeof(mainMenuItems) / sizeof(mainMenuItems[0])};
|
||||
|
||||
// BadUSB submenu
|
||||
const char *badusbItems[] = {
|
||||
"Demo",
|
||||
"Open CMD",
|
||||
"Rickroll"};
|
||||
|
||||
Menu badusbMenu = {badusbItems, 3};
|
||||
|
||||
// ================= MENU STATE =================
|
||||
|
||||
Menu *currentMenu = &mainMenu;
|
||||
|
||||
int menuIndex = 0;
|
||||
int menuOffset = 0;
|
||||
|
||||
#define MENU_VISIBLE_ROWS 4
|
||||
|
||||
bool insideFeature = false;
|
||||
|
||||
// ================= DRAW =================
|
||||
|
||||
void drawMenu()
|
||||
{
|
||||
u8g2.clearBuffer();
|
||||
|
||||
// scroll handling
|
||||
if (menuIndex < menuOffset)
|
||||
menuOffset = menuIndex;
|
||||
|
||||
if (menuIndex >= menuOffset + MENU_VISIBLE_ROWS)
|
||||
menuOffset = menuIndex - MENU_VISIBLE_ROWS + 1;
|
||||
|
||||
for (int i = 0; i < MENU_VISIBLE_ROWS; i++)
|
||||
{
|
||||
int item = menuOffset + i;
|
||||
|
||||
if (item >= currentMenu->size)
|
||||
break;
|
||||
|
||||
if (item == menuIndex)
|
||||
u8g2.drawStr(0, 14 + i * 14, ">");
|
||||
|
||||
u8g2.drawStr(10, 14 + i * 14, currentMenu->items[item]);
|
||||
}
|
||||
|
||||
// scroll indicators
|
||||
if (menuOffset > 0)
|
||||
u8g2.drawStr(118, 10, "^");
|
||||
|
||||
if (menuOffset + MENU_VISIBLE_ROWS < currentMenu->size)
|
||||
u8g2.drawStr(118, 62, "v");
|
||||
|
||||
u8g2.sendBuffer();
|
||||
}
|
||||
|
||||
// ================= FEATURE EXECUTION =================
|
||||
|
||||
void launchFeature()
|
||||
{
|
||||
insideFeature = true;
|
||||
|
||||
if (currentMenu == &mainMenu)
|
||||
{
|
||||
switch (menuIndex)
|
||||
{
|
||||
case 0: // BadUSB → enter submenu
|
||||
currentMenu = &badusbMenu;
|
||||
menuIndex = 0;
|
||||
menuOffset = 0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (!isCC1101Ready()) {
|
||||
if (!initCC1101()) {
|
||||
Serial.println("CC1101 failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("Ready to capture...");
|
||||
|
||||
startCapture();
|
||||
delay(5000);
|
||||
stopCapture();
|
||||
printCapture();
|
||||
break;
|
||||
case 2:
|
||||
startNRFJammer();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
ble_scan();
|
||||
ble_drawMenu();
|
||||
while (1) {
|
||||
ble_loop();
|
||||
if (btnBack())
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
{
|
||||
// Start scan once
|
||||
wifi_scan_start();
|
||||
wifi_scan_draw();
|
||||
|
||||
while (1) {
|
||||
wifi_scan_loop();
|
||||
// EXIT condition handled ONLY here
|
||||
if (btnBack()) {
|
||||
delay(150); // debounce
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
|
||||
wifi_analyzer_start();
|
||||
|
||||
bool prevBack = false;
|
||||
while (1)
|
||||
{
|
||||
wifi_analyzer_loop();
|
||||
bool nowBack = btnBack();
|
||||
if (nowBack && !prevBack)
|
||||
{
|
||||
delay(150);
|
||||
break;
|
||||
}
|
||||
prevBack = nowBack;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 6:
|
||||
runSystemInfoFeature();
|
||||
break;
|
||||
case 7:
|
||||
device_check_run();
|
||||
break;
|
||||
case 8:
|
||||
u8g2.clearBuffer();
|
||||
u8g2.setFont(u8g2_font_6x13_tr);
|
||||
u8g2.drawStr(30, 30, "Restarting...");
|
||||
u8g2.sendBuffer();
|
||||
delay(1000);
|
||||
ESP.restart();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (currentMenu == &badusbMenu)
|
||||
{
|
||||
switch (menuIndex)
|
||||
{
|
||||
case 0:
|
||||
runBadUSBDemo();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
Serial.println("Open CMD payload");
|
||||
runBadUSBOpenCMD();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
Serial.println("Rickroll payload");
|
||||
runBadUSBRickroll();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
insideFeature = false;
|
||||
|
||||
drawMenu();
|
||||
}
|
||||
|
||||
// ================= INIT =================
|
||||
|
||||
void menuInit()
|
||||
{
|
||||
currentMenu = &mainMenu;
|
||||
menuIndex = 0;
|
||||
menuOffset = 0;
|
||||
|
||||
drawMenu();
|
||||
}
|
||||
|
||||
// ================= LOOP =================
|
||||
|
||||
void menuLoop()
|
||||
{
|
||||
static uint32_t lastPress = 0;
|
||||
|
||||
if (insideFeature)
|
||||
return;
|
||||
|
||||
if (millis() - lastPress < 150)
|
||||
return;
|
||||
|
||||
if (btnUp())
|
||||
{
|
||||
menuIndex--;
|
||||
|
||||
if (menuIndex < 0)
|
||||
menuIndex = currentMenu->size - 1;
|
||||
|
||||
drawMenu();
|
||||
lastPress = millis();
|
||||
}
|
||||
|
||||
else if (btnDown())
|
||||
{
|
||||
menuIndex++;
|
||||
|
||||
if (menuIndex >= currentMenu->size)
|
||||
menuIndex = 0;
|
||||
|
||||
drawMenu();
|
||||
lastPress = millis();
|
||||
}
|
||||
|
||||
else if (btnSelect())
|
||||
{
|
||||
launchFeature();
|
||||
lastPress = millis();
|
||||
}
|
||||
|
||||
else if (btnBack())
|
||||
{
|
||||
if (currentMenu != &mainMenu)
|
||||
{
|
||||
currentMenu = &mainMenu;
|
||||
menuIndex = 0;
|
||||
menuOffset = 0;
|
||||
|
||||
drawMenu();
|
||||
}
|
||||
|
||||
lastPress = millis();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
struct Menu
|
||||
{
|
||||
const char **items;
|
||||
int size;
|
||||
};
|
||||
|
||||
void menuInit();
|
||||
void menuLoop();
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
#include <Arduino.h>
|
||||
#include <RF24.h>
|
||||
#include "buttons.h"
|
||||
#include "nrf24.h"
|
||||
#include "display.h"
|
||||
#define JAM_DURATION 500
|
||||
|
||||
extern SPIClass *RADIO_SPI;
|
||||
extern RF24 radio1;
|
||||
extern RF24 radio2;
|
||||
|
||||
void initNRF(RF24 &radio)
|
||||
{
|
||||
radio.begin(RADIO_SPI);
|
||||
|
||||
radio.setAutoAck(false);
|
||||
radio.stopListening();
|
||||
|
||||
radio.setRetries(0, 0);
|
||||
radio.setDataRate(RF24_2MBPS);
|
||||
radio.setPALevel(RF24_PA_MAX);
|
||||
|
||||
radio.openWritingPipe(0xE7E7E7E7E7LL);
|
||||
}
|
||||
|
||||
|
||||
void jamChannels(const char* label, int startCh, int endCh) {
|
||||
byte data1[32], data2[32];
|
||||
for (int i = 0; i < 32; i++) {
|
||||
data1[i] = random(0, 256);
|
||||
data2[i] = random(0, 256);
|
||||
}
|
||||
|
||||
for (int ch = startCh; ch <= endCh; ch++) {
|
||||
// Status screen
|
||||
u8g2.clearBuffer();
|
||||
u8g2.drawStr(0, 10, "Jamming:");
|
||||
u8g2.setCursor(60, 10);
|
||||
u8g2.print(label);
|
||||
u8g2.setCursor(0, 30);
|
||||
u8g2.print("Channel: ");
|
||||
u8g2.print(ch);
|
||||
u8g2.sendBuffer();
|
||||
|
||||
unsigned long startTime = millis();
|
||||
while (millis() - startTime < JAM_DURATION) {
|
||||
radio1.setChannel(ch);
|
||||
radio1.stopListening();
|
||||
radio1.write(data1, sizeof(data1));
|
||||
delayMicroseconds(100);
|
||||
|
||||
radio2.setChannel(ch);
|
||||
radio2.stopListening();
|
||||
radio2.write(data2, sizeof(data2));
|
||||
delayMicroseconds(100);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void nrfJammerSweep()
|
||||
{
|
||||
static uint8_t ch1 = 0;
|
||||
static uint8_t ch2 = 124;
|
||||
|
||||
uint8_t payload[32] = {0xFF};
|
||||
|
||||
radio1.setChannel(ch1);
|
||||
radio1.writeFast(payload, sizeof(payload));
|
||||
|
||||
radio2.setChannel(ch2);
|
||||
radio2.writeFast(payload, sizeof(payload));
|
||||
|
||||
ch1++;
|
||||
ch2--;
|
||||
|
||||
if (ch1 > 124) ch1 = 0;
|
||||
if (ch2 > 124) ch2 = 124;
|
||||
}
|
||||
|
||||
void startNRFJammer()
|
||||
{
|
||||
initNRF(radio1);
|
||||
initNRF(radio2);
|
||||
|
||||
Serial.println("NRF JAMMER STARTED");
|
||||
// nrfJammerSweep();
|
||||
jamChannels("Bluetooth", 0, 78);
|
||||
|
||||
|
||||
if (btnBack())
|
||||
{
|
||||
Serial.println("Jammer stopped");
|
||||
return;
|
||||
}
|
||||
|
||||
delayMicroseconds(200);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <RF24.h>
|
||||
|
||||
// Initialization
|
||||
void initNRF(RF24 &radio);
|
||||
|
||||
// Jammer modes
|
||||
void startNRFJammer(); // dual-radio sweep jammer
|
||||
void stopNRFJammer(); // (optional, for future)
|
||||
|
||||
// Advanced (later)
|
||||
void nrfJammerSweep(); // internal, but can expose if needed
|
||||
void nrfSetChannel(uint8_t ch);
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#include <Arduino.h>
|
||||
|
||||
|
||||
void runRFCaptureFeature()
|
||||
{
|
||||
Serial.println("RF Capture not implemented yet");
|
||||
}
|
||||
|
||||
|
||||
void runBLEScanFeature()
|
||||
{
|
||||
Serial.println("BLE Scan not implemented yet");
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
#include <Arduino.h>
|
||||
#include "display.h"
|
||||
#include "buttons.h"
|
||||
#include <esp_chip_info.h>
|
||||
#include <esp_heap_caps.h>
|
||||
|
||||
void runSystemInfoFeature()
|
||||
{
|
||||
esp_chip_info_t chip_info;
|
||||
|
||||
esp_chip_info(&chip_info);
|
||||
|
||||
while (true)
|
||||
{
|
||||
//u8g2.clearBuffer();
|
||||
|
||||
//char buf[32];
|
||||
|
||||
//sprintf(buf, "Cores: %d", chip_info.cores);
|
||||
//u8g2.drawStr(0, 14, buf);
|
||||
|
||||
//sprintf(buf, "Heap: %d",
|
||||
// heap_caps_get_free_size(MALLOC_CAP_DEFAULT));
|
||||
//u8g2.drawStr(0, 28, buf);
|
||||
|
||||
|
||||
//u8g2.drawStr(0, 60, "BACK to exit");
|
||||
|
||||
// Get RAM info
|
||||
size_t freeHeap = heap_caps_get_free_size(MALLOC_CAP_DEFAULT);
|
||||
size_t totalHeap = heap_caps_get_total_size(MALLOC_CAP_DEFAULT);
|
||||
int ramUsage = 100 - ((freeHeap * 100) / totalHeap);
|
||||
|
||||
// Get Flash info
|
||||
//uint32_t flashSize = spi_flash_get_chip_size();
|
||||
uint32_t flashSize = ESP.getFlashChipSize();
|
||||
uint32_t flashUsed = ESP.getSketchSize();
|
||||
int flashUsage = (flashUsed * 100) / flashSize;
|
||||
|
||||
// Temperature (approx)
|
||||
uint8_t temperature = temperatureRead();
|
||||
|
||||
// Chip info
|
||||
esp_chip_info_t chip_info;
|
||||
esp_chip_info(&chip_info);
|
||||
|
||||
u8g2.clearBuffer();
|
||||
u8g2.setFont(u8g2_font_6x12_tr);
|
||||
|
||||
char buf[32];
|
||||
|
||||
// Box 1 - RAM
|
||||
u8g2.drawFrame(0, 0, 128, 12);
|
||||
sprintf(buf, "RAM: %d%% used", ramUsage);
|
||||
u8g2.drawStr(4, 9, buf);
|
||||
|
||||
// Box 2 - Flash
|
||||
u8g2.drawFrame(0, 12, 128, 12);
|
||||
sprintf(buf, "Flash: %d%% used", flashUsage);
|
||||
u8g2.drawStr(4, 21, buf);
|
||||
|
||||
// Box 3 - Temp (FULL WIDTH now)
|
||||
u8g2.drawFrame(0, 24, 128, 12);
|
||||
sprintf(buf, "Temp: %d C", temperature);
|
||||
u8g2.drawStr(4, 33, buf);
|
||||
|
||||
// Box 4 - Chip info (FULL WIDTH)
|
||||
u8g2.drawFrame(0, 36, 128, 12);
|
||||
sprintf(buf, "Cores: %d Rev: %d", chip_info.cores, chip_info.revision);
|
||||
u8g2.drawStr(4, 45, buf);
|
||||
|
||||
// Box 5 - PSRAM (KB)
|
||||
u8g2.drawFrame(0, 48, 128, 12);
|
||||
sprintf(buf, "PSRAM: %lu KB", heap_caps_get_free_size(MALLOC_CAP_SPIRAM) / 1024);
|
||||
u8g2.drawStr(4, 57, buf);
|
||||
|
||||
u8g2.sendBuffer();
|
||||
|
||||
if (btnBack())
|
||||
{
|
||||
delay(200);
|
||||
return;
|
||||
}
|
||||
|
||||
delay(100);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
void runSystemInfoFeature();
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
#include <esp_wifi.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "buttons.h"
|
||||
|
||||
// ===== CONFIG =====
|
||||
#define GRAPH_WIDTH 128
|
||||
#define GRAPH_HEIGHT 44
|
||||
#define GRAPH_TOP 10
|
||||
#define MAX_POINTS 128
|
||||
#define SPIKE_THRESHOLD 30
|
||||
|
||||
// ===== STATE =====
|
||||
struct SnifferGraph {
|
||||
uint8_t graphData[MAX_POINTS];
|
||||
uint8_t currentChannel = 1;
|
||||
volatile uint16_t packetCounter = 0;
|
||||
unsigned long lastChannelSwitch = 0;
|
||||
unsigned long lastUpdate = 0;
|
||||
};
|
||||
|
||||
static SnifferGraph sniffer;
|
||||
|
||||
// ===== CALLBACK =====
|
||||
void IRAM_ATTR snifferCallback(void *buf, wifi_promiscuous_pkt_type_t type)
|
||||
{
|
||||
if (type == WIFI_PKT_MGMT || type == WIFI_PKT_DATA || type == WIFI_PKT_CTRL)
|
||||
{
|
||||
sniffer.packetCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
// ===== INIT =====
|
||||
void wifi_analyzer_start()
|
||||
{
|
||||
// display init (safe to call again)
|
||||
u8g2.clearBuffer();
|
||||
u8g2.setFont(u8g2_font_5x8_tr);
|
||||
u8g2.drawStr(0, 10, "Starting analyzer...");
|
||||
u8g2.sendBuffer();
|
||||
|
||||
// reset graph
|
||||
memset(sniffer.graphData, 0, sizeof(sniffer.graphData));
|
||||
sniffer.packetCounter = 0;
|
||||
sniffer.currentChannel = 1;
|
||||
|
||||
// reset WiFi
|
||||
WiFi.disconnect(true, true);
|
||||
esp_wifi_stop();
|
||||
delay(200);
|
||||
esp_wifi_deinit();
|
||||
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
esp_wifi_init(&cfg);
|
||||
esp_wifi_set_storage(WIFI_STORAGE_RAM);
|
||||
esp_wifi_set_mode(WIFI_MODE_NULL);
|
||||
esp_wifi_start();
|
||||
|
||||
esp_wifi_set_channel(sniffer.currentChannel, WIFI_SECOND_CHAN_NONE);
|
||||
esp_wifi_set_promiscuous_rx_cb(snifferCallback);
|
||||
esp_wifi_set_promiscuous(true);
|
||||
}
|
||||
|
||||
// ===== HELPERS =====
|
||||
static void switchChannel()
|
||||
{
|
||||
sniffer.currentChannel++;
|
||||
if (sniffer.currentChannel > 13) sniffer.currentChannel = 1;
|
||||
|
||||
esp_wifi_set_channel(sniffer.currentChannel, WIFI_SECOND_CHAN_NONE);
|
||||
}
|
||||
|
||||
static void updateGraph(uint8_t value)
|
||||
{
|
||||
for (int i = 0; i < MAX_POINTS - 1; i++)
|
||||
{
|
||||
sniffer.graphData[i] = sniffer.graphData[i + 1];
|
||||
}
|
||||
|
||||
sniffer.graphData[MAX_POINTS - 1] = value;
|
||||
}
|
||||
|
||||
static void drawGraph(uint16_t pktCount)
|
||||
{
|
||||
u8g2.clearBuffer();
|
||||
u8g2.setFont(u8g2_font_5x8_tr);
|
||||
|
||||
char line1[16];
|
||||
char line2[16];
|
||||
|
||||
sprintf(line1, "Ch:%d", sniffer.currentChannel);
|
||||
sprintf(line2, "Pkts:%d", pktCount * 5);
|
||||
|
||||
u8g2.drawStr(0, 8, line1);
|
||||
u8g2.drawStr(60, 8, line2);
|
||||
|
||||
for (int x = 1; x < GRAPH_WIDTH; x++)
|
||||
{
|
||||
int y1 = GRAPH_TOP + GRAPH_HEIGHT - sniffer.graphData[x - 1];
|
||||
int y2 = GRAPH_TOP + GRAPH_HEIGHT - sniffer.graphData[x];
|
||||
|
||||
u8g2.drawLine(x - 1, y1, x, y2);
|
||||
}
|
||||
|
||||
if (pktCount >= SPIKE_THRESHOLD)
|
||||
{
|
||||
u8g2.drawVLine(GRAPH_WIDTH / 2, GRAPH_TOP, GRAPH_HEIGHT);
|
||||
}
|
||||
|
||||
u8g2.sendBuffer();
|
||||
}
|
||||
|
||||
// ===== LOOP =====
|
||||
void wifi_analyzer_loop()
|
||||
{
|
||||
static uint32_t lastPress = 0;
|
||||
unsigned long now = millis();
|
||||
|
||||
// channel hopping
|
||||
if (now - sniffer.lastChannelSwitch >= 1000)
|
||||
{
|
||||
sniffer.lastChannelSwitch = now;
|
||||
switchChannel();
|
||||
}
|
||||
|
||||
// graph update
|
||||
if (now - sniffer.lastUpdate >= 200)
|
||||
{
|
||||
sniffer.lastUpdate = now;
|
||||
|
||||
uint16_t pktCount = sniffer.packetCounter;
|
||||
|
||||
uint8_t scaled = pktCount * 2;
|
||||
uint8_t value = min(scaled, (uint8_t)GRAPH_HEIGHT);
|
||||
|
||||
updateGraph(value);
|
||||
drawGraph(pktCount);
|
||||
|
||||
sniffer.packetCounter = 0;
|
||||
}
|
||||
|
||||
// optional: small debounce to not hammer CPU
|
||||
if (millis() - lastPress < 10)
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
void wifi_analyzer_start();
|
||||
void wifi_analyzer_loop();
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
#include "display.h"
|
||||
#include "buttons.h"
|
||||
|
||||
#define MAX_NETWORKS 30
|
||||
|
||||
struct WiFiNet {
|
||||
String ssid;
|
||||
int rssi;
|
||||
int channel;
|
||||
bool encrypted;
|
||||
};
|
||||
|
||||
static WiFiNet networks[MAX_NETWORKS];
|
||||
static int networkCount = 0;
|
||||
static int selectedIndex = 0;
|
||||
|
||||
// ===== SCAN =====
|
||||
void wifi_scan_start()
|
||||
{
|
||||
u8g2.clearBuffer();
|
||||
u8g2.drawStr(10, 30, "Scanning WiFi...");
|
||||
u8g2.sendBuffer();
|
||||
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.disconnect();
|
||||
|
||||
delay(100);
|
||||
|
||||
int n = WiFi.scanNetworks();
|
||||
|
||||
networkCount = min(n, MAX_NETWORKS);
|
||||
|
||||
for (int i = 0; i < networkCount; i++)
|
||||
{
|
||||
networks[i].ssid = WiFi.SSID(i);
|
||||
networks[i].rssi = WiFi.RSSI(i);
|
||||
networks[i].channel = WiFi.channel(i);
|
||||
networks[i].encrypted = (WiFi.encryptionType(i) != WIFI_AUTH_OPEN);
|
||||
}
|
||||
|
||||
selectedIndex = 0;
|
||||
}
|
||||
|
||||
// ===== DRAW =====
|
||||
void wifi_scan_draw()
|
||||
{
|
||||
u8g2.clearBuffer();
|
||||
|
||||
if (networkCount == 0)
|
||||
{
|
||||
u8g2.drawStr(0, 30, "No networks");
|
||||
u8g2.drawStr(0, 45, "Press BACK");
|
||||
}
|
||||
else
|
||||
{
|
||||
char counter[20];
|
||||
sprintf(counter, "%d/%d", selectedIndex + 1, networkCount);
|
||||
u8g2.setFont(u8g2_font_5x8_tr);
|
||||
u8g2.drawStr(0, 8, counter);
|
||||
|
||||
u8g2.setFont(u8g2_font_6x10_tr);
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
int idx = selectedIndex + i;
|
||||
if (idx >= networkCount) break;
|
||||
|
||||
int y = 22 + i * 14;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
u8g2.drawBox(0, y - 10, 128, 12);
|
||||
u8g2.setDrawColor(0);
|
||||
}
|
||||
|
||||
String text = networks[idx].ssid;
|
||||
if (text.length() > 10)
|
||||
text = text.substring(0, 10) + "..";
|
||||
|
||||
text += " (" + String(networks[idx].rssi) + ")";
|
||||
|
||||
u8g2.drawStr(2, y, text.c_str());
|
||||
|
||||
if (i == 0)
|
||||
u8g2.setDrawColor(1);
|
||||
}
|
||||
}
|
||||
|
||||
u8g2.sendBuffer();
|
||||
}
|
||||
|
||||
// ===== DETAILS =====
|
||||
void wifi_drawDetails()
|
||||
{
|
||||
if (networkCount == 0) return;
|
||||
|
||||
WiFiNet &net = networks[selectedIndex];
|
||||
|
||||
u8g2.clearBuffer();
|
||||
u8g2.setFont(u8g2_font_5x8_tr);
|
||||
|
||||
u8g2.drawStr(0, 10, net.ssid.c_str());
|
||||
|
||||
char rssi[20];
|
||||
sprintf(rssi, "RSSI: %d", net.rssi);
|
||||
u8g2.drawStr(0, 20, rssi);
|
||||
|
||||
char ch[20];
|
||||
sprintf(ch, "CH: %d", net.channel);
|
||||
u8g2.drawStr(0, 30, ch);
|
||||
|
||||
u8g2.drawStr(0, 40, net.encrypted ? "Secured" : "Open");
|
||||
|
||||
u8g2.sendBuffer();
|
||||
}
|
||||
|
||||
// ===== LOOP =====
|
||||
void wifi_scan_loop()
|
||||
{
|
||||
static uint32_t lastPress = 0;
|
||||
|
||||
if (millis() - lastPress < 150)
|
||||
return;
|
||||
|
||||
if (btnDown() && selectedIndex < networkCount - 1)
|
||||
{
|
||||
selectedIndex++;
|
||||
wifi_scan_draw();
|
||||
lastPress = millis();
|
||||
}
|
||||
else if (btnUp() && selectedIndex > 0)
|
||||
{
|
||||
selectedIndex--;
|
||||
wifi_scan_draw();
|
||||
lastPress = millis();
|
||||
}
|
||||
else if (btnSelect() && networkCount > 0)
|
||||
{
|
||||
wifi_drawDetails();
|
||||
delay(3000);
|
||||
wifi_scan_draw();
|
||||
lastPress = millis();
|
||||
}
|
||||
// else if (btnBack())
|
||||
// {
|
||||
// wifi_scan_start();
|
||||
// wifi_scan_draw();
|
||||
// lastPress = millis();
|
||||
// }
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
void wifi_scan_start();
|
||||
void wifi_scan_loop();
|
||||
void wifi_scan_draw();
|
||||
Loading…
Reference in New Issue