diff --git a/Firmware/RTK_Surveyor/AP-Config/index.html b/Firmware/RTK_Surveyor/AP-Config/index.html index f4c3b968e..9e76027ab 100644 --- a/Firmware/RTK_Surveyor/AP-Config/index.html +++ b/Firmware/RTK_Surveyor/AP-Config/index.html @@ -814,66 +814,128 @@
- + Host 0:
- +

- + Port 0:
- +

- + User 0:
- +

- + User PW 0:
- +

- +
- +

- + PW 0:
- +

- ", ntripServerStateName[ntripServerState]); + systemPrintf("%d: %s --> ", serverIndex, ntripServerStateName[ntripServer->state]); } - ntripServerState = newState; + ntripServer->state = newState; if (settings.debugNtripServerState || PERIODIC_DISPLAY(PD_NTRIP_SERVER_STATE)) { PERIODIC_CLEAR(PD_NTRIP_SERVER_STATE); if (newState >= NTRIP_SERVER_STATE_MAX) { - systemPrintf("Unknown NTRIP Server state: %d\r\n", newState); + systemPrintf("Unknown NTRIP Server %d state: %d\r\n", serverIndex, newState); reportFatalError("Unknown NTRIP Server state"); } else - systemPrintln(ntripServerStateName[ntripServerState]); + systemPrintln(ntripServerStateName[ntripServer->state]); } } // Shutdown the NTRIP server -void ntripServerShutdown() +void ntripServerShutdown(int serverIndex) { - ntripServerStop(true); + ntripServerStop(serverIndex, true); } // Start the NTRIP server -void ntripServerStart() +void ntripServerStart(int serverIndex) { // Display the heap state reportHeapNow(settings.debugNtripServerState); // Start the NTRIP server - systemPrintln ("NTRIP Server start"); - ntripServerStop(false); + systemPrintf("NTRIP Server %d start\r\n", serverIndex); + ntripServerStop(serverIndex, false); } // Shutdown or restart the NTRIP server -void ntripServerStop(bool shutdown) +void ntripServerStop(int serverIndex, bool shutdown) { - if (ntripServer) + bool enabled; + int index; + NTRIP_SERVER_DATA * ntripServer = &ntripServerArray[serverIndex]; + + if (ntripServer->networkClient) { // Break the NTRIP server connection if necessary - if (ntripServer->connected()) - ntripServer->stop(); + if (ntripServer->networkClient->connected()) + ntripServer->networkClient->stop(); // Free the NTRIP server resources - delete ntripServer; - ntripServer = nullptr; + delete ntripServer->networkClient; + ntripServer->networkClient = nullptr; reportHeapNow(settings.debugNtripServerState); } // Increase timeouts if we started the network - if (ntripServerState > NTRIP_SERVER_ON) + if (ntripServer->state > NTRIP_SERVER_ON) { // Mark the Server stop so that we don't immediately attempt re-connect to Caster - ntripServerTimer = millis(); + ntripServer->timer = millis(); // Done with the network - if (networkGetUserNetwork(NETWORK_USER_NTRIP_SERVER)) - networkUserClose(NETWORK_USER_NTRIP_SERVER); + if (networkGetUserNetwork(NETWORK_USER_NTRIP_SERVER + serverIndex)) + networkUserClose(NETWORK_USER_NTRIP_SERVER + serverIndex); } // Determine the next NTRIP server state - online.ntripServer = false; - if (shutdown) - { - ntripServerSetState(NTRIP_SERVER_OFF); - settings.enableNtripServer = false; - ntripServerConnectionAttempts = 0; - ntripServerConnectionAttemptTimeout = 0; + online.ntripServer[serverIndex] = false; + if (shutdown + || (!settings.ntripServer_CasterHost[serverIndex][0]) + || (!settings.ntripServer_CasterPort[serverIndex]) + || (!settings.ntripServer_MountPoint[serverIndex][0])) + { + if (shutdown) + { + if (settings.debugNtripServerState) + systemPrintf("NTRIP Server %d shutdown requested!\r\n", serverIndex); + } + else + { + if (settings.debugNtripServerState && (!settings.ntripServer_CasterHost[serverIndex][0])) + systemPrintf("NTRIP Server %d caster host not configured!\r\n", serverIndex); + if (settings.debugNtripServerState && (!settings.ntripServer_CasterPort[serverIndex])) + systemPrintf("NTRIP Server %d caster port not configured!\r\n", serverIndex); + if (settings.debugNtripServerState && (!settings.ntripServer_MountPoint[serverIndex][0])) + systemPrintf("NTRIP Server %d mount point not configured!\r\n", serverIndex); + } + ntripServerSetState(ntripServer, NTRIP_SERVER_OFF); + ntripServer->connectionAttempts = 0; + ntripServer->connectionAttemptTimeout = 0; + + // Determine if any of the NTRIP servers are enabled + enabled = false; + for (index = 0; index < NTRIP_SERVER_MAX; index++) + if (online.ntripServer[index]) + { + enabled = true; + break; + } + settings.enableNtripServer = enabled; } else - ntripServerSetState(NTRIP_SERVER_ON); + ntripServerSetState(ntripServer, NTRIP_SERVER_ON); } // Update the NTRIP server state machine -void ntripServerUpdate() +void ntripServerUpdate(int serverIndex) { + // Get the NTRIP data structure + NTRIP_SERVER_DATA * ntripServer = &ntripServerArray[serverIndex]; + // For Ref Stn, process any RTCM data waiting in the u-blox library RTCM Buffer // This causes the state change from NTRIP_SERVER_WAIT_GNSS_DATA to NTRIP_SERVER_CONNECTING processRTCMBuffer(); // Shutdown the NTRIP server when the mode or setting changes - DMW_st(ntripServerSetState, ntripServerState); + DMW_ds(ntripServerSetState, ntripServer); if (NEQ_RTK_MODE(ntripServerMode) || (!settings.enableNtripServer)) { - if (ntripServerState > NTRIP_SERVER_OFF) + if (ntripServer->state > NTRIP_SERVER_OFF) { - ntripServerStop(false); - ntripServerConnectionAttempts = 0; - ntripServerConnectionAttemptTimeout = 0; - ntripServerSetState(NTRIP_SERVER_OFF); + ntripServerStop(serverIndex, false); + ntripServer->connectionAttempts = 0; + ntripServer->connectionAttemptTimeout = 0; + ntripServerSetState(ntripServer, NTRIP_SERVER_OFF); } } // Enable the network and the NTRIP server if requested - switch (ntripServerState) + switch (ntripServer->state) { case NTRIP_SERVER_OFF: - if (EQ_RTK_MODE(ntripServerMode) && settings.enableNtripServer) - ntripServerStart(); + if (EQ_RTK_MODE(ntripServerMode) && settings.enableNtripServer + && settings.ntripServer_CasterHost[serverIndex][0] + && settings.ntripServer_CasterPort[serverIndex] + && settings.ntripServer_MountPoint[serverIndex][0]) + { + ntripServerStart(serverIndex); + } break; // Start the network case NTRIP_SERVER_ON: - if (networkUserOpen(NETWORK_USER_NTRIP_SERVER, NETWORK_TYPE_ACTIVE)) - ntripServerSetState(NTRIP_SERVER_NETWORK_STARTED); + if (networkUserOpen(NETWORK_USER_NTRIP_SERVER + serverIndex, NETWORK_TYPE_ACTIVE)) + ntripServerSetState(ntripServer, NTRIP_SERVER_NETWORK_STARTED); break; // Wait for a network media connection case NTRIP_SERVER_NETWORK_STARTED: // Determine if the network has failed - if (networkIsShuttingDown(NETWORK_USER_NTRIP_SERVER)) + if (networkIsShuttingDown(NETWORK_USER_NTRIP_SERVER + serverIndex)) // Failed to connect to to the network, attempt to restart the network - ntripServerRestart(); + ntripServerRestart(serverIndex); // Determine if the network is connected to the media - else if (networkUserConnected(NETWORK_USER_NTRIP_SERVER)) + else if (networkUserConnected(NETWORK_USER_NTRIP_SERVER + serverIndex)) { // Allocate the ntripServer structure - ntripServer = new NetworkClient(NETWORK_USER_NTRIP_SERVER); - if (!ntripServer) + ntripServer->networkClient = new NetworkClient(NETWORK_USER_NTRIP_SERVER + serverIndex); + if (!ntripServer->networkClient) { // Failed to allocate the ntripServer structure - systemPrintln("ERROR: Failed to allocate the ntripServer structure!"); - ntripServerShutdown(); + systemPrintf("ERROR: Failed to allocate the ntripServer %d structure!\r\n", serverIndex); + ntripServerShutdown(serverIndex); } else { reportHeapNow(settings.debugNtripServerState); // The network is available for the NTRIP server - ntripServerSetState(NTRIP_SERVER_NETWORK_CONNECTED); + ntripServerSetState(ntripServer, NTRIP_SERVER_NETWORK_CONNECTED); } } break; @@ -608,27 +636,27 @@ void ntripServerUpdate() // Network available case NTRIP_SERVER_NETWORK_CONNECTED: // Determine if the network has failed - if (networkIsShuttingDown(NETWORK_USER_NTRIP_SERVER)) + if (networkIsShuttingDown(NETWORK_USER_NTRIP_SERVER + serverIndex)) // Failed to connect to to the network, attempt to restart the network - ntripServerRestart(); + ntripServerRestart(serverIndex); else if (settings.enableNtripServer - && (millis() - ntripServerLastConnectionAttempt > ntripServerConnectionAttemptTimeout)) + && (millis() - ntripServer->lastConnectionAttempt > ntripServer->connectionAttemptTimeout)) { // No RTCM correction data sent yet rtcmPacketsSent = 0; // Open socket to NTRIP caster - ntripServerSetState(NTRIP_SERVER_WAIT_GNSS_DATA); + ntripServerSetState(ntripServer, NTRIP_SERVER_WAIT_GNSS_DATA); } break; // Wait for GNSS correction data case NTRIP_SERVER_WAIT_GNSS_DATA: // Determine if the network has failed - if (networkIsShuttingDown(NETWORK_USER_NTRIP_SERVER)) + if (networkIsShuttingDown(NETWORK_USER_NTRIP_SERVER + serverIndex)) // Failed to connect to to the network, attempt to restart the network - ntripServerRestart(); + ntripServerRestart(serverIndex); // State change handled in ntripServerProcessRTCM break; @@ -636,25 +664,25 @@ void ntripServerUpdate() // Initiate the connection to the NTRIP caster case NTRIP_SERVER_CONNECTING: // Determine if the network has failed - if (networkIsShuttingDown(NETWORK_USER_NTRIP_SERVER)) + if (networkIsShuttingDown(NETWORK_USER_NTRIP_SERVER + serverIndex)) // Failed to connect to to the network, attempt to restart the network - ntripServerRestart(); + ntripServerRestart(serverIndex); // Delay before opening the NTRIP server connection - else if ((millis() - ntripServerTimer) >= ntripServerConnectionAttemptTimeout) + else if ((millis() - ntripServer->timer) >= ntripServer->connectionAttemptTimeout) { // Attempt a connection to the NTRIP caster - if (!ntripServerConnectCaster()) + if (!ntripServerConnectCaster(serverIndex)) { // Assume service not available - if (ntripServerConnectLimitReached()) // Update ntripServerConnectionAttemptTimeout - systemPrintln("NTRIP Server failed to connect! Do you have your caster address and port correct?"); + if (ntripServerConnectLimitReached(serverIndex)) // Update ntripServer->connectionAttemptTimeout + systemPrintf("NTRIP Server %d failed to connect! Do you have your caster address and port correct?\r\n", serverIndex); } else { // Connection open to NTRIP caster, wait for the authorization response - ntripServerTimer = millis(); - ntripServerSetState(NTRIP_SERVER_AUTHORIZATION); + ntripServer->timer = millis(); + ntripServerSetState(ntripServer, NTRIP_SERVER_AUTHORIZATION); } } break; @@ -662,30 +690,30 @@ void ntripServerUpdate() // Wait for authorization response case NTRIP_SERVER_AUTHORIZATION: // Determine if the network has failed - if (networkIsShuttingDown(NETWORK_USER_NTRIP_SERVER)) + if (networkIsShuttingDown(NETWORK_USER_NTRIP_SERVER + serverIndex)) // Failed to connect to to the network, attempt to restart the network - ntripServerRestart(); + ntripServerRestart(serverIndex); // Check if caster service responded - else if (ntripServer->available() < strlen("ICY 200 OK")) // Wait until at least a few bytes have arrived + else if (ntripServer->networkClient->available() < strlen("ICY 200 OK")) // Wait until at least a few bytes have arrived { // Check for response timeout - if (millis() - ntripServerTimer > 10000) + if (millis() - ntripServer->timer > 10000) { - if (ntripServerConnectLimitReached()) - systemPrintln("Caster failed to respond. Do you have your caster address and port correct?"); + if (ntripServerConnectLimitReached(serverIndex)) + systemPrintf("Caster %d failed to respond. Do you have your caster address and port correct?\r\n", serverIndex); } } else { // NTRIP caster's authorization response received char response[512]; - ntripServerResponse(response, sizeof(response)); + ntripServerResponse(serverIndex, response, sizeof(response)); if (settings.debugNtripServerState) - systemPrintf("Server Response: %s\r\n", response); + systemPrintf("Server %d Response: %s\r\n", serverIndex, response); else - log_d("Server Response: %s", response); + log_d("Server %d Response: %s", serverIndex, response); // Look for various responses if (strstr(response, "200") != nullptr) //'200' found @@ -693,52 +721,54 @@ void ntripServerUpdate() // We got a response, now check it for possible errors if (strcasestr(response, "banned") != nullptr) { - systemPrintf("NTRIP Server connected to caster but caster responded with banned error: %s\r\n", - response); + systemPrintf("NTRIP Server %d connected to caster but caster responded with banned error: %s\r\n", + serverIndex, response); // Stop NTRIP Server operations - ntripServerShutdown(); + ntripServerShutdown(serverIndex); } else if (strcasestr(response, "sandbox") != nullptr) { - systemPrintf("NTRIP Server connected to caster but caster responded with sandbox error: %s\r\n", - response); + systemPrintf("NTRIP Server %d connected to caster but caster responded with sandbox error: %s\r\n", + serverIndex, response); // Stop NTRIP Server operations - ntripServerShutdown(); + ntripServerShutdown(serverIndex); } - systemPrintf("NTRIP Server connected to %s:%d %s\r\n", settings.ntripServer_CasterHost, - settings.ntripServer_CasterPort, settings.ntripServer_MountPoint); + systemPrintf("NTRIP Server %d connected to %s:%d %s\r\n", serverIndex, + settings.ntripServer_CasterHost[serverIndex], + settings.ntripServer_CasterPort[serverIndex], + settings.ntripServer_MountPoint[serverIndex]); // Connection is now open, start the RTCM correction data timer - ntripServerTimer = millis(); + ntripServer->timer = millis(); // We don't use a task because we use I2C hardware (and don't have a semphore). - online.ntripServer = true; - ntripServerStartTime = millis(); - ntripServerSetState(NTRIP_SERVER_CASTING); + online.ntripServer[serverIndex] = true; + ntripServer->startTime = millis(); + ntripServerSetState(ntripServer, NTRIP_SERVER_CASTING); } // Look for '401 Unauthorized' else if (strstr(response, "401") != nullptr) { systemPrintf( - "NTRIP Caster responded with unauthorized error: %s. Are you sure your caster credentials are correct?\r\n", - response); + "NTRIP Caster %d responded with unauthorized error: %s. Are you sure your caster credentials are correct?\r\n", + serverIndex, response); // Give up - Shutdown NTRIP server, no further retries - ntripServerShutdown(); + ntripServerShutdown(serverIndex); } // Other errors returned by the caster else { - systemPrintf("NTRIP Server connected but caster responded with problem: %s\r\n", response); + systemPrintf("NTRIP Server %d connected but caster responded with problem: %s\r\n", serverIndex, response); // Check for connection limit - if (ntripServerConnectLimitReached()) - systemPrintln("NTRIP Server retry limit reached; do you have your caster address and port correct?"); + if (ntripServerConnectLimitReached(serverIndex)) + systemPrintf("NTRIP Server %d retry limit reached; do you have your caster address and port correct?\r\n", serverIndex); } } break; @@ -746,22 +776,22 @@ void ntripServerUpdate() // NTRIP server authorized to send RTCM correction data to NTRIP caster case NTRIP_SERVER_CASTING: // Determine if the network has failed - if (networkIsShuttingDown(NETWORK_USER_NTRIP_SERVER)) + if (networkIsShuttingDown(NETWORK_USER_NTRIP_SERVER + serverIndex)) // Failed to connect to to the network, attempt to restart the network - ntripServerRestart(); + ntripServerRestart(serverIndex); // Check for a broken connection - else if (!ntripServer->connected()) + else if (!ntripServer->networkClient->connected()) { // Broken connection, retry the NTRIP connection - systemPrintln("Connection to NTRIP Caster was lost"); - ntripServerRestart(); + systemPrintf("Connection to NTRIP Caster %d was lost\r\n", serverIndex); + ntripServerRestart(serverIndex); } - else if ((millis() - ntripServerTimer) > (15 * 1000)) + else if ((millis() - ntripServer->timer) > (15 * 1000)) { // GNSS stopped sending RTCM correction data - systemPrintln("NTRIP Server breaking connection to caster due to lack of RTCM data!"); - ntripServerRestart(); + systemPrintf("NTRIP Server %d breaking connection to caster due to lack of RTCM data!\r\n", serverIndex); + ntripServerRestart(serverIndex); } else { @@ -771,14 +801,14 @@ void ntripServerUpdate() // connection. However increasing backoff delays should be // added when the NTRIP caster fails after a short connection // interval. - if (((millis() - ntripServerStartTime) > NTRIP_SERVER_CONNECTION_TIME) - && (ntripServerConnectionAttempts || ntripServerConnectionAttemptTimeout)) + if (((millis() - ntripServer->startTime) > NTRIP_SERVER_CONNECTION_TIME) + && (ntripServer->connectionAttempts || ntripServer->connectionAttemptTimeout)) { // After a long connection period, reset the attempt counter - ntripServerConnectionAttempts = 0; - ntripServerConnectionAttemptTimeout = 0; + ntripServer->connectionAttempts = 0; + ntripServer->connectionAttemptTimeout = 0; if (settings.debugNtripServerState) - systemPrintln("NTRIP Server resetting connection attempt counter and timeout"); + systemPrintf("NTRIP Server %d resetting connection attempt counter and timeout\r\n", serverIndex); } // All is well @@ -789,7 +819,14 @@ void ntripServerUpdate() // Periodically display the state if (PERIODIC_DISPLAY(PD_NTRIP_SERVER_STATE)) - ntripServerSetState(ntripServerState); + ntripServerSetState(ntripServer, ntripServer->state); +} + +// Update the NTRIP server state machine +void ntripServerUpdate() +{ + for (int serverIndex = 0; serverIndex < NTRIP_SERVER_MAX; serverIndex++) + ntripServerUpdate(serverIndex); } // Verify the NTRIP server tables @@ -797,6 +834,8 @@ void ntripServerValidateTables() { if (ntripServerStateNameEntries != NTRIP_SERVER_STATE_MAX) reportFatalError("Fix ntripServerStateNameEntries to match NTRIPServerState"); + if (NETWORK_USER_MAX > (sizeof(NETWORK_USER) * 8)) + reportFatalError("Increase the NETWORK_USER type"); } #endif // COMPILE_NETWORK diff --git a/Firmware/RTK_Surveyor/RTK_Surveyor.ino b/Firmware/RTK_Surveyor/RTK_Surveyor.ino index c911bd30f..11dda03d0 100644 --- a/Firmware/RTK_Surveyor/RTK_Surveyor.ino +++ b/Firmware/RTK_Surveyor/RTK_Surveyor.ino @@ -60,6 +60,30 @@ // the minor firmware version #define RTK_IDENTIFIER (FIRMWARE_VERSION_MAJOR * 0x10 + FIRMWARE_VERSION_MINOR) +#define NTRIP_SERVER_MAX 2 + +#ifdef COMPILE_ETHERNET +#include // http://librarymanager/All#Arduino_Ethernet +#include "SparkFun_WebServer_ESP32_W5500.h" //http://librarymanager/All#SparkFun_WebServer_ESP32_W5500 v1.5.5 +#endif // COMPILE_ETHERNET + +#ifdef COMPILE_WIFI +#include "ESP32OTAPull.h" //http://librarymanager/All#ESP-OTA-Pull Used for getting +#include "esp_wifi.h" //Needed for esp_wifi_set_protocol() +#include //Built-in. +#include //Built-in. +#include //Built-in. Needed for ThingStream API for ZTP +#include //http://librarymanager/All#PubSubClient_MQTT_Lightweight by Nick O'Leary v2.8.0 Used for MQTT obtaining of keys +#include //Built-in. +#include //Built-in. +#include //Built-in. +#endif // COMPILE_WIFI + +#if COMPILE_NETWORK +#include // http://librarymanager/All#SSLClientESP32 +#include "X509_Certificate_Bundle.h" // Root certificates +#endif // COMPILE_NETWORK + #include "settings.h" #define MAX_CPU_CORES 2 @@ -200,10 +224,6 @@ char logFileName[sizeof("SFE_Reference_Station_230101_120101.ubx_plusExtraSpace" // Over-the-Air (OTA) update support //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -#if COMPILE_NETWORK -#include // http://librarymanager/All#SSLClientESP32 -#include "X509_Certificate_Bundle.h" // Root certificates -#endif // COMPILE_NETWORK #include //http://librarymanager/All#Arduino_JSON_messagepack v6.19.4 #include "esp_ota_ops.h" //Needed for partition counting and updateFromSD @@ -216,7 +236,6 @@ char logFileName[sizeof("SFE_Reference_Station_230101_120101.ubx_plusExtraSpace" } #ifdef COMPILE_WIFI -#include "ESP32OTAPull.h" //http://librarymanager/All#ESP-OTA-Pull Used for getting #define WIFI_STOP() \ { \ @@ -237,19 +256,6 @@ unsigned int binBytesSent = 0; // Tracks firmware bytes sent over WiFi O //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // Connection settings to NTRIP Caster //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -#ifdef COMPILE_WIFI -#include //Built-in. -#include //Built-in. Needed for ThingStream API for ZTP -#include //http://librarymanager/All#PubSubClient_MQTT_Lightweight by Nick O'Leary v2.8.0 Used for MQTT obtaining of keys -#include //Built-in. -#include //Built-in. -#include //Built-in. -#include //Built-in. - -#include "esp_wifi.h" //Needed for esp_wifi_set_protocol() - -#endif // COMPILE_WIFI - #include "base64.h" //Built-in. Needed for NTRIP Client credential encoding. bool enableRCFirmware = false; // Goes true from AP config page @@ -574,7 +580,6 @@ const uint8_t ESPNOW_MAX_PEERS = 5; // Maximum of 5 rovers // Ethernet //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #ifdef COMPILE_ETHERNET -#include // http://librarymanager/All#Arduino_Ethernet IPAddress ethernetIPAddress; IPAddress ethernetDNS; IPAddress ethernetGateway; @@ -591,15 +596,11 @@ class derivedEthernetUDP : public EthernetUDP volatile struct timeval ethernetNtpTv; // This will hold the time the Ethernet NTP packet arrived bool ntpLogIncreasing; -#include "SparkFun_WebServer_ESP32_W5500.h" //http://librarymanager/All#SparkFun_WebServer_ESP32_W5500 v1.5.5 #endif // COMPILE_ETHERNET unsigned long lastEthernetCheck = 0; // Prevents cable checking from continually happening //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -#include "NetworkClient.h" //Supports both WiFiClient and EthernetClient -#include "NetworkUDP.h" //Supports both WiFiUdp and EthernetUdp - // Global variables //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #define lbandMACAddress btMACAddress @@ -735,6 +736,7 @@ bool sdCardForcedOffline = false; //Goes true if a isPresent() test passes, but volatile bool deadManWalking; #define DMW_if if (deadManWalking) #define DMW_c(string) DMW_if systemPrintf("%s called\r\n", string); +#define DMW_ds(routine, dataStructure) DMW_if routine(dataStructure, dataStructure->state); #define DMW_m(string) DMW_if systemPrintln(string); #define DMW_r(string) DMW_if systemPrintf("%s returning\r\n",string); #define DMW_rs(string, status) DMW_if systemPrintf("%s returning %d\r\n",string, (int32_t)status); @@ -783,6 +785,7 @@ volatile bool deadManWalking; #define deadManWalking 0 #define DMW_if if (0) #define DMW_c(string) +#define DMW_ds(routine, dataStructure) #define DMW_m(string) #define DMW_r(string) #define DMW_rs(string, status) diff --git a/Firmware/RTK_Surveyor/Tasks.ino b/Firmware/RTK_Surveyor/Tasks.ino index 99cd15433..35122bd95 100644 --- a/Firmware/RTK_Surveyor/Tasks.ino +++ b/Firmware/RTK_Surveyor/Tasks.ino @@ -1017,7 +1017,7 @@ void updateBTled() ledcWrite(ledBTChannel, 255); // Pulse LED while no BT and we wait for WiFi connection - else if (wifiState == WIFI_CONNECTING || wifiState == WIFI_CONNECTED) + else if (wifiState == WIFI_STATE_CONNECTING || wifiState == WIFI_STATE_CONNECTED) { // Fade in/out the BT LED during WiFi AP mode btFadeLevel += pwmFadeAmount; diff --git a/Firmware/RTK_Surveyor/WiFi.ino b/Firmware/RTK_Surveyor/WiFi.ino index dd23b52c8..e9101f451 100644 --- a/Firmware/RTK_Surveyor/WiFi.ino +++ b/Firmware/RTK_Surveyor/WiFi.ino @@ -14,19 +14,19 @@ WiFi Station States: - WIFI_OFF<--------------------. + WIFI_STATE_OFF<-------------------. | | wifiStart() | | | | WL_CONNECT_FAILED (Bad password) | | WL_NO_SSID_AVAIL (Out of range) v Fail | - WIFI_CONNECTING------------->+ + WIFI_STATE_CONNECTING------------->+ | ^ ^ wifiConnect() | | | wifiShutdown() | | WL_CONNECTION_LOST | | | WL_DISCONNECTED | v | | - WIFI_CONNECTED --------------' + WIFI_STATE_CONNECTED -------------' =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ //---------------------------------------- @@ -196,17 +196,17 @@ void wifiSetState(byte newState) default: systemPrintf("Unknown WiFi state: %d\r\n", newState); break; - case WIFI_OFF: - systemPrintln("WIFI_OFF"); + case WIFI_STATE_OFF: + systemPrintln("WIFI_STATE_OFF"); break; - case WIFI_START: - systemPrintln("WIFI_START"); + case WIFI_STATE_START: + systemPrintln("WIFI_STATE_START"); break; - case WIFI_CONNECTING: - systemPrintln("WIFI_CONNECTING"); + case WIFI_STATE_CONNECTING: + systemPrintln("WIFI_STATE_CONNECTING"); break; - case WIFI_CONNECTED: - systemPrintln("WIFI_CONNECTED"); + case WIFI_STATE_CONNECTED: + systemPrintln("WIFI_STATE_CONNECTED"); break; } } @@ -322,11 +322,11 @@ void wifiUpdate() systemPrintf("Unknown wifiState: %d\r\n", wifiState); break; - case WIFI_OFF: + case WIFI_STATE_OFF: // Any service that needs WiFi will call wifiStart() break; - case WIFI_CONNECTING: + case WIFI_STATE_CONNECTING: // Pause until connection timeout has passed if (millis() - wifiLastConnectionAttempt > wifiConnectionAttemptTimeout) { @@ -337,7 +337,7 @@ void wifiUpdate() if (espnowState > ESPNOW_OFF) espnowStart(); - wifiSetState(WIFI_CONNECTED); + wifiSetState(WIFI_STATE_CONNECTED); } else { @@ -353,20 +353,20 @@ void wifiUpdate() { systemPrintln("WiFi connection failed. Giving up."); displayNoWiFi(2000); - WIFI_STOP(); // Move back to WIFI_OFF + WIFI_STOP(); // Move back to WIFI_STATE_OFF } } } break; - case WIFI_CONNECTED: + case WIFI_STATE_CONNECTED: // Verify link is still up if (wifiIsConnected() == false) { systemPrintln("WiFi link lost"); wifiConnectionAttempts = 0; // Reset the timeout - wifiSetState(WIFI_CONNECTING); + wifiSetState(WIFI_STATE_CONNECTING); } // If WiFi is connected, and no services require WiFi, shut it off @@ -383,7 +383,7 @@ void wifiUpdate() } } -// Starts the WiFi connection state machine (moves from WIFI_OFF to WIFI_CONNECTING) +// Starts the WiFi connection state machine (moves from WIFI_STATE_OFF to WIFI_STATE_CONNECTING) // Sets the appropriate protocols (WiFi + ESP-Now) // If radio is off entirely, start WiFi // If ESP-Now is active, only add the LR protocol @@ -400,12 +400,12 @@ void wifiStart() if (wifiIsConnected() == true) return; // We don't need to do anything - if (wifiState > WIFI_OFF) + if (wifiState > WIFI_STATE_OFF) return; // We're in the midst of connecting log_d("Starting WiFi"); - wifiSetState(WIFI_CONNECTING); // This starts the state machine running + wifiSetState(WIFI_STATE_CONNECTING); // This starts the state machine running // Display the heap state reportHeapNow(settings.debugWifiState); @@ -433,7 +433,7 @@ void wifiStop() // If ESP NOW is active, leave WiFi on enough for ESP NOW void wifiShutdown() { - wifiSetState(WIFI_OFF); + wifiSetState(WIFI_STATE_OFF); wifiConnectionAttempts = 0; // Reset the timeout diff --git a/Firmware/RTK_Surveyor/menuBase.ino b/Firmware/RTK_Surveyor/menuBase.ino index 03586c4fb..724996242 100644 --- a/Firmware/RTK_Surveyor/menuBase.ino +++ b/Firmware/RTK_Surveyor/menuBase.ino @@ -17,6 +17,9 @@ static const float maxSurveyInStartingAccuracy = 10.0; // Set the ECEF coordinates for a known location void menuBase() { + int serverIndex = 0; + int value; + while (1) { systemPrintln(); @@ -105,23 +108,25 @@ void menuBase() if (settings.enableNtripServer == true) { - systemPrint("8) Set Caster Address: "); - systemPrintln(settings.ntripServer_CasterHost); + systemPrintf("8) Select NTRIP server index: %d\r\n", serverIndex); + + systemPrint("9) Set Caster Address: "); + systemPrintln(&settings.ntripServer_CasterHost[serverIndex][0]); - systemPrint("9) Set Caster Port: "); - systemPrintln(settings.ntripServer_CasterPort); + systemPrint("10) Set Caster Port: "); + systemPrintln(settings.ntripServer_CasterPort[serverIndex]); - systemPrint("10) Set Mountpoint: "); - systemPrintln(settings.ntripServer_MountPoint); + systemPrint("11) Set Mountpoint: "); + systemPrintln(&settings.ntripServer_MountPoint[serverIndex][0]); - systemPrint("11) Set Mountpoint PW: "); - systemPrintln(settings.ntripServer_MountPointPW); + systemPrint("12) Set Mountpoint PW: "); + systemPrintln(&settings.ntripServer_MountPointPW[serverIndex][0]); - systemPrint("12) Set RTCM Message Rates\r\n"); + systemPrint("13) Set RTCM Message Rates\r\n"); if (settings.fixedBase == false) // Survey-in { - systemPrint("13) Select survey-in radio: "); + systemPrint("14) Select survey-in radio: "); systemPrintf("%s\r\n", settings.ntripServer_StartAtSurveyIn ? "WiFi" : "Bluetooth"); } } @@ -302,11 +307,28 @@ void menuBase() else if ((incoming == 8) && settings.enableNtripServer == true) { - systemPrint("Enter new Caster Address: "); - getString(settings.ntripServer_CasterHost, sizeof(settings.ntripServer_CasterHost)); - restartBase = true; + systemPrint("Enter NTRIP server index: "); + + int value = getNumber(); // Returns EXIT, TIMEOUT, or long + // Get the index into the NTRIP server array + if ((value != INPUT_RESPONSE_GETNUMBER_EXIT) && + (value != INPUT_RESPONSE_GETNUMBER_TIMEOUT)) + { + if ((value < 0) || (value >= NTRIP_SERVER_MAX)) + systemPrintf("Error: NTRIP Server index out of range (0 - %d)\r\n", NTRIP_SERVER_MAX - 1); + else + serverIndex = value; + } } else if ((incoming == 9) && settings.enableNtripServer == true) + { + systemPrint("Enter new Caster Address: "); + if (getString(&settings.ntripServer_CasterHost[serverIndex][0], + sizeof(settings.ntripServer_CasterHost[serverIndex]) + == INPUT_RESPONSE_VALID)) + restartBase = true; + } + else if ((incoming == 10) && settings.enableNtripServer == true) { systemPrint("Enter new Caster Port: "); @@ -314,32 +336,36 @@ void menuBase() if ((ntripServer_CasterPort != INPUT_RESPONSE_GETNUMBER_EXIT) && (ntripServer_CasterPort != INPUT_RESPONSE_GETNUMBER_TIMEOUT)) { - if (ntripServer_CasterPort < 1 || ntripServer_CasterPort > 99999) // Arbitrary 99k max port # + if (ntripServer_CasterPort < 1 || ntripServer_CasterPort > 65535) systemPrintln("Error: Caster port out of range"); else - settings.ntripServer_CasterPort = + settings.ntripServer_CasterPort[serverIndex] = ntripServer_CasterPort; // Recorded to NVM and file at main menu exit restartBase = true; } } - else if ((incoming == 10) && settings.enableNtripServer == true) + else if ((incoming == 11) && settings.enableNtripServer == true) { systemPrint("Enter new Mount Point: "); - getString(settings.ntripServer_MountPoint, sizeof(settings.ntripServer_MountPoint)); - restartBase = true; + if (getString(&settings.ntripServer_MountPoint[serverIndex][0], + sizeof(settings.ntripServer_MountPoint[serverIndex])) + == INPUT_RESPONSE_VALID) + restartBase = true; } - else if ((incoming == 11) && settings.enableNtripServer == true) + else if ((incoming == 12) && settings.enableNtripServer == true) { systemPrintf("Enter password for Mount Point %s: ", settings.ntripServer_MountPoint); - getString(settings.ntripServer_MountPointPW, sizeof(settings.ntripServer_MountPointPW)); - restartBase = true; + if (getString(&settings.ntripServer_MountPointPW[serverIndex][0], + sizeof(settings.ntripServer_MountPointPW[serverIndex])) + == INPUT_RESPONSE_VALID) + restartBase = true; } - else if (((settings.enableNtripServer == true) && ((incoming == 12))) || + else if (((settings.enableNtripServer == true) && ((incoming == 13))) || ((settings.enableNtripServer == false) && (incoming == 8))) { menuMessagesBaseRTCM(); // Set rates for RTCM during Base mode } - else if (((settings.enableNtripServer == true) && (settings.fixedBase == false) && ((incoming == 13))) || + else if (((settings.enableNtripServer == true) && (settings.fixedBase == false) && ((incoming == 14))) || ((settings.enableNtripServer == false) && (settings.fixedBase == false) && (incoming == 9))) { settings.ntripServer_StartAtSurveyIn ^= 1; diff --git a/Firmware/RTK_Surveyor/menuSystem.ino b/Firmware/RTK_Surveyor/menuSystem.ino index 067c1c394..d914f75ac 100644 --- a/Firmware/RTK_Surveyor/menuSystem.ino +++ b/Firmware/RTK_Surveyor/menuSystem.ino @@ -80,7 +80,7 @@ void menuSystem() systemPrint("WiFi MAC Address: "); systemPrintf("%02X:%02X:%02X:%02X:%02X:%02X\r\n", wifiMACAddress[0], wifiMACAddress[1], wifiMACAddress[2], wifiMACAddress[3], wifiMACAddress[4], wifiMACAddress[5]); - if (wifiState == WIFI_CONNECTED) + if (wifiState == WIFI_STATE_CONNECTED) wifiDisplayIpAddress(); #endif // COMPILE_WIFI @@ -136,7 +136,8 @@ void menuSystem() ntripClientPrintStatus(); // Display NTRIP Server status and uptime - ntripServerPrintStatus(); + for (int serverIndex = 0; serverIndex < NTRIP_SERVER_MAX; serverIndex++) + ntripServerPrintStatus(serverIndex); systemPrintf("Filtered by parser: %d NMEA / %d RTCM / %d UBX\r\n", failedParserMessages_NMEA, failedParserMessages_RTCM, failedParserMessages_UBX); diff --git a/Firmware/RTK_Surveyor/settings.h b/Firmware/RTK_Surveyor/settings.h index 184442dd0..b964f8555 100644 --- a/Firmware/RTK_Surveyor/settings.h +++ b/Firmware/RTK_Surveyor/settings.h @@ -1,3 +1,6 @@ +#ifndef __SETTINGS_H__ +#define __SETTINGS_H__ + // System can enter a variety of states // See statemachine diagram at: // https://lucid.app/lucidchart/53519501-9fa5-4352-aa40-673f88ca0c9b/edit?invitationId=inv_ebd4b988-513d-4169-93fd-c291851108f8 @@ -237,16 +240,18 @@ enum NetworkUsers { NETWORK_USER_NTP_SERVER = 0, // NTP server NETWORK_USER_NTRIP_CLIENT, // NTRIP client - NETWORK_USER_NTRIP_SERVER, // NTRIP server NETWORK_USER_OTA_FIRMWARE_UPDATE, // Over-The-Air firmware updates NETWORK_USER_PVT_CLIENT, // PVT client NETWORK_USER_PVT_SERVER, // PVT server NETWORK_USER_PVT_UDP_SERVER, // PVT UDP server + + // Add new users above this line + NETWORK_USER_NTRIP_SERVER, // NTRIP server // Last network user - NETWORK_USER_MAX + NETWORK_USER_MAX = NETWORK_USER_NTRIP_SERVER + NTRIP_SERVER_MAX }; -typedef uint8_t NETWORK_USER; +typedef uint16_t NETWORK_USER; typedef struct _NETWORK_DATA { @@ -267,12 +272,41 @@ typedef struct _NETWORK_DATA // either WiFi or ESP-Now are active enum WiFiState { - WIFI_OFF = 0, - WIFI_START, - WIFI_CONNECTING, - WIFI_CONNECTED, + WIFI_STATE_OFF = 0, + WIFI_STATE_START, + WIFI_STATE_CONNECTING, + WIFI_STATE_CONNECTED, }; -volatile byte wifiState = WIFI_OFF; +volatile byte wifiState = WIFI_STATE_OFF; + +#include "NetworkClient.h" // Built-in - Supports both WiFiClient and EthernetClient +#include "NetworkUDP.h" //Built-in - Supports both WiFiUdp and EthernetUdp + +// NTRIP Server data +typedef struct _NTRIP_SERVER_DATA +{ + // Network connection used to push RTCM to NTRIP caster + NetworkClient *networkClient; + volatile uint8_t state; + + // Count of bytes sent by the NTRIP server to the NTRIP caster + uint32_t bytesSent; + + // Throttle the time between connection attempts + // ms - Max of 4,294,967,295 or 4.3M seconds or 71,000 minutes or 1193 hours or 49 days between attempts + uint32_t connectionAttemptTimeout; + uint32_t lastConnectionAttempt; + int connectionAttempts; // Count the number of connection attempts between restarts + + // NTRIP server timer usage: + // * Reconnection delay + // * Measure the connection response time + // * Receive RTCM correction data timeout + // * Monitor last RTCM byte received for frame counting + uint32_t timer; + uint32_t startTime; + int connectionAttemptsTotal; // Count the number of connection attempts absolutely +} NTRIP_SERVER_DATA; typedef enum { @@ -1112,13 +1146,36 @@ typedef struct bool debugNtripServerState = false; bool enableNtripServer = false; bool ntripServer_StartAtSurveyIn = false; // true = Start WiFi instead of Bluetooth at Survey-In - char ntripServer_CasterHost[50] = "rtk2go.com"; // It's free... - uint16_t ntripServer_CasterPort = 2101; - char ntripServer_CasterUser[50] = - "test@test.com"; // Some free casters require auth. User must provide their own email address to use RTK2Go - char ntripServer_CasterUserPW[50] = ""; - char ntripServer_MountPoint[50] = "bldr_dwntwn2"; // NTRIP Server - char ntripServer_MountPointPW[50] = "WR5wRo4H"; + char ntripServer_CasterHost[NTRIP_SERVER_MAX][50] = // It's free... + { + "rtk2go.com", + "", + }; + uint16_t ntripServer_CasterPort[NTRIP_SERVER_MAX] = + { + 2101, + 0, + }; + char ntripServer_CasterUser[NTRIP_SERVER_MAX][50] = + { + "test@test.com" // Some free casters require auth. User must provide their own email address to use RTK2Go + "", + }; + char ntripServer_CasterUserPW[NTRIP_SERVER_MAX][50] = + { + "", + "", + }; + char ntripServer_MountPoint[NTRIP_SERVER_MAX][50] = + { + "bldr_dwntwn2", // NTRIP Server + "", + }; + char ntripServer_MountPointPW[NTRIP_SERVER_MAX][50] = + { + "WR5wRo4H", + "", + }; // TCP Client bool debugPvtClient = false; @@ -1171,7 +1228,7 @@ struct struct_online bool battery = false; bool accelerometer = false; bool ntripClient = false; - bool ntripServer = false; + bool ntripServer[NTRIP_SERVER_MAX] = {false, false}; bool lband = false; bool lbandCorrections = false; bool i2c = false; @@ -1210,3 +1267,4 @@ rqXRfboQnoZsG4q5WTP468SQvvG5 )====="; #endif // COMPILE_L_BAND #endif // COMPILE_WIFI +#endif // __SETTINGS_H__ diff --git a/Firmware/Tools/makefile b/Firmware/Tools/makefile index 543c296cb..292ba343a 100644 --- a/Firmware/Tools/makefile +++ b/Firmware/Tools/makefile @@ -207,6 +207,10 @@ partition: ../app3M_fat9M_16MB.csv ESP_VERSION=$$(basename $$ESP_VERSION_PATH) cp --verbose $< ~/.arduino15/packages/esp32/hardware/esp32/$$ESP_VERSION/tools/partitions/app3M_fat9M_16MB.csv +../RTK_Surveyor/form.h: makefile ../RTK_Surveyor/* ../RTK_Surveyor/AP-Config/* ../RTK_Surveyor/AP-Config/src/* ../RTK_Surveyor/AP-Config/src/fonts/* + python index_html_zipper.py ../RTK_Surveyor/AP-Config/index.html ../RTK_Surveyor/form.h + python main_js_zipper.py ../RTK_Surveyor/AP-Config/src/main.js ../RTK_Surveyor/form.h + RTK: ../RTK_Surveyor/RTK_Surveyor.ino ../RTK_Surveyor/*.h ~/Arduino/arduino-cli compile --fqbn "esp32:esp32:esp32":DebugLevel=$(DEBUG_LEVEL) ../RTK_Surveyor/RTK_Surveyor.ino --build-property build.partitions=app3M_fat9M_16MB --build-property upload.maximum_size=3145728 --build-property "compiler.cpp.extra_flags=\"-DPOINTPERFECT_TOKEN=$(POINTPERFECT_TOKEN)\" \"-DFIRMWARE_VERSION_MAJOR=$(FIRMWARE_VERSION_MAJOR)\" \"-DFIRMWARE_VERSION_MINOR=$(FIRMWARE_VERSION_MINOR)\" \"-DENABLE_DEVELOPER=$(ENABLE_DEVELOPER)\"" --export-binaries