Skip to content

Commit

Permalink
added subghz submenu (still wip, only tested with rcswitch codes) (#66)
Browse files Browse the repository at this point in the history
  • Loading branch information
eadmaster committed Jul 25, 2024
1 parent 1bab3ee commit 7a4c96c
Show file tree
Hide file tree
Showing 4 changed files with 285 additions and 2 deletions.
3 changes: 2 additions & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ build_flags =
-DLH=8
-DLW=6
-DCONFIG_FILE='"/config.conf"'

lib_deps =
WireGuard-ESP32
IRremoteESP8266
Expand All @@ -34,6 +33,8 @@ lib_deps =
Timezone
ESP32Time
bblanchon/ArduinoJson
rc-switch
;https://github.com/Martin-Laclaustra/rc-switch.git#transmittimingsarray


[env:m5stack-cplus2]
Expand Down
1 change: 1 addition & 0 deletions src/core/main_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ void rfOptions(){
options = {
//{"Scan/copy", [=]() { displayRedStripe("Scan/Copy"); }},
//{"Replay", [=]() { displayRedStripe("Replay"); }},
{"Custom SubGhz", [=]() { otherRFcodes(); }},
{"Spectrum", [=]() { rf_spectrum(); }}, //@IncursioHack
{"Jammer Itmt", [=]() { rf_jammerIntermittent(); }}, //@IncursioHack
{"Jammer Full", [=]() { rf_jammerFull(); }}, //@IncursioHack
Expand Down
278 changes: 278 additions & 0 deletions src/modules/rf/rf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,282 @@ void rf_jammerIntermittent() { //@IncursioHack - https://github.com/IncursioHack
}


struct RfCodes {
uint32_t frequency = 0;
String protocol = "";
String preset = "";
String data = "";
int te = 0;
String filepath = "";
};


#include <RCSwitch.h>

void RCSwitch_send(uint64_t data, unsigned int bits, int pulse, int protocol, int repeat)
{
RCSwitch mySwitch = RCSwitch();
mySwitch.enableTransmit(RfTx);
mySwitch.setProtocol(protocol);
if (pulse) { mySwitch.setPulseLength(pulse); }
mySwitch.setPulseLength(pulse);
mySwitch.setRepeatTransmit(repeat);
mySwitch.send(data, bits);
}

struct HighLow {
uint8_t high; // 1
uint8_t low; //31
};

struct Protocol {
uint16_t pulseLength; // base pulse length in microseconds, e.g. 350
HighLow syncFactor;
HighLow zero;
HighLow one;
bool invertedSignal;
};

// ported from https://github.com/sui77/rc-switch/blob/3a536a172ab752f3c7a58d831c5075ca24fd920b/RCSwitch.cpp

void RCSwitch_RAW_send(int nTransmitterPin, int * ptrtransmittimings, struct Protocol protocol) {
if (nTransmitterPin == -1)
return;

if (!ptrtransmittimings)
return;

bool currentlogiclevel = true;
int nRepeatTransmit = 1;
//HighLow pulses ;

for (int nRepeat = 0; nRepeat < nRepeatTransmit; nRepeat++) {
unsigned int currenttiming = 0;
while( ptrtransmittimings[currenttiming] ) { // && currenttiming < RCSWITCH_MAX_CHANGES
if(ptrtransmittimings[currenttiming] >= 0) {
currentlogiclevel = true;
//pulses = protocol.one;
} else {
// negative value
currentlogiclevel = false;
ptrtransmittimings[currenttiming] = (-1) * ptrtransmittimings[currenttiming]; // invert sign
//pulses = protocol.zero;
}

digitalWrite(nTransmitterPin, currentlogiclevel ? HIGH : LOW);
delayMicroseconds( ptrtransmittimings[currenttiming] );

/*
uint8_t firstLogicLevel = (protocol.invertedSignal) ? LOW : HIGH;
uint8_t secondLogicLevel = (protocol.invertedSignal) ? HIGH : LOW;
digitalWrite(nTransmitterPin, firstLogicLevel);
delayMicroseconds( protocol.pulseLength * pulses.high);
digitalWrite(nTransmitterPin, secondLogicLevel);
delayMicroseconds( protocol.pulseLength * pulses.low);
* */

Serial.print(ptrtransmittimings[currenttiming]);
Serial.print("=");
Serial.println(currentlogiclevel);

currenttiming++;
}
digitalWrite(nTransmitterPin, LOW);
} // end for
}


void sendRfCommand(struct RfCodes rfcode) {
uint32_t frequency = rfcode.frequency;
String protocol = rfcode.protocol;
String preset = rfcode.preset;
String data = rfcode.data;
/*
Serial.println("sendRawRfCommand");
Serial.println(data);
Serial.println(frequency);
Serial.println(preset);
Serial.println(protocol);
*/
if(frequency != 433920000) {
Serial.print("unsupported frequency: ");
Serial.println(frequency);
return;
}
// MEMO: frequency is fixed with some transmitters https://github.com/sui77/rc-switch/issues/256
// TODO: add frequency switching via CC1101 https://github.com/LSatan/SmartRC-CC1101-Driver-Lib

// Radio preset name (configures modulation, bandwidth, filters, etc.).
struct Protocol rcswitch_protocol;
int rcswitch_protocol_no = 1;
if(preset == "FuriHalSubGhzPresetOok270Async") {
rcswitch_protocol_no = 1;
// pulseLength , syncFactor , zero , one, invertedSignal
rcswitch_protocol = { 350, { 1, 31 }, { 1, 3 }, { 3, 1 }, false };
}
else if(preset == "FuriHalSubGhzPresetOok650Async") {
rcswitch_protocol_no = 2;
rcswitch_protocol = { 650, { 1, 10 }, { 1, 2 }, { 2, 1 }, false };
}
else {
Serial.print("unsupported preset: ");
Serial.println(preset);
return;
}
/* supported flipper presets:
FuriHalSubGhzPresetIDLE, // < default configuration
FuriHalSubGhzPresetOok270Async, ///< OOK, bandwidth 270kHz, asynchronous
FuriHalSubGhzPresetOok650Async, ///< OOK, bandwidth 650kHz, asynchronous
FuriHalSubGhzPreset2FSKDev238Async, //< FM, deviation 2.380371 kHz, asynchronous
FuriHalSubGhzPreset2FSKDev476Async, //< FM, deviation 47.60742 kHz, asynchronous
FuriHalSubGhzPresetMSK99_97KbAsync, //< MSK, deviation 47.60742 kHz, 99.97Kb/s, asynchronous
FuriHalSubGhzPresetGFSK9_99KbAsync, //< GFSK, deviation 19.042969 kHz, 9.996Kb/s, asynchronous
FuriHalSubGhzPresetCustom, //Custom Preset
*/

// init output pin
digitalWrite(RfTx, LED_OFF);
if(RfTx==0) RfTx=GROVE_SDA; // quick fix
pinMode(RfTx, OUTPUT);

if(protocol == "RAW") {
// alloc buffer for transmittimings
int* transmittimings = (int *) calloc(sizeof(int), data.length()); // should be smaller the data.length()
size_t transmittimings_idx = 0;

// split data into words, convert to int, and store them in transmittimings
String curr_word = "";
int curr_val = 0;
for(int i=0; i<data.length(); i++) {
if(isspace(data[i])) {
if(curr_word == "") continue; // skip if empty
// else append to transmittimings
//transmittimings[transmittimings_idx] = curr_word.toInt(); // does not handle negative numbers
transmittimings[transmittimings_idx] = atoi(curr_word.c_str());
//if(transmittimings[transmittimings_idx]==0) invalid int?
transmittimings_idx += 1;
curr_word = ""; // reset

} else {
curr_word += data[i]; // append to current word
}
}
transmittimings[transmittimings_idx] = 0; // termination

// send rf command
displayRedStripe("Sending..",TFT_WHITE,FGCOLOR);
//mySwitch.send(transmittimings); // req. forked ver
RCSwitch_RAW_send(RfTx, transmittimings, rcswitch_protocol);
free(transmittimings);
}
else if(protocol == "RcSwitch") {
data.replace(" ", ""); // remove spaces
uint64_t data_val = strtoul(data.c_str(), nullptr, 16);
int bits = data.length() * 4;
int pulse = rfcode.te; // not sure about this...
int repeat = 10;
/*
Serial.print("RcSwitch: ");
Serial.println(data);
Serial.println(bits);
Serial.println(pulse);
Serial.println(rcswitch_protocol_no);
* */
displayRedStripe("Sending..",TFT_WHITE,FGCOLOR);
RCSwitch_send(data_val, bits, pulse, rcswitch_protocol_no, repeat);
}
else {
Serial.print("unsupported protocol: ");
Serial.println(protocol);
return;
}

digitalWrite(RfTx, LED_OFF);
}


RfCodes recent_rfcodes[16]; // TODO: save/load in EEPROM
int recent_rfcodes_last_used = 0; // TODO: save/load in EEPROM

void addToRecentCodes(struct RfCodes rfcode) {
// copy rfcode -> recent_rfcodes[recent_rfcodes_last_used]
recent_rfcodes[recent_rfcodes_last_used] = rfcode;
recent_rfcodes_last_used += 1;
if(recent_rfcodes_last_used == 16) recent_rfcodes_last_used = 0; // cycle
}

struct RfCodes selectRecentRfMenu() {
// show menu with filenames
options = { };
bool exit = false;
struct RfCodes selected_code;
for(int i=0; i<16; i++) {
if(recent_rfcodes[i].filepath=="") continue; // not inited
// else
options.push_back({ recent_rfcodes[i].filepath.c_str(), [i, &selected_code](){ selected_code = recent_rfcodes[i]; }});
}
options.push_back({ "Main Menu" , [&](){ exit=true; }});
delay(200);
loopOptions(options);
return(selected_code);
}

void otherRFcodes() {
File databaseFile;
FS *fs = NULL;
String filepath = "";
struct RfCodes selected_code;
options = {
{"Recent", [&]() { selected_code = selectRecentRfMenu(); }},
{"LittleFS", [&]() { fs=&LittleFS; }},
};
if(setupSdCard()) options.push_back({"SD Card", [&]() { fs=&SD; }});

delay(200);
loopOptions(options);
delay(200);

if(fs == NULL) { // recent menu was selected
if(selected_code.filepath!="") sendRfCommand(selected_code); // a code was selected
return;
// no need to proceed, go back
}

//filepath = loopSD(*fs, true, "SUB");
filepath = loopSD(*fs, true);
databaseFile = fs->open(filepath, FILE_READ);
drawMainBorder();

if (!databaseFile) {
Serial.println("Failed to open database file.");
displayError("Fail to open file");
delay(2000);
return;
}
Serial.println("Opened sub file.");
selected_code.filepath = filepath.substring( 1 + filepath.lastIndexOf("/") );

// format specs: https://github.com/flipperdevices/flipperzero-firmware/blob/dev/documentation/file_formats/SubGhzFileFormats.md
String line;
String txt;
while (databaseFile.available() ) {
line = databaseFile.readStringUntil('\n');
txt=line.substring(line.indexOf(":") + 1);
txt.trim();
if(line.startsWith("Protocol:")) selected_code.protocol = txt;
if(line.startsWith("Preset:")) selected_code.preset = txt;
if(line.startsWith("Frequency:")) selected_code.frequency = txt.toInt();
if(line.startsWith("TE:")) selected_code.te = txt.toInt();
if(line.startsWith("RAW_Data:") || line.startsWith("Key:")) { selected_code.data += txt; }
}
databaseFile.close();

addToRecentCodes(selected_code);
sendRfCommand(selected_code);

// TODO: menu to resend command/pick another file from the same dir?

digitalWrite(RfTx, LED_OFF);
}

5 changes: 4 additions & 1 deletion src/modules/rf/rf.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ const int PCA9554TRX_PIN = 0;

void rf_spectrum();
void rf_jammerIntermittent();
void rf_jammerFull();
void rf_jammerFull();
void otherRFcodes();

void RCSwitch_send(uint64_t data, unsigned int bits, int pulse=0, int protocol=1, int repeat=10);

0 comments on commit 7a4c96c

Please sign in to comment.