mirror of
https://github.com/meshtastic/firmware.git
synced 2025-05-06 21:58:24 +00:00
Merge pull request #38 from mc-hamster/master
update from master to osthread
This commit is contained in:
commit
35bcb5297a
@ -39,9 +39,20 @@ cd Meshtastic-device
|
|||||||
|
|
||||||
## Decoding stack traces
|
## Decoding stack traces
|
||||||
|
|
||||||
|
### Option 1
|
||||||
|
|
||||||
If you get a crash, you can decode the addresses from the `Backtrace:` line:
|
If you get a crash, you can decode the addresses from the `Backtrace:` line:
|
||||||
|
|
||||||
1. Save the `Backtrace: 0x....` line to a file, e.g., `backtrace.txt`.
|
1. Save the `Backtrace: 0x....` line to a file, e.g., `backtrace.txt`.
|
||||||
2. Run `bin/exception_decoder.py backtrace.txt` (this uses symbols from the
|
2. Run `bin/exception_decoder.py backtrace.txt` (this uses symbols from the
|
||||||
last `firmware.elf`, so you must be running the same binary that's still in
|
last `firmware.elf`, so you must be running the same binary that's still in
|
||||||
your `.pio/build` directory).
|
your `.pio/build` directory).
|
||||||
|
|
||||||
|
### Option 2
|
||||||
|
|
||||||
|
You can run the exception decoder to monitor the serial output and decode backtraces in real time.
|
||||||
|
|
||||||
|
1. From within PlatformIO, open a new terminal.
|
||||||
|
2. At the the terminal, enter:
|
||||||
|
`pio device monitor --port /dev/cu.SLAB_USBtoUART -f esp32_exception_decoder`
|
||||||
|
Replace the value of port with the location of your serial port.
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
; https://docs.platformio.org/page/projectconf.html
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
[platformio]
|
[platformio]
|
||||||
default_envs = tbeam # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
|
default_envs = linux # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
|
||||||
;default_envs = heltec # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
|
;default_envs = heltec # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here
|
||||||
|
|
||||||
[common]
|
[common]
|
||||||
@ -65,7 +65,7 @@ lib_deps =
|
|||||||
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
|
1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib
|
||||||
https://github.com/meshtastic/arduino-fsm.git#2f106146071fc7bc620e1e8d4b88dc4e0266ce39
|
https://github.com/meshtastic/arduino-fsm.git#2f106146071fc7bc620e1e8d4b88dc4e0266ce39
|
||||||
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
|
https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad
|
||||||
https://github.com/meshtastic/RadioLib.git#8657380241bce681c33aab46598bbf13b11f876c
|
https://github.com/meshtastic/RadioLib.git#07de964e929238949035fb0d5887026a3058df1a
|
||||||
https://github.com/meshtastic/TinyGPSPlus.git#9c1d584d2469523381e077b0b9c1bf868d6c0206
|
https://github.com/meshtastic/TinyGPSPlus.git#9c1d584d2469523381e077b0b9c1bf868d6c0206
|
||||||
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
|
https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460
|
||||||
Wire ; explicitly needed here because the AXP202 library forgets to add it
|
Wire ; explicitly needed here because the AXP202 library forgets to add it
|
||||||
@ -183,7 +183,7 @@ build_flags =
|
|||||||
-Isdk-nrfxlib/crypto/nrf_oberon/include -Lsdk-nrfxlib/crypto/nrf_oberon/lib/cortex-m4/hard-float/ -lliboberon_3.0.3
|
-Isdk-nrfxlib/crypto/nrf_oberon/include -Lsdk-nrfxlib/crypto/nrf_oberon/lib/cortex-m4/hard-float/ -lliboberon_3.0.3
|
||||||
;-DCFG_DEBUG=3
|
;-DCFG_DEBUG=3
|
||||||
src_filter =
|
src_filter =
|
||||||
${arduino_base.src_filter} -<esp32/> -<nimble/> -<meshwifi/>
|
${arduino_base.src_filter} -<esp32/> -<nimble/> -<meshwifi/> -<mesh/wifi/>
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
BluetoothOTA
|
BluetoothOTA
|
||||||
monitor_port = /dev/ttyACM1
|
monitor_port = /dev/ttyACM1
|
||||||
@ -314,6 +314,9 @@ src_filter = ${env.src_filter} -<esp32/> -<nimble/> -<nrf52/> -<meshwifi/>
|
|||||||
build_flags = ${arduino_base.build_flags} -O0
|
build_flags = ${arduino_base.build_flags} -O0
|
||||||
framework = arduino
|
framework = arduino
|
||||||
board = linux_x86_64
|
board = linux_x86_64
|
||||||
|
lib_deps =
|
||||||
|
${arduino_base.lib_deps}
|
||||||
|
rweather/Crypto
|
||||||
|
|
||||||
; The GenieBlocks LORA prototype board
|
; The GenieBlocks LORA prototype board
|
||||||
[env:genieblocks_lora]
|
[env:genieblocks_lora]
|
||||||
|
2
proto
2
proto
@ -1 +1 @@
|
|||||||
Subproject commit dfe7bc1217a00c23eecb9dfcf1d56fe95ebddc3b
|
Subproject commit 75078afe43934f4ce15ef86ebc6950658a170145
|
@ -394,7 +394,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#define USE_RF95
|
#define USE_RF95
|
||||||
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
#define LORA_DIO0 26 // a No connect on the SX1262 module
|
||||||
#define LORA_RESET 23
|
#define LORA_RESET RADIOLIB_NC
|
||||||
#define LORA_DIO1 33 // Not really used
|
#define LORA_DIO1 33 // Not really used
|
||||||
#define LORA_DIO2 32 // Not really used
|
#define LORA_DIO2 32 // Not really used
|
||||||
|
|
||||||
@ -402,7 +402,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define RF95_SCK 5
|
#define RF95_SCK 5
|
||||||
#define RF95_MISO 19
|
#define RF95_MISO 19
|
||||||
#define RF95_MOSI 27
|
#define RF95_MOSI 27
|
||||||
#define RF95_NSS 18
|
#define RF95_NSS RADIOLIB_NC // the ch341f spi controller does CS for us
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -239,6 +239,7 @@ int32_t GPS::runOnce()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We've been awake too long - force sleep
|
// We've been awake too long - force sleep
|
||||||
|
now = millis();
|
||||||
auto wakeTime = getWakeTime();
|
auto wakeTime = getWakeTime();
|
||||||
bool tooLong = wakeTime != UINT32_MAX && (now - lastWakeStartMsec) > wakeTime;
|
bool tooLong = wakeTime != UINT32_MAX && (now - lastWakeStartMsec) > wakeTime;
|
||||||
|
|
||||||
|
@ -21,11 +21,17 @@ void PhoneAPI::init()
|
|||||||
observe(&service.fromNumChanged);
|
observe(&service.fromNumChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PhoneAPI::~PhoneAPI() {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
void PhoneAPI::close() {
|
void PhoneAPI::close() {
|
||||||
unobserve();
|
unobserve();
|
||||||
state = STATE_SEND_NOTHING;
|
state = STATE_SEND_NOTHING;
|
||||||
|
bool oldConnected = isConnected;
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
onConnectionChanged(isConnected);
|
if(oldConnected != isConnected)
|
||||||
|
onConnectionChanged(isConnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhoneAPI::checkConnectionTimeout()
|
void PhoneAPI::checkConnectionTimeout()
|
||||||
|
@ -55,12 +55,15 @@ class PhoneAPI
|
|||||||
public:
|
public:
|
||||||
PhoneAPI();
|
PhoneAPI();
|
||||||
|
|
||||||
|
/// Destructor - calls close()
|
||||||
|
virtual ~PhoneAPI();
|
||||||
|
|
||||||
/// Do late init that can't happen at constructor time
|
/// Do late init that can't happen at constructor time
|
||||||
virtual void init();
|
virtual void init();
|
||||||
|
|
||||||
// Call this when the client drops the connection, resets the state to STATE_SEND_NOTHING
|
// Call this when the client drops the connection, resets the state to STATE_SEND_NOTHING
|
||||||
// Unregisters our observer
|
// Unregisters our observer. A closed connection **can** be reopened by calling init again.
|
||||||
void close();
|
virtual void close();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a ToRadio protobuf
|
* Handle a ToRadio protobuf
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#define POWER_DEFAULT 17 // How much power to use if the user hasn't set a power level
|
#define POWER_DEFAULT 17 // How much power to use if the user hasn't set a power level
|
||||||
|
|
||||||
RF95Interface::RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi)
|
RF95Interface::RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi)
|
||||||
: RadioLibInterface(cs, irq, rst, 0, spi)
|
: RadioLibInterface(cs, irq, rst, RADIOLIB_NC, spi)
|
||||||
{
|
{
|
||||||
// FIXME - we assume devices never get destroyed
|
// FIXME - we assume devices never get destroyed
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,9 @@ class RF95Interface : public RadioLibInterface
|
|||||||
public:
|
public:
|
||||||
RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi);
|
RF95Interface(RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, SPIClass &spi);
|
||||||
|
|
||||||
|
/// Some boards (Pinetab Lora module) have broken IRQ wires, so we need to poll via i2c registers
|
||||||
|
bool isIRQPending() { return lora->getPendingIRQ(); }
|
||||||
|
|
||||||
/// Initialise the Driver transport hardware and software.
|
/// Initialise the Driver transport hardware and software.
|
||||||
/// Make sure the Driver is properly configured before calling init().
|
/// Make sure the Driver is properly configured before calling init().
|
||||||
/// \return true if initialisation succeeded.
|
/// \return true if initialisation succeeded.
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
WiFiServerAPI::WiFiServerAPI(WiFiClient &_client) : StreamAPI(&client), client(_client)
|
WiFiServerAPI::WiFiServerAPI(WiFiClient &_client) : StreamAPI(&client), client(_client)
|
||||||
{
|
{
|
||||||
DEBUG_MSG("Incoming connection from %s\n", client.remoteIP().toString().c_str());
|
DEBUG_MSG("Incoming wifi connection\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
WiFiServerAPI::~WiFiServerAPI()
|
WiFiServerAPI::~WiFiServerAPI()
|
||||||
@ -28,18 +28,19 @@ void WiFiServerAPI::onConnectionChanged(bool connected)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiFiServerAPI::loop()
|
/// override close to also shutdown the TCP link
|
||||||
|
void WiFiServerAPI::close() {
|
||||||
|
client.stop(); // drop tcp connection
|
||||||
|
StreamAPI::close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WiFiServerAPI::loop()
|
||||||
{
|
{
|
||||||
if (client.connected()) {
|
if (client.connected()) {
|
||||||
StreamAPI::loop();
|
StreamAPI::loop();
|
||||||
} else if(isConnected) {
|
return true;
|
||||||
// If our API link was up, shut it down
|
} else {
|
||||||
|
return false;
|
||||||
DEBUG_MSG("Client dropped connection, closing API client\n");
|
|
||||||
// Note: we can't call delete here because this object includes other state
|
|
||||||
// besides the stream API. Instead kill it later when we start a new instance
|
|
||||||
// delete this;
|
|
||||||
close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,15 +59,25 @@ int32_t WiFiServerPort::runOnce()
|
|||||||
auto client = available();
|
auto client = available();
|
||||||
if (client) {
|
if (client) {
|
||||||
// Close any previous connection (see FIXME in header file)
|
// Close any previous connection (see FIXME in header file)
|
||||||
if (openAPI)
|
if (openAPI) {
|
||||||
|
DEBUG_MSG("Force closing previous TCP connection\n");
|
||||||
delete openAPI;
|
delete openAPI;
|
||||||
|
}
|
||||||
|
|
||||||
openAPI = new WiFiServerAPI(client);
|
openAPI = new WiFiServerAPI(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (openAPI) {
|
if (openAPI) {
|
||||||
// Allow idle processing so the API can read from its incoming stream
|
// Allow idle processing so the API can read from its incoming stream
|
||||||
openAPI->loop();
|
if(!openAPI->loop()) {
|
||||||
|
// If our API link was up, shut it down
|
||||||
|
|
||||||
|
DEBUG_MSG("Client dropped connection, closing API client\n");
|
||||||
|
// Note: we can't call delete here because this object includes other state
|
||||||
|
// besides the stream API. Instead kill it later when we start a new instance
|
||||||
|
delete openAPI;
|
||||||
|
openAPI = NULL;
|
||||||
|
}
|
||||||
return 0; // run fast while our API server is running
|
return 0; // run fast while our API server is running
|
||||||
} else
|
} else
|
||||||
return 100; // only check occasionally for incoming connections
|
return 100; // only check occasionally for incoming connections
|
@ -18,7 +18,11 @@ class WiFiServerAPI : public StreamAPI
|
|||||||
|
|
||||||
virtual ~WiFiServerAPI();
|
virtual ~WiFiServerAPI();
|
||||||
|
|
||||||
virtual void loop(); // Check for dropped client connections
|
/// @return true if we want to keep running, or false if we are ready to be destroyed
|
||||||
|
virtual bool loop(); // Check for dropped client connections
|
||||||
|
|
||||||
|
/// override close to also shutdown the TCP link
|
||||||
|
virtual void close();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Hookable to find out when connection changes
|
/// Hookable to find out when connection changes
|
@ -495,6 +495,9 @@ void handleStaticBrowse(HTTPRequest *req, HTTPResponse *res)
|
|||||||
std::string paramValDelete;
|
std::string paramValDelete;
|
||||||
std::string paramValEdit;
|
std::string paramValEdit;
|
||||||
|
|
||||||
|
DEBUG_MSG("Static Browse - Disabling keep-alive\n");
|
||||||
|
res->setHeader("Connection", "close");
|
||||||
|
|
||||||
// Set a default content type
|
// Set a default content type
|
||||||
res->setHeader("Content-Type", "text/html");
|
res->setHeader("Content-Type", "text/html");
|
||||||
|
|
||||||
@ -560,9 +563,7 @@ void handleStaticBrowse(HTTPRequest *req, HTTPResponse *res)
|
|||||||
}
|
}
|
||||||
|
|
||||||
res->println("<h2>Upload new file</h2>");
|
res->println("<h2>Upload new file</h2>");
|
||||||
res->println("<p><b>*** This interface is experimental ***</b></p>");
|
res->println("<p>This form allows you to upload files. Keep your filenames small and files under 200k.</p>");
|
||||||
res->println("<p>This form allows you to upload files. Keep your filenames very short and files small. Big filenames and big "
|
|
||||||
"files (>200k) are a known problem.</p>");
|
|
||||||
res->println("<form method=\"POST\" action=\"/upload\" enctype=\"multipart/form-data\">");
|
res->println("<form method=\"POST\" action=\"/upload\" enctype=\"multipart/form-data\">");
|
||||||
res->println("file: <input type=\"file\" name=\"file\"><br>");
|
res->println("file: <input type=\"file\" name=\"file\"><br>");
|
||||||
res->println("<input type=\"submit\" value=\"Upload\">");
|
res->println("<input type=\"submit\" value=\"Upload\">");
|
||||||
@ -703,6 +704,11 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res)
|
|||||||
|
|
||||||
void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
|
void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
DEBUG_MSG("Form Upload - Disabling keep-alive\n");
|
||||||
|
res->setHeader("Connection", "close");
|
||||||
|
|
||||||
|
DEBUG_MSG("Form Upload - Set frequency to 240mhz\n");
|
||||||
// The upload process is very CPU intensive. Let's speed things up a bit.
|
// The upload process is very CPU intensive. Let's speed things up a bit.
|
||||||
setCpuFrequencyMhz(240);
|
setCpuFrequencyMhz(240);
|
||||||
|
|
||||||
@ -711,6 +717,7 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
|
|||||||
// Then we select the body parser based on the encoding.
|
// Then we select the body parser based on the encoding.
|
||||||
// Actually we do this only for documentary purposes, we know the form is going
|
// Actually we do this only for documentary purposes, we know the form is going
|
||||||
// to be multipart/form-data.
|
// to be multipart/form-data.
|
||||||
|
DEBUG_MSG("Form Upload - Creating body parser reference\n");
|
||||||
HTTPBodyParser *parser;
|
HTTPBodyParser *parser;
|
||||||
std::string contentType = req->getHeader("Content-Type");
|
std::string contentType = req->getHeader("Content-Type");
|
||||||
|
|
||||||
@ -726,6 +733,7 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
|
|||||||
|
|
||||||
// Now, we can decide based on the content type:
|
// Now, we can decide based on the content type:
|
||||||
if (contentType == "multipart/form-data") {
|
if (contentType == "multipart/form-data") {
|
||||||
|
DEBUG_MSG("Form Upload - multipart/form-data\n");
|
||||||
parser = new HTTPMultipartBodyParser(req);
|
parser = new HTTPMultipartBodyParser(req);
|
||||||
} else {
|
} else {
|
||||||
Serial.printf("Unknown POST Content-Type: %s\n", contentType.c_str());
|
Serial.printf("Unknown POST Content-Type: %s\n", contentType.c_str());
|
||||||
@ -760,21 +768,21 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res)
|
|||||||
|
|
||||||
// Double check that it is what we expect
|
// Double check that it is what we expect
|
||||||
if (name != "file") {
|
if (name != "file") {
|
||||||
DEBUG_MSG("Skipping unexpected field");
|
DEBUG_MSG("Skipping unexpected field\n");
|
||||||
res->println("<p>No file found.</p>");
|
res->println("<p>No file found.</p>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Double check that it is what we expect
|
// Double check that it is what we expect
|
||||||
if (filename == "") {
|
if (filename == "") {
|
||||||
DEBUG_MSG("Skipping unexpected field");
|
DEBUG_MSG("Skipping unexpected field\n");
|
||||||
res->println("<p>No file found.</p>");
|
res->println("<p>No file found.</p>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SPIFFS limits the total lenth of a path + file to 31 characters.
|
// SPIFFS limits the total lenth of a path + file to 31 characters.
|
||||||
if (filename.length() + 8 > 31) {
|
if (filename.length() + 8 > 31) {
|
||||||
DEBUG_MSG("Uploaded filename too long!");
|
DEBUG_MSG("Uploaded filename too long!\n");
|
||||||
res->println("<p>Uploaded filename too long! Limit of 23 characters.</p>");
|
res->println("<p>Uploaded filename too long! Limit of 23 characters.</p>");
|
||||||
delete parser;
|
delete parser;
|
||||||
return;
|
return;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "meshwifi.h"
|
#include "meshwifi.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "WiFiServerAPI.h"
|
#include "mesh/wifi/WiFiServerAPI.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "meshwifi/meshhttp.h"
|
#include "meshwifi/meshhttp.h"
|
||||||
|
@ -31,10 +31,16 @@ MeshPacket *PositionPlugin::allocReply()
|
|||||||
{
|
{
|
||||||
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());
|
||||||
assert(node);
|
assert(node);
|
||||||
assert(node->has_position);
|
|
||||||
|
// We might not have a position yet for our local node, in that case, at least try to send the time
|
||||||
|
if(!node->has_position) {
|
||||||
|
memset(&node->position, 0, sizeof(node->position));
|
||||||
|
node->has_position = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Position &position = node->position;
|
||||||
|
|
||||||
// Update our local node info with our position (even if we don't decide to update anyone else)
|
// Update our local node info with our position (even if we don't decide to update anyone else)
|
||||||
auto position = node->position;
|
|
||||||
position.time = getValidTime(RTCQualityGPS); // This nodedb timestamp might be stale, so update it if our clock is valid.
|
position.time = getValidTime(RTCQualityGPS); // This nodedb timestamp might be stale, so update it if our clock is valid.
|
||||||
|
|
||||||
return allocDataProtobuf(position);
|
return allocDataProtobuf(position);
|
||||||
|
82
src/portduino/CrossPlatformCryptoEngine.cpp
Normal file
82
src/portduino/CrossPlatformCryptoEngine.cpp
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#include "AES.h"
|
||||||
|
#include "CTR.h"
|
||||||
|
#include "CryptoEngine.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
/** A platform independent AES engine implemented using Tiny-AES
|
||||||
|
*/
|
||||||
|
class CrossPlatformCryptoEngine : public CryptoEngine
|
||||||
|
{
|
||||||
|
|
||||||
|
CTRCommon *ctr = NULL;
|
||||||
|
|
||||||
|
/// How many bytes in our key
|
||||||
|
uint8_t keySize = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CrossPlatformCryptoEngine() {}
|
||||||
|
|
||||||
|
~CrossPlatformCryptoEngine() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the key used for encrypt, decrypt.
|
||||||
|
*
|
||||||
|
* As a special case: If all bytes are zero, we assume _no encryption_ and send all data in cleartext.
|
||||||
|
*
|
||||||
|
* @param numBytes must be 16 (AES128), 32 (AES256) or 0 (no crypt)
|
||||||
|
* @param bytes a _static_ buffer that will remain valid for the life of this crypto instance (i.e. this class will cache the
|
||||||
|
* provided pointer)
|
||||||
|
*/
|
||||||
|
virtual void setKey(size_t numBytes, uint8_t *bytes)
|
||||||
|
{
|
||||||
|
keySize = numBytes;
|
||||||
|
DEBUG_MSG("Installing AES%d key!\n", numBytes * 8);
|
||||||
|
if (ctr) {
|
||||||
|
delete ctr;
|
||||||
|
ctr = NULL;
|
||||||
|
}
|
||||||
|
if (numBytes != 0) {
|
||||||
|
if (numBytes == 16)
|
||||||
|
ctr = new CTR<AES128>();
|
||||||
|
else
|
||||||
|
ctr = new CTR<AES256>();
|
||||||
|
|
||||||
|
ctr->setKey(bytes, numBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt a packet
|
||||||
|
*
|
||||||
|
* @param bytes is updated in place
|
||||||
|
*/
|
||||||
|
virtual void encrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes)
|
||||||
|
{
|
||||||
|
if (keySize != 0) {
|
||||||
|
uint8_t stream_block[16];
|
||||||
|
static uint8_t scratch[MAX_BLOCKSIZE];
|
||||||
|
size_t nc_off = 0;
|
||||||
|
|
||||||
|
// DEBUG_MSG("ESP32 encrypt!\n");
|
||||||
|
initNonce(fromNode, packetNum);
|
||||||
|
assert(numBytes <= MAX_BLOCKSIZE);
|
||||||
|
memcpy(scratch, bytes, numBytes);
|
||||||
|
memset(scratch + numBytes, 0,
|
||||||
|
sizeof(scratch) - numBytes); // Fill rest of buffer with zero (in case cypher looks at it)
|
||||||
|
|
||||||
|
ctr->setIV(nonce, sizeof(nonce));
|
||||||
|
ctr->setCounterSize(4);
|
||||||
|
ctr->encrypt(bytes, scratch, numBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void decrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes)
|
||||||
|
{
|
||||||
|
// For CTR, the implementation is the same
|
||||||
|
encrypt(fromNode, packetNum, numBytes, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
CryptoEngine *crypto = new CrossPlatformCryptoEngine();
|
@ -1,8 +1,12 @@
|
|||||||
#include "CryptoEngine.h"
|
#include "CryptoEngine.h"
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
#include <Utility.h>
|
#include "PortduinoGPIO.h"
|
||||||
|
#include "mesh/RF95Interface.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
|
||||||
|
#include <Utility.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
// FIXME - move getMacAddr/setBluetoothEnable into a HALPlatform class
|
// FIXME - move getMacAddr/setBluetoothEnable into a HALPlatform class
|
||||||
|
|
||||||
uint32_t hwId; // fixme move into portduino
|
uint32_t hwId; // fixme move into portduino
|
||||||
@ -31,7 +35,60 @@ void cpuDeepSleep(uint64_t msecs) {
|
|||||||
notImplemented("cpuDeepSleep");
|
notImplemented("cpuDeepSleep");
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME - implement real crypto for linux
|
void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel");
|
||||||
CryptoEngine *crypto = new CryptoEngine();
|
|
||||||
|
|
||||||
void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel");
|
/** Dear pinetab hardware geeks!
|
||||||
|
*
|
||||||
|
* The current pinetab lora module has a slight bug. The ch341 part only provides ISR assertions on edges.
|
||||||
|
* This makes sense because USB interrupts happen through fast/repeated special irq urbs that are constantly
|
||||||
|
* chattering on the USB bus.
|
||||||
|
*
|
||||||
|
* But this isn't sufficient for level triggered ISR sources like the sx127x radios. The common way that seems to
|
||||||
|
* be addressed by cs341 users is to **always** connect the INT# (pin 26 on the ch341f) signal to one of the GPIO signals
|
||||||
|
* on the part. I'd recommend connecting that LORA_DIO0/INT# line to pin 19 (data 4) on the pinetab board. This would
|
||||||
|
* provide an efficent mechanism so that the (kernel) code in the cs341 driver that I've slightly hacked up to see the
|
||||||
|
* current state of LORA_DIO0. Without that access, I can't know if the interrupt is still pending - which would create
|
||||||
|
* race conditions in packet handling.
|
||||||
|
*
|
||||||
|
* My workaround is to poll the status register internally to the sx127x. Which is expensive because it involves a number of
|
||||||
|
* i2c transactions and many trips back and forth between kernel and my userspace app. I think shipping the current version
|
||||||
|
* of the pinetab lora device would be fine because I can poll slowly (because lora is slow). But if you ever have cause to
|
||||||
|
* rev this board. I highly encourage this small change.
|
||||||
|
*
|
||||||
|
* Btw - your little "USB lora dongle" is really neat. I encourage you to sell it, because even non pinetab customers could
|
||||||
|
* use it to easily add lora to rasberry pi, desktop pcs etc...
|
||||||
|
*
|
||||||
|
* Porduino helper class to do this i2c based polling:
|
||||||
|
*/
|
||||||
|
class R595PolledIrqPin : public GPIOPin {
|
||||||
|
public:
|
||||||
|
R595PolledIrqPin() : GPIOPin(LORA_DIO0, "LORA_DIO0") {}
|
||||||
|
|
||||||
|
/// Read the low level hardware for this pin
|
||||||
|
virtual PinStatus readPinHardware()
|
||||||
|
{
|
||||||
|
if(isrPinStatus < 0)
|
||||||
|
return LOW; // No interrupt handler attached, don't bother polling i2c right now
|
||||||
|
else {
|
||||||
|
extern RadioInterface *rIf; // FIXME, temporary hack until we know if we need to keep this
|
||||||
|
|
||||||
|
assert(rIf);
|
||||||
|
RF95Interface *rIf95 = static_cast<RF95Interface *>(rIf);
|
||||||
|
bool p = rIf95->isIRQPending();
|
||||||
|
// log(SysGPIO, LogDebug, "R595PolledIrqPin::readPinHardware(%s, %d, %d)", getName(), getPinNum(), p);
|
||||||
|
return p ? HIGH : LOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** apps run under portduino can optionally define a portduinoSetup() to
|
||||||
|
* use portduino specific init code (such as gpioBind) to setup portduino on their host machine,
|
||||||
|
* before running 'arduino' code.
|
||||||
|
*/
|
||||||
|
void portduinoSetup() {
|
||||||
|
printf("Setting up Meshtastic on Porduino...\n");
|
||||||
|
gpioBind(new R595PolledIrqPin());
|
||||||
|
// gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET")));
|
||||||
|
// gpioBind((new SimGPIOPin(RF95_NSS, "RF95_NSS"))->setSilent());
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
[VERSION]
|
[VERSION]
|
||||||
major = 1
|
major = 1
|
||||||
minor = 1
|
minor = 1
|
||||||
build = 30
|
build = 32
|
||||||
|
Loading…
Reference in New Issue
Block a user