mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-05 17:40:51 +00:00
Merge branch 'develop' into mqtt-fix
This commit is contained in:
@@ -191,9 +191,20 @@ void Channels::onConfigChanged()
|
||||
|
||||
Channel &Channels::getByIndex(ChannelIndex chIndex)
|
||||
{
|
||||
assert(chIndex < channelFile.channels_count); // This should be equal to MAX_NUM_CHANNELS
|
||||
Channel *ch = channelFile.channels + chIndex;
|
||||
return *ch;
|
||||
// remove this assert cause malformed packets can make our firmware reboot here.
|
||||
if (chIndex < channelFile.channels_count) { // This should be equal to MAX_NUM_CHANNELS
|
||||
Channel *ch = channelFile.channels + chIndex;
|
||||
return *ch;
|
||||
} else {
|
||||
LOG_ERROR("Invalid channel index %d > %d, malformed packet received?\n", chIndex , channelFile.channels_count);
|
||||
|
||||
static Channel *ch = (Channel *)malloc(sizeof(Channel));
|
||||
memset(ch, 0, sizeof(Channel));
|
||||
// ch.index -1 means we don't know the channel locally and need to look it up by settings.name
|
||||
// not sure this is handled right everywhere
|
||||
ch->index = -1;
|
||||
return *ch;
|
||||
}
|
||||
}
|
||||
|
||||
Channel &Channels::getByName(const char* chName)
|
||||
|
||||
@@ -2,9 +2,23 @@
|
||||
#include "SX126xInterface.cpp"
|
||||
#include "SX128xInterface.h"
|
||||
#include "SX128xInterface.cpp"
|
||||
#include "api/ServerAPI.h"
|
||||
#include "api/ServerAPI.cpp"
|
||||
|
||||
// We need this declaration for proper linking in derived classes
|
||||
template class SX126xInterface<SX1262>;
|
||||
template class SX126xInterface<SX1268>;
|
||||
template class SX126xInterface<LLCC68>;
|
||||
template class SX128xInterface<SX1280>;
|
||||
|
||||
#if HAS_ETHERNET
|
||||
#include "api/ethServerAPI.h"
|
||||
template class ServerAPI<EthernetClient>;
|
||||
template class APIServerPort<ethServerAPI, EthernetServer>;
|
||||
#endif
|
||||
|
||||
#if HAS_WIFI
|
||||
#include "api/WiFiServerAPI.h"
|
||||
template class ServerAPI<WiFiClient>;
|
||||
template class APIServerPort<WiFiServerAPI, WiFiServer>;
|
||||
#endif
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "configuration.h"
|
||||
#include "MeshPacketQueue.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "MeshTypes.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <queue>
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <string>
|
||||
|
||||
#include "GPS.h"
|
||||
//#include "MeshBluetoothService.h"
|
||||
#include "../concurrency/Periodic.h"
|
||||
#include "BluetoothCommon.h" // needed for updateBatteryLevel, FIXME, eventually when we pull mesh out into a lib we shouldn't be whacking bluetooth from here
|
||||
#include "MeshService.h"
|
||||
@@ -61,7 +60,6 @@ Allocator<QueueStatus> &queueStatusPool = staticQueueStatusPool;
|
||||
MeshService::MeshService() : toPhoneQueue(MAX_RX_TOPHONE), toPhoneQueueStatusQueue(MAX_RX_TOPHONE)
|
||||
{
|
||||
lastQueueStatus = { 0, 0, 16, 0 };
|
||||
// assert(MAX_RX_TOPHONE == 32); // FIXME, delete this, just checking my clever macro
|
||||
}
|
||||
|
||||
void MeshService::init()
|
||||
@@ -261,7 +259,7 @@ void MeshService::sendToPhone(MeshPacket *p)
|
||||
|
||||
MeshPacket *copied = packetPool.allocCopy(*p);
|
||||
perhapsDecode(copied);
|
||||
assert(toPhoneQueue.enqueue(copied, 0)); // FIXME, instead of failing for full queue, delete the oldest mssages
|
||||
assert(toPhoneQueue.enqueue(copied, 0));
|
||||
fromNum++;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "configuration.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include "Channels.h"
|
||||
#include "CryptoEngine.h"
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "PowerFSM.h"
|
||||
#include "RadioInterface.h"
|
||||
#include "configuration.h"
|
||||
#include <assert.h>
|
||||
|
||||
#if FromRadio_size > MAX_TO_FROM_RADIO_SIZE
|
||||
#error FromRadio is too big
|
||||
@@ -209,6 +208,8 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
fromRadioScratch.config.which_payload_variant = Config_bluetooth_tag;
|
||||
fromRadioScratch.config.payload_variant.bluetooth = config.bluetooth;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Unknown config type %d\n", config_state);
|
||||
}
|
||||
// NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior.
|
||||
// So even if we internally use 0 to represent 'use default' we still need to send the value we are
|
||||
@@ -262,6 +263,8 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
fromRadioScratch.moduleConfig.which_payload_variant = ModuleConfig_remote_hardware_tag;
|
||||
fromRadioScratch.moduleConfig.payload_variant.remote_hardware = moduleConfig.remote_hardware;
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Unknown module config type %d\n", config_state);
|
||||
}
|
||||
|
||||
config_state++;
|
||||
@@ -299,7 +302,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0); // unexpected state - FIXME, make an error code and reboot
|
||||
LOG_ERROR("getFromRadio unexpected state %d\n", state);
|
||||
}
|
||||
|
||||
// Do we have a message from the mesh?
|
||||
@@ -369,7 +372,7 @@ bool PhoneAPI::available()
|
||||
return hasPacket;
|
||||
}
|
||||
default:
|
||||
assert(0); // unexpected state - FIXME, make an error code and reboot
|
||||
LOG_ERROR("PhoneAPI::available unexpected state %d\n", state);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -86,9 +86,6 @@ class PhoneAPI : public Observer<uint32_t> // FIXME, we shouldn't be inheriting
|
||||
|
||||
void setInitialState() { state = STATE_SEND_MY_INFO; }
|
||||
|
||||
/// emit a debugging log character, FIXME - implement
|
||||
void debugOut(char c) { }
|
||||
|
||||
protected:
|
||||
/// Our fromradio packet while it is being assembled
|
||||
FromRadio fromRadioScratch = {};
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "Router.h"
|
||||
#include "assert.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "sleep.h"
|
||||
@@ -111,6 +110,8 @@ const RegionInfo regions[] = {
|
||||
|
||||
const RegionInfo *myRegion;
|
||||
|
||||
static uint8_t bytes[MAX_RHPACKETLEN];
|
||||
|
||||
void initRegion()
|
||||
{
|
||||
const RegionInfo *r = regions;
|
||||
@@ -164,17 +165,19 @@ uint32_t RadioInterface::getPacketTime(uint32_t pl)
|
||||
|
||||
uint32_t RadioInterface::getPacketTime(MeshPacket *p)
|
||||
{
|
||||
assert(p->which_payload_variant == MeshPacket_encrypted_tag); // It should have already been encoded by now
|
||||
uint32_t pl = p->encrypted.size + sizeof(PacketHeader);
|
||||
|
||||
uint32_t pl = 0;
|
||||
if(p->which_payload_variant == MeshPacket_encrypted_tag) {
|
||||
pl = p->encrypted.size + sizeof(PacketHeader);
|
||||
} else {
|
||||
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &Data_msg, &p->decoded);
|
||||
pl = numbytes + sizeof(PacketHeader);
|
||||
}
|
||||
return getPacketTime(pl);
|
||||
}
|
||||
|
||||
/** The delay to use for retransmitting dropped packets */
|
||||
uint32_t RadioInterface::getRetransmissionMsec(const MeshPacket *p)
|
||||
{
|
||||
assert(slotTimeMsec); // Better be non zero
|
||||
static uint8_t bytes[MAX_RHPACKETLEN];
|
||||
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &Data_msg, &p->decoded);
|
||||
uint32_t packetAirtime = getPacketTime(numbytes + sizeof(PacketHeader));
|
||||
// Make sure enough time has elapsed for this packet to be sent and an ACK is received.
|
||||
@@ -271,9 +274,6 @@ void printPacket(const char *prefix, const MeshPacket *p)
|
||||
RadioInterface::RadioInterface()
|
||||
{
|
||||
assert(sizeof(PacketHeader) == 16); // make sure the compiler did what we expected
|
||||
|
||||
// Can't print strings this early - serial not setup yet
|
||||
// LOG_DEBUG("Set meshradio defaults name=%s\n", channelSettings.name);
|
||||
}
|
||||
|
||||
bool RadioInterface::reconfigure()
|
||||
@@ -384,7 +384,7 @@ void RadioInterface::applyModemConfig()
|
||||
cr = 8;
|
||||
sf = 10;
|
||||
break;
|
||||
case Config_LoRaConfig_ModemPreset_LONG_FAST:
|
||||
default: // Config_LoRaConfig_ModemPreset_LONG_FAST is default. Gracefully use this is preset is something illegal.
|
||||
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||
cr = 8;
|
||||
sf = 11;
|
||||
@@ -399,8 +399,6 @@ void RadioInterface::applyModemConfig()
|
||||
cr = 8;
|
||||
sf = 12;
|
||||
break;
|
||||
default:
|
||||
assert(0); // Unknown enum
|
||||
}
|
||||
} else {
|
||||
sf = loraConfig.spread_factor;
|
||||
@@ -422,7 +420,6 @@ void RadioInterface::applyModemConfig()
|
||||
}
|
||||
|
||||
power = loraConfig.tx_power;
|
||||
assert(myRegion); // Should have been found in init
|
||||
|
||||
if ((power == 0) || ((power > myRegion->powerLimit) && !devicestate.owner.is_licensed))
|
||||
power = myRegion->powerLimit;
|
||||
@@ -502,7 +499,10 @@ size_t RadioInterface::beginSending(MeshPacket *p)
|
||||
h->to = p->to;
|
||||
h->id = p->id;
|
||||
h->channel = p->channel;
|
||||
assert(p->hop_limit <= HOP_MAX);
|
||||
if (p->hop_limit > HOP_MAX) {
|
||||
LOG_WARN("hop limit %d is too high, setting to %d\n", p->hop_limit, HOP_MAX);
|
||||
p->hop_limit = HOP_MAX;
|
||||
}
|
||||
h->flags = p->hop_limit | (p->want_ack ? PACKET_FLAGS_WANT_ACK_MASK : 0);
|
||||
|
||||
// if the sender nodenum is zero, that means uninitialized
|
||||
|
||||
@@ -372,7 +372,6 @@ QueueStatus RadioLibInterface::getQueueStatus()
|
||||
|
||||
printPacket("Lora RX", mp);
|
||||
|
||||
// xmitMsec = getPacketTime(mp);
|
||||
airTime->logAirtime(RX_LOG, xmitMsec);
|
||||
|
||||
deliverToReceiver(mp);
|
||||
|
||||
@@ -39,6 +39,8 @@ static MemoryDynamic<MeshPacket> staticPool;
|
||||
|
||||
Allocator<MeshPacket> &packetPool = staticPool;
|
||||
|
||||
static uint8_t bytes[MAX_RHPACKETLEN];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -94,8 +96,7 @@ PacketId generatePacketId()
|
||||
static uint32_t i; // Note: trying to keep this in noinit didn't help for working across reboots
|
||||
static bool didInit = false;
|
||||
|
||||
assert(sizeof(PacketId) == 4 || sizeof(PacketId) == 1); // only supported values
|
||||
uint32_t numPacketId = sizeof(PacketId) == 1 ? UINT8_MAX : UINT32_MAX; // 0 is consider invalid
|
||||
uint32_t numPacketId = UINT32_MAX;
|
||||
|
||||
if (!didInit) {
|
||||
didInit = true;
|
||||
@@ -191,7 +192,11 @@ void printBytes(const char *label, const uint8_t *p, size_t numbytes)
|
||||
*/
|
||||
ErrorCode Router::send(MeshPacket *p)
|
||||
{
|
||||
assert(p->to != nodeDB.getNodeNum()); // should have already been handled by sendLocal
|
||||
if (p->to == nodeDB.getNodeNum()) {
|
||||
LOG_ERROR("BUG! send() called with packet destined for local node!\n");
|
||||
packetPool.release(p);
|
||||
return Routing_Error_BAD_REQUEST;
|
||||
} // should have already been handled by sendLocal
|
||||
|
||||
// Abort sending if we are violating the duty cycle
|
||||
if (!config.lora.override_duty_cycle && myRegion->dutyCycle != 100) {
|
||||
@@ -286,7 +291,6 @@ bool Router::cancelSending(NodeNum from, PacketId id)
|
||||
*/
|
||||
void Router::sniffReceived(const MeshPacket *p, const Routing *c)
|
||||
{
|
||||
LOG_DEBUG("FIXME-update-db Sniffing packet\n");
|
||||
// FIXME, update nodedb here for any packet that passes through us
|
||||
}
|
||||
|
||||
@@ -305,7 +309,6 @@ bool perhapsDecode(MeshPacket *p)
|
||||
// Try to use this hash/channel pair
|
||||
if (channels.decryptForHash(chIndex, p->channel)) {
|
||||
// Try to decrypt the packet if we can
|
||||
static uint8_t bytes[MAX_RHPACKETLEN];
|
||||
size_t rawSize = p->encrypted.size;
|
||||
assert(rawSize <= sizeof(bytes));
|
||||
memcpy(bytes, p->encrypted.bytes,
|
||||
@@ -325,14 +328,6 @@ bool perhapsDecode(MeshPacket *p)
|
||||
p->which_payload_variant = MeshPacket_decoded_tag; // change type to decoded
|
||||
p->channel = chIndex; // change to store the index instead of the hash
|
||||
|
||||
/*
|
||||
if (p->decoded.portnum == PortNum_TEXT_MESSAGE_APP) {
|
||||
LOG_DEBUG("\n\n** TEXT_MESSAGE_APP\n");
|
||||
} else if (p->decoded.portnum == PortNum_TEXT_MESSAGE_COMPRESSED_APP) {
|
||||
LOG_DEBUG("\n\n** PortNum_TEXT_MESSAGE_COMPRESSED_APP\n");
|
||||
}
|
||||
*/
|
||||
|
||||
// Decompress if needed. jm
|
||||
if (p->decoded.portnum == PortNum_TEXT_MESSAGE_COMPRESSED_APP) {
|
||||
// Decompress the payload
|
||||
@@ -368,7 +363,6 @@ Routing_Error perhapsEncode(MeshPacket *p)
|
||||
{
|
||||
// If the packet is not yet encrypted, do so now
|
||||
if (p->which_payload_variant == MeshPacket_decoded_tag) {
|
||||
static uint8_t bytes[MAX_RHPACKETLEN]; // we have to use a scratch buffer because a union
|
||||
|
||||
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &Data_msg, &p->decoded);
|
||||
|
||||
|
||||
67
src/mesh/api/ServerAPI.cpp
Normal file
67
src/mesh/api/ServerAPI.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "ServerAPI.h"
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
template<typename T>
|
||||
ServerAPI<T>::ServerAPI(T &_client) : StreamAPI(&client), concurrency::OSThread("ServerAPI"), client(_client)
|
||||
{
|
||||
LOG_INFO("Incoming wifi connection\n");
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ServerAPI<T>::~ServerAPI()
|
||||
{
|
||||
client.stop();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ServerAPI<T>::close()
|
||||
{
|
||||
client.stop(); // drop tcp connection
|
||||
StreamAPI::close();
|
||||
}
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
template<typename T>
|
||||
bool ServerAPI<T>::checkIsConnected()
|
||||
{
|
||||
return client.connected();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int32_t ServerAPI<T>::runOnce()
|
||||
{
|
||||
if (client.connected()) {
|
||||
return StreamAPI::runOncePart();
|
||||
} else {
|
||||
LOG_INFO("Client dropped connection, suspending API service\n");
|
||||
enabled = false; // we no longer need to run
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
APIServerPort<T, U>::APIServerPort(int port) : U(port), concurrency::OSThread("ApiServer") {}
|
||||
|
||||
template<class T, class U>
|
||||
void APIServerPort<T, U>::init()
|
||||
{
|
||||
U::begin();
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
int32_t APIServerPort<T, U>::runOnce()
|
||||
{
|
||||
auto client = U::available();
|
||||
if (client) {
|
||||
// Close any previous connection (see FIXME in header file)
|
||||
if (openAPI) {
|
||||
LOG_INFO("Force closing previous TCP connection\n");
|
||||
delete openAPI;
|
||||
}
|
||||
|
||||
openAPI = new T(client);
|
||||
}
|
||||
|
||||
return 100; // only check occasionally for incoming connections
|
||||
}
|
||||
@@ -1,21 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "StreamAPI.h"
|
||||
#include <WiFi.h>
|
||||
|
||||
/**
|
||||
* Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs
|
||||
* (and starts dropping debug printing - FIXME, eventually those prints should be encapsulated in protobufs).
|
||||
*/
|
||||
class WiFiServerAPI : public StreamAPI, private concurrency::OSThread
|
||||
template<class T>
|
||||
class ServerAPI : public StreamAPI, private concurrency::OSThread
|
||||
{
|
||||
private:
|
||||
WiFiClient client;
|
||||
T client;
|
||||
|
||||
public:
|
||||
explicit WiFiServerAPI(WiFiClient &_client);
|
||||
explicit ServerAPI(T &_client);
|
||||
|
||||
virtual ~WiFiServerAPI();
|
||||
virtual ~ServerAPI();
|
||||
|
||||
/// override close to also shutdown the TCP link
|
||||
virtual void close();
|
||||
@@ -34,25 +34,21 @@ class WiFiServerAPI : public StreamAPI, private concurrency::OSThread
|
||||
/**
|
||||
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
|
||||
*/
|
||||
class WiFiServerPort : public WiFiServer, private concurrency::OSThread
|
||||
template<class T, class U>
|
||||
class APIServerPort : public U, private concurrency::OSThread
|
||||
{
|
||||
/** The currently open port
|
||||
*
|
||||
* FIXME: We currently only allow one open TCP connection at a time, because we depend on the loop() call in this class to
|
||||
* delegate to the worker. Once coroutines are implemented we can relax this restriction.
|
||||
*/
|
||||
WiFiServerAPI *openAPI = NULL;
|
||||
T *openAPI = NULL;
|
||||
|
||||
public:
|
||||
explicit WiFiServerPort(int port);
|
||||
explicit APIServerPort(int port);
|
||||
|
||||
void init();
|
||||
|
||||
/// If an api server is running, we try to spit out debug 'serial' characters there
|
||||
static void debugOut(char c);
|
||||
|
||||
protected:
|
||||
int32_t runOnce() override;
|
||||
};
|
||||
|
||||
void initApiServer(int port=4403);
|
||||
25
src/mesh/api/WiFiServerAPI.cpp
Normal file
25
src/mesh/api/WiFiServerAPI.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
#if HAS_WIFI
|
||||
#include "WiFiServerAPI.h"
|
||||
|
||||
static WiFiServerPort *apiPort;
|
||||
|
||||
void initApiServer(int port)
|
||||
{
|
||||
// Start API server on port 4403
|
||||
if (!apiPort) {
|
||||
apiPort = new WiFiServerPort(port);
|
||||
LOG_INFO("API server listening on TCP port %d\n", port);
|
||||
apiPort->init();
|
||||
}
|
||||
}
|
||||
|
||||
WiFiServerAPI::WiFiServerAPI(WiFiClient &_client) : ServerAPI(_client)
|
||||
{
|
||||
LOG_INFO("Incoming wifi connection\n");
|
||||
}
|
||||
|
||||
WiFiServerPort::WiFiServerPort(int port) : APIServerPort(port) {}
|
||||
#endif
|
||||
25
src/mesh/api/WiFiServerAPI.h
Normal file
25
src/mesh/api/WiFiServerAPI.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "ServerAPI.h"
|
||||
#include <WiFi.h>
|
||||
|
||||
/**
|
||||
* Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs
|
||||
* (and starts dropping debug printing - FIXME, eventually those prints should be encapsulated in protobufs).
|
||||
*/
|
||||
class WiFiServerAPI : public ServerAPI<WiFiClient>
|
||||
{
|
||||
public:
|
||||
explicit WiFiServerAPI(WiFiClient &_client);
|
||||
};
|
||||
|
||||
/**
|
||||
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
|
||||
*/
|
||||
class WiFiServerPort : public APIServerPort<WiFiServerAPI, WiFiServer>
|
||||
{
|
||||
public:
|
||||
explicit WiFiServerPort(int port);
|
||||
};
|
||||
|
||||
void initApiServer(int port=4403);
|
||||
27
src/mesh/api/ethServerAPI.cpp
Normal file
27
src/mesh/api/ethServerAPI.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
#if HAS_ETHERNET
|
||||
|
||||
#include "ethServerAPI.h"
|
||||
|
||||
static ethServerPort *apiPort;
|
||||
|
||||
void initApiServer(int port)
|
||||
{
|
||||
// Start API server on port 4403
|
||||
if (!apiPort) {
|
||||
apiPort = new ethServerPort(port);
|
||||
LOG_INFO("API server listening on TCP port %d\n", port);
|
||||
apiPort->init();
|
||||
}
|
||||
}
|
||||
|
||||
ethServerAPI::ethServerAPI(EthernetClient &_client) : ServerAPI(_client)
|
||||
{
|
||||
LOG_INFO("Incoming ethernet connection\n");
|
||||
}
|
||||
|
||||
ethServerPort::ethServerPort(int port) : APIServerPort(port) {}
|
||||
|
||||
#endif
|
||||
25
src/mesh/api/ethServerAPI.h
Normal file
25
src/mesh/api/ethServerAPI.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "ServerAPI.h"
|
||||
#include <RAK13800_W5100S.h>
|
||||
|
||||
/**
|
||||
* Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs
|
||||
* (and starts dropping debug printing - FIXME, eventually those prints should be encapsulated in protobufs).
|
||||
*/
|
||||
class ethServerAPI : public ServerAPI<EthernetClient>
|
||||
{
|
||||
public:
|
||||
explicit ethServerAPI(EthernetClient &_client);
|
||||
};
|
||||
|
||||
/**
|
||||
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
|
||||
*/
|
||||
class ethServerPort : public APIServerPort<ethServerAPI, EthernetServer>
|
||||
{
|
||||
public:
|
||||
explicit ethServerPort(int port);
|
||||
};
|
||||
|
||||
void initApiServer(int port=4403);
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <SPI.h>
|
||||
#include <RAK13800_W5100S.h>
|
||||
#include "target_specific.h"
|
||||
#include "mesh/eth/ethServerAPI.h"
|
||||
#include "mesh/api/ethServerAPI.h"
|
||||
#include "mqtt/MQTT.h"
|
||||
|
||||
#ifndef DISABLE_NTP
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
#include "ethServerAPI.h"
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
static ethServerPort *apiPort;
|
||||
|
||||
void initApiServer(int port)
|
||||
{
|
||||
// Start API server on port 4403
|
||||
if (!apiPort) {
|
||||
apiPort = new ethServerPort(port);
|
||||
LOG_INFO("API server listening on TCP port %d\n", port);
|
||||
apiPort->init();
|
||||
}
|
||||
}
|
||||
|
||||
ethServerAPI::ethServerAPI(EthernetClient &_client) : StreamAPI(&client), concurrency::OSThread("ethServerAPI"), client(_client)
|
||||
{
|
||||
LOG_INFO("Incoming ethernet connection\n");
|
||||
}
|
||||
|
||||
ethServerAPI::~ethServerAPI()
|
||||
{
|
||||
client.stop();
|
||||
|
||||
// FIXME - delete this if the client dropps the connection!
|
||||
}
|
||||
|
||||
/// override close to also shutdown the TCP link
|
||||
void ethServerAPI::close()
|
||||
{
|
||||
client.stop(); // drop tcp connection
|
||||
StreamAPI::close();
|
||||
}
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
bool ethServerAPI::checkIsConnected()
|
||||
{
|
||||
return client.connected();
|
||||
}
|
||||
|
||||
int32_t ethServerAPI::runOnce()
|
||||
{
|
||||
if (client.connected()) {
|
||||
return StreamAPI::runOncePart();
|
||||
} else {
|
||||
LOG_INFO("Client dropped connection, suspending API service\n");
|
||||
enabled = false; // we no longer need to run
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// If an api server is running, we try to spit out debug 'serial' characters there
|
||||
void ethServerPort::debugOut(char c)
|
||||
{
|
||||
if (apiPort && apiPort->openAPI)
|
||||
apiPort->openAPI->debugOut(c);
|
||||
}
|
||||
|
||||
|
||||
ethServerPort::ethServerPort(int port) : EthernetServer(port), concurrency::OSThread("ApiServer") {}
|
||||
|
||||
void ethServerPort::init()
|
||||
{
|
||||
begin();
|
||||
}
|
||||
|
||||
int32_t ethServerPort::runOnce()
|
||||
{
|
||||
auto client = available();
|
||||
if (client) {
|
||||
// Close any previous connection (see FIXME in header file)
|
||||
if (openAPI) {
|
||||
LOG_WARN("Force closing previous TCP connection\n");
|
||||
delete openAPI;
|
||||
}
|
||||
|
||||
openAPI = new ethServerAPI(client);
|
||||
}
|
||||
|
||||
return 100; // only check occasionally for incoming connections
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "StreamAPI.h"
|
||||
#include <RAK13800_W5100S.h>
|
||||
|
||||
/**
|
||||
* Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs
|
||||
* (and starts dropping debug printing - FIXME, eventually those prints should be encapsulated in protobufs).
|
||||
*/
|
||||
class ethServerAPI : public StreamAPI, private concurrency::OSThread
|
||||
{
|
||||
private:
|
||||
EthernetClient client;
|
||||
|
||||
public:
|
||||
explicit ethServerAPI(EthernetClient &_client);
|
||||
|
||||
virtual ~ethServerAPI();
|
||||
|
||||
/// override close to also shutdown the TCP link
|
||||
virtual void close();
|
||||
|
||||
protected:
|
||||
/// We override this method to prevent publishing EVENT_SERIAL_CONNECTED/DISCONNECTED for wifi links (we want the board to
|
||||
/// stay in the POWERED state to prevent disabling wifi)
|
||||
virtual void onConnectionChanged(bool connected) override {}
|
||||
|
||||
virtual int32_t runOnce() override; // Check for dropped client connections
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
virtual bool checkIsConnected() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Listens for incoming connections and does accepts and creates instances of WiFiServerAPI as needed
|
||||
*/
|
||||
class ethServerPort : public EthernetServer, private concurrency::OSThread
|
||||
{
|
||||
/** The currently open port
|
||||
*
|
||||
* FIXME: We currently only allow one open TCP connection at a time, because we depend on the loop() call in this class to
|
||||
* delegate to the worker. Once coroutines are implemented we can relax this restriction.
|
||||
*/
|
||||
ethServerAPI *openAPI = NULL;
|
||||
|
||||
public:
|
||||
explicit ethServerPort(int port);
|
||||
|
||||
void init();
|
||||
|
||||
/// If an api server is running, we try to spit out debug 'serial' characters there
|
||||
static void debugOut(char c);
|
||||
|
||||
protected:
|
||||
int32_t runOnce() override;
|
||||
};
|
||||
|
||||
void initApiServer(int port=4403);
|
||||
@@ -184,6 +184,7 @@ bool initWifi()
|
||||
|
||||
WiFi.onEvent(
|
||||
[](WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||
|
||||
LOG_WARN("WiFi lost connection. Reason: %d\n", info.wifi_sta_disconnected.reason);
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
#include "WiFiServerAPI.h"
|
||||
#include "configuration.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
static WiFiServerPort *apiPort;
|
||||
|
||||
void initApiServer(int port)
|
||||
{
|
||||
// Start API server on port 4403
|
||||
if (!apiPort) {
|
||||
apiPort = new WiFiServerPort(port);
|
||||
LOG_INFO("API server listening on TCP port %d\n", port);
|
||||
apiPort->init();
|
||||
}
|
||||
}
|
||||
|
||||
WiFiServerAPI::WiFiServerAPI(WiFiClient &_client) : StreamAPI(&client), concurrency::OSThread("WiFiServerAPI"), client(_client)
|
||||
{
|
||||
LOG_INFO("Incoming wifi connection\n");
|
||||
}
|
||||
|
||||
WiFiServerAPI::~WiFiServerAPI()
|
||||
{
|
||||
client.stop();
|
||||
|
||||
// FIXME - delete this if the client dropps the connection!
|
||||
}
|
||||
|
||||
/// override close to also shutdown the TCP link
|
||||
void WiFiServerAPI::close()
|
||||
{
|
||||
client.stop(); // drop tcp connection
|
||||
StreamAPI::close();
|
||||
}
|
||||
|
||||
/// Check the current underlying physical link to see if the client is currently connected
|
||||
bool WiFiServerAPI::checkIsConnected()
|
||||
{
|
||||
return client.connected();
|
||||
}
|
||||
|
||||
int32_t WiFiServerAPI::runOnce()
|
||||
{
|
||||
if (client.connected()) {
|
||||
return StreamAPI::runOncePart();
|
||||
} else {
|
||||
LOG_INFO("Client dropped connection, suspending API service\n");
|
||||
enabled = false; // we no longer need to run
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// If an api server is running, we try to spit out debug 'serial' characters there
|
||||
void WiFiServerPort::debugOut(char c)
|
||||
{
|
||||
if (apiPort && apiPort->openAPI)
|
||||
apiPort->openAPI->debugOut(c);
|
||||
}
|
||||
|
||||
|
||||
WiFiServerPort::WiFiServerPort(int port) : WiFiServer(port), concurrency::OSThread("ApiServer") {}
|
||||
|
||||
void WiFiServerPort::init()
|
||||
{
|
||||
begin();
|
||||
}
|
||||
|
||||
int32_t WiFiServerPort::runOnce()
|
||||
{
|
||||
auto client = available();
|
||||
if (client) {
|
||||
// Close any previous connection (see FIXME in header file)
|
||||
if (openAPI) {
|
||||
LOG_INFO("Force closing previous TCP connection\n");
|
||||
delete openAPI;
|
||||
}
|
||||
|
||||
openAPI = new WiFiServerAPI(client);
|
||||
}
|
||||
|
||||
return 100; // only check occasionally for incoming connections
|
||||
}
|
||||
Reference in New Issue
Block a user