Removed self made ack handling. Now it seems to work very stable.

This commit is contained in:
Marcel Schulz 2018-02-11 14:14:40 +01:00
parent 5f809c2aa0
commit 9b632383a8
4 changed files with 106 additions and 108 deletions

View File

@ -14,9 +14,11 @@ SBMasterStorage SBMasterStorage::initialize() {
EEPROM.put(0 + sizeof(SBNetworkDevice), storage); EEPROM.put(0 + sizeof(SBNetworkDevice), storage);
#if defined(ESP8266) #if defined(ESP8266)
EEPROM.commit(); EEPROM.commit();
EEPROM.end();
#endif #endif
} }
#if defined(ESP8266)
EEPROM.end();
#endif
return storage; return storage;
} }

View File

@ -47,7 +47,7 @@ void SBNetwork::initialize(SBMacAddress mac){
if (!this->RunAsClient) { if (!this->RunAsClient) {
this->MasterStorage = SBMasterStorage::initialize(); this->MasterStorage = SBMasterStorage::initialize();
for (uint8_t i = 0; i < MAX_CLIENTS; i++) { for (uint8_t i = 0; i < MAX_CLIENTS; i++) {
Serial.print("Masterstorage Slot "); Serial.print(i); Serial.print(" "); Serial.print(F("Masterstorage Slot ")); Serial.print(i); Serial.print(" ");
printAddress(MasterStorage.Slaves[i]); printAddress(MasterStorage.Slaves[i]);
Serial.println(); Serial.println();
} }
@ -62,9 +62,9 @@ void SBNetwork::initialize(SBMacAddress mac){
this->radio.enableDynamicPayloads(); this->radio.enableDynamicPayloads();
//this->radio.enableDynamicAck(); //this->radio.enableDynamicAck();
this->radio.setAutoAck(false); // We use our own ack handling this->radio.setAutoAck(true); // We use the integrated package handling
//this->radio.enableAckPayload(); //this->radio.enableAckPayload();
this->radio.setRetries(40, 5); this->radio.setRetries(0, 15);
// Listen at the own address // Listen at the own address
this->radio.openReadingPipe(0, NetworkDevice.MAC); this->radio.openReadingPipe(0, NetworkDevice.MAC);
@ -109,7 +109,7 @@ void SBNetwork::initializeNetworkDevice(SBNetworkDevice &device, SBMacAddress ma
#if defined(ESP8266) #if defined(ESP8266)
EEPROM.commit(); EEPROM.commit();
#endif #endif
Serial.println("Done"); Serial.println(F("Done"));
printDeviceData(device); printDeviceData(device);
} }
#if defined(ESP8266) #if defined(ESP8266)
@ -136,7 +136,7 @@ void SBNetwork::resetData(){
bool SBNetwork::sendToDevice(SBMacAddress mac, void* message, uint8_t messageSize){ bool SBNetwork::sendToDevice(SBMacAddress mac, void* message, uint8_t messageSize){
#if defined(_DEBUG) #if defined(_DEBUG)
Serial.print("Sending transmission"); Serial.println(F("Sending transmission"));
#endif #endif
SBNetworkHeader header; SBNetworkHeader header;
header.ToAddress = mac; header.ToAddress = mac;
@ -156,10 +156,10 @@ bool SBNetwork::sendToDevice(SBMacAddress mac, void* message, uint8_t messageSiz
bool bSuccess = this->sendToDevice(frame); bool bSuccess = this->sendToDevice(frame);
#if defined(_DEBUG) #if defined(_DEBUG)
if (bSuccess) { if (bSuccess) {
Serial.println(" Done"); Serial.println(F(" Done"));
} }
else { else {
Serial.println(" Failed"); Serial.println(F(" Failed"));
} }
#endif #endif
return bSuccess; return bSuccess;
@ -171,6 +171,7 @@ bool SBNetwork::sendToDevice(SBMacAddress mac, void* message, uint8_t messageSiz
fragmentCount++; fragmentCount++;
} }
for (uint8_t i = 0; i < fragmentCount; i++){ for (uint8_t i = 0; i < fragmentCount; i++){
delay(FRAGMENT_DELAY);
#if defined(_DEBUG) #if defined(_DEBUG)
Serial.print("."); Serial.print(".");
#endif #endif
@ -191,19 +192,19 @@ bool SBNetwork::sendToDevice(SBMacAddress mac, void* message, uint8_t messageSiz
bool bSuccess = this->sendToDevice(frame); bool bSuccess = this->sendToDevice(frame);
if (!bSuccess){ if (!bSuccess){
#if defined(_DEBUG) #if defined(_DEBUG)
Serial.println(" Failed "); Serial.println(F(" Failed "));
#endif #endif
return false; return false;
} }
} }
#if defined(_DEBUG) #if defined(_DEBUG)
Serial.println(" Done"); Serial.println(F(" Done"));
#endif #endif
return true; return true;
} }
} }
bool SBNetwork::sendToDeviceInternal(SBNetworkFrame frame, bool waitForAck) { bool SBNetwork::sendToDeviceInternal(SBNetworkFrame frame) {
uint8_t bufferSize = sizeof(SBNetworkHeader) + frame.MessageSize; uint8_t bufferSize = sizeof(SBNetworkHeader) + frame.MessageSize;
uint8_t buffer[32]; // = (uint8_t*)malloc(bufferSize); uint8_t buffer[32]; // = (uint8_t*)malloc(bufferSize);
memcpy(buffer, &frame.Header, sizeof(SBNetworkHeader)); memcpy(buffer, &frame.Header, sizeof(SBNetworkHeader));
@ -211,64 +212,21 @@ bool SBNetwork::sendToDeviceInternal(SBNetworkFrame frame, bool waitForAck) {
memcpy(buffer + sizeof(SBNetworkHeader), frame.Message, frame.MessageSize); memcpy(buffer + sizeof(SBNetworkHeader), frame.Message, frame.MessageSize);
} }
bool bSuccess = false; bool bSuccess = false;
uint8_t iCounter = 0; radio.stopListening();
while (!bSuccess && iCounter < RETRY_COUNT) { radio.openWritingPipe(frame.Header.ToAddress);
// Send to broadcast
radio.stopListening(); #if defined(_DEBUG)
radio.openWritingPipe(frame.Header.ToAddress); Serial.print(millis());
bSuccess = radio.write(buffer, bufferSize); Serial.println(F(" Sending physical data"));
radio.openReadingPipe(0, this->NetworkDevice.MAC); #endif
radio.startListening(); bSuccess = radio.write(buffer, bufferSize);
if (bSuccess) { radio.openReadingPipe(0, this->NetworkDevice.MAC);
bSuccess = waitForAck ? waitForAckFrom(frame.Header.ToAddress) : true; radio.startListening();
}
delay(40); // Waittime between two sendings
iCounter++;
}
return bSuccess; return bSuccess;
} }
bool SBNetwork::sendToDevice(SBNetworkFrame frame){ bool SBNetwork::sendToDevice(SBNetworkFrame frame){
return sendToDeviceInternal(frame, true); return sendToDeviceInternal(frame);
}
bool SBNetwork::waitForAckFrom(SBMacAddress mac) {
#if defined(_DEBUG)
Serial.print(F("Wait for Ack... "));
#endif
long lNow = millis();
// We need the counter in case of the unoccationally case, that during the wait, the timer overflows ans starts with 0
uint16_t iCounter = 1;
SBNetworkFrame frame;
while (lNow + ACK_WAIT > millis() && iCounter) {
if (this->receiveInternal(&frame)) {
if (frame.Header.FromAddress.isEquals(mac)) {
if (frame.Header.CommandType == SB_COMMAND_ACK) {
#if defined(_DEBUG)
Serial.print(F("Done - Counter = ")); Serial.println(iCounter);
#endif
return true;
}
}
}
iCounter++;
}
#if defined(_DEBUG)
Serial.print(F("Failed - Counter = ")); Serial.println(iCounter);
#endif
return false;
}
bool SBNetwork::sendAckTo(SBMacAddress mac) {
SBNetworkFrame frame;
frame.Header.ToAddress = mac;
frame.Header.FromAddress = this->NetworkDevice.MAC;
frame.Header.FragmentCount = 1;
frame.Header.FragmentNr = 0;
frame.Header.PackageId = millis();
frame.Header.CommandType = SB_COMMAND_ACK;
frame.MessageSize = 0;
return sendToDeviceInternal(frame, false);
} }
bool SBNetwork::receiveInternal(SBNetworkFrame *frame) { bool SBNetwork::receiveInternal(SBNetworkFrame *frame) {
@ -301,50 +259,71 @@ bool SBNetwork::receive(SBNetworkFrame *frame){
// We must check, if the received package is a NO_COMMAND_PACKAGE otherwise we have to handle it internally // We must check, if the received package is a NO_COMMAND_PACKAGE otherwise we have to handle it internally
return this->handleCommandPackage(frame); return this->handleCommandPackage(frame);
} }
return false;
} }
bool SBNetwork::receiveMessage(void **message, uint8_t *messageSize, SBMacAddress *mac){ bool SBNetwork::receiveMessage(void **message, uint8_t *messageSize, SBMacAddress *mac){
uint8_t pipe = -1; uint8_t pipe = -1;
uint8_t maxPackageSize = MAX_PACKAGE_SIZE; uint8_t maxPackageSize = MAX_PACKAGE_SIZE;
if (radio.available()){ if (radio.available()){
#if defined(_DEBUG)
Serial.print(millis());
Serial.println(F(" Radio available"));
#endif
SBNetworkFrame frame; SBNetworkFrame frame;
bool bReceive = this->receive(&frame); bool bReceive = this->receive(&frame);
if (bReceive) { if (bReceive) {
#ifdef _DEBUG #ifdef _DEBUG
Serial.print("Incomming transmission from "); Serial.print(F("Incomming transmission from "));
printAddress(frame.Header.FromAddress); printAddress(frame.Header.FromAddress);
Serial.println(); Serial.println();
#endif #endif
if (frame.Header.FragmentCount == 1) { if (frame.Header.FragmentCount == 1) {
#ifdef _DEBUG
Serial.println(F("no fragments"));
#endif
// We only have to receive this package // We only have to receive this package
memcpy(_ReadBuffer, frame.Message, maxPackageSize); memcpy(_ReadBuffer, frame.Message, maxPackageSize);
(*message) = _ReadBuffer; (*message) = _ReadBuffer;
(*messageSize) = frame.MessageSize; (*messageSize) = frame.MessageSize;
(*mac) = frame.Header.FromAddress; (*mac) = frame.Header.FromAddress;
return true; return true;
} }
else if (frame.Header.FragmentNr == 0) { else if (frame.Header.FragmentNr == 0) {
//Serial.print(frame.Header.FragmentNr + 1); Serial.print("/"); Serial.println(frame.Header.FragmentCount); #ifdef _DEBUG
Serial.println(F("with fragments"));
#endif
Serial.print(millis()); Serial.print(F(" Fragment received ")); Serial.print(frame.Header.FragmentNr + 1); Serial.print("/"); Serial.println(frame.Header.FragmentCount);
// We have to receive more packages // We have to receive more packages
memcpy(_ReadBuffer, frame.Message, maxPackageSize); memcpy(_ReadBuffer, frame.Message, maxPackageSize);
delay(50); // We need a delay here, because the opposite needs time to send the next package //delay(50); // We need a delay here, because the opposite needs time to send the next package
while (radio.available()) { unsigned long timeout = millis() + FRAGMENT_TIMEOUT;
bReceive = this->receive(&frame); _AwaitingFragmentPackage = true;
if (!bReceive) { while (radio.available() || timeout > millis()) {
return false; if (this->receive(&frame)){
} Serial.print(millis()); Serial.print(F(" Fragment received ")); Serial.print(frame.Header.FragmentNr + 1);
else { Serial.print(F("/")); Serial.println(frame.Header.FragmentCount);
memcpy(_ReadBuffer + (frame.Header.FragmentNr * maxPackageSize), frame.Message, frame.MessageSize); memcpy(_ReadBuffer + (frame.Header.FragmentNr * maxPackageSize), frame.Message, frame.MessageSize);
// Now wait again for the next fragment
timeout = millis() + FRAGMENT_TIMEOUT;
if (frame.Header.FragmentNr == (frame.Header.FragmentCount - 1)) { if (frame.Header.FragmentNr == (frame.Header.FragmentCount - 1)) {
// Last fragment received // Last fragment received
*message = _ReadBuffer; *message = _ReadBuffer;
*messageSize = ((frame.Header.FragmentCount - 1) * maxPackageSize) + frame.MessageSize; *messageSize = ((frame.Header.FragmentCount - 1) * maxPackageSize) + frame.MessageSize;
(*mac) = frame.Header.FromAddress; (*mac) = frame.Header.FromAddress;
_AwaitingFragmentPackage = false;
return true; return true;
} }
delay(10); //delay(10);
} }
delay(1);
} }
_AwaitingFragmentPackage = false;
Serial.print(millis());
Serial.println(F(" Fragment timeout"));
return false; return false;
} }
else { else {
@ -377,7 +356,8 @@ bool SBNetwork::connectToNetwork(){
frame.Header = header; frame.Header = header;
frame.Message = NULL; frame.Message = NULL;
frame.MessageSize = 0; frame.MessageSize = 0;
bool bMasterAck = this->sendToDeviceInternal(frame, false); bool bMasterAck = this->sendToDeviceInternal(frame);
unsigned long started_waiting_at = millis(); unsigned long started_waiting_at = millis();
boolean timeout = false; boolean timeout = false;
while (!this->receive(&frame)) { while (!this->receive(&frame)) {
@ -394,9 +374,10 @@ bool SBNetwork::connectToNetwork(){
else { else {
if (frame.Header.CommandType != SB_COMMAND_MASTER_ACK) { if (frame.Header.CommandType != SB_COMMAND_MASTER_ACK) {
if (frame.MessageSize > 0) { if (frame.MessageSize > 0) {
free(frame.Message); //free(frame.Message);
} }
Serial.println(F("Failed - Got answer but no master ack")); Serial.println(F("Failed - Got answer but no master ack"));
Serial.println(frame.Header.CommandType);
return false; return false;
} }
else { else {
@ -413,7 +394,7 @@ bool SBNetwork::connectToNetwork(){
conFrame.Header.PackageId = millis(); conFrame.Header.PackageId = millis();
conFrame.Header.ToAddress = frame.Header.FromAddress; conFrame.Header.ToAddress = frame.Header.FromAddress;
conFrame.MessageSize = 0; conFrame.MessageSize = 0;
if (!this->sendToDeviceInternal(conFrame, false)) { if (!this->sendToDeviceInternal(conFrame)) {
Serial.println(F("Failed - Sending pairing request")); Serial.println(F("Failed - Sending pairing request"));
} }
else { else {
@ -429,6 +410,7 @@ bool SBNetwork::connectToNetwork(){
} }
if (frame.Header.CommandType != SB_COMMAND_PAIRING_ACK) { if (frame.Header.CommandType != SB_COMMAND_PAIRING_ACK) {
Serial.println(F("Failed - Pairing rejected from the master")); Serial.println(F("Failed - Pairing rejected from the master"));
Serial.println(frame.Header.CommandType);
return false; return false;
} }
else { else {
@ -436,8 +418,8 @@ bool SBNetwork::connectToNetwork(){
this->NetworkDevice.NetworkKey = *(frame.Message); this->NetworkDevice.NetworkKey = *(frame.Message);
this->NetworkDevice.ConnectedToMaster = -1; this->NetworkDevice.ConnectedToMaster = -1;
EEPROM.put(0, NetworkDevice); EEPROM.put(0, NetworkDevice);
Serial.println("Suceeded"); Serial.println(F("Suceeded"));
Serial.print("Try to ping to master..."); Serial.print(F("Try to ping to master..."));
delay(100); delay(100);
} }
} }
@ -472,7 +454,7 @@ bool SBNetwork::pingDevice(SBMacAddress mac){
Serial.println(F("Done - Device available")); Serial.println(F("Done - Device available"));
} }
else { else {
Serial.println("Failed - Device not responding"); Serial.println(F("Failed - Device not responding"));
} }
return bSend; return bSend;
} }
@ -495,10 +477,6 @@ bool SBNetwork::handleCommandPackage(SBNetworkFrame *frame){
#ifdef _DEBUG #ifdef _DEBUG
Serial.println(F("Received 'PING'")); Serial.println(F("Received 'PING'"));
#endif #endif
// Only, when the device is a paired slave, send a ping back
if (bFound) {
sendAckTo(frame->Header.FromAddress);
}
break; break;
} }
case SB_COMMAND_SEARCH_MASTER: { case SB_COMMAND_SEARCH_MASTER: {
@ -506,7 +484,7 @@ bool SBNetwork::handleCommandPackage(SBNetworkFrame *frame){
// When automatic Client adding is activated // When automatic Client adding is activated
if (_EnableAutomaticClientAdding) { if (_EnableAutomaticClientAdding) {
Serial.print(F("Send MasterACK...")); Serial.print(F("Send MasterACK..."));
delay(20); delay(100);
bool bSend = sendMasterAck(frame->Header.FromAddress); bool bSend = sendMasterAck(frame->Header.FromAddress);
if (bSend) { if (bSend) {
Serial.println(F("Done")); Serial.println(F("Done"));
@ -525,7 +503,7 @@ bool SBNetwork::handleCommandPackage(SBNetworkFrame *frame){
// When automatic Client adding is activated // When automatic Client adding is activated
if (_EnableAutomaticClientAdding) { if (_EnableAutomaticClientAdding) {
Serial.print(F("Send PairingACK... ")); Serial.print(F("Send PairingACK... "));
delay(20); delay(100);
// This is the point where we could stop prpcessing and wait for an user input on the controller to let the new device access the network // This is the point where we could stop prpcessing and wait for an user input on the controller to let the new device access the network
bool bSend = sendPairingAck(frame->Header.FromAddress); bool bSend = sendPairingAck(frame->Header.FromAddress);
// If sending was successfull, then add the new slave // If sending was successfull, then add the new slave
@ -544,19 +522,37 @@ bool SBNetwork::handleCommandPackage(SBNetworkFrame *frame){
} }
break; break;
} }
case SB_COMMAND_NO_COMMAND: case SB_COMMAND_NO_COMMAND: {
#ifdef _DEBUG #ifdef _DEBUG
Serial.println(F("Received 'NO_COMMAND'")); Serial.println(F("Received 'NO_COMMAND'"));
#endif #endif
if (bFound) { if (bFound) {
return sendAckTo(frame->Header.FromAddress); if ((_AwaitingFragmentPackage && frame->Header.FragmentNr > 0) || (!_AwaitingFragmentPackage && frame->Header.FragmentNr == 0)) {
return true;
}
} }
break;
}
} }
// Package was handled by handleCommandPackage(); // Package was handled by handleCommandPackage();
return false; return false;
} }
else { else {
return sendAckTo(frame->Header.FromAddress); // Look, if we must handle a command package for a client
switch (frame->Header.CommandType) {
case SB_COMMAND_NO_COMMAND: {
#ifdef _DEBUG
Serial.println(F("Received 'NO_COMMAND'"));
#endif
if ((_AwaitingFragmentPackage && frame->Header.FragmentNr > 0) || (!_AwaitingFragmentPackage && frame->Header.FragmentNr == 0)) {
return true;
}
}
case SB_COMMAND_MASTER_ACK:
case SB_COMMAND_PAIRING_ACK:
return true;
}
return false;
} }
} }
@ -573,7 +569,7 @@ bool SBNetwork::sendMasterAck(SBMacAddress mac){
frame.Header = header; frame.Header = header;
frame.Message = (uint8_t*)&(this->NetworkDevice.NetworkKey); frame.Message = (uint8_t*)&(this->NetworkDevice.NetworkKey);
frame.MessageSize = sizeof(uint32_t); frame.MessageSize = sizeof(uint32_t);
return this->sendToDeviceInternal(frame, false); return this->sendToDeviceInternal(frame);
} }
else { else {
return false; return false;
@ -594,7 +590,7 @@ bool SBNetwork::sendPairingAck(SBMacAddress mac){
frame.Header = header; frame.Header = header;
frame.Message = NULL; frame.Message = NULL;
frame.MessageSize = 0; frame.MessageSize = 0;
return this->sendToDeviceInternal(frame, false); return this->sendToDeviceInternal(frame);
} }
else { else {
return false; return false;
@ -605,13 +601,13 @@ bool SBNetwork::checkMaster(){
if (this->RunAsClient) { if (this->RunAsClient) {
if (this->pingDevice(this->NetworkDevice.MasterMAC)) { if (this->pingDevice(this->NetworkDevice.MasterMAC)) {
#ifdef _DEBUG #ifdef _DEBUG
Serial.println("Master OK"); Serial.println(F("Master OK"));
#endif #endif
return true; return true;
} }
else { else {
#ifdef _DEBUG #ifdef _DEBUG
Serial.println("Master ERROR"); Serial.println(F("Master ERROR"));
#endif #endif
return false; return false;
} }

View File

@ -2,7 +2,7 @@
#ifndef _SB_NETWORK_ #ifndef _SB_NETWORK_
#define _SB_NETWORK_ #define _SB_NETWORK_
#define SB_VERSION "1.0.4" #define SB_VERSION "1.0.5"
#include <RF24_config.h> #include <RF24_config.h>
#include <RF24.h> #include <RF24.h>
@ -13,6 +13,8 @@
#define BROADCAST_MAC (SBMacAddress(0x9E, 0x0E, 0x9E, 0x0E, 0x9E)) #define BROADCAST_MAC (SBMacAddress(0x9E, 0x0E, 0x9E, 0x0E, 0x9E))
#define EMPTY_MAC (SBMacAddress(0x00, 0x00, 0x00, 0x00, 0x00)) #define EMPTY_MAC (SBMacAddress(0x00, 0x00, 0x00, 0x00, 0x00))
void printAddress(byte address[5]);
class SBNetwork{ class SBNetwork{
private: private:
/* /*
@ -56,6 +58,10 @@ class SBNetwork{
*/ */
SBMacAddress _LastReceivedFromAddress; SBMacAddress _LastReceivedFromAddress;
/** /**
/ Stores the flag, that tells the handle command function to await a fragent or not
*/
bool _AwaitingFragmentPackage = false;
/**
Enables or disables automatical client adding, when receiving a pairing resuest. Enables or disables automatical client adding, when receiving a pairing resuest.
This is false by default. This is false by default.
*/ */
@ -63,7 +69,7 @@ class SBNetwork{
void initializeNetworkDevice(SBNetworkDevice &device, SBMacAddress mac); void initializeNetworkDevice(SBNetworkDevice &device, SBMacAddress mac);
bool sendToDeviceInternal(SBNetworkFrame frame, bool waitForAck); bool sendToDeviceInternal(SBNetworkFrame frame);
bool sendToDevice(SBNetworkFrame frame); bool sendToDevice(SBNetworkFrame frame);
@ -80,10 +86,6 @@ class SBNetwork{
bool receiveMessage(void **message, uint8_t *messageSize, SBMacAddress *mac); bool receiveMessage(void **message, uint8_t *messageSize, SBMacAddress *mac);
bool waitForAckFrom(SBMacAddress mac);
bool sendAckTo(SBMacAddress mac);
public: public:
/* /*
* Define the standard addresses for the sensor network * Define the standard addresses for the sensor network

View File

@ -3,6 +3,7 @@
#define _SB_NETWORK_CONFIG_ #define _SB_NETWORK_CONFIG_
// Generates details debug messages about sending and receiving data packages // Generates details debug messages about sending and receiving data packages
//#define _DEBUG //#define _DEBUG
// All slaves will ping the master every xxx milliseconds. if set to 0, they will not ping the master // All slaves will ping the master every xxx milliseconds. if set to 0, they will not ping the master
@ -12,13 +13,10 @@
#define CLIENT_TIMEOUT 60000 #define CLIENT_TIMEOUT 60000
// Waittime for an ACK package // Milliseconds to wait for fragmented packages
#define ACK_WAIT 50 #define FRAGMENT_TIMEOUT 80
// Count of trys to send a data package // Milliseconds to wait between two fragment sendings
#define RETRY_COUNT 10 #define FRAGMENT_DELAY 10
// Milliseconds to wait between two retries
#define RETRY_DALY 40
#endif #endif