diff --git a/host/host_central_mast/lib/NetworkConnectionManager/ConnectionManager.cpp b/host/host_central_mast/lib/NetworkConnectionManager/ConnectionManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2b1d10661d556c667cd5f7e9ec91c7ad084caeac --- /dev/null +++ b/host/host_central_mast/lib/NetworkConnectionManager/ConnectionManager.cpp @@ -0,0 +1,133 @@ +// +// Created by zoe on 12/20/22. +// + +#include "ConnectionManager.h" +#include "LTEConnectionException.hpp" +#include "ModemFunctionalityLevel.h" + +#include <utility> + +ConnectionManager::ConnectionManager(TinyGsm &client, GPRSCredentials credentials) + : modem(client), credentials(std::move(credentials)) {} + +void ConnectionManager::restartModem() { + // Restart takes quite some time + // To skip it, call init() instead of restart() + esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Restarting modem...\n"); + if (!modem.restart()) { + esp_log_write(ESP_LOG_WARN, TAG_GSM.c_str(), + "Failed to restart modem, attempting to continue without restarting\n"); + } +} + +void ConnectionManager::initModem() { + esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Initializing modem...\n"); + if (!modem.init()) { + esp_log_write(ESP_LOG_WARN, TAG_GSM.c_str(), + "Failed to initialize modem, attempting to continue by restarting\n"); + // might not be the cleanest design + restartModem(); + } + setModemFunctionalityLevel(MINIMAL); +} + +void ConnectionManager::setModemFunctionalityLevel( + ModemFunctionalityLevel functionalityLevel) { // This sets the level of functionality of the modem. Full + // functionality is where the highest + // level of power is drawn. Minimum functionality (default) is where the lowest level of power is drawn. + // https://m2msupport.net/m2msupport/atcfun-set-phone-functionality/ + modem.sendAT(("+CFUN=" + std::to_string(ModemFunctionalityLevel::MINIMAL) + " ").c_str()); + if (modem.waitResponse(10000L) != 1) { + DBG(" +CFUN=0 false "); + } +} + +void ConnectionManager::disableGPS() { + // Set SIM7000G GPIO4 LOW ,turn off GPS power + // CMD:AT+SGPIO=0,4,1,0 + // Only in version 20200415 is there a function to control GPS power + modem.sendAT("+SGPIO=0,4,1,0"); + if (modem.waitResponse(10000L) != 1) { + DBG(" SGPIO=0,4,1,0 false "); + } + modem.disableGPS(); +} + +void ConnectionManager::enableGPS() { + // Set SIM7000G GPIO4 LOW ,turn on GPS power + // CMD:AT+SGPIO=0,4,1,1 + // Only in version 20200415 is there a function to control GPS power + modem.sendAT("+SGPIO=0,4,1,1"); + if (modem.waitResponse(10000L) != 1) { + DBG(" SGPIO=0,4,1,1 false "); + } + modem.enableGPS(); +} + +void ConnectionManager::setNetworkMode(NetworkMode networkMode) { + + String res; + res = modem.setNetworkMode(networkMode); + if (res != "1") { + DBG("setNetworkMode false "); + throw LTEConnectionException("Failed to set network mode"); + } + delay(200); +} + +void ConnectionManager::setPreferredMode(Mode mode) { + /*AT+CBANDCFG=<mode>,<band>[,<band>…] + * <mode> "CAT-M" "NB-IOT" + * <band> The value of <band> must is in the band list of getting from AT+CBANDCFG=? + * For example, my SIM card carrier "NB-iot" supports B8. I will configure +CBANDCFG= "Nb-iot ",8 + */ + modem.sendAT("+CBANDCFG=\"CAT-M\",8 "); + if (modem.waitResponse(10000L) != 1) { + DBG(" +CBANDCFG=\"NB-IOT\" "); + } + delay(200); +} +void ConnectionManager::setBand(BandMode bandMode, int band) { + /*AT+CBANDCFG=<mode>,<band>[,<band>…] + * <mode> "CAT-M" "NB-IOT" + * <band> The value of <band> must is in the band list of getting from AT+CBANDCFG=? + * For example, my SIM card carrier "NB-iot" supports B8. I will configure +CBANDCFG= "Nb-iot ",8 + */ + + bandMode == BandMode::BAND_CAT_M ? modem.sendAT(("+CBANDCFG=\"CAT-M\"," + std::to_string(band) + " ").c_str()) + : modem.sendAT(("+CBANDCFG=\"NB-IOT\"," + std::to_string(band) + " ").c_str()); + + if (modem.waitResponse(10000L) != 1) { + DBG(" +CBANDCFG=\"NB-IOT\" "); + } + delay(200); +} +bool ConnectionManager::gprsConnect() { + return modem.gprsConnect(credentials.apn.c_str(), credentials.user.c_str(), credentials.password.c_str()); +} +bool ConnectionManager::isNetworkConnected() { + return modem.isNetworkConnected(); +} +std::string ConnectionManager::connect(const std::string &host, int port, RequestInformation requestInformation) { + TinyGsmClient client{modem}; + if (!client.connect(host.c_str(), port)) { + throw LTEConnectionException("Failed to connect to host"); + } + + String request = requestInformation.buildRequest(); + + client.print(request); + + String line; + // print response + while (client.connected()) { + line += client.readStringUntil('\n'); + if (line == "\r") { + esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "headers received\n"); + break; + } + } + client.stop(); + return line.c_str(); +} diff --git a/host/host_central_mast/lib/NetworkConnectionManager/LTEConnection.h b/host/host_central_mast/lib/NetworkConnectionManager/ConnectionManager.h similarity index 53% rename from host/host_central_mast/lib/NetworkConnectionManager/LTEConnection.h rename to host/host_central_mast/lib/NetworkConnectionManager/ConnectionManager.h index a02298769e52234bd458a1bcc013fed08f6bed4d..ea475a4d7af31ada005ea92586e41baba043f947 100644 --- a/host/host_central_mast/lib/NetworkConnectionManager/LTEConnection.h +++ b/host/host_central_mast/lib/NetworkConnectionManager/ConnectionManager.h @@ -2,31 +2,30 @@ // Created by zoe on 12/20/22. // -#ifndef HOST_CENTRAL_MAST_LTECONNECTION_H -#define HOST_CENTRAL_MAST_LTECONNECTION_H +#ifndef HOST_CENTRAL_MAST_CONNECTIONMANAGER_H +#define HOST_CENTRAL_MAST_CONNECTIONMANAGER_H #define TINY_GSM_MODEM_SIM7000 -#include <TinyGsmClient.h> #include "GPRSCredentials.h" -#include "StreamDebugger.h" +#include "Mode.h" #include "ModemFunctionalityLevel.h" #include "NetworkMode.h" -#include "Mode.h" +#include "RequestInformation.h" +#include "StreamDebugger.h" +#include <TinyGsmClient.h> static const std::string TAG_GSM = "GSM"; -class LTEConnection { -private: - TinyGsm &client; +class ConnectionManager { + private: + TinyGsm &modem; const GPRSCredentials credentials; + public: + ConnectionManager(TinyGsm &client, GPRSCredentials credentials); -public: - LTEConnection(TinyGsm &client, GPRSCredentials credentials); - - - std::string connect(const std::string &host, const std::string &port); + std::string connect(const std::string &host, int port, RequestInformation requestInformation); void enableGPS(); @@ -41,7 +40,14 @@ public: void setPreferredMode(Mode mode = Mode::CAT_M); void setModemFunctionalityLevel(ModemFunctionalityLevel functionalityLevel = MINIMAL); -}; + enum BandMode { BAND_CAT_M, BAND_NB_IoT }; + + void setBand(BandMode bandMode, int band); + + bool gprsConnect(); + + bool isNetworkConnected(); +}; -#endif //HOST_CENTRAL_MAST_LTECONNECTION_H +#endif // HOST_CENTRAL_MAST_CONNECTIONMANAGER_H diff --git a/host/host_central_mast/lib/NetworkConnectionManager/LTEConnection.cpp b/host/host_central_mast/lib/NetworkConnectionManager/LTEConnection.cpp deleted file mode 100644 index c509bf072ddfa235fab4debdacee361fa8ff096b..0000000000000000000000000000000000000000 --- a/host/host_central_mast/lib/NetworkConnectionManager/LTEConnection.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// -// Created by zoe on 12/20/22. -// - -#include "LTEConnection.h" -#include "ModemFunctionalityLevel.h" -#include "LTEConnectionException.hpp" - -#include <utility> - -std::string LTEConnection::connect(const std::string &host, const std::string &port) { - return std::__cxx11::string(); -} - -LTEConnection::LTEConnection(TinyGsm &client, GPRSCredentials credentials) : client(client), - credentials( - std::move( - credentials)) {} - - -void LTEConnection::restartModem() { - // Restart takes quite some time - // To skip it, call init() instead of restart() - esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Restarting modem...\n"); - if (!client.restart()) { - esp_log_write(ESP_LOG_WARN, TAG_GSM.c_str(), - "Failed to restart modem, attempting to continue without restarting\n"); - } -} - -void LTEConnection::initModem() { - esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Initializing modem...\n"); - if (!client.init()) { - esp_log_write(ESP_LOG_WARN, TAG_GSM.c_str(), - "Failed to initialize modem, attempting to continue by restarting\n"); - // might not be the cleanest design - restartModem(); - } - setModemFunctionalityLevel(MINIMAL); -} - -void -LTEConnection::setModemFunctionalityLevel( - ModemFunctionalityLevel functionalityLevel) {// This sets the level of functionality of the modem. Full functionality is where the highest -// level of power is drawn. Minimum functionality (default) is where the lowest level of power is drawn. -// https://m2msupport.net/m2msupport/atcfun-set-phone-functionality/ - client.sendAT(("+CFUN=" + std::to_string(ModemFunctionalityLevel::MINIMAL) + " ").c_str()); - if (client.waitResponse(10000L) != 1) { - DBG(" +CFUN=0 false "); - } -} - -void LTEConnection::disableGPS() { - // Set SIM7000G GPIO4 LOW ,turn off GPS power - // CMD:AT+SGPIO=0,4,1,0 - // Only in version 20200415 is there a function to control GPS power - client.sendAT("+SGPIO=0,4,1,0"); - if (client.waitResponse(10000L) != 1) { - DBG(" SGPIO=0,4,1,0 false "); - } - client.disableGPS(); -} - -void LTEConnection::enableGPS() { - // Set SIM7000G GPIO4 LOW ,turn on GPS power - // CMD:AT+SGPIO=0,4,1,1 - // Only in version 20200415 is there a function to control GPS power - client.sendAT("+SGPIO=0,4,1,1"); - if (client.waitResponse(10000L) != 1) { - DBG(" SGPIO=0,4,1,1 false "); - } - client.enableGPS(); -} - -void LTEConnection::setNetworkMode(NetworkMode networkMode) { - - String res; - res = client.setNetworkMode(networkMode); - if (res != "1") { - DBG("setNetworkMode false "); - throw LTEConnectionException("Failed to set network mode"); - } - delay(200); -} - -void LTEConnection::setPreferredMode(Mode mode) { - /*AT+CBANDCFG=<mode>,<band>[,<band>…] - * <mode> "CAT-M" "NB-IOT" - * <band> The value of <band> must is in the band list of getting from AT+CBANDCFG=? - * For example, my SIM card carrier "NB-iot" supports B8. I will configure +CBANDCFG= "Nb-iot ",8 - */ - client.sendAT("+CBANDCFG=\"CAT-M\",8 "); - if (client.waitResponse(10000L) != 1) { - DBG(" +CBANDCFG=\"NB-IOT\" "); - } - delay(200); - -} - - - diff --git a/host/host_central_mast/lib/NetworkConnectionManager/RequestInformation.h b/host/host_central_mast/lib/NetworkConnectionManager/RequestInformation.h new file mode 100644 index 0000000000000000000000000000000000000000..a6d0bdd47057d105f49bda283498c6951394cf14 --- /dev/null +++ b/host/host_central_mast/lib/NetworkConnectionManager/RequestInformation.h @@ -0,0 +1,41 @@ +// +// Created by zoe on 1/9/23. +// + +#ifndef HOST_CENTRAL_MAST_REQUESTINFORMATION_H +#define HOST_CENTRAL_MAST_REQUESTINFORMATION_H + +#include <Arduino.h> + +struct RequestInformation { + String method; + String host; + String path; + String body; + + RequestInformation(String method, String host, String path, String body) { + this->method = method; + this->host = host; + this->path = path; + this->body = body; + } + + // TODO: Move to configuration file + const String INFLUXDB_TOKEN = + "dUh2gbVLv7e3egqocxriDsJQNUacA9qZ5YXsYtdnVAglnHgy4nx-jDVO7nGlSF34BosfnuwnUDaviC7dQeC5RQ=="; + + String buildRequest() { + String request = ""; + request += method + " " + path + " HTTP/1.1\r\n"; + request += "Host: " + host + "\r\n"; + request += "Authorization: Token " + INFLUXDB_TOKEN + "\r\n"; + request += "User-Agent: ESP32\r\n"; + request += "Content-Type: text/plain\r\n"; + request += "Content-Length: " + String(body.length()) + "\r\n"; + request += "\r\n"; + request += body; + return request; + } +}; + +#endif // HOST_CENTRAL_MAST_REQUESTINFORMATION_H diff --git a/host/host_central_mast/lib/TimeManager/TimeManager.cpp b/host/host_central_mast/lib/TimeManager/TimeManager.cpp index 603d717f06257f4dbf37b3370890434fcef2ba5e..2ece1bafb1203041383b40585cf6a5d445ededf5 100644 --- a/host/host_central_mast/lib/TimeManager/TimeManager.cpp +++ b/host/host_central_mast/lib/TimeManager/TimeManager.cpp @@ -31,15 +31,15 @@ void TimeManager::syncNTP(const std::string &ntpServer) { } } -time_t TimeManager::timeToUnixEpochSeconds(const std::string &time) { +time_t TimeManager::timeToUnixEpochSeconds(const std::string &time, const std::string &format) { // 22/10/27,10:16:20+00 - struct tm tm{}; + struct tm tm {}; time_t dateInEpoch = 0; std::stringstream stringStream(time); try { - stringStream >> std::get_time(&tm, "%y/%m/%d,%H:%M:%S%z"); + stringStream >> std::get_time(&tm, format.c_str()); } catch (std::exception &e) { throw StringToTimeConversionException(("Error converting time to epoch %s", e.what())); } diff --git a/host/host_central_mast/lib/TimeManager/TimeManager.h b/host/host_central_mast/lib/TimeManager/TimeManager.h index 44b552bdf9acaae00ca5d74480454cd5fd559641..3de9998854400d36fdf04240b4bf346a4cb7502b 100644 --- a/host/host_central_mast/lib/TimeManager/TimeManager.h +++ b/host/host_central_mast/lib/TimeManager/TimeManager.h @@ -7,19 +7,19 @@ #define TINY_GSM_MODEM_SIM7000 -#include <TinyGsmClientSIM7000.h> -#include <string> +#include "ESP32Time.h" #include "NTPException.hpp" #include "StringToTimeConversionException.hpp" -#include "ESP32Time.h" +#include <TinyGsmClientSIM7000.h> #include <iomanip> +#include <string> class TimeManager { -public: + public: explicit TimeManager(TinyGsmSim7000 &modem); -private: - constexpr static char *TAG = "GSM"; + private: + constexpr static char *TAG = "TimeManager"; ESP32Time rtc; int timeZone = 0; @@ -30,11 +30,10 @@ private: void syncNTP(const std::string &ntpServer = "time1.uibk.ac.at"); // convert time to unix epoch seconds - time_t timeToUnixEpochSeconds(const std::string &time); + static time_t timeToUnixEpochSeconds(const std::string &time, const std::string &format = "%y/%m/%d,%H:%M:%S%z"); // write modem time to rtc void writeModemTimeToRTC(); }; - -#endif //HOST_CENTRAL_MAST_TIMEMANAGER_H \ No newline at end of file +#endif // HOST_CENTRAL_MAST_TIMEMANAGER_H \ No newline at end of file