diff --git a/pocsag-transmit-test/platformio.ini b/pocsag-transmit-test/platformio.ini index 8ce6ab8..271066a 100644 --- a/pocsag-transmit-test/platformio.ini +++ b/pocsag-transmit-test/platformio.ini @@ -13,5 +13,6 @@ platform = espressif32 board = ttgo-t-beam framework = arduino lib_deps = jgromes/RadioLib@^4.3.0 + m5ez/ezTime@^0.8.3 monitor_speed = 115200 -upload_speed = 115200 \ No newline at end of file +upload_speed = 921600 \ No newline at end of file diff --git a/pocsag-transmit-test/src/dapnetv1_client.cpp b/pocsag-transmit-test/src/dapnetv1_client.cpp new file mode 100644 index 0000000..985347c --- /dev/null +++ b/pocsag-transmit-test/src/dapnetv1_client.cpp @@ -0,0 +1,110 @@ +#include "dapnetv1_client.h" + +char _dapnetRICSubstring[10]; +uint16_t dapnetQueueLength; +static DAPNETMessage dapnetQueue[DAPNET_QUEUE_MAX]; +DAPNETV1Client::DAPNETV1Client(WiFiClient* client) { + _client = client; + lastMsgAck = 0x00; + dapnetQueueLength = 0; + for (int i=0;i<16;i++) timeSlot[i] = false; +} + +void DAPNETV1Client::begin() { + if (_client->connect("10.13.0.180", 43434)) { + Serial.println("Connected to DAPNET"); + _client->println("[ESP32LoraPager v1.0.0 xx1337 123]"); + } + +} +void DAPNETV1Client::sendAck() { + _client->println(F("+")); + _client->flush(); +} +void DAPNETV1Client::loop() { + if (_client->connected()) { + if (_client->available()) { + String line = _client->readStringUntil('\n'); + DAPNET_DEBUG_PRINT(F("DAPNET>")); DAPNET_DEBUG_PRINTLN(line); + DAPNET_DEBUG_PRINTLN(line[0], HEX); + switch (line[0]) { + case 0x32: // "timesync" + DAPNET_DEBUG_PRINTLN("timesync"); + DAPNET_DEBUG_PRINTLN(String(" <") + line + F(":0000")); + _client->println(line + F(":0000")); + sendAck(); + break; + case 0x33:// "timeset" + sendAck(); + break; + case 0x34: // "timeslot" + for (int i = 2; i < line.length(); i++) { + uint8_t timeSlotIndex = line.charAt(i); + // very rudimentary single hex char to number parser + timeSlotIndex = timeSlotIndex > 57 ? timeSlotIndex - 55 : timeSlotIndex - 48; + timeSlot[ timeSlotIndex ] = true; + } + #ifdef DAPNET_DEBUG + DAPNET_DEBUG_PRINT("TimeslotConfig: "); for (int i=0;i<16;i++) DAPNET_DEBUG_PRINT(timeSlot[i] ? 49 : 48, 0); DAPNET_DEBUG_PRINTLN(); + #endif + sendAck(); + break; + case 0x23: // Message + if (line[4] == 0x36 && line[6] == 0x31) { // type msg &speed is 1200baud + //DAPNET_DEBUG_PRINTLN(F("going to indexOf")); + uint8_t endOfRICLoc = line.indexOf(0x3A, 8); + uint8_t beforeStringLoc = line.lastIndexOf(0x3A) + 1; + uint8_t lineLength = line.length(); + dapnetQueue[ dapnetQueueLength ].length = lineLength - beforeStringLoc; + + //DAPNET_DEBUG_PRINT(F("endOfRICLoc:")); DAPNET_DEBUG_PRINTLN(endOfRICLoc); + for (int j = 0; j < 10; j++) _dapnetRICSubstring[j] = j + 8 < endOfRICLoc ? line[ j + 8 ] : 0x00; + //DAPNET_DEBUG_PRINT(F("_dapnetRICSubstring:")); DAPNET_DEBUG_PRINTLN(_dapnetRICSubstring); + dapnetQueue[ dapnetQueueLength ].ric = strtol(_dapnetRICSubstring, 0, 16); + dapnetQueue[ dapnetQueueLength ].function = line[ endOfRICLoc + 1 ] - 0x30; + for (int j = 0; j < 80; j++) dapnetQueue[ dapnetQueueLength ].message[ j ] = 0x00; + for (int j = 0; j < dapnetQueue[ dapnetQueueLength ].length; j++) dapnetQueue[ dapnetQueueLength ].message[ j ] = line[ beforeStringLoc + j ]; + + DAPNET_DEBUG_PRINT(F("RIC:")); DAPNET_DEBUG_PRINTLN(dapnetQueue[ dapnetQueueLength ].ric); + DAPNET_DEBUG_PRINT(F("FNC:")); DAPNET_DEBUG_PRINTLN(dapnetQueue[ dapnetQueueLength ].function); + DAPNET_DEBUG_PRINT(F("LEN:")); DAPNET_DEBUG_PRINTLN(dapnetQueue[ dapnetQueueLength ].length); + DAPNET_DEBUG_PRINT(F("TXT:")); DAPNET_DEBUG_PRINTLN(dapnetQueue[ dapnetQueueLength ].message); + + dapnetQueueLength++; + } + //msgAck + _client->print(0x23, 0); + DAPNET_DEBUG_PRINT(0x23, 0); + lastMsgAck = hex2c(line[1], line[2]); + lastMsgAck++; + if (lastMsgAck < 0x10) { + _client->print(0x30, 0); + DAPNET_DEBUG_PRINT(0x30, 0); + } + _client->print(lastMsgAck, HEX); + DAPNET_DEBUG_PRINT(lastMsgAck, HEX); + _client->print(0x20, 0); + DAPNET_DEBUG_PRINT(0x20, 0); + _client->println(0x2B, 0); + DAPNET_DEBUG_PRINTLN(0x2B, 0); + _client->flush(); + break; + } + } + } +} + +uint8_t nibble2c(char c) { + if ((c>='0') && (c<='9')) + return c-'0'; + if ((c>='A') && (c<='F')) + return c+10-'A'; + if ((c>='a') && (c<='a')) + return c+10-'a'; + return -1; +} +uint8_t hex2c(char c1, char c2) { + if(nibble2c(c2) >= 0) + return nibble2c(c1) * 16 + nibble2c(c2); + return nibble2c(c1); +} \ No newline at end of file diff --git a/pocsag-transmit-test/src/dapnetv1_client.h b/pocsag-transmit-test/src/dapnetv1_client.h new file mode 100644 index 0000000..657ad1b --- /dev/null +++ b/pocsag-transmit-test/src/dapnetv1_client.h @@ -0,0 +1,46 @@ +#if !defined(_DAPNETV1_CLIENT_H) +#define _DAPNETV1_CLIENT_H +#include +#include + +#define DAPNET_QUEUE_MAX 200 + +#define DAPNET_DEBUG +#define DAPNET_DEBUG_PORT Serial +#if defined(DAPNET_DEBUG) + #define DAPNET_DEBUG_PRINT(...) { DAPNET_DEBUG_PORT.print(__VA_ARGS__); } + #define DAPNET_DEBUG_PRINTLN(...) { DAPNET_DEBUG_PORT.println(__VA_ARGS__); } +#else + #define DAPNET_DEBUG_PRINT(...) {} + #define DAPNET_DEBUG_PRINTLN(...) {} +#endif + + +/*! +* DAPNET v1 Protocol Parser +- catSIXe, encoder is partly transformed from RPITX, with my old contributions(batch-encoding etc.) from the old github +*/ +class DAPNETV1Client { + public: + WiFiClient* _client; + bool timeSlot[16]; + explicit DAPNETV1Client(WiFiClient* client); + void begin(); + void test(); + void loop(); + private: + uint8_t lastMsgAck; + void sendAck(); +}; +uint8_t nibble2c(char c); +uint8_t hex2c(char c1, char c2); + +typedef struct { + uint32_t ric; + uint8_t function; + uint8_t length; + char message[80]; +} DAPNETMessage; + + +#endif \ No newline at end of file diff --git a/pocsag-transmit-test/src/main.cpp b/pocsag-transmit-test/src/main.cpp index ad44014..a82dc71 100644 --- a/pocsag-transmit-test/src/main.cpp +++ b/pocsag-transmit-test/src/main.cpp @@ -1,8 +1,12 @@ #include +#include +#include + #define RADIOLIB_LOW_LEVEL #define RADIOLIB_GODMODE #include +#include #include //Better #define LORA_SCK 5 @@ -16,6 +20,8 @@ SX1276 radio = new Module(LORA_SS, LORA_DIO0, LORA_RST, LORA_DIO1); POCSAGTransmitter transmitter; +WiFiClient client; +DAPNETV1Client dapnet(&client); void setup() { Serial.begin(115200); @@ -30,18 +36,36 @@ void setup() { Serial.println("initialized modem"); transmitter.begin(&radio); Serial.println("initialized transmitter"); - delay(2e2); + + WiFi.begin("devtest","devtest1337"); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(WiFi.localIP()); + Serial.println(F("waiting for Timesync")); + waitForSync(); + Serial.println(); + Serial.println("UTC: " + UTC.dateTime()); + + dapnet.begin(); + //ToDo we need wificonnection stuff here + + + /*delay(2e2); transmitter.queuePage(133701, 3, "Testbericht 0"); // should never be sent transmitter.clearQueue(); transmitter.queuePage(133701, 3, "Testbericht 1"); transmitter.queuePage(133703, 3, "Testbericht -2"); transmitter.queuePage(133706, 3, "Testbericht --3"); transmitter.queuePage(133707, 3, "Testbericht ---4"); - transmitter.transmitBatch(); + transmitter.transmitBatch();*/ } void loop() { //Serial.print("."); - delay(50); + dapnet.loop(); + time_t x = UTC.now(); + // put your main code here, to run repeatedly: } \ No newline at end of file diff --git a/pocsag-transmit-test/src/pocsag_transmitter.h b/pocsag-transmit-test/src/pocsag_transmitter.h index ba6a923..4aff470 100644 --- a/pocsag-transmit-test/src/pocsag_transmitter.h +++ b/pocsag-transmit-test/src/pocsag_transmitter.h @@ -10,8 +10,8 @@ // #define POCSAG_DEBUG #define POCSAG_DEBUG_PORT Serial #if defined(POCSAG_DEBUG) - #define POCSAG_DEBUG_PRINT(...) { RADIOLIB_DEBUG_PORT.print(__VA_ARGS__); } - #define POCSAG_DEBUG_PRINTLN(...) { RADIOLIB_DEBUG_PORT.println(__VA_ARGS__); } + #define POCSAG_DEBUG_PRINT(...) { POCSAG_DEBUG_PORT.print(__VA_ARGS__); } + #define POCSAG_DEBUG_PRINTLN(...) { POCSAG_DEBUG_PORT.println(__VA_ARGS__); } #else #define POCSAG_DEBUG_PRINT(...) {} #define POCSAG_DEBUG_PRINTLN(...) {}