diff --git a/data/igate_conf.json b/data/igate_conf.json index 681c02a..2aae297 100644 --- a/data/igate_conf.json +++ b/data/igate_conf.json @@ -21,6 +21,11 @@ "digi": { "mode": 0 }, + "tnc": { + "enableServer": false, + "enableSerial": false, + "acceptOwn": false + }, "aprs_is": { "active": false, "passcode": "XYZVW", diff --git a/data_embed/index.html b/data_embed/index.html index ccab1f8..6c45bf0 100644 --- a/data_embed/index.html +++ b/data_embed/index.html @@ -540,6 +540,91 @@
+
+
+
+ + + + + + + TNC +
+ TNC and KISS configuration +
+
+
+
+
+
+ Server will be available at port 8001 +
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+
diff --git a/data_embed/script.js b/data_embed/script.js index c3ac079..ef7f4b3 100644 --- a/data_embed/script.js +++ b/data_embed/script.js @@ -150,6 +150,11 @@ function loadSettings(settings) { // document.getElementById("digi.longitude").value = settings.digi.longitude; document.getElementById("digi.mode").value = settings.digi.mode; + // TNC + document.getElementById("tnc.enableServer").checked = settings.tnc.enableServer; + document.getElementById("tnc.enableSerial").checked = settings.tnc.enableSerial; + document.getElementById("tnc.acceptOwn").checked = settings.tnc.acceptOwn; + // OTA document.getElementById("ota.username").value = settings.ota.username; document.getElementById("ota.password").value = settings.ota.password; diff --git a/src/LoRa_APRS_iGate.cpp b/src/LoRa_APRS_iGate.cpp index 04db05a..6a27fa1 100644 --- a/src/LoRa_APRS_iGate.cpp +++ b/src/LoRa_APRS_iGate.cpp @@ -125,7 +125,13 @@ void loop() { DIGI_Utils::loop(packet); // Send received packet to Digi } - TNC_Utils::sendToClients(packet); // Send received packet to TNC KISS + if (Config.tnc.enableServer) { // If TNC server enabled + TNC_Utils::sendToClients(packet); // Send received packet to TNC KISS + } + + if (Config.tnc.enableSerial) { // If Serial KISS enabled + TNC_Utils::sendToSerial(packet); // Send received packet to Serial KISS + } } show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0); diff --git a/src/aprs_is_utils.cpp b/src/aprs_is_utils.cpp index 7e82a49..51e3383 100644 --- a/src/aprs_is_utils.cpp +++ b/src/aprs_is_utils.cpp @@ -28,7 +28,7 @@ namespace APRS_IS_Utils { espClient.print(line + "\r\n"); } - void connect(){ + void connect() { int count = 0; String aprsauth; Serial.print("Connecting to APRS-IS ... "); @@ -44,8 +44,9 @@ namespace APRS_IS_Utils { } if (count == 20) { Serial.println("Tried: " + String(count) + " FAILED!"); - } else { - Serial.println("Connected!\n(Server: " + String(Config.aprs_is.server) + " / Port: " + String(Config.aprs_is.port) +")"); + } + else { + Serial.println("Connected!\n(Server: " + String(Config.aprs_is.server) + " / Port: " + String(Config.aprs_is.port) + ")"); // String filter = "t/m/" + Config.callsign + "/" + (String)Config.aprs_is.reportingDistance; @@ -58,8 +59,9 @@ namespace APRS_IS_Utils { void checkStatus() { String wifiState, aprsisState; if (WiFi.status() == WL_CONNECTED) { - wifiState = "OK"; - } else { + wifiState = "OK"; + } + else { wifiState = "AP"; if (!Config.display.alwaysOn) { @@ -70,10 +72,12 @@ namespace APRS_IS_Utils { } if (!Config.aprs_is.active) { - aprsisState = "OFF"; - } else if (espClient.connected()) { - aprsisState = "OK"; - } else { + aprsisState = "OFF"; + } + else if (espClient.connected()) { + aprsisState = "OK"; + } + else { aprsisState = "--"; if (!Config.display.alwaysOn) { @@ -89,25 +93,27 @@ namespace APRS_IS_Utils { String createPacket(String packet) { if (!(Config.aprs_is.active && Config.digi.mode == 0)) { // Check if NOT only IGate return packet.substring(3, packet.indexOf(":")) + ",qAR," + Config.callsign + packet.substring(packet.indexOf(":")); - } else { + } + else { return packet.substring(3, packet.indexOf(":")) + ",qAO," + Config.callsign + packet.substring(packet.indexOf(":")); } } bool processReceivedLoRaMessage(String sender, String packet) { String ackMessage, receivedMessage; - if (packet.indexOf("{")>0) { // ack? - ackMessage = "ack" + packet.substring(packet.indexOf("{")+1); + if (packet.indexOf("{") > 0) { // ack? + ackMessage = "ack" + packet.substring(packet.indexOf("{") + 1); ackMessage.trim(); delay(4000); //Serial.println(ackMessage); - for(int i = sender.length(); i < 9; i++) { + for (int i = sender.length(); i < 9; i++) { sender += ' '; } LoRa_Utils::sendNewPacket("APRS", Config.callsign + ">APLRG1,RFONLY,WIDE1-1::" + sender + ":" + ackMessage); - receivedMessage = packet.substring(packet.indexOf(":")+1, packet.indexOf("{")); - } else { - receivedMessage = packet.substring(packet.indexOf(":")+1); + receivedMessage = packet.substring(packet.indexOf(":") + 1, packet.indexOf("{")); + } + else { + receivedMessage = packet.substring(packet.indexOf(":") + 1); } if (receivedMessage.indexOf("?") == 0) { delay(2000); @@ -116,9 +122,10 @@ namespace APRS_IS_Utils { } LoRa_Utils::sendNewPacket("APRS", QUERY_Utils::process(receivedMessage, sender, "LoRa")); lastScreenOn = millis(); - show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, "Callsign = " + sender, "TYPE --> QUERY", 0); + show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, "Callsign = " + sender, "TYPE --> QUERY", 0); return true; - } else { + } + else { return false; } } @@ -127,24 +134,16 @@ namespace APRS_IS_Utils { bool queryMessage = false; String aprsPacket, Sender, AddresseeAndMessage, Addressee; if (packet != "") { - #ifdef TextSerialOutputForApp - Serial.println(packet.substring(3)); - #else - Serial.print("Received Lora Packet : " + String(packet)); - #endif - if ((packet.substring(0,3) == "\x3c\xff\x01") && (packet.indexOf("TCPIP") == -1) && (packet.indexOf("NOGATE") == -1) && (packet.indexOf("RFONLY") == -1)) { - #ifndef TextSerialOutputForApp - Serial.print(" ---> APRS LoRa Packet!"); - #endif - Sender = packet.substring(3,packet.indexOf(">")); + if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("TCPIP") == -1) && (packet.indexOf("NOGATE") == -1) && (packet.indexOf("RFONLY") == -1)) { + Sender = packet.substring(3, packet.indexOf(">")); STATION_Utils::updateLastHeard(Sender); //STATION_Utils::updatePacketBuffer(packet); Utils::typeOfPacket(aprsPacket, "LoRa-APRS"); if (Sender != Config.callsign) { // avoid listening yourself by digirepeating - AddresseeAndMessage = packet.substring(packet.indexOf("::")+2); - Addressee = AddresseeAndMessage.substring(0,AddresseeAndMessage.indexOf(":")); + AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2); + Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":")); Addressee.trim(); - + if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me! queryMessage = processReceivedLoRaMessage(Sender, AddresseeAndMessage); } @@ -155,47 +154,41 @@ namespace APRS_IS_Utils { } lastScreenOn = millis(); upload(aprsPacket); - #ifndef TextSerialOutputForApp - Serial.println(" ---> Uploaded to APRS-IS"); - #endif + Utils::println("---> Uploaded to APRS-IS"); + STATION_Utils::updateLastHeard(Sender); + Utils::typeOfPacket(aprsPacket, "LoRa-APRS"); show_display(firstLine, secondLine, thirdLine, fourthLine, fifthLine, sixthLine, seventhLine, 0); } - } - } else { - #ifndef TextSerialOutputForApp - Serial.println(" ---> LoRa Packet Ignored (first 3 bytes or TCPIP/NOGATE/RFONLY)\n"); - #endif + } } } } void processAPRSISPacket(String packet) { String Sender, AddresseeAndMessage, Addressee, receivedMessage; - if (!packet.startsWith("#")){ - if (packet.indexOf("::")>0) { - Sender = packet.substring(0,packet.indexOf(">")); - AddresseeAndMessage = packet.substring(packet.indexOf("::")+2); + if (!packet.startsWith("#")) { + if (packet.indexOf("::") > 0) { + Sender = packet.substring(0, packet.indexOf(">")); + AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2); Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":")); Addressee.trim(); if (Addressee == Config.callsign) { // its for me! - if (AddresseeAndMessage.indexOf("{")>0) { // ack? - String ackMessage = "ack" + AddresseeAndMessage.substring(AddresseeAndMessage.indexOf("{")+1); + if (AddresseeAndMessage.indexOf("{") > 0) { // ack? + String ackMessage = "ack" + AddresseeAndMessage.substring(AddresseeAndMessage.indexOf("{") + 1); ackMessage.trim(); delay(4000); - //Serial.println(ackMessage); - for(int i = Sender.length(); i < 9; i++) { + for (int i = Sender.length(); i < 9; i++) { Sender += ' '; } String ackPacket = Config.callsign + ">APLRG1,TCPIP,qAC::" + Sender + ":" + ackMessage;// + "\n"; upload(ackPacket); - receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":")+1, AddresseeAndMessage.indexOf("{")); - } else { - receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":")+1); + receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1, AddresseeAndMessage.indexOf("{")); + } + else { + receivedMessage = AddresseeAndMessage.substring(AddresseeAndMessage.indexOf(":") + 1); } if (receivedMessage.indexOf("?") == 0) { - #ifndef TextSerialOutputForApp - Serial.println("Received Query APRS-IS : " + packet); - #endif + Utils::println("Received Query APRS-IS : " + packet); String queryAnswer = QUERY_Utils::process(receivedMessage, Sender, "APRSIS"); //Serial.println("---> QUERY Answer : " + queryAnswer.substring(0,queryAnswer.indexOf("\n"))); if (!Config.display.alwaysOn) { @@ -204,19 +197,18 @@ namespace APRS_IS_Utils { lastScreenOn = millis(); delay(500); upload(queryAnswer); - SYSLOG_Utils::log("APRSIS Tx", queryAnswer,0,0,0); + SYSLOG_Utils::log("APRSIS Tx", queryAnswer, 0, 0, 0); fifthLine = "APRS-IS ----> APRS-IS"; sixthLine = Config.callsign; - for (int j=sixthLine.length();j<9;j++) { + for (int j = sixthLine.length();j < 9;j++) { sixthLine += " "; } sixthLine += "> " + Sender; seventhLine = "QUERY = " + receivedMessage; } - } else { - #ifndef TextSerialOutputForApp - Serial.print("Received from APRS-IS : " + packet); - #endif + } + else { + Utils::print("Received from APRS-IS : " + packet); if (Config.aprs_is.toRF && STATION_Utils::wasHeard(Addressee)) { LoRa_Utils::sendNewPacket("APRS", LoRa_Utils::generatePacket(packet)); diff --git a/src/aprs_is_utils.h b/src/aprs_is_utils.h index b18c385..c21f19b 100644 --- a/src/aprs_is_utils.h +++ b/src/aprs_is_utils.h @@ -4,13 +4,6 @@ #include -//#define TextSerialOutputForApp -/* uncomment the previous line to get text from Serial-Output over USB into PC for: - - PinPoint App ( https://www.pinpointaprs.com ) - - APRSIS32 App ( http://aprsisce.wikidot.com ) -*/ - - namespace APRS_IS_Utils { void upload(String line); diff --git a/src/configuration.cpp b/src/configuration.cpp index 8bcbad2..ee4597e 100644 --- a/src/configuration.cpp +++ b/src/configuration.cpp @@ -48,6 +48,10 @@ void Configuration::writeFile() { // data["digi"]["latitude"] = digi.latitude; // data["digi"]["longitude"] = digi.longitude; + data["tnc"]["enableServer"] = tnc.enableServer; + data["tnc"]["enableSerial"] = tnc.enableSerial; + data["tnc"]["acceptOwn"] = tnc.acceptOwn; + data["aprs_is"]["active"] = aprs_is.active; data["aprs_is"]["passcode"] = aprs_is.passcode; data["aprs_is"]["server"] = aprs_is.server; @@ -152,6 +156,10 @@ bool Configuration::readFile() { ota.username = data["ota"]["username"].as(); ota.password = data["ota"]["password"].as(); + tnc.enableServer = data["tnc"]["enableServer"].as(); + tnc.enableSerial = data["tnc"]["enableSerial"].as(); + tnc.acceptOwn = data["tnc"]["acceptOwn"].as(); + int stationMode = data["stationMode"].as(); // deprecated but need to specify config version if (stationMode == 0) { @@ -279,6 +287,10 @@ void Configuration::init() { // digi.latitude = 0.0; // deprecated // digi.longitude = 0.0; // deprecated + tnc.enableServer = false; + tnc.enableSerial = false; + tnc.acceptOwn = false; + aprs_is.active = false; // new aprs_is.passcode = "XYZVW"; aprs_is.server = "rotate.aprs2.net"; diff --git a/src/configuration.h b/src/configuration.h index 4b2d138..8507c9f 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -73,6 +73,13 @@ public: bool turn180; }; +class TNC { +public: + bool enableServer; + bool enableSerial; + bool acceptOwn; +}; + class SYSLOG { public: bool active; @@ -111,6 +118,7 @@ public: WiFi_Auto_AP wifiAutoAP; Beacon beacon; // new DIGI digi; + TNC tnc; // new APRS_IS aprs_is; LoraModule loramodule; Display display; diff --git a/src/digi_utils.cpp b/src/digi_utils.cpp index 2a4edbd..0fc3459 100644 --- a/src/digi_utils.cpp +++ b/src/digi_utils.cpp @@ -26,28 +26,32 @@ namespace DIGI_Utils { String generateDigiRepeatedPacket(String packet, String callsign) { String sender, temp0, tocall, path; - sender = packet.substring(0,packet.indexOf(">")); - temp0 = packet.substring(packet.indexOf(">")+1,packet.indexOf(":")); + sender = packet.substring(0, packet.indexOf(">")); + temp0 = packet.substring(packet.indexOf(">") + 1, packet.indexOf(":")); if (temp0.indexOf(",") > 2) { - tocall = temp0.substring(0,temp0.indexOf(",")); - path = temp0.substring(temp0.indexOf(",")+1,temp0.indexOf(":")); - if (path.indexOf("WIDE1-")>=0) { - String hop = path.substring(path.indexOf("WIDE1-")+6, path.indexOf("WIDE1-")+7); - if (hop.toInt()>=1 && hop.toInt()<=7) { - if (hop.toInt()==1) { + tocall = temp0.substring(0, temp0.indexOf(",")); + path = temp0.substring(temp0.indexOf(",") + 1, temp0.indexOf(":")); + if (path.indexOf("WIDE1-") >= 0) { + String hop = path.substring(path.indexOf("WIDE1-") + 6, path.indexOf("WIDE1-") + 7); + if (hop.toInt() >= 1 && hop.toInt() <= 7) { + if (hop.toInt() == 1) { path.replace("WIDE1-1", callsign + "*"); - } else { - path.replace("WIDE1-" + hop , callsign + "*,WIDE1-" + String(hop.toInt()-1)); + } + else { + path.replace("WIDE1-" + hop, callsign + "*,WIDE1-" + String(hop.toInt() - 1)); } String repeatedPacket = sender + ">" + tocall + "," + path + packet.substring(packet.indexOf(":")); return repeatedPacket; - } else { + } + else { return ""; } - } else { + } + else { return ""; } - } else { + } + else { return ""; } } @@ -56,34 +60,29 @@ namespace DIGI_Utils { bool queryMessage = false; String loraPacket, Sender, AddresseeAndMessage, Addressee; if (packet != "") { - Serial.print("Received Lora Packet : " + String(packet)); - if (packet.substring(0, 3) == "\x3c\xff\x01") { - Serial.println(" ---> APRS LoRa Packet"); - Sender = packet.substring(3,packet.indexOf(">")); + if ((packet.substring(0, 3) == "\x3c\xff\x01") && (packet.indexOf("NOGATE") == -1)) { if (Sender != Config.callsign) { - STATION_Utils::updateLastHeard(Sender); - //STATION_Utils::updatePacketBuffer(packet); + String sender = packet.substring(3, packet.indexOf(">")); + STATION_Utils::updateLastHeard(sender); + // STATION_Utils::updatePacketBuffer(packet); Utils::typeOfPacket(packet.substring(3), "Digi"); - AddresseeAndMessage = packet.substring(packet.indexOf("::")+2); - Addressee = AddresseeAndMessage.substring(0,AddresseeAndMessage.indexOf(":")); + AddresseeAndMessage = packet.substring(packet.indexOf("::") + 2); + Addressee = AddresseeAndMessage.substring(0, AddresseeAndMessage.indexOf(":")); Addressee.trim(); if (packet.indexOf("::") > 10 && Addressee == Config.callsign) { // its a message for me! - queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender,AddresseeAndMessage); + queryMessage = APRS_IS_Utils::processReceivedLoRaMessage(Sender, AddresseeAndMessage); } if (!queryMessage && packet.indexOf("WIDE1-") > 10 && Config.digi.mode == 2) { // If should repeat packet (WIDE1 Digi) loraPacket = generateDigiRepeatedPacket(packet.substring(3), Config.callsign); if (loraPacket != "") { delay(500); - Serial.println(loraPacket); LoRa_Utils::sendNewPacket("APRS", loraPacket); display_toggle(true); lastScreenOn = millis(); } - } - } - } /*else { - Serial.println(" ---> LoRa Packet Ignored (first 3 bytes or NOGATE)\n"); - }*/ + } + } + } } } diff --git a/src/gps_utils.cpp b/src/gps_utils.cpp index 9fd2d53..0381c2d 100644 --- a/src/gps_utils.cpp +++ b/src/gps_utils.cpp @@ -35,7 +35,6 @@ namespace GPS_Utils { if (abs(degrees.toFloat()) < 10) { latitude += "0"; } - Serial.println(latitude); if (degrees.indexOf("-") == 0) { north_south = "S"; latitude += degrees.substring(1,degrees.indexOf(".")); diff --git a/src/lora_utils.cpp b/src/lora_utils.cpp index d36d5e8..8030f8b 100644 --- a/src/lora_utils.cpp +++ b/src/lora_utils.cpp @@ -6,6 +6,7 @@ #include "syslog_utils.h" #include "pins_config.h" #include "display.h" +#include "utils.h" extern Configuration Config; @@ -27,13 +28,13 @@ float snr; namespace LoRa_Utils { void setFlag(void) { - #ifdef HAS_SX126X +#ifdef HAS_SX126X transmissionFlag = true; - #endif +#endif } void setup() { - #ifdef HAS_SX127X +#ifdef HAS_SX127X SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS); LoRa.setPins(LORA_CS, LORA_RST, LORA_IRQ); long freq = Config.loramodule.rxFreq; @@ -50,16 +51,17 @@ namespace LoRa_Utils { LoRa.enableCrc(); LoRa.setTxPower(Config.loramodule.power); Serial.print("init : LoRa Module ... done!"); - #endif - #ifdef HAS_SX126X +#endif +#ifdef HAS_SX126X SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN); - float freq = (float)Config.loramodule.rxFreq/1000000; + float freq = (float)Config.loramodule.rxFreq / 1000000; int state = radio.begin(freq); if (state == RADIOLIB_ERR_NONE) { Serial.print("Initializing SX126X LoRa Module"); - } else { + } + else { Serial.println("Starting LoRa failed!"); - while (true); + while (true); } radio.setDio1Action(setFlag); radio.setSpreadingFactor(Config.loramodule.spreadingFactor); @@ -67,87 +69,93 @@ namespace LoRa_Utils { radio.setBandwidth(signalBandwidth); radio.setCodingRate(Config.loramodule.codingRate4); radio.setCRC(true); - #if defined(ESP32_DIY_1W_LoRa) +#if defined(ESP32_DIY_1W_LoRa) radio.setRfSwitchPins(RADIO_RXEN, RADIO_TXEN); - #endif - #if defined(HELTEC_V3) || defined(HELTEC_WS) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262) +#endif +#if defined(HELTEC_V3) || defined(HELTEC_WS) || defined(TTGO_T_Beam_V1_0_SX1268) || defined(TTGO_T_Beam_V1_2_SX1262) state = radio.setOutputPower(Config.loramodule.power + 2); // values available: 10, 17, 22 --> if 20 in tracker_conf.json it will be updated to 22. - #endif - #ifdef ESP32_DIY_1W_LoRa_GPS +#endif +#ifdef ESP32_DIY_1W_LoRa_GPS state = radio.setOutputPower(Config.loramodule.power); // max value 20 (when 20dB in setup 30dB in output as 400M30S has Low Noise Amp) - #endif +#endif if (state == RADIOLIB_ERR_NONE) { Serial.println("init : LoRa Module ... done!"); - } else { + } + else { Serial.println("Starting LoRa failed!"); while (true); } - #endif +#endif } void changeFreqTx() { delay(500); - #ifdef HAS_SX127X +#ifdef HAS_SX127X LoRa.setFrequency(Config.loramodule.txFreq); - #endif - #ifdef HAS_SX126X - float freq = (float)Config.loramodule.txFreq/1000000; +#endif +#ifdef HAS_SX126X + float freq = (float)Config.loramodule.txFreq / 1000000; radio.setFrequency(freq); - #endif +#endif } void changeFreqRx() { delay(500); - #ifdef HAS_SX127X +#ifdef HAS_SX127X LoRa.setFrequency(Config.loramodule.rxFreq); - #endif - #ifdef HAS_SX126X - float freq = (float)Config.loramodule.rxFreq/1000000; +#endif +#ifdef HAS_SX126X + float freq = (float)Config.loramodule.rxFreq / 1000000; radio.setFrequency(freq); - #endif +#endif } - - void sendNewPacket(const String &typeOfMessage, const String &newPacket) { + + void sendNewPacket(const String& typeOfMessage, const String& newPacket) { if (!Config.loramodule.txActive) return; if (Config.loramodule.txFreq != Config.loramodule.rxFreq) { - changeFreqTx(); + changeFreqTx(); } - #ifdef HAS_INTERNAL_LED - digitalWrite(internalLedPin,HIGH); - #endif - #ifdef HAS_SX127X +#ifdef HAS_INTERNAL_LED + digitalWrite(internalLedPin, HIGH); +#endif +#ifdef HAS_SX127X LoRa.beginPacket(); LoRa.write('<'); - if (typeOfMessage == "APRS") { + if (typeOfMessage == "APRS") { LoRa.write(0xFF); - } else if (typeOfMessage == "LoRa") { + } + else if (typeOfMessage == "LoRa") { LoRa.write(0xF8); } LoRa.write(0x01); - LoRa.write((const uint8_t *)newPacket.c_str(), newPacket.length()); + LoRa.write((const uint8_t*)newPacket.c_str(), newPacket.length()); LoRa.endPacket(); - #endif - #ifdef HAS_SX126X +#endif +#ifdef HAS_SX126X int state = radio.transmit("\x3c\xff\x01" + newPacket); if (state == RADIOLIB_ERR_NONE) { //Serial.println(F("success!")); - } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { + } + else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { Serial.println(F("too long!")); - } else if (state == RADIOLIB_ERR_TX_TIMEOUT) { + } + else if (state == RADIOLIB_ERR_TX_TIMEOUT) { Serial.println(F("timeout!")); - } else { + } + else { Serial.print(F("failed, code ")); Serial.println(state); } - #endif - #ifdef HAS_INTERNAL_LED - digitalWrite(internalLedPin,LOW); - #endif - SYSLOG_Utils::log("Tx", newPacket,0,0,0); - Serial.print("---> LoRa Packet Tx : "); - Serial.println(newPacket); +#endif +#ifdef HAS_INTERNAL_LED + digitalWrite(internalLedPin, LOW); +#endif + SYSLOG_Utils::log("Tx", newPacket, 0, 0, 0); + + Utils::print("---> LoRa Packet Tx : "); + Utils::println(newPacket); if (Config.loramodule.txFreq != Config.loramodule.rxFreq) { changeFreqRx(); @@ -158,71 +166,69 @@ namespace LoRa_Utils { String firstPart, messagePart; aprsisPacket.trim(); firstPart = aprsisPacket.substring(0, aprsisPacket.indexOf(",")); - messagePart = aprsisPacket.substring(aprsisPacket.indexOf("::")+2); + messagePart = aprsisPacket.substring(aprsisPacket.indexOf("::") + 2); return firstPart + ",TCPIP,WIDE1-1," + Config.callsign + "::" + messagePart; } String packetSanitization(String packet) { - //Serial.println(packet); - if (packet.indexOf("\0")>0) { - packet.replace("\0",""); + if (packet.indexOf("\0") > 0) { + packet.replace("\0", ""); } - if (packet.indexOf("\r")>0) { - packet.replace("\r",""); + if (packet.indexOf("\r") > 0) { + packet.replace("\r", ""); } - if (packet.indexOf("\n")>0) { - packet.replace("\n",""); + if (packet.indexOf("\n") > 0) { + packet.replace("\n", ""); } return packet; } String receivePacket() { String loraPacket = ""; - #ifdef HAS_SX127X +#ifdef HAS_SX127X int packetSize = LoRa.parsePacket(); if (packetSize) { while (LoRa.available()) { int inChar = LoRa.read(); loraPacket += (char)inChar; } - rssi = LoRa.packetRssi(); - snr = LoRa.packetSnr(); + rssi = LoRa.packetRssi(); + snr = LoRa.packetSnr(); freqError = LoRa.packetFrequencyError(); } - #endif - #ifdef HAS_SX126X +#endif +#ifdef HAS_SX126X if (transmissionFlag) { transmissionFlag = false; radio.startReceive(); int state = radio.readData(loraPacket); if (state == RADIOLIB_ERR_NONE) { - if(!loraPacket.isEmpty()) { - Serial.println("LoRa Rx ---> " + loraPacket); - } - rssi = radio.getRSSI(); - snr = radio.getSNR(); + rssi = radio.getRSSI(); + snr = radio.getSNR(); freqError = radio.getFrequencyError(); - } else if (state == RADIOLIB_ERR_RX_TIMEOUT) { + } + else if (state == RADIOLIB_ERR_RX_TIMEOUT) { // timeout occurred while waiting for a packet - } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { + } + else if (state == RADIOLIB_ERR_CRC_MISMATCH) { Serial.println(F("CRC error!")); - } else { + } + else { Serial.print(F("failed, code ")); Serial.println(state); } } - #endif +#endif - if ((loraPacket.indexOf("\0")!=-1) || (loraPacket.indexOf("\r")!=-1) || (loraPacket.indexOf("\n")!=-1)) { + if ((loraPacket.indexOf("\0") != -1) || (loraPacket.indexOf("\r") != -1) || (loraPacket.indexOf("\n") != -1)) { loraPacket = packetSanitization(loraPacket); } - #ifndef TextSerialOutputForApp - if (loraPacket!="") { - Serial.println("(RSSI:" +String(rssi) + " / SNR:" + String(snr) + " / FreqErr:" + String(freqError) + ")"); + if (loraPacket != "") { + Utils::println("<--- LoRa Packet Rx : " + loraPacket); + Utils::println("(RSSI:" + String(rssi) + " / SNR:" + String(snr) + " / FreqErr:" + String(freqError) + ")"); } - #endif - + if (Config.syslog.active && WiFi.status() == WL_CONNECTED && loraPacket != "") { SYSLOG_Utils::log("Rx", loraPacket, rssi, snr, freqError); } diff --git a/src/station_utils.cpp b/src/station_utils.cpp index 246990d..2319f77 100644 --- a/src/station_utils.cpp +++ b/src/station_utils.cpp @@ -1,6 +1,7 @@ #include "station_utils.h" #include "aprs_is_utils.h" #include "configuration.h" +#include "utils.h" #include extern Configuration Config; @@ -14,15 +15,15 @@ extern String fourthLine; namespace STATION_Utils { void deleteNotHeard() { - for (int i=0; i Listened Station"); + for (int i = 0; i < lastHeardStation.size(); i++) { + if (lastHeardStation[i].substring(0, lastHeardStation[i].indexOf(",")) == station) { + Utils::println(" ---> Listened Station"); return true; - } + } } - Serial.println(" ---> Station not Heard for last 30 min (Not Tx)\n"); + Utils::println(" ---> Station not Heard for last 30 min (Not Tx)\n"); return false; } void checkBuffer() { - for (int i=0; i") == -1) && (packet.indexOf(":`") == -1)) { - String sender = packet.substring(3,packet.indexOf(">")); + String sender = packet.substring(3, packet.indexOf(">")); String tempAddressee = packet.substring(packet.indexOf("::") + 2); - String addressee = tempAddressee.substring(0,tempAddressee.indexOf(":")); + String addressee = tempAddressee.substring(0, tempAddressee.indexOf(":")); addressee.trim(); - String message = tempAddressee.substring(tempAddressee.indexOf(":")+1); + String message = tempAddressee.substring(tempAddressee.indexOf(":") + 1); //Serial.println(String(millis()) + "," + sender + "," + addressee + "," + message); packetBuffer.push_back(String(millis()) + "," + sender + "," + addressee + "," + message); checkBuffer(); diff --git a/src/tnc_utils.cpp b/src/tnc_utils.cpp index 0798059..a5f91ee 100644 --- a/src/tnc_utils.cpp +++ b/src/tnc_utils.cpp @@ -2,9 +2,13 @@ #include "kiss_utils.h" #include "kiss_protocol.h" #include "lora_utils.h" +#include "configuration.h" +#include "utils.h" + +extern Configuration Config; #define MAX_CLIENTS 4 -#define INPUT_TNC_BUFFER_SIZE (2 + MAX_CLIENTS) +#define INPUT_BUFFER_SIZE (2 + MAX_CLIENTS) #define TNC_PORT 8001 @@ -12,12 +16,15 @@ WiFiClient* clients[MAX_CLIENTS]; WiFiServer tncServer(TNC_PORT); -String inputBuffer[INPUT_TNC_BUFFER_SIZE]; +String inputServerBuffer[INPUT_BUFFER_SIZE]; +String inputSerialBuffer = ""; namespace TNC_Utils { void setup() { - tncServer.stop(); - tncServer.begin(); + if (Config.tnc.enableServer) { + tncServer.stop(); + tncServer.begin(); + } } void checkNewClients() { @@ -30,7 +37,7 @@ namespace TNC_Utils { if (client == nullptr) { clients[i] = new WiFiClient(new_client); - Serial.println("New TNC client connected"); + Utils::println("New TNC client connected"); break; } @@ -38,8 +45,8 @@ namespace TNC_Utils { } } - void handleInputData(char character, int bufferIndex) { - String* inTNCData = &inputBuffer[bufferIndex]; + void handleServerInputData(char character, int bufferIndex) { + String* inTNCData = &inputServerBuffer[bufferIndex]; if (inTNCData->length() == 0 && character != (char)FEND) { return; @@ -52,10 +59,16 @@ namespace TNC_Utils { const String& frame = decodeKISS(*inTNCData, isDataFrame); if (isDataFrame) { - Serial.print("---> Got from TNC : "); - Serial.println(frame); + Utils::print("<--- Got from TNC : "); + Utils::println(frame); - LoRa_Utils::sendNewPacket("APRS", frame); + String sender = frame.substring(0,frame.indexOf(">")); + + if (Config.tnc.acceptOwn || sender != Config.callsign) { + LoRa_Utils::sendNewPacket("APRS", frame); + } else { + Utils::println("Ignored own frame from TNC"); + } } inTNCData->clear(); @@ -66,6 +79,33 @@ namespace TNC_Utils { } } + void handleSerialInputData(char character) { + if (inputSerialBuffer.length() == 0 && character != (char)FEND) { + return; + } + + inputSerialBuffer.concat(character); + + if (character == (char)FEND && inputSerialBuffer.length() > 3) { + bool isDataFrame = false; + const String& frame = decodeKISS(inputSerialBuffer, isDataFrame); + + if (isDataFrame) { + String sender = frame.substring(0,frame.indexOf(">")); + + if (Config.tnc.acceptOwn || sender != Config.callsign) { + LoRa_Utils::sendNewPacket("APRS", frame); + } + } + + inputSerialBuffer.clear(); + } + + if (inputSerialBuffer.length() > 255) { + inputSerialBuffer.clear(); + } + } + void readFromClients() { for (int i = 0; i < MAX_CLIENTS; i++) { auto client = clients[i]; @@ -73,7 +113,7 @@ namespace TNC_Utils { if (client->connected()) { while (client->available() > 0) { char character = client->read(); - handleInputData(character, 2 + i); + handleServerInputData(character, 2 + i); } } else { delete client; @@ -83,6 +123,13 @@ namespace TNC_Utils { } } + void readFromSerial() { + while (Serial.available() > 0) { + char character = Serial.read(); + handleSerialInputData(character); + } + } + void sendToClients(String packet) { packet = packet.substring(3); @@ -101,13 +148,26 @@ namespace TNC_Utils { } } - Serial.print("---> Sent to TNC : "); - Serial.println(packet); + Utils::print("---> Sent to TNC : "); + Utils::println(packet); + } + + void sendToSerial(String packet) { + packet = packet.substring(3); + + Serial.print(encodeKISS(packet)); + Serial.flush(); } void loop() { - checkNewClients(); + if (Config.tnc.enableServer) { + checkNewClients(); - readFromClients(); + readFromClients(); + } + + if (Config.tnc.enableSerial) { + readFromSerial(); + } } } \ No newline at end of file diff --git a/src/tnc_utils.h b/src/tnc_utils.h index 8464a9a..3b4b0b2 100644 --- a/src/tnc_utils.h +++ b/src/tnc_utils.h @@ -9,6 +9,7 @@ namespace TNC_Utils { void loop(); void sendToClients(String packet); + void sendToSerial(String packet); } diff --git a/src/utils.cpp b/src/utils.cpp index 8783baa..7aecffc 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -99,7 +99,9 @@ namespace Utils { if (beaconUpdate) { display_toggle(true); - Serial.println("-- Sending Beacon to APRSIS --"); + + Utils::println("-- Sending Beacon to APRSIS --"); + STATION_Utils::deleteNotHeard(); activeStations(); @@ -232,4 +234,16 @@ namespace Utils { } } + void print(String text) { + if (!Config.tnc.enableSerial) { + Serial.print(text); + } + } + + void println(String text) { + if (!Config.tnc.enableSerial) { + Serial.println(text); + } + } + } \ No newline at end of file diff --git a/src/utils.h b/src/utils.h index adbc609..ad741f2 100644 --- a/src/utils.h +++ b/src/utils.h @@ -15,9 +15,8 @@ namespace Utils { void checkWiFiInterval(); void validateFreqs(); void typeOfPacket(String packet, String packetType); - void onOTAStart(); - void onOTAProgress(size_t current, size_t final); - void onOTAEnd(bool success); + void print(String text); + void println(String text); } diff --git a/src/web_utils.cpp b/src/web_utils.cpp index a299b57..4b3fae6 100644 --- a/src/web_utils.cpp +++ b/src/web_utils.cpp @@ -84,6 +84,10 @@ namespace WEB_Utils { // Config.digi.latitude = request->getParam("digi.latitude", true)->value().toDouble(); // Config.digi.longitude = request->getParam("digi.longitude", true)->value().toDouble(); + Config.tnc.enableServer = request->hasParam("tnc.enableServer", true); + Config.tnc.enableSerial = request->hasParam("tnc.enableSerial", true); + Config.tnc.acceptOwn = request->hasParam("tnc.acceptOwn", true); + Config.aprs_is.active = request->hasParam("aprs_is.active", true); Config.aprs_is.passcode = request->getParam("aprs_is.passcode", true)->value(); Config.aprs_is.server = request->getParam("aprs_is.server", true)->value();