diff --git a/docs/software/TODO.md b/docs/software/TODO.md index d2c4a7c97..1c6714e84 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -14,7 +14,9 @@ You probably don't care about this section - skip to the next one. * enable remote setttings access by moving settings operations into a regular plugin (move settings ops out of PhoneAPI) * DONE move portnum up? * DONE remove region specific builds from the firmware +* restrict settings operations to the admin channel * add gui in android app for setting region +* "FIXME - move the radioconfig/user/channel READ operations into SettingsMessage as well" * scrub protobufs to make sure they are absoloute minimum wiresize (in particular packets, ChannelSets and positions) * send a hint that can be used to select which channel to try and hash against with each message * change syncword diff --git a/proto b/proto index f23417aa7..649c3deb7 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit f23417aa7dcb8f61bbb2c1ea07c7b988ae66ec38 +Subproject commit 649c3deb71d1780416fac5db33ad3c957c0278b6 diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 6ec09b2ca..7f63fc18e 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -78,20 +78,6 @@ void PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength) // this will break once we have multiple instances of PhoneAPI running independently break; - case ToRadio_set_owner_tag: - DEBUG_MSG("Client is setting owner\n"); - handleSetOwner(toRadioScratch.set_owner); - break; - - case ToRadio_set_radio_tag: - DEBUG_MSG("Client is setting radio\n"); - handleSetRadio(toRadioScratch.set_radio); - break; - - case ToRadio_set_channel_tag: - DEBUG_MSG("Client is setting channel\n"); - handleSetChannel(toRadioScratch.set_channel); - break; default: DEBUG_MSG("Error: unexpected ToRadio variant\n"); break; @@ -255,52 +241,6 @@ bool PhoneAPI::available() return false; } -// -// The following routines are only public for now - until the rev1 bluetooth API is removed -// - -void PhoneAPI::handleSetOwner(const User &o) -{ - int changed = 0; - - if (*o.long_name) { - changed |= strcmp(owner.long_name, o.long_name); - strcpy(owner.long_name, o.long_name); - } - if (*o.short_name) { - changed |= strcmp(owner.short_name, o.short_name); - strcpy(owner.short_name, o.short_name); - } - if (*o.id) { - changed |= strcmp(owner.id, o.id); - strcpy(owner.id, o.id); - } - - if (changed) // If nothing really changed, don't broadcast on the network or write to flash - service.reloadOwner(); -} - -void PhoneAPI::handleSetChannel(const Channel &cc) -{ - channels.setChannel(cc); - - bool didReset = service.reloadConfig(); - if (didReset) { - state = STATE_SEND_MY_INFO; // Squirt a completely new set of configs to the client - } - -} - -void PhoneAPI::handleSetRadio(const RadioConfig &r) -{ - radioConfig = r; - - bool didReset = service.reloadConfig(); - if (didReset) { - state = STATE_SEND_MY_INFO; // Squirt a completely new set of configs to the client - } -} - /** * Handle a packet that the phone wants us to send. It is our responsibility to free the packet to the pool */ diff --git a/src/mesh/generated/mesh.pb.c b/src/mesh/generated/mesh.pb.c index c4fd0d8e5..f0b3f8c66 100644 --- a/src/mesh/generated/mesh.pb.c +++ b/src/mesh/generated/mesh.pb.c @@ -51,6 +51,9 @@ PB_BIND(FromRadio, FromRadio, 2) PB_BIND(ToRadio, ToRadio, 2) +PB_BIND(AdminMessage, AdminMessage, 2) + + diff --git a/src/mesh/generated/mesh.pb.h b/src/mesh/generated/mesh.pb.h index 106444eb3..d29f6c86b 100644 --- a/src/mesh/generated/mesh.pb.h +++ b/src/mesh/generated/mesh.pb.h @@ -281,6 +281,15 @@ typedef struct _Routing { uint32_t original_id; } Routing; +typedef struct _AdminMessage { + pb_size_t which_variant; + union { + RadioConfig set_radio; + User set_owner; + Channel set_channel; + }; +} AdminMessage; + typedef struct _FromRadio { uint32_t num; pb_size_t which_payloadVariant; @@ -301,9 +310,6 @@ typedef struct _ToRadio { union { MeshPacket packet; uint32_t want_config_id; - RadioConfig set_radio; - User set_owner; - Channel set_channel; }; } ToRadio; @@ -374,6 +380,7 @@ extern "C" { #define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN} #define FromRadio_init_default {0, 0, {MyNodeInfo_init_default}} #define ToRadio_init_default {0, {MeshPacket_init_default}} +#define AdminMessage_init_default {0, {RadioConfig_init_default}} #define Position_init_zero {0, 0, 0, 0, 0} #define User_init_zero {"", "", "", {0}} #define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}} @@ -389,6 +396,7 @@ extern "C" { #define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN} #define FromRadio_init_zero {0, 0, {MyNodeInfo_init_zero}} #define ToRadio_init_zero {0, {MeshPacket_init_zero}} +#define AdminMessage_init_zero {0, {RadioConfig_init_zero}} /* Field tags (for use in manual encoding/decoding) */ #define ChannelSettings_tx_power_tag 1 @@ -501,6 +509,9 @@ extern "C" { #define Routing_success_id_tag 4 #define Routing_fail_id_tag 5 #define Routing_original_id_tag 6 +#define AdminMessage_set_radio_tag 1 +#define AdminMessage_set_owner_tag 2 +#define AdminMessage_set_channel_tag 3 #define FromRadio_num_tag 1 #define FromRadio_my_info_tag 3 #define FromRadio_node_info_tag 4 @@ -512,9 +523,6 @@ extern "C" { #define FromRadio_packet_tag 11 #define ToRadio_packet_tag 2 #define ToRadio_want_config_id_tag 100 -#define ToRadio_set_radio_tag 101 -#define ToRadio_set_owner_tag 102 -#define ToRadio_set_channel_tag 104 /* Struct field encoding specification for nanopb */ #define Position_FIELDLIST(X, a) \ @@ -707,16 +715,20 @@ X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 11) #define ToRadio_FIELDLIST(X, a) \ X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 2) \ -X(a, STATIC, ONEOF, UINT32, (payloadVariant,want_config_id,want_config_id), 100) \ -X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,set_radio,set_radio), 101) \ -X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,set_owner,set_owner), 102) \ -X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,set_channel,set_channel), 104) +X(a, STATIC, ONEOF, UINT32, (payloadVariant,want_config_id,want_config_id), 100) #define ToRadio_CALLBACK NULL #define ToRadio_DEFAULT NULL #define ToRadio_payloadVariant_packet_MSGTYPE MeshPacket -#define ToRadio_payloadVariant_set_radio_MSGTYPE RadioConfig -#define ToRadio_payloadVariant_set_owner_MSGTYPE User -#define ToRadio_payloadVariant_set_channel_MSGTYPE Channel + +#define AdminMessage_FIELDLIST(X, a) \ +X(a, STATIC, ONEOF, MESSAGE, (variant,set_radio,set_radio), 1) \ +X(a, STATIC, ONEOF, MESSAGE, (variant,set_owner,set_owner), 2) \ +X(a, STATIC, ONEOF, MESSAGE, (variant,set_channel,set_channel), 3) +#define AdminMessage_CALLBACK NULL +#define AdminMessage_DEFAULT NULL +#define AdminMessage_variant_set_radio_MSGTYPE RadioConfig +#define AdminMessage_variant_set_owner_MSGTYPE User +#define AdminMessage_variant_set_channel_MSGTYPE Channel extern const pb_msgdesc_t Position_msg; extern const pb_msgdesc_t User_msg; @@ -733,6 +745,7 @@ extern const pb_msgdesc_t MyNodeInfo_msg; extern const pb_msgdesc_t LogRecord_msg; extern const pb_msgdesc_t FromRadio_msg; extern const pb_msgdesc_t ToRadio_msg; +extern const pb_msgdesc_t AdminMessage_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define Position_fields &Position_msg @@ -750,6 +763,7 @@ extern const pb_msgdesc_t ToRadio_msg; #define LogRecord_fields &LogRecord_msg #define FromRadio_fields &FromRadio_msg #define ToRadio_fields &ToRadio_msg +#define AdminMessage_fields &AdminMessage_msg /* Maximum encoded size of messages (where known) */ #define Position_size 37 @@ -766,7 +780,8 @@ extern const pb_msgdesc_t ToRadio_msg; #define MyNodeInfo_size 89 #define LogRecord_size 81 #define FromRadio_size 317 -#define ToRadio_size 312 +#define ToRadio_size 305 +#define AdminMessage_size 311 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/portnums.pb.h b/src/mesh/generated/portnums.pb.h index 72360f295..3ddd806ea 100644 --- a/src/mesh/generated/portnums.pb.h +++ b/src/mesh/generated/portnums.pb.h @@ -17,6 +17,7 @@ typedef enum _PortNum { PortNum_POSITION_APP = 3, PortNum_NODEINFO_APP = 4, PortNum_ROUTING_APP = 5, + PortNum_ADMIN_APP = 6, PortNum_REPLY_APP = 32, PortNum_IP_TUNNEL_APP = 33, PortNum_SERIAL_APP = 64, diff --git a/src/plugins/AdminPlugin.cpp b/src/plugins/AdminPlugin.cpp new file mode 100644 index 000000000..248a4ebd3 --- /dev/null +++ b/src/plugins/AdminPlugin.cpp @@ -0,0 +1,93 @@ +#include "AdminPlugin.h" +#include "MeshService.h" +#include "NodeDB.h" +#include "Router.h" +#include "configuration.h" +#include "main.h" +#include "Channels.h" + +AdminPlugin *adminPlugin; + +bool AdminPlugin::handleReceivedProtobuf(const MeshPacket &mp, const AdminMessage *r) +{ + assert(r); + switch(r->which_variant) { + case AdminMessage_set_owner_tag: + DEBUG_MSG("Client is setting owner\n"); + handleSetOwner(r->set_owner); + break; + + case AdminMessage_set_radio_tag: + DEBUG_MSG("Client is setting radio\n"); + handleSetRadio(r->set_radio); + break; + + case AdminMessage_set_channel_tag: + DEBUG_MSG("Client is setting channel\n"); + handleSetChannel(r->set_channel); + break; + } + return false; // Let others look at this message also if they want +} + + + +void AdminPlugin::handleSetOwner(const User &o) +{ + int changed = 0; + + if (*o.long_name) { + changed |= strcmp(owner.long_name, o.long_name); + strcpy(owner.long_name, o.long_name); + } + if (*o.short_name) { + changed |= strcmp(owner.short_name, o.short_name); + strcpy(owner.short_name, o.short_name); + } + if (*o.id) { + changed |= strcmp(owner.id, o.id); + strcpy(owner.id, o.id); + } + + if (changed) // If nothing really changed, don't broadcast on the network or write to flash + service.reloadOwner(); +} + +void AdminPlugin::handleSetChannel(const Channel &cc) +{ + channels.setChannel(cc); + + bool didReset = service.reloadConfig(); + /* FIXME - do we need this still? + if (didReset) { + state = STATE_SEND_MY_INFO; // Squirt a completely new set of configs to the client + } */ + +} + +void AdminPlugin::handleSetRadio(const RadioConfig &r) +{ + radioConfig = r; + + bool didReset = service.reloadConfig(); + /* FIXME - do we need this still? if (didReset) { + state = STATE_SEND_MY_INFO; // Squirt a completely new set of configs to the client + } */ +} + + +MeshPacket *AdminPlugin::allocReply() +{ + assert(0); // 1.2 refactoring fixme, Not sure if anything needs this yet? + // return allocDataProtobuf(u); + return NULL; +} + +AdminPlugin::AdminPlugin() + : ProtobufPlugin("Admin", PortNum_ADMIN_APP, AdminMessage_fields) +{ + // FIXME, restrict to the admin channel for rx +} + + + diff --git a/src/plugins/AdminPlugin.h b/src/plugins/AdminPlugin.h new file mode 100644 index 000000000..de8ffac11 --- /dev/null +++ b/src/plugins/AdminPlugin.h @@ -0,0 +1,32 @@ +#pragma once +#include "ProtobufPlugin.h" + +/** + * Routing plugin for router control messages + */ +class AdminPlugin : public ProtobufPlugin +{ + public: + /** Constructor + * name is for debugging output + */ + AdminPlugin(); + + protected: + /** Called to handle a particular incoming message + + @return true if you've guaranteed you've handled this message and no other handlers should be considered for it + */ + virtual bool handleReceivedProtobuf(const MeshPacket &mp, const AdminMessage *p); + + /** Messages can be received that have the want_response bit set. If set, this callback will be invoked + * so that subclasses can (optionally) send a response back to the original sender. */ + virtual MeshPacket *allocReply(); + + private: + void handleSetOwner(const User &o); + void handleSetChannel(const Channel &cc); + void handleSetRadio(const RadioConfig &r); +}; + +extern AdminPlugin *adminPlugin; \ No newline at end of file diff --git a/src/plugins/Plugins.cpp b/src/plugins/Plugins.cpp index 65cfdcee4..12246f8c8 100644 --- a/src/plugins/Plugins.cpp +++ b/src/plugins/Plugins.cpp @@ -8,6 +8,7 @@ #include "plugins/StoreForwardPlugin.h" #include "plugins/TextMessagePlugin.h" #include "plugins/RoutingPlugin.h" +#include "plugins/AdminPlugin.h" /** * Create plugin instances here. If you are adding a new plugin, you must 'new' it here (or somewhere else) @@ -15,6 +16,7 @@ void setupPlugins() { routingPlugin = new RoutingPlugin(); + adminPlugin = new AdminPlugin(); nodeInfoPlugin = new NodeInfoPlugin(); positionPlugin = new PositionPlugin(); textMessagePlugin = new TextMessagePlugin(); diff --git a/src/plugins/RoutingPlugin.cpp b/src/plugins/RoutingPlugin.cpp index c3709ea5a..58b3f08ae 100644 --- a/src/plugins/RoutingPlugin.cpp +++ b/src/plugins/RoutingPlugin.cpp @@ -1,7 +1,6 @@ #include "RoutingPlugin.h" #include "MeshService.h" #include "NodeDB.h" -#include "RTC.h" #include "Router.h" #include "configuration.h" #include "main.h" @@ -53,7 +52,7 @@ void RoutingPlugin::sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom) } RoutingPlugin::RoutingPlugin() - : ProtobufPlugin("routing", PortNum_ROUTING_APP, User_fields) + : ProtobufPlugin("routing", PortNum_ROUTING_APP, Routing_fields) { isPromiscuous = true; }