diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 2743c7356..83880d9a5 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -147,6 +147,17 @@ static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int1 drawIconScreen(region, display, state, x, y); } +// Used on boot when a certificate is being created +static void drawSSLScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +{ + display->setTextAlignment(TEXT_ALIGN_CENTER); + display->setFont(FONT_SMALL); + display->drawString(64 + x, y, "Creating SSL certificate"); + + display->setFont(FONT_SMALL); + display->drawString(64 + x, FONT_HEIGHT_SMALL + y + 2, "Please wait..."); +} + #ifdef HAS_EINK /// Used on eink displays while in deep sleep static void drawSleepScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) @@ -905,6 +916,16 @@ void Screen::drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiStat screen->debugInfo.drawFrameWiFi(display, state, x, y); } +/* show a message that the SSL cert is being built + * it is expected that this will be used during the boot phase */ +void Screen::setSSLFrames() +{ + DEBUG_MSG("showing SSL frames\n"); + static FrameCallback sslFrames[] = {drawSSLScreen}; + ui.setFrames(sslFrames, 1); + ui.update(); +} + // restore our regular frame list void Screen::setFrames() { diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h index 1c543dbf0..e4b9044c7 100644 --- a/src/graphics/Screen.h +++ b/src/graphics/Screen.h @@ -220,6 +220,9 @@ class Screen : public concurrency::OSThread /// Used to force (super slow) eink displays to draw critical frames void forceDisplay(); + /// Draws our SSL cert screen during boot (called from WebServer) + void setSSLFrames(); + protected: /// Updates the UI. // diff --git a/src/mesh/generated/admin.pb.h b/src/mesh/generated/admin.pb.h index b176b83e2..ab4152434 100644 --- a/src/mesh/generated/admin.pb.h +++ b/src/mesh/generated/admin.pb.h @@ -79,7 +79,7 @@ extern const pb_msgdesc_t AdminMessage_msg; #define AdminMessage_fields &AdminMessage_msg /* Maximum encoded size of messages (where known) */ -#define AdminMessage_size 430 +#define AdminMessage_size 447 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/radioconfig.pb.h b/src/mesh/generated/radioconfig.pb.h index 37780ca6e..4cbb693b3 100644 --- a/src/mesh/generated/radioconfig.pb.h +++ b/src/mesh/generated/radioconfig.pb.h @@ -136,6 +136,8 @@ typedef struct _RadioConfig_UserPreferences { uint32_t range_test_plugin_sender; bool range_test_plugin_save; uint32_t store_forward_plugin_records; + uint32_t store_forward_plugin_history_return_max; + uint32_t store_forward_plugin_history_return_window; bool environmental_measurement_plugin_measurement_enabled; bool environmental_measurement_plugin_screen_enabled; uint32_t environmental_measurement_plugin_read_error_count_threshold; @@ -145,6 +147,7 @@ typedef struct _RadioConfig_UserPreferences { RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType environmental_measurement_plugin_sensor_type; uint32_t environmental_measurement_plugin_sensor_pin; bool store_forward_plugin_enabled; + bool store_forward_plugin_heartbeat; uint32_t position_flags; bool is_always_powered; uint32_t auto_screen_carousel_secs; @@ -192,9 +195,9 @@ extern "C" { /* Initializer values for message structs */ #define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default} -#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0} +#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0} #define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero} -#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0} +#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0} /* Field tags (for use in manual encoding/decoding) */ #define RadioConfig_UserPreferences_position_broadcast_secs_tag 1 @@ -246,6 +249,8 @@ extern "C" { #define RadioConfig_UserPreferences_range_test_plugin_sender_tag 133 #define RadioConfig_UserPreferences_range_test_plugin_save_tag 134 #define RadioConfig_UserPreferences_store_forward_plugin_records_tag 137 +#define RadioConfig_UserPreferences_store_forward_plugin_history_return_max_tag 138 +#define RadioConfig_UserPreferences_store_forward_plugin_history_return_window_tag 139 #define RadioConfig_UserPreferences_environmental_measurement_plugin_measurement_enabled_tag 140 #define RadioConfig_UserPreferences_environmental_measurement_plugin_screen_enabled_tag 141 #define RadioConfig_UserPreferences_environmental_measurement_plugin_read_error_count_threshold_tag 142 @@ -255,6 +260,7 @@ extern "C" { #define RadioConfig_UserPreferences_environmental_measurement_plugin_sensor_type_tag 146 #define RadioConfig_UserPreferences_environmental_measurement_plugin_sensor_pin_tag 147 #define RadioConfig_UserPreferences_store_forward_plugin_enabled_tag 148 +#define RadioConfig_UserPreferences_store_forward_plugin_heartbeat_tag 149 #define RadioConfig_UserPreferences_position_flags_tag 150 #define RadioConfig_UserPreferences_is_always_powered_tag 151 #define RadioConfig_UserPreferences_auto_screen_carousel_secs_tag 152 @@ -317,6 +323,8 @@ X(a, STATIC, SINGULAR, BOOL, range_test_plugin_enabled, 132) \ X(a, STATIC, SINGULAR, UINT32, range_test_plugin_sender, 133) \ X(a, STATIC, SINGULAR, BOOL, range_test_plugin_save, 134) \ X(a, STATIC, SINGULAR, UINT32, store_forward_plugin_records, 137) \ +X(a, STATIC, SINGULAR, UINT32, store_forward_plugin_history_return_max, 138) \ +X(a, STATIC, SINGULAR, UINT32, store_forward_plugin_history_return_window, 139) \ X(a, STATIC, SINGULAR, BOOL, environmental_measurement_plugin_measurement_enabled, 140) \ X(a, STATIC, SINGULAR, BOOL, environmental_measurement_plugin_screen_enabled, 141) \ X(a, STATIC, SINGULAR, UINT32, environmental_measurement_plugin_read_error_count_threshold, 142) \ @@ -326,6 +334,7 @@ X(a, STATIC, SINGULAR, BOOL, environmental_measurement_plugin_display_fare X(a, STATIC, SINGULAR, UENUM, environmental_measurement_plugin_sensor_type, 146) \ X(a, STATIC, SINGULAR, UINT32, environmental_measurement_plugin_sensor_pin, 147) \ X(a, STATIC, SINGULAR, BOOL, store_forward_plugin_enabled, 148) \ +X(a, STATIC, SINGULAR, BOOL, store_forward_plugin_heartbeat, 149) \ X(a, STATIC, SINGULAR, UINT32, position_flags, 150) \ X(a, STATIC, SINGULAR, BOOL, is_always_powered, 151) \ X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 152) @@ -340,8 +349,8 @@ extern const pb_msgdesc_t RadioConfig_UserPreferences_msg; #define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg /* Maximum encoded size of messages (where known) */ -#define RadioConfig_size 427 -#define RadioConfig_UserPreferences_size 424 +#define RadioConfig_size 444 +#define RadioConfig_UserPreferences_size 441 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/storeforward.pb.c b/src/mesh/generated/storeforward.pb.c new file mode 100644 index 000000000..a348ee01b --- /dev/null +++ b/src/mesh/generated/storeforward.pb.c @@ -0,0 +1,19 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.4 */ + +#include "storeforward.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(StoreAndForwardMessage, StoreAndForwardMessage, AUTO) + + +PB_BIND(StoreAndForwardMessage_Statistics, StoreAndForwardMessage_Statistics, AUTO) + + +PB_BIND(StoreAndForwardMessage_History, StoreAndForwardMessage_History, AUTO) + + + + diff --git a/src/mesh/generated/storeforward.pb.h b/src/mesh/generated/storeforward.pb.h new file mode 100644 index 000000000..988ff3276 --- /dev/null +++ b/src/mesh/generated/storeforward.pb.h @@ -0,0 +1,136 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.4 */ + +#ifndef PB_STOREFORWARD_PB_H_INCLUDED +#define PB_STOREFORWARD_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Enum definitions */ +typedef enum _StoreAndForwardMessage_RequestResponse { + StoreAndForwardMessage_RequestResponse_UNSET = 0, + StoreAndForwardMessage_RequestResponse_ROUTER_ERROR = 1, + StoreAndForwardMessage_RequestResponse_ROUTER_HEARTBEAT = 2, + StoreAndForwardMessage_RequestResponse_ROUTER_PING = 3, + StoreAndForwardMessage_RequestResponse_ROUTER_PONG = 4, + StoreAndForwardMessage_RequestResponse_ROUTER_BUSY = 5, + StoreAndForwardMessage_RequestResponse_CLIENT_ERROR = 101, + StoreAndForwardMessage_RequestResponse_CLIENT_HISTORY = 102, + StoreAndForwardMessage_RequestResponse_CLIENT_STATS = 103, + StoreAndForwardMessage_RequestResponse_CLIENT_PING = 104, + StoreAndForwardMessage_RequestResponse_CLIENT_PONG = 105, + StoreAndForwardMessage_RequestResponse_MAX = 255 +} StoreAndForwardMessage_RequestResponse; + +/* Struct definitions */ +typedef struct _StoreAndForwardMessage_History { + uint32_t HistoryMessages; + uint32_t Window; +} StoreAndForwardMessage_History; + +typedef struct _StoreAndForwardMessage_Statistics { + uint32_t MessagesTotal; + uint32_t MessagesSaved; + uint32_t MessagesMax; + uint32_t UpTime; + uint32_t Requests; + uint32_t RequestsHistory; + bool Heartbeat; + uint32_t ReturnMax; + uint32_t ReturnWindow; +} StoreAndForwardMessage_Statistics; + +typedef struct _StoreAndForwardMessage { + StoreAndForwardMessage_RequestResponse rr; + bool has_stats; + StoreAndForwardMessage_Statistics stats; + bool has_history; + StoreAndForwardMessage_History history; +} StoreAndForwardMessage; + + +/* Helper constants for enums */ +#define _StoreAndForwardMessage_RequestResponse_MIN StoreAndForwardMessage_RequestResponse_UNSET +#define _StoreAndForwardMessage_RequestResponse_MAX StoreAndForwardMessage_RequestResponse_MAX +#define _StoreAndForwardMessage_RequestResponse_ARRAYSIZE ((StoreAndForwardMessage_RequestResponse)(StoreAndForwardMessage_RequestResponse_MAX+1)) + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define StoreAndForwardMessage_init_default {_StoreAndForwardMessage_RequestResponse_MIN, false, StoreAndForwardMessage_Statistics_init_default, false, StoreAndForwardMessage_History_init_default} +#define StoreAndForwardMessage_Statistics_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0} +#define StoreAndForwardMessage_History_init_default {0, 0} +#define StoreAndForwardMessage_init_zero {_StoreAndForwardMessage_RequestResponse_MIN, false, StoreAndForwardMessage_Statistics_init_zero, false, StoreAndForwardMessage_History_init_zero} +#define StoreAndForwardMessage_Statistics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0} +#define StoreAndForwardMessage_History_init_zero {0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define StoreAndForwardMessage_History_HistoryMessages_tag 1 +#define StoreAndForwardMessage_History_Window_tag 2 +#define StoreAndForwardMessage_Statistics_MessagesTotal_tag 1 +#define StoreAndForwardMessage_Statistics_MessagesSaved_tag 2 +#define StoreAndForwardMessage_Statistics_MessagesMax_tag 3 +#define StoreAndForwardMessage_Statistics_UpTime_tag 4 +#define StoreAndForwardMessage_Statistics_Requests_tag 5 +#define StoreAndForwardMessage_Statistics_RequestsHistory_tag 6 +#define StoreAndForwardMessage_Statistics_Heartbeat_tag 7 +#define StoreAndForwardMessage_Statistics_ReturnMax_tag 8 +#define StoreAndForwardMessage_Statistics_ReturnWindow_tag 9 +#define StoreAndForwardMessage_rr_tag 1 +#define StoreAndForwardMessage_stats_tag 2 +#define StoreAndForwardMessage_history_tag 3 + +/* Struct field encoding specification for nanopb */ +#define StoreAndForwardMessage_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, rr, 1) \ +X(a, STATIC, OPTIONAL, MESSAGE, stats, 2) \ +X(a, STATIC, OPTIONAL, MESSAGE, history, 3) +#define StoreAndForwardMessage_CALLBACK NULL +#define StoreAndForwardMessage_DEFAULT NULL +#define StoreAndForwardMessage_stats_MSGTYPE StoreAndForwardMessage_Statistics +#define StoreAndForwardMessage_history_MSGTYPE StoreAndForwardMessage_History + +#define StoreAndForwardMessage_Statistics_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, MessagesTotal, 1) \ +X(a, STATIC, SINGULAR, UINT32, MessagesSaved, 2) \ +X(a, STATIC, SINGULAR, UINT32, MessagesMax, 3) \ +X(a, STATIC, SINGULAR, UINT32, UpTime, 4) \ +X(a, STATIC, SINGULAR, UINT32, Requests, 5) \ +X(a, STATIC, SINGULAR, UINT32, RequestsHistory, 6) \ +X(a, STATIC, SINGULAR, BOOL, Heartbeat, 7) \ +X(a, STATIC, SINGULAR, UINT32, ReturnMax, 8) \ +X(a, STATIC, SINGULAR, UINT32, ReturnWindow, 9) +#define StoreAndForwardMessage_Statistics_CALLBACK NULL +#define StoreAndForwardMessage_Statistics_DEFAULT NULL + +#define StoreAndForwardMessage_History_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, HistoryMessages, 1) \ +X(a, STATIC, SINGULAR, UINT32, Window, 2) +#define StoreAndForwardMessage_History_CALLBACK NULL +#define StoreAndForwardMessage_History_DEFAULT NULL + +extern const pb_msgdesc_t StoreAndForwardMessage_msg; +extern const pb_msgdesc_t StoreAndForwardMessage_Statistics_msg; +extern const pb_msgdesc_t StoreAndForwardMessage_History_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define StoreAndForwardMessage_fields &StoreAndForwardMessage_msg +#define StoreAndForwardMessage_Statistics_fields &StoreAndForwardMessage_Statistics_msg +#define StoreAndForwardMessage_History_fields &StoreAndForwardMessage_History_msg + +/* Maximum encoded size of messages (where known) */ +#define StoreAndForwardMessage_size 69 +#define StoreAndForwardMessage_Statistics_size 50 +#define StoreAndForwardMessage_History_size 12 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/mesh/http/WebServer.cpp b/src/mesh/http/WebServer.cpp index 0f3ae5cd7..f9e2e99dc 100644 --- a/src/mesh/http/WebServer.cpp +++ b/src/mesh/http/WebServer.cpp @@ -1,3 +1,4 @@ +#include "main.h" #include "mesh/http/WebServer.h" #include "NodeDB.h" #include "mesh/http/WiFiAPClient.h" @@ -77,7 +78,7 @@ static void taskCreateCert(void *parameter) { prefs.begin("MeshtasticHTTPS", false); - // Delete the saved certs + // Delete the saved certs (used in debugging) if (0) { DEBUG_MSG("Deleting any saved SSL keys ...\n"); // prefs.clear(); @@ -166,11 +167,16 @@ void createSSLCert() NULL); /* Task handle. */ DEBUG_MSG("Waiting for SSL Cert to be generated.\n"); + int seconds = 0; while (!isCertReady) { DEBUG_MSG("."); delay(1000); yield(); esp_task_wdt_reset(); + seconds++; + if ((seconds == 3) && screen) { + screen->setSSLFrames(); + } } DEBUG_MSG("SSL Cert Ready!\n"); } diff --git a/src/mesh/http/WiFiAPClient.cpp b/src/mesh/http/WiFiAPClient.cpp index 4408739dd..5eee529f6 100644 --- a/src/mesh/http/WiFiAPClient.cpp +++ b/src/mesh/http/WiFiAPClient.cpp @@ -57,7 +57,7 @@ static int32_t reconnectWiFi() if (*wifiName) { needReconnect = false; - DEBUG_MSG("... Reconnecting to WiFi access point"); + DEBUG_MSG("... Reconnecting to WiFi access point\n"); WiFi.mode(WIFI_MODE_STA); WiFi.begin(wifiName, wifiPsw); } diff --git a/src/nimble/BluetoothUtil.cpp b/src/nimble/BluetoothUtil.cpp index cd95c91ed..2c69b0bcc 100644 --- a/src/nimble/BluetoothUtil.cpp +++ b/src/nimble/BluetoothUtil.cpp @@ -557,7 +557,7 @@ void setBluetoothEnable(bool on) bluetoothOn = on; if (on) { - if (!initWifi(0)) // if we are using wifi, don't turn on bluetooth also + if (!initWifi(isSoftAPForced())) // if we are using wifi, don't turn on bluetooth also { Serial.printf("Pre BT: %u heap size\n", ESP.getFreeHeap()); // ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) ); diff --git a/src/plugins/PositionPlugin.cpp b/src/plugins/PositionPlugin.cpp index 509750c83..11d13abae 100644 --- a/src/plugins/PositionPlugin.cpp +++ b/src/plugins/PositionPlugin.cpp @@ -1,9 +1,10 @@ -#include "configuration.h" #include "PositionPlugin.h" #include "MeshService.h" #include "NodeDB.h" #include "RTC.h" #include "Router.h" +#include "configuration.h" +#include "gps/GeoCoord.h" PositionPlugin *positionPlugin; @@ -30,23 +31,11 @@ bool PositionPlugin::handleReceivedProtobuf(const MeshPacket &mp, Position *pptr } // Log packet size and list of fields - DEBUG_MSG("POSITION node=%08x l=%d %s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", - getFrom(&mp), - mp.decoded.payload.size, - p.latitude_i ? "LAT ":"", - p.longitude_i ? "LON ":"", - p.altitude ? "MSL ":"", - p.altitude_hae ? "HAE ":"", - p.alt_geoid_sep ? "GEO ":"", - p.PDOP ? "PDOP ":"", - p.HDOP ? "HDOP ":"", - p.VDOP ? "VDOP ":"", - p.sats_in_view ? "SIV ":"", - p.fix_quality ? "FXQ ":"", - p.fix_type ? "FXT ":"", - p.pos_timestamp ? "PTS ":"", - p.time ? "TIME ":"", - p.battery_level ? "BAT ":""); + DEBUG_MSG("POSITION node=%08x l=%d %s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", getFrom(&mp), mp.decoded.payload.size, + p.latitude_i ? "LAT " : "", p.longitude_i ? "LON " : "", p.altitude ? "MSL " : "", p.altitude_hae ? "HAE " : "", + p.alt_geoid_sep ? "GEO " : "", p.PDOP ? "PDOP " : "", p.HDOP ? "HDOP " : "", p.VDOP ? "VDOP " : "", + p.sats_in_view ? "SIV " : "", p.fix_quality ? "FXQ " : "", p.fix_type ? "FXT " : "", p.pos_timestamp ? "PTS " : "", + p.time ? "TIME " : "", p.battery_level ? "BAT " : ""); if (p.time) { struct timeval tv; @@ -73,7 +62,7 @@ MeshPacket *PositionPlugin::allocReply() uint32_t pos_flags = radioConfig.preferences.position_flags; // Populate a Position struct with ONLY the requested fields - Position p = Position_init_default; // Start with an empty structure + Position p = Position_init_default; // Start with an empty structure // lat/lon are unconditionally included - IF AVAILABLE! p.latitude_i = node->position.latitude_i; @@ -138,19 +127,51 @@ int32_t PositionPlugin::runOnce() { NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); + // radioConfig.preferences.position_broadcast_smart = true; + // We limit our GPS broadcasts to a max rate uint32_t now = millis(); if (lastGpsSend == 0 || now - lastGpsSend >= getPref_position_broadcast_secs() * 1000) { lastGpsSend = now; + lastGpsLatitude = node->position.latitude_i; + lastGpsLongitude = node->position.longitude_i; + // If we changed channels, ask everyone else for their latest info bool requestReplies = currentGeneration != radioGeneration; currentGeneration = radioGeneration; - DEBUG_MSG("Sending pos@%x:6 to mesh (wantReplies=%d)\n", - node->position.pos_timestamp, requestReplies); + DEBUG_MSG("Sending pos@%x:6 to mesh (wantReplies=%d)\n", node->position.pos_timestamp, requestReplies); sendOurPosition(NODENUM_BROADCAST, requestReplies); + } else if (radioConfig.preferences.position_broadcast_smart == true) { + // NodeInfo *node = service.refreshMyNodeInfo(); // should guarantee there is now a position + + if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) { + float distance = GeoCoord::latLongToMeter(lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, + node->position.latitude_i * 1e-7, node->position.longitude_i * 1e-7); + + /* Please don't change these values. This accomodates for possible poor positioning + in the event the GPS has a poor satelite lock. + */ + const uint8_t distanceTravel = 150; + + /* Minimum time between position updates. + Note: At an average walking speed of 3.5mph, it takes 90 seconds to travel 150 meters. + */ + const uint8_t timeTravel = 60; + + // If the distance traveled since the last update is greater than 100 meters + // and it's been at least 60 seconds since the last update + if ((abs(distance) >= distanceTravel) && + (lastGpsSend == 0 || now - timeTravel >= getPref_position_broadcast_secs() * 1000)) { + bool requestReplies = currentGeneration != radioGeneration; + currentGeneration = radioGeneration; + + DEBUG_MSG("Sending smart pos@%x:6 to mesh (wantReplies=%d)\n", node->position.pos_timestamp, requestReplies); + sendOurPosition(NODENUM_BROADCAST, requestReplies); + } + } } return 5000; // to save power only wake for our callback occasionally diff --git a/src/plugins/PositionPlugin.h b/src/plugins/PositionPlugin.h index 3e4034d4f..5ffe04803 100644 --- a/src/plugins/PositionPlugin.h +++ b/src/plugins/PositionPlugin.h @@ -13,6 +13,10 @@ class PositionPlugin : public ProtobufPlugin, private concurrency::OST /// We limit our GPS broadcasts to a max rate uint32_t lastGpsSend = 0; + // Store the latest good lat / long + uint32_t lastGpsLatitude = 0; + uint32_t lastGpsLongitude = 0; + /// We force a rebroadcast if the radio settings change uint32_t currentGeneration = 0; diff --git a/src/plugins/esp32/RangeTestPlugin.cpp b/src/plugins/esp32/RangeTestPlugin.cpp index 1252fe74b..f5cc87d1a 100644 --- a/src/plugins/esp32/RangeTestPlugin.cpp +++ b/src/plugins/esp32/RangeTestPlugin.cpp @@ -151,6 +151,7 @@ ProcessMessage RangeTestPluginRadio::handleReceived(const MeshPacket &mp) appendFile(mp); } + /* DEBUG_MSG("-----------------------------------------\n"); DEBUG_MSG("p.payload.bytes \"%s\"\n", p.payload.bytes); DEBUG_MSG("p.payload.size %d\n", p.payload.size); @@ -174,6 +175,7 @@ ProcessMessage RangeTestPluginRadio::handleReceived(const MeshPacket &mp) DEBUG_MSG("gpsStatus->getHasLock() %d\n", gpsStatus->getHasLock()); DEBUG_MSG("gpsStatus->getDOP() %d\n", gpsStatus->getDOP()); DEBUG_MSG("-----------------------------------------\n"); + */ } } else { diff --git a/src/plugins/esp32/StoreForwardPlugin.cpp b/src/plugins/esp32/StoreForwardPlugin.cpp index 6c3263432..3b2372ccc 100644 --- a/src/plugins/esp32/StoreForwardPlugin.cpp +++ b/src/plugins/esp32/StoreForwardPlugin.cpp @@ -5,11 +5,11 @@ #include "Router.h" #include "configuration.h" #include "mesh-pb-constants.h" +#include "mesh/generated/storeforward.pb.h" #include "plugins/PluginDev.h" #include -#include #include - +#include StoreForwardPlugin *storeForwardPlugin; @@ -25,22 +25,22 @@ int32_t StoreForwardPlugin::runOnce() if (this->busy) { // Send out the message queue. - //DEBUG_MSG("--- --- --- In busy loop 1 %d\n", this->packetHistoryTXQueue_index); + // DEBUG_MSG("--- --- --- In busy loop 1 %d\n", this->packetHistoryTXQueue_index); storeForwardPlugin->sendPayload(this->busyTo, this->packetHistoryTXQueue_index); - + if (this->packetHistoryTXQueue_index == packetHistoryTXQueue_size) { strcpy(this->routerMessage, "** S&F - Done"); storeForwardPlugin->sendMessage(this->busyTo, this->routerMessage); - //DEBUG_MSG("--- --- --- In busy loop - Done \n"); + // DEBUG_MSG("--- --- --- In busy loop - Done \n"); this->packetHistoryTXQueue_index = 0; this->busy = false; } else { this->packetHistoryTXQueue_index++; } - } - // TODO: Dynamicly adjust the time this returns in the loop based on the size of the packets being actually transmitted. + // TODO: Dynamicly adjust the time this returns in the loop based on the size of the packets being actually + // transmitted. return (this->packetTimeMax); } else { DEBUG_MSG("Store & Forward Plugin - Disabled (is_router = false)\n"); @@ -83,7 +83,8 @@ void StoreForwardPlugin::populatePSRAM() : (((ESP.getFreePsram() / 3) * 2) / sizeof(PacketHistoryStruct))); this->packetHistory = static_cast(ps_calloc(numberOfPackets, sizeof(PacketHistoryStruct))); - this->packetHistoryTXQueue = static_cast(ps_calloc(store_forward_plugin_replay_max_records, sizeof(PacketHistoryStruct))); + this->packetHistoryTXQueue = + static_cast(ps_calloc(store_forward_plugin_replay_max_records, sizeof(PacketHistoryStruct))); DEBUG_MSG("After PSRAM initilization:\n"); DEBUG_MSG(" Total heap: %d\n", ESP.getHeapSize()); @@ -107,7 +108,6 @@ void StoreForwardPlugin::historySend(uint32_t msAgo, uint32_t to) { uint32_t packetsSent = 0; - uint32_t queueSize = storeForwardPlugin->historyQueueCreate(msAgo, to); @@ -124,9 +124,10 @@ void StoreForwardPlugin::historySend(uint32_t msAgo, uint32_t to) } } -uint32_t StoreForwardPlugin::historyQueueCreate(uint32_t msAgo, uint32_t to) { - - //uint32_t packetHistoryTXQueueIndex = 0; +uint32_t StoreForwardPlugin::historyQueueCreate(uint32_t msAgo, uint32_t to) +{ + + // uint32_t packetHistoryTXQueueIndex = 0; this->packetHistoryTXQueue_size = 0; @@ -146,24 +147,19 @@ uint32_t StoreForwardPlugin::historyQueueCreate(uint32_t msAgo, uint32_t to) { TODO: The condition (this->packetHistory[i].to & 0xffffffff) == to) is not tested since I don't have an easy way to target a specific user. Will need to do this soon. */ - if ((this->packetHistory[i].to & 0xffffffff) == 0xffffffff - || - ((this->packetHistory[i].to & 0xffffffff) == to) - ) { + if ((this->packetHistory[i].to & 0xffffffff) == 0xffffffff || ((this->packetHistory[i].to & 0xffffffff) == to)) { this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].time = this->packetHistory[i].time; this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].to = this->packetHistory[i].to; this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].from = this->packetHistory[i].from; this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].payload_size = this->packetHistory[i].payload_size; - memcpy(this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].payload, this->packetHistory[i].payload, Constants_DATA_PAYLOAD_LEN); + memcpy(this->packetHistoryTXQueue[this->packetHistoryTXQueue_size].payload, this->packetHistory[i].payload, + Constants_DATA_PAYLOAD_LEN); this->packetHistoryTXQueue_size++; DEBUG_MSG("PacketHistoryStruct time=%d\n", this->packetHistory[i].time); DEBUG_MSG("PacketHistoryStruct msg=%.*s\n", this->packetHistory[i].payload); - //DEBUG_MSG("PacketHistoryStruct msg=%.*s\n", this->packetHistoryTXQueue[packetHistoryTXQueueIndex].payload); - - + // DEBUG_MSG("PacketHistoryStruct msg=%.*s\n", this->packetHistoryTXQueue[packetHistoryTXQueueIndex].payload); } - } } return this->packetHistoryTXQueue_size; @@ -221,8 +217,9 @@ void StoreForwardPlugin::sendMessage(NodeNum dest, char *str) p->decoded.payload.size = strlen(str); // You must specify how many bytes are in the reply memcpy(p->decoded.payload.bytes, str, strlen(str)); - service.sendToMesh(p); + + // HardwareMessage_init_default } ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp) @@ -232,6 +229,11 @@ ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp) DEBUG_MSG("--- S&F Received something\n"); + StoreAndForwardMessage sfm = StoreAndForwardMessage_init_default; + + switch (sfm.rr) { + } + auto &p = mp.decoded; // The router node should not be sending messages as a client. @@ -250,14 +252,19 @@ ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp) } else { storeForwardPlugin->historySend(1000 * 60, getFrom(&mp)); } - } else if ((p.payload.bytes[0] == 'S') && (p.payload.bytes[1] == 'F') && (p.payload.bytes[2] == 'm') && (p.payload.bytes[3] == 0x00)) { - strcpy(this->routerMessage, "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456"); + } else if ((p.payload.bytes[0] == 'S') && (p.payload.bytes[1] == 'F') && (p.payload.bytes[2] == 'm') && + (p.payload.bytes[3] == 0x00)) { + strcpy(this->routerMessage, "01234567890123456789012345678901234567890123456789012345678901234567890123456789" + "01234567890123456789012345678901234567890123456789012345678901234567890123456789" + "01234567890123456789012345678901234567890123456789012345678901234567890123456"); storeForwardPlugin->sendMessage(getFrom(&mp), this->routerMessage); } else { storeForwardPlugin->historyAdd(mp); } + } else if (mp.decoded.portnum == PortNum_STORE_FORWARD_APP) { + } else { DEBUG_MSG("Packet came from an unknown port %u\n", mp.decoded.portnum); } @@ -306,9 +313,9 @@ StoreForwardPlugin::StoreForwardPlugin() // Calculate the packet time. // this->packetTimeMax = RadioLibInterface::instance->getPacketTime(Constants_DATA_PAYLOAD_LEN); - //RadioLibInterface::instance->getPacketTime(Constants_DATA_PAYLOAD_LEN); - //RadioLibInterface::instance->getPacketTime(Constants_DATA_PAYLOAD_LEN); - //RadioInterface::getPacketTime(500)l + // RadioLibInterface::instance->getPacketTime(Constants_DATA_PAYLOAD_LEN); + // RadioLibInterface::instance->getPacketTime(Constants_DATA_PAYLOAD_LEN); + // RadioInterface::getPacketTime(500)l this->packetTimeMax = 2000; diff --git a/src/plugins/esp32/StoreForwardPlugin.h b/src/plugins/esp32/StoreForwardPlugin.h index 3df640778..cd8daed7c 100644 --- a/src/plugins/esp32/StoreForwardPlugin.h +++ b/src/plugins/esp32/StoreForwardPlugin.h @@ -2,6 +2,8 @@ #include "SinglePortPlugin.h" #include "concurrency/OSThread.h" +#include "mesh/generated/storeforward.pb.h" + #include "configuration.h" #include #include @@ -17,7 +19,7 @@ struct PacketHistoryStruct { class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThread { - //bool firstTime = 1; + // bool firstTime = 1; bool busy = 0; uint32_t busyTo; char routerMessage[80]; @@ -30,9 +32,8 @@ class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThrea PacketHistoryStruct *packetHistoryTXQueue; uint32_t packetHistoryTXQueue_size; uint32_t packetHistoryTXQueue_index = 0; - - uint32_t packetTimeMax = 0; + uint32_t packetTimeMax = 0; public: StoreForwardPlugin(); @@ -53,6 +54,9 @@ class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThrea void sendPayload(NodeNum dest = NODENUM_BROADCAST, uint32_t packetHistory_index = 0); void sendMessage(NodeNum dest, char *str); virtual MeshPacket *allocReply(); + /* + Override the wantPortnum method. + */ virtual bool wantPortnum(PortNum p) { return true; }; private: