Skip to content
Snippets Groups Projects
Commit f873cec4 authored by Callum Inglis's avatar Callum Inglis
Browse files

Handle Ack payloads

parent bee24cf4
No related branches found
No related tags found
1 merge request!1Reliable polling
...@@ -209,7 +209,7 @@ boolean readPMSdata(Stream *s) { ...@@ -209,7 +209,7 @@ boolean readPMSdata(Stream *s) {
memcpy((void *)&data, (void *)buffer_u16, 30); memcpy((void *)&data, (void *)buffer_u16, 30);
if (sum != data.checksum) { if (sum != data.checksum) {
Serial.println("Checksum failure"); Serial.print("\n Checksum failure... ");
Serial.print("Expected: "); Serial.print(sum); Serial.print("Expected: "); Serial.print(sum);
Serial.print(", Got: "); Serial.print(data.checksum); Serial.print(", Got: "); Serial.print(data.checksum);
return false; return false;
...@@ -241,12 +241,12 @@ boolean clearToSend(int listenDuration) { ...@@ -241,12 +241,12 @@ boolean clearToSend(int listenDuration) {
// Listen of listenDuration seconds // Listen of listenDuration seconds
// If we see a response to our txHello packet, and txHello.okToTransmit is True, we can send our packet // If we see a response to our txHello packet, and txHello.okToTransmit is True, we can send our packet
boolean listenTxHelloAccept(int listenDuration) { boolean listenTxHelloAccept(int listenDuration, int messageID) {
int time_now = now() + listenDuration; int time_now = now() + listenDuration;
// Listen until timeout expires // Listen until timeout expires
Serial.println("[+] Transmit - \"Hello\" - Listening for ack & clear to send");
while (time_now >= now()) { while (time_now >= now()) {
Serial.println("Listening for auth");
int packetSize = LoRa.parsePacket(); int packetSize = LoRa.parsePacket();
if (packetSize) { if (packetSize) {
...@@ -280,16 +280,24 @@ boolean listenTxHelloAccept(int listenDuration) { ...@@ -280,16 +280,24 @@ boolean listenTxHelloAccept(int listenDuration) {
StaticJsonDocument<200> doc; StaticJsonDocument<200> doc;
deserializeJson(doc, incoming); deserializeJson(doc, incoming);
const bool okToCopy = doc["okToTransmit"]; const bool okToTransmit = doc["okTransmit"];
const String authIsForUid = doc["uid"]; const String authIsForUid = doc["uid"];
const int authIsForMessageID = doc["messageID"];
const String gatewayUid = doc["gatewayUid"];
// Verify txHello.okToTransmit is True & UID Match // Verify txHello.okToTransmit is True & UID Match & Message IDs Match
return (okToCopy && authIsForUid == getSensorUID()); if (authIsForUid == getSensorUID()) { Serial.println("[+] Transmit - \"Hello\" - Sensor UID Match!"); } else { Serial.println("[-] Transmit - \"Hello\" - Sensor UID Mis-Match! " + String(authIsForUid) + " vs " + String(getSensorUID())); }
if (authIsForMessageID == messageID) { Serial.println("[+] Transmit - \"Hello\" - Message ID Match!"); } else { Serial.println("[-] Transmit - \"Hello\" - MessageID Mis-Match!"); }
return (okToTransmit
&& authIsForUid == getSensorUID()
&& authIsForMessageID == messageID);
} }
delay(5); delay(3);
} }
Serial.println("[-] Transmit - \"Hello\" - Timeout while waiting for Clear to Send\n\n");
return false; // We didn't hear anything, conside this as meaning "Can't Send" return false; // We didn't hear anything, conside this as meaning "Can't Send"
} }
...@@ -304,38 +312,103 @@ boolean transmitData(DynamicJsonDocument payload) { ...@@ -304,38 +312,103 @@ boolean transmitData(DynamicJsonDocument payload) {
// Listen for other communication // Listen for other communication
// Rx - Listen for other messages, if no messages heard then continue // Rx - Listen for other messages, if no messages heard then continue
// if (!clearToSend(0.5)) { if (!clearToSend(0.5)) {
// Serial.println("[-] Airways busy, could not send"); Serial.println("[-] Airways busy, could not send");
// delay(random(500, 1250)); // Introduce random delay to avoid another collision delay(random(500, 1250)); // Introduce random delay to avoid another collision
// return false;
// } // TODO Refactor
while (!clearToSend(0.5)) {
Serial.println("[-] Airways busy, could not send");
delay(random(500, 1250)); // Introduce random delay to avoid another collision
}
//return false;
}
Serial.println("[+] Transmit - \"Hello\"");
// Send short "clear to send?" packet // Send short "clear to send?" packet
// Tx - "I've got data to send!" + UID // Tx - "I've got data to send!" + UID
// RX - Continue upon recieving "OK" + UID + TX_Auth_ID // RX - Continue upon recieving "OK" + UID + TX_Auth_ID
DynamicJsonDocument txHello(2048); DynamicJsonDocument txHello(2048);
txHello["uid"] = sensorID; txHello["uid"] = sensorID;
txHello["reservationTime"] = reservationTime; // How long do we require reservation of radio? txHello["reservationTime"] = reservationTime; // How long do we require reservation of radio?
txHello["messageID"] = msgCount;
sendJsonPayloadWithLoRa(txHello); sendJsonPayloadWithLoRa(txHello);
if (!listenTxHelloAccept(reservationTime * 1.1)) { // Else we have clear to send if (!listenTxHelloAccept(reservationTime * 1.5, msgCount)) { // Can't transmit just now
return false; // Can't transmit just now Serial.println("[-] Transmit - \"Hello\" - Can Not Transmit At This Time\n");
return false;
} else {
Serial.println("OK To Transmit");
} }
Serial.println("[+] Recieved - Clear to Transmit Payload"); // Else we have clear to send
// Transmit Payload // Transmit Payload
// Tx - Send payload + UID + TX_Auth_ID // Tx - Send payload + UID + TX_Auth_ID
// Rx - Listen for Ack/Nack // Rx - Listen for Ack/Nack
Serial.println("Sending Payload Now"); Serial.println("[+] Transmit - Payload");
sendJsonPayloadWithLoRa(payload); sendJsonPayloadWithLoRa(payload);
// TODO Await Response Ack/Nak // TODO Await Response Ack/Nak
int ackTimeout = 2; // Seconds
int time_now = now() + ackTimeout;
// Listen until timeout expires
Serial.println("[.] Transmit - Payload - Listening for Ack");
while (time_now >= now()) {
int packetSize = LoRa.parsePacket();
if (packetSize) {
String incoming = "";
char temp;
while (LoRa.available()) {
// TODO - Tidy this up, ensure we only read in valid JSON
temp = (char)LoRa.read();
// Opening {
if (incoming.length() == 0 && temp == '{') {
incoming = "{";
// Closing }
} else if (temp == '}') {
incoming.concat("}");
break;
// Anything else that's valid
} else if (incoming.length() > 0) {
incoming.concat(temp);
}
}
// DEBUG
// Serial.print("\nin listedForAck() Recieved: \n");
// Serial.println(incoming);
StaticJsonDocument<200> doc;
deserializeJson(doc, incoming);
const bool ackStatus = doc["ackStatus"];
const String authIsForUid = doc["uid"];
const String gatewayUid = doc["gatewayUid"];
// Verify txHello.okToTransmit is True & UID Match
if (authIsForUid == getSensorUID()) {
Serial.println("[+] Transmit - Payload - Ack Recieved: " + String(ackStatus) + "\n");
if (ackStatus) { return true; } // It all worked :)
// TODO Retransmit, recover, etc
return false;
}
// Else UID Mis-Match so we wait for next message
}
delay(5);
}
// TODO After Timeout we need to deal with!
Serial.println("[-] Transmit - Payload - Ack Timeout Reached - Assuming Message Was Not Delivered");
// TODO Listen for ack/nak // TODO Listen for ack/nak
...@@ -359,7 +432,7 @@ void setup() { ...@@ -359,7 +432,7 @@ void setup() {
delay(1000); delay(1000);
Serial.begin(115200); // Console Debug Serial.begin(115200); // Console Debug
Serial.println("[+] Transmitter Node"); Serial.println("\n\n[+] Transmitter Node");
sensorID = getSensorUID(); sensorID = getSensorUID();
...@@ -385,7 +458,7 @@ void loop() { ...@@ -385,7 +458,7 @@ void loop() {
pollEventCount++; pollEventCount++;
Serial.println(); Serial.println();
Serial.print(String(pollEventCount) + ") Std Units: "); Serial.print(String(pollEventCount) + ") ");
Serial.print("PM 1.0: "); Serial.print(data.pm10_standard); Serial.print("PM 1.0: "); Serial.print(data.pm10_standard);
Serial.print("\t\tPM 2.5: "); Serial.print(data.pm25_standard); Serial.print("\t\tPM 2.5: "); Serial.print(data.pm25_standard);
Serial.print("\t\tPM 10: "); Serial.print(data.pm100_standard); Serial.print("\t\tPM 10: "); Serial.print(data.pm100_standard);
...@@ -408,13 +481,13 @@ void loop() { ...@@ -408,13 +481,13 @@ void loop() {
avgHumidity = humidity / sendAfterPolls; avgHumidity = humidity / sendAfterPolls;
// TODO Transmit Sensor Data // TODO Transmit Sensor Data
Serial.println("---------------------------------------"); Serial.println("");
Serial.print("Avg ppm10: "); Serial.print(avgPpm10); Serial.print("Avg ppm10: "); Serial.print(avgPpm10);
Serial.print("\t\tAvg ppm25: "); Serial.print(avgPpm25); Serial.print("\t\tAvg ppm25: "); Serial.print(avgPpm25);
Serial.print("\t\tAvg ppm100: "); Serial.print(avgPpm100); Serial.print("\t\tAvg ppm100: "); Serial.print(avgPpm100);
Serial.print("\t\tAvg Temp: "); Serial.print(avgTemperature); Serial.print("\t\tAvg Temp: "); Serial.print(avgTemperature);
Serial.print("\t\tAvg Humidity: "); Serial.println(avgHumidity); Serial.print("\t\tAvg Humidity: "); Serial.print(avgHumidity);
Serial.print("Chip ID: "); Serial.println(sensorID); Serial.print("\t\tChip ID: "); Serial.println(sensorID);
Serial.println(""); Serial.println("");
// LORA SEND // LORA SEND
...@@ -443,40 +516,22 @@ void loop() { ...@@ -443,40 +516,22 @@ void loop() {
Serial.println("Packet Sent\n"); Serial.println("Packet Sent\n");
} else { } else {
while (!transmitData(doc)){ int maxRetries = 10; // TODO Move to Config
Serial.println("[-] Failed to send packet, retrying\n"); int numRetries = 1;
delay(reservationTime + random(250, 1250)); // Introduce random delay to avoid another collision
while (!transmitData(doc) && numRetries < maxRetries){
numRetries++;
Serial.println("[-] Failed to send packet, retrying. Attempt " + String(numRetries) + " of " + String(maxRetries) + "\n");
delay(reservationTime + random(1250, 5250)); // Introduce random delay to avoid another collision
} }
}
Serial.println("---------------------------------------"); if (numRetries >= maxRetries) {
Serial.println("[-] Failed to send packet, max retries reached. Aborting");
// TODO Wait for reply
// int i = 3000;
// int j = 0;
// String incoming = "";
//
// while (j < i) {
//
// int packetSize = LoRa.parsePacket();
// if (packetSize) {
// while (LoRa.available()) {
// incoming.concat((char)LoRa.read());
// }
//
// // TODO Parse response to JSON, check if matches device & message ID
// Serial.print("Inbound!: \n");
// Serial.print(incoming);
// break;
// }
//
// j+=10;
// delay(10);
//
// // TODO If no response then consider not delivered
// }
// Serial.print("\n");
// TODO Don't Clear Counters, record more values then try to retransmit
}
}
// Reset Loop Values // Reset Loop Values
ppm10 = 0; ppm10 = 0;
ppm25 = 0; ppm25 = 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment