diff --git a/.vscode/settings.json b/.vscode/settings.json index e25c8a46..0d507e75 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,6 +9,44 @@ "vector": "cpp", "memory": "cpp", "random": "cpp", - "initializer_list": "cpp" + "initializer_list": "cpp", + "atomic": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "map": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp" } } \ No newline at end of file diff --git a/tinyGS/src/ConfigManager/ConfigManager.cpp b/tinyGS/src/ConfigManager/ConfigManager.cpp index 4b9d4534..003f3462 100644 --- a/tinyGS/src/ConfigManager/ConfigManager.cpp +++ b/tinyGS/src/ConfigManager/ConfigManager.cpp @@ -83,6 +83,8 @@ ConfigManager::ConfigManager() #endif }) { + server.on("/radioBegin", [this] { handleRadioBegin(); }); + server.on("/packets", [this] { handleGetAllPackets(); }); server.on(ROOT_URL, [this] { handleRoot(); }); server.on(CONFIG_URL, [this] { handleConfig(); }); server.on(DASHBOARD_URL, [this] { handleDashboard(); }); @@ -127,6 +129,47 @@ ConfigManager::ConfigManager() addParameterGroup(&groupAdvanced); } +void ConfigManager::handleRadioBegin() +{ + if (!Radio::getInstance().isReady()) + { + server.send(200, "application/json; charset=UTF-8", "{\"message\":\"Radio is not ready to begin\"}"); + Log::console(PSTR("Radio is not ready to begin")); + return; + } + if (Radio::getInstance().begin() == 0) + { + server.send(200, "application/json; charset=UTF-8", "{\"message\":\"Radio begun successfully after /radioBegin request\"}"); + Log::console(PSTR("Radio begun successfully after /radioBegin request")); + return; + } + server.send(200, "application/json; charset=UTF-8", "{\"message\":\"An error occurred while trying to start the Radio\"}"); + Log::console(PSTR("An error occurred while trying to start the Radio")); +} + +void ConfigManager::handleGetAllPackets() +{ + String string = String(FPSTR("{\"message\":\"Packets were fetched successfully\",\"packets\":[")); + for (size_t i = 0; i < status.allPackets.size(); i++) + { + string += "{\"time\":\"" + status.allPackets.at(i).time + + "\",\"encoded_message\":\"" + status.allPackets.at(i).encoded_message + + "\",\"decoded_message\":\"" + status.allPackets.at(i).decoded_message + + "\",\"rssi\":" + status.allPackets.at(i).rssi + + ",\"snr\":" + status.allPackets.at(i).snr + + ",\"frequencyerror\":" + status.allPackets.at(i).frequencyerror + + ",\"crc_error\":" + status.allPackets.at(i).crc_error + + "}"; + if (i < status.allPackets.size() - 1) + { + string += ","; + } + } + string += "]}"; + server.send(200, "application/json; charset=UTF-8", string); + Log::console(PSTR("Endpoint /packets was requested and handled successfully")); +} + void ConfigManager::handleRoot() { // -- Let IotWebConf2 test and handle captive portal requests. @@ -149,7 +192,7 @@ void ConfigManager::handleRoot() s.replace("{v}", FPSTR(TITLE_TEXT)); - server.sendHeader("Content-Length", String(s.length())); + // server.sendHeader("Content-Length", String(s.length())); server.send(200, "text/html; charset=UTF-8", s); } @@ -256,7 +299,7 @@ void ConfigManager::handleDashboard() s.replace("{v}", FPSTR(TITLE_TEXT)); - server.sendHeader("Content-Length", String(s.length())); + // server.sendHeader("Content-Length", String(s.length())); server.send(200, "text/html; charset=UTF-8", s); } @@ -304,7 +347,15 @@ void ConfigManager::handleRefreshConsole() } else { - Log::console(PSTR("%s"), F("Command still not supported in web serial console!")); + // Log::console(PSTR("%s"), F("Command still not supported in web serial console!")); + if (Radio::getInstance().sendTx((uint8_t *) svalue.c_str(), strlen(svalue.c_str())) == 0) + { + Log::console(PSTR("%s"), F("Message was sent successfully")); + } + else + { + Log::console(PSTR("%s"), F("An error occurred while sending the message!")); + } } } @@ -443,7 +494,7 @@ void ConfigManager::handleRestart() s.replace("{v}", FPSTR(TITLE_TEXT)); - server.sendHeader("Content-Length", String(s.length())); + // server.sendHeader("Content-Length", String(s.length())); server.send(200, "text/html; charset=UTF-8", s); delay(100); ESP.restart(); diff --git a/tinyGS/src/ConfigManager/ConfigManager.h b/tinyGS/src/ConfigManager/ConfigManager.h index ebfe35fb..0f83343e 100644 --- a/tinyGS/src/ConfigManager/ConfigManager.h +++ b/tinyGS/src/ConfigManager/ConfigManager.h @@ -236,6 +236,8 @@ class ConfigManager : public IotWebConf2 }; ConfigManager(); + void handleRadioBegin(); + void handleGetAllPackets(); void handleRoot(); void handleDashboard(); void handleRefreshConsole(); diff --git a/tinyGS/src/Radio/Radio.cpp b/tinyGS/src/Radio/Radio.cpp index a3cae365..588a2e12 100644 --- a/tinyGS/src/Radio/Radio.cpp +++ b/tinyGS/src/Radio/Radio.cpp @@ -38,6 +38,23 @@ bool noisyInterrupt = false; bool allow_decode=true; +std::string hexToASCII(std::string hex) +{ + std::string ascii = ""; + for (size_t i = 0; i < hex.length(); i += 2) + { + // extract two characters from hex string + std::string part = hex.substr(i, 2); + + // change it into base 16 and typecast as the character + char ch = (char) strtol(part.c_str(), nullptr, 16); + + // add this char to final ASCII string + ascii += ch; + } + return ascii; +} + Radio::Radio() #if CONFIG_IDF_TARGET_ESP32S3 : spi(HSPI) @@ -272,12 +289,12 @@ uint8_t Radio::listen() { // store time of the last packet received: timeinfo = localtime(¤ttime); - String thisTime = ""; - if (timeinfo->tm_hour < 10) - { - thisTime = thisTime + " "; - } // add leading space if required - thisTime = String(timeinfo->tm_hour) + ":"; + String thisTime = String(timeinfo->tm_mday) + "/" + String(timeinfo->tm_mon + 1) + "/" + String(timeinfo->tm_year + 1900) + " "; + // if (timeinfo->tm_hour < 10) + // { + // thisTime = thisTime + " "; + // } // add leading space if required + thisTime = thisTime + String(timeinfo->tm_hour) + ":"; if (timeinfo->tm_min < 10) { thisTime = thisTime + "0"; @@ -297,30 +314,40 @@ uint8_t Radio::listen() status.lastPacketInfo.frequencyerror = newPacketInfo.frequencyerror; // print RSSI (Received Signal Strength Indicator) - Log::console(PSTR("[%s] RSSI:\t\t%f dBm\n[%s] SNR:\t\t%f dB\n[%s] Frequency error:\t%f Hz"), - moduleNameString, status.lastPacketInfo.rssi, - moduleNameString, status.lastPacketInfo.snr, - moduleNameString, status.lastPacketInfo.frequencyerror); + Log::console(PSTR("[%s] RSSI:\t\t%f dBm\n\t [%s] SNR:\t\t%f dB\n\t [%s] Frequency error:\t%f Hz"), + moduleNameString, status.lastPacketInfo.rssi, + moduleNameString, status.lastPacketInfo.snr, + moduleNameString, status.lastPacketInfo.frequencyerror + ); if (state == RADIOLIB_ERR_NONE && respLen > 0) { // read optional data - Log::console(PSTR("Packet (%u bytes):"), respLen); + // Log::console(PSTR("Packet (%u bytes):"), respLen); + uint16_t buffSize = respLen * 2 + 1; - if (buffSize > 255) - buffSize = 255; + // if (buffSize > 255) + // buffSize = 255; + char *byteStr = new char[buffSize]; for (int i = 0; i < respLen; i++) { sprintf(byteStr + i * 2 % (buffSize - 1), "%02x", respFrame[i]); - if (i * 2 % buffSize == buffSize - 3 || i == respLen - 1) - Log::console(PSTR("%s"), byteStr); // print before the buffer is going to loop back + // if (i * 2 % buffSize == buffSize - 3 || i == respLen - 1) { + // Log::console(PSTR("\tEncoded: %s"), byteStr); // print before the buffer is going to loop back + // } } + + status.lastPacketInfo.encoded_message = byteStr; + status.lastPacketInfo.decoded_message = hexToASCII(std::string(byteStr)).c_str(); + + // Log::console(PSTR("\tDecoded: %s"), hexToASCII(std::string(byteStr)).c_str()); + Log::console(PSTR("Packet (%u bytes):\n\t - Encoded: %s\n\t - Decoded: %s"), respLen, byteStr, status.lastPacketInfo.decoded_message.c_str()); delete[] byteStr; - if (allow_decode){ + if (allow_decode) { String modo=status.modeminfo.modem_mode; - if (modo=="FSK"){ + if (modo=="FSK") { int bytes_sincro=0; for (int i=0;i + struct PacketInfo { String time = "Waiting"; + String encoded_message = ""; + String decoded_message = ""; float rssi = 0; float snr = 0; - float frequencyerror = 0; // Hz + float frequencyerror = 0; // Hz bool crc_error = false; }; @@ -73,6 +77,7 @@ struct Status { bool radio_ready = false; int16_t radio_error = 0; PacketInfo lastPacketInfo; + std::vector allPackets; ModemInfo modeminfo; float satPos[2] = {0, 0}; uint8_t remoteTextFrameLength[4] = {0, 0, 0, 0}; diff --git a/tinyGS/tinyGS.ino b/tinyGS/tinyGS.ino index ea480350..8197d922 100644 --- a/tinyGS/tinyGS.ino +++ b/tinyGS/tinyGS.ino @@ -314,9 +314,10 @@ void handleSerial() // function to print controls void printControls() { - Log::console(PSTR("------------- Controls -------------")); + Log::console(PSTR("----------------- Controls -----------------")); Log::console(PSTR("!e - erase board config and reset")); Log::console(PSTR("!b - reboot the board")); Log::console(PSTR("!p - send test packet to nearby stations (to check transmission)")); - Log::console(PSTR("------------------------------------")); + Log::console(PSTR(" - send packet with custom message")); + Log::console(PSTR("--------------------------------------------")); } \ No newline at end of file