Skip to content

Commit

Permalink
Add experimental privacy option
Browse files Browse the repository at this point in the history
  • Loading branch information
sh123 committed Dec 4, 2023
1 parent a8f7dc0 commit 780078c
Show file tree
Hide file tree
Showing 11 changed files with 147 additions and 67 deletions.
28 changes: 17 additions & 11 deletions include/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
#include <RadioLib.h>

// saved settings version, increment to load new settings
#define CFG_VERSION 6
#define CFG_VERSION 7

// Comment out for SX127X module usage
// Comment out for SX127X module usage, passed from platform.io
//#define USE_SX126X

// Check your module name at https://github.com/jgromes/RadioLib/wiki/Modules
Expand Down Expand Up @@ -80,12 +80,6 @@
#define CFG_ENCODER_PIN_VCC -1
#define CFG_ENCODER_STEPS 4

// audio
#define CFG_AUDIO_CODEC2_MODE CODEC2_MODE_1600
#define CFG_AUDIO_MAX_PKT_SIZE 48
#define CFG_AUDIO_MAX_VOL 500
#define CFG_AUDIO_VOL 300

// i2s speaker
#define CFG_AUDIO_SPK_PIN_BCLK 26
#define CFG_AUDIO_SPK_PIN_LRC 13
Expand All @@ -101,8 +95,20 @@
#define CFG_AUDIO_BATTERY_MON_CAL 0.25f

// power management
#define CFG_PM_LSLEEP_AFTER_MS 60000
#define CFG_PM_LSLEEP_DURATION_MS 3000
#define CFG_PM_LSLEEP_AWAKE_MS 100
#define CFG_PM_LSLEEP_AFTER_MS 60000 // how long to wait before going to sleep
#define CFG_PM_LSLEEP_DURATION_MS 3000 // light sleep duration for polling
#define CFG_PM_LSLEEP_AWAKE_MS 100 // how long to be awake in light sleep polling

// audio
#define CFG_AUDIO_CODEC2_MODE CODEC2_MODE_1600
#define CFG_AUDIO_MAX_PKT_SIZE 48 // maximum super frame size
#define CFG_AUDIO_MAX_VOL 500 // maximum volume
#define CFG_AUDIO_VOL 300 // default volume

// audio, experimental
#define CFG_AUDIO_ENABLE_PRIVACY false
#define CFG_AUDIO_PRIVACY_KEY \
byte AudioPrivacyKey[32] = {0xe7,0x5c,0xf0,0x43,0x80,0xec,0x45,0x93,0xe8,0x3b,0xfb,0x72,0x22,0x40,0x19,0x57,\
0x6c,0xde,0x05,0x00,0xff,0x88,0x12,0x42,0x20,0xf2,0x89,0x9d,0x7f,0x57,0xee,0xd6}

#endif // CONFIG_H
4 changes: 4 additions & 0 deletions include/loradv_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ class Config {
int AudioMaxVol_; // maximum volume
int AudioVol; // current volume

// encryption
bool AudioEnPriv; // enable/disable privacy
byte AudioPrivacyKey_[32]; // privacy key

// battery monitor
byte BatteryMonPin_; // Battery monitor adc pin
float BatteryMonCal; // Battery monitor calibrarion value
Expand Down
12 changes: 7 additions & 5 deletions include/radio_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
#include <DebugLog.h>
#include <RadioLib.h>
#include <CircularBuffer.h>
#include <ChaCha.h>

#include "loradv_config.h"
#include "audio_task.h"
#include "utils.h"
#include "config.h"

namespace LoraDv {
Expand All @@ -26,9 +28,6 @@ class RadioTask {

void setFreq(long freq) const;
inline bool isHalfDuplex() const { return config_->LoraFreqTx != config_->LoraFreqRx; }

static int getSpeed(int sf, int cr, long bw) { return (int)(sf * (4.0 / cr) / (pow(2.0, sf) / bw)); }
static float getSnrLimit(int sf, long bw);
inline float getRssi() const { return lastRssi_; }

bool hasData() const;
Expand Down Expand Up @@ -62,8 +61,8 @@ class RadioTask {
static void task(void *param);

void rigTask();
void rigTaskReceive(byte *packetBuf);
void rigTaskTransmit(byte *packetBuf);
void rigTaskReceive(byte *packetBuf, byte *tmpBuf);
void rigTaskTransmit(byte *packetBuf, byte *tmpBuf);
void rigTaskStartReceive();
void rigTaskStartTransmit();

Expand All @@ -73,6 +72,9 @@ class RadioTask {
std::shared_ptr<MODULE_NAME> rig_;
std::shared_ptr<AudioTask> audioTask_;

uint8_t iv_[8];
std::shared_ptr<ChaCha> cipher_;

static TaskHandle_t loraTaskHandle_;

CircularBuffer<uint8_t, CfgRadioQueueLen> loraRadioRxQueue_;
Expand Down
1 change: 1 addition & 0 deletions include/settings_menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "loradv_config.h"
#include "radio_task.h"
#include "utils.h"

namespace LoraDv {

Expand Down
17 changes: 17 additions & 0 deletions include/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef UTILS_H
#define UTILS_H

#include <Arduino.h>

namespace LoraDv {

class Utils {

public:
static float getLoraSnrLimit(int sf, long bw);
static int getLoraSpeed(int sf, int cr, long bw) { return (int)(sf * (4.0 / cr) / (pow(2.0, sf) / bw)); }
};

} // LoraDv

#endif // UTILS_H
2 changes: 1 addition & 1 deletion include/version.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#ifndef VERSION_H
#define VERSION_H

#define LORADV_VERSION "1.0.11"
#define LORADV_VERSION "1.0.13"

#endif // VERSION_H
1 change: 1 addition & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ lib_deps =
sh123/esp32_codec2 @ 1.0.5
adafruit/Adafruit SSD1306 @ 2.5.7
igorantolic/Ai Esp32 Rotary Encoder @ 1.6
rweather/Crypto @ 0.4.0
check_tool = cppcheck
check_flags =
cppcheck: --suppress=*:*.pio\* --inline-suppr -DCPPCHECK
Expand Down
12 changes: 12 additions & 0 deletions src/loradv_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ namespace LoraDv {

#define N(v) #v

CFG_AUDIO_PRIVACY_KEY;

Config::Config()
{
InitializeDefault();
Expand Down Expand Up @@ -63,6 +65,7 @@ void Config::InitializeDefault()
AudioMaxPktSize = CFG_AUDIO_MAX_PKT_SIZE;
AudioMaxVol_ = CFG_AUDIO_MAX_VOL;
AudioVol = CFG_AUDIO_VOL;
AudioEnPriv = CFG_AUDIO_ENABLE_PRIVACY;

// i2s speaker
AudioSpkPinBclk_ = CFG_AUDIO_SPK_PIN_BCLK;
Expand All @@ -82,6 +85,9 @@ void Config::InitializeDefault()
PmSleepAfterMs = CFG_PM_LSLEEP_AFTER_MS;
PmLightSleepDurationMs_ = CFG_PM_LSLEEP_DURATION_MS;
PmLightSleepAwakeMs_ = CFG_PM_LSLEEP_AWAKE_MS;

// encryption key
memcpy(AudioPrivacyKey_, AudioPrivacyKey, sizeof(AudioPrivacyKey));
}

void Config::Reset()
Expand Down Expand Up @@ -162,6 +168,11 @@ void Config::Load()
} else {
prefs_.putInt(N(AudioMaxPktSize), AudioMaxPktSize);
}
if (prefs_.isKey(N(AudioEnPriv))) {
AudioEnPriv = prefs_.getBool(N(AudioEnPriv));
} else {
prefs_.putBool(N(AudioEnPriv), AudioEnPriv);
}
if (prefs_.isKey(N(BatteryMonCal))) {
BatteryMonCal = prefs_.getFloat(N(BatteryMonCal));
} else {
Expand Down Expand Up @@ -216,6 +227,7 @@ void Config::Save()
prefs_.putInt(N(AudioCodec2Mode), AudioCodec2Mode);
prefs_.putInt(N(AudioVol), AudioVol);
prefs_.putInt(N(AudioMaxPktSize), AudioMaxPktSize);
prefs_.putBool(N(AudioEnPriv), AudioEnPriv);
prefs_.putFloat(N(BatteryMonCal), BatteryMonCal);
prefs_.putInt(N(PmSleepAfterMs), PmSleepAfterMs);
prefs_.putFloat(N(FskBitRate), FskBitRate);
Expand Down
92 changes: 44 additions & 48 deletions src/radio_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,18 @@ RadioTask::RadioTask()
, isRunning_(false)
, shouldUpdateScreen_(false)
, lastRssi_(0)
, cipher_(new ChaCha())
{
}

void RadioTask::start(std::shared_ptr<Config> config, std::shared_ptr<AudioTask> audioTask)
{
config_ = config;
audioTask_ = audioTask;
cipher_->setKey(config->AudioPrivacyKey_, sizeof(config->AudioPrivacyKey_));
xTaskCreate(&task, "RadioTask", CfgRadioTaskStack, this, 5, &loraTaskHandle_);
}

float RadioTask::getSnrLimit(int sf, long bw)
{
float snrLimit = -7;
switch (sf) {
case 7:
snrLimit = -7.5;
break;
case 8:
snrLimit = -10.0;
break;
case 9:
snrLimit = -12.6;
break;
case 10:
snrLimit = -15.0;
break;
case 11:
snrLimit = -17.5;
break;
case 12:
snrLimit = -20.0;
break;
}
return -174 + 10 * log10(bw) + 6 + snrLimit;
}

void RadioTask::setupRig(long loraFreq, long bw, int sf, int cr, int pwr, int sync, int crcBytes)
{
LOG_INFO("Initializing LoRa");
Expand All @@ -57,8 +33,8 @@ void RadioTask::setupRig(long loraFreq, long bw, int sf, int cr, int pwr, int sy
LOG_INFO("Power:", pwr, "dBm");
LOG_INFO("Sync:", "0x" + String(sync, HEX));
LOG_INFO("CRC:", crcBytes);
LOG_INFO("Speed:", getSpeed(sf, cr, bw), "bps");
LOG_INFO("Min level:", getSnrLimit(sf, bw));
LOG_INFO("Speed:", Utils::getLoraSpeed(sf, cr, bw), "bps");
LOG_INFO("Min level:", Utils::getLoraSnrLimit(sf, bw));
rig_ = std::make_shared<MODULE_NAME>(new Module(config_->LoraPinSs_, config_->LoraPinA_, config_->LoraPinRst_, config_->LoraPinB_));
int state = rig_->begin((float)loraFreq / 1e6, (float)bw / 1e3, sf, cr, sync, pwr);
if (state != RADIOLIB_ERR_NONE) {
Expand All @@ -81,12 +57,6 @@ void RadioTask::setupRig(long loraFreq, long bw, int sf, int cr, int pwr, int sy
isIsrInstalled_ = true;
#endif
rig_->explicitHeader();

state = rig_->startReceive();
if (state != RADIOLIB_ERR_NONE) {
LOG_ERROR("Receive start error:", state);
}

LOG_INFO("LoRa initialized");
}

Expand Down Expand Up @@ -120,12 +90,6 @@ void RadioTask::setupRigFsk(long freq, float bitRate, float freqDev, float rxBw,
rig_->setDio0Action(onRigIsrRxPacket, RISING);
isIsrInstalled_ = true;
#endif

state = rig_->startReceive();
if (state != RADIOLIB_ERR_NONE) {
LOG_ERROR("Receive start error:", state);
}

LOG_INFO("FSK initialized");
}

Expand Down Expand Up @@ -202,19 +166,22 @@ void RadioTask::rigTask()
setupRigFsk(config_->LoraFreqRx, config_->FskBitRate, config_->FskFreqDev,
config_->FskRxBw, config_->LoraPower, config_->FskShaping);
}
randomSeed(rig_->random(0x7FFFFFFF));
rigTaskStartReceive();

byte *packetBuf = new byte[CfgRadioPacketBufLen];
byte *tmpBuf = new byte[CfgRadioPacketBufLen];

while (isRunning_) {
uint32_t cmdBits = 0;
xTaskNotifyWaitIndexed(0, 0x00, ULONG_MAX, &cmdBits, portMAX_DELAY);

LOG_DEBUG("Radio task bits", cmdBits);
if (cmdBits & CfgRadioRxBit) {
rigTaskReceive(packetBuf);
rigTaskReceive(packetBuf, tmpBuf);
}
else if (cmdBits & CfgRadioTxBit) {
rigTaskTransmit(packetBuf);
rigTaskTransmit(packetBuf, tmpBuf);
}
if (cmdBits & CfgRadioRxStartBit) {
rigTaskStartReceive();
Expand All @@ -224,6 +191,7 @@ void RadioTask::rigTask()
}
}

delete tmpBuf;
delete packetBuf;
LOG_INFO("Radio task stopped");
vTaskDelete(NULL);
Expand Down Expand Up @@ -255,16 +223,26 @@ void RadioTask::rigTaskStartTransmit()
if (isHalfDuplex()) setFreq(config_->LoraFreqTx);
}

void RadioTask::rigTaskReceive(byte *packetBuf)
void RadioTask::rigTaskReceive(byte *packetBuf, byte *tmpBuf)
{
int packetSize = rig_->getPacketLength();
if (packetSize > 0 && packetSize < CfgRadioPacketBufLen) {
if (packetSize > 8 && packetSize < CfgRadioPacketBufLen) {
// receive packet
int state = rig_->readData(packetBuf, packetSize);
if (state == RADIOLIB_ERR_NONE) {
// process packet
byte *receiveBuf = packetBuf;
// if privacy enabled
if (config_->AudioEnPriv){
// read iv and decrypt packet
cipher_->setIV(packetBuf, sizeof(iv_));
packetSize -= sizeof(iv_);
cipher_->decrypt(tmpBuf, packetBuf + sizeof(iv_), packetSize);
receiveBuf = tmpBuf;
}
// send packet to the queue
LOG_DEBUG("Received packet, size", packetSize);
for (int i = 0; i < packetSize; i++) {
loraRadioRxQueue_.push(packetBuf[i]);
loraRadioRxQueue_.push(receiveBuf[i]);
}
loraRadioRxQueueIndex_.push(packetSize);
audioTask_->play();
Expand All @@ -277,17 +255,35 @@ void RadioTask::rigTaskReceive(byte *packetBuf)
if (state != RADIOLIB_ERR_NONE) {
LOG_ERROR("Start receive error: ", state);
}
} else {
LOG_ERROR("Wrong packet size: ", packetSize);
}
}

void RadioTask::rigTaskTransmit(byte *packetBuf)
void RadioTask::rigTaskTransmit(byte *packetBuf, byte *tmpBuf)
{
while (loraRadioTxQueueIndex_.size() > 0) {
// fetch packet size and packet from the queue
int txBytesCnt = loraRadioTxQueueIndex_.shift();
for (int i = 0; i < txBytesCnt; i++) {
packetBuf[i] = loraRadioTxQueue_.shift();
}
int loraRadioState = rig_->transmit(packetBuf, txBytesCnt);
byte *sendBuf = packetBuf;
// if privacy enabled
if (config_->AudioEnPriv) {
// generate IV
for (int i = 0; i < sizeof(iv_); i++) {
iv_[i] = random(255);
tmpBuf[i] = iv_[i];
}
// encrypt
cipher_->setIV(iv_, sizeof(iv_));
cipher_->encrypt(tmpBuf + sizeof(iv_), packetBuf, txBytesCnt);
txBytesCnt += sizeof(iv_);
sendBuf = tmpBuf;
}
// transmit
int loraRadioState = rig_->transmit(sendBuf, txBytesCnt);
if (loraRadioState != RADIOLIB_ERR_NONE) {
LOG_ERROR("Lora radio transmit failed:", loraRadioState);
}
Expand Down
Loading

0 comments on commit 780078c

Please sign in to comment.