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);
#if defined(ESP8266)
EEPROM.commit();
EEPROM.end();
#endif
}
#if defined(ESP8266)
EEPROM.end();
#endif
return storage;
}

View File

@ -47,7 +47,7 @@ void SBNetwork::initialize(SBMacAddress mac){
if (!this->RunAsClient) {
this->MasterStorage = SBMasterStorage::initialize();
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]);
Serial.println();
}
@ -62,9 +62,9 @@ void SBNetwork::initialize(SBMacAddress mac){
this->radio.enableDynamicPayloads();
//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.setRetries(40, 5);
this->radio.setRetries(0, 15);
// Listen at the own address
this->radio.openReadingPipe(0, NetworkDevice.MAC);
@ -109,7 +109,7 @@ void SBNetwork::initializeNetworkDevice(SBNetworkDevice &device, SBMacAddress ma
#if defined(ESP8266)
EEPROM.commit();
#endif
Serial.println("Done");
Serial.println(F("Done"));
printDeviceData(device);
}
#if defined(ESP8266)
@ -136,7 +136,7 @@ void SBNetwork::resetData(){
bool SBNetwork::sendToDevice(SBMacAddress mac, void* message, uint8_t messageSize){
#if defined(_DEBUG)
Serial.print("Sending transmission");
Serial.println(F("Sending transmission"));
#endif
SBNetworkHeader header;
header.ToAddress = mac;
@ -156,10 +156,10 @@ bool SBNetwork::sendToDevice(SBMacAddress mac, void* message, uint8_t messageSiz
bool bSuccess = this->sendToDevice(frame);
#if defined(_DEBUG)
if (bSuccess) {
Serial.println(" Done");
Serial.println(F(" Done"));
}
else {
Serial.println(" Failed");
Serial.println(F(" Failed"));
}
#endif
return bSuccess;
@ -171,6 +171,7 @@ bool SBNetwork::sendToDevice(SBMacAddress mac, void* message, uint8_t messageSiz
fragmentCount++;
}
for (uint8_t i = 0; i < fragmentCount; i++){
delay(FRAGMENT_DELAY);
#if defined(_DEBUG)
Serial.print(".");
#endif
@ -191,19 +192,19 @@ bool SBNetwork::sendToDevice(SBMacAddress mac, void* message, uint8_t messageSiz
bool bSuccess = this->sendToDevice(frame);
if (!bSuccess){
#if defined(_DEBUG)
Serial.println(" Failed ");
Serial.println(F(" Failed "));
#endif
return false;
}
}
#if defined(_DEBUG)
Serial.println(" Done");
Serial.println(F(" Done"));
#endif
return true;
}
}
bool SBNetwork::sendToDeviceInternal(SBNetworkFrame frame, bool waitForAck) {
bool SBNetwork::sendToDeviceInternal(SBNetworkFrame frame) {
uint8_t bufferSize = sizeof(SBNetworkHeader) + frame.MessageSize;
uint8_t buffer[32]; // = (uint8_t*)malloc(bufferSize);
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);
}
bool bSuccess = false;
uint8_t iCounter = 0;
while (!bSuccess && iCounter < RETRY_COUNT) {
// Send to broadcast
radio.stopListening();
radio.openWritingPipe(frame.Header.ToAddress);
#if defined(_DEBUG)
Serial.print(millis());
Serial.println(F(" Sending physical data"));
#endif
bSuccess = radio.write(buffer, bufferSize);
radio.openReadingPipe(0, this->NetworkDevice.MAC);
radio.startListening();
if (bSuccess) {
bSuccess = waitForAck ? waitForAckFrom(frame.Header.ToAddress) : true;
}
delay(40); // Waittime between two sendings
iCounter++;
}
return bSuccess;
}
bool SBNetwork::sendToDevice(SBNetworkFrame frame){
return sendToDeviceInternal(frame, true);
}
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);
return sendToDeviceInternal(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
return this->handleCommandPackage(frame);
}
return false;
}
bool SBNetwork::receiveMessage(void **message, uint8_t *messageSize, SBMacAddress *mac){
uint8_t pipe = -1;
uint8_t maxPackageSize = MAX_PACKAGE_SIZE;
if (radio.available()){
#if defined(_DEBUG)
Serial.print(millis());
Serial.println(F(" Radio available"));
#endif
SBNetworkFrame frame;
bool bReceive = this->receive(&frame);
if (bReceive) {
#ifdef _DEBUG
Serial.print("Incomming transmission from ");
Serial.print(F("Incomming transmission from "));
printAddress(frame.Header.FromAddress);
Serial.println();
#endif
if (frame.Header.FragmentCount == 1) {
#ifdef _DEBUG
Serial.println(F("no fragments"));
#endif
// We only have to receive this package
memcpy(_ReadBuffer, frame.Message, maxPackageSize);
(*message) = _ReadBuffer;
(*messageSize) = frame.MessageSize;
(*mac) = frame.Header.FromAddress;
return true;
}
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
memcpy(_ReadBuffer, frame.Message, maxPackageSize);
delay(50); // We need a delay here, because the opposite needs time to send the next package
while (radio.available()) {
bReceive = this->receive(&frame);
if (!bReceive) {
return false;
}
else {
//delay(50); // We need a delay here, because the opposite needs time to send the next package
unsigned long timeout = millis() + FRAGMENT_TIMEOUT;
_AwaitingFragmentPackage = true;
while (radio.available() || timeout > millis()) {
if (this->receive(&frame)){
Serial.print(millis()); Serial.print(F(" Fragment received ")); Serial.print(frame.Header.FragmentNr + 1);
Serial.print(F("/")); Serial.println(frame.Header.FragmentCount);
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)) {
// Last fragment received
*message = _ReadBuffer;
*messageSize = ((frame.Header.FragmentCount - 1) * maxPackageSize) + frame.MessageSize;
(*mac) = frame.Header.FromAddress;
_AwaitingFragmentPackage = false;
return true;
}
delay(10);
//delay(10);
}
delay(1);
}
_AwaitingFragmentPackage = false;
Serial.print(millis());
Serial.println(F(" Fragment timeout"));
return false;
}
else {
@ -377,7 +356,8 @@ bool SBNetwork::connectToNetwork(){
frame.Header = header;
frame.Message = NULL;
frame.MessageSize = 0;
bool bMasterAck = this->sendToDeviceInternal(frame, false);
bool bMasterAck = this->sendToDeviceInternal(frame);
unsigned long started_waiting_at = millis();
boolean timeout = false;
while (!this->receive(&frame)) {
@ -394,9 +374,10 @@ bool SBNetwork::connectToNetwork(){
else {
if (frame.Header.CommandType != SB_COMMAND_MASTER_ACK) {
if (frame.MessageSize > 0) {
free(frame.Message);
//free(frame.Message);
}
Serial.println(F("Failed - Got answer but no master ack"));
Serial.println(frame.Header.CommandType);
return false;
}
else {
@ -413,7 +394,7 @@ bool SBNetwork::connectToNetwork(){
conFrame.Header.PackageId = millis();
conFrame.Header.ToAddress = frame.Header.FromAddress;
conFrame.MessageSize = 0;
if (!this->sendToDeviceInternal(conFrame, false)) {
if (!this->sendToDeviceInternal(conFrame)) {
Serial.println(F("Failed - Sending pairing request"));
}
else {
@ -429,6 +410,7 @@ bool SBNetwork::connectToNetwork(){
}
if (frame.Header.CommandType != SB_COMMAND_PAIRING_ACK) {
Serial.println(F("Failed - Pairing rejected from the master"));
Serial.println(frame.Header.CommandType);
return false;
}
else {
@ -436,8 +418,8 @@ bool SBNetwork::connectToNetwork(){
this->NetworkDevice.NetworkKey = *(frame.Message);
this->NetworkDevice.ConnectedToMaster = -1;
EEPROM.put(0, NetworkDevice);
Serial.println("Suceeded");
Serial.print("Try to ping to master...");
Serial.println(F("Suceeded"));
Serial.print(F("Try to ping to master..."));
delay(100);
}
}
@ -472,7 +454,7 @@ bool SBNetwork::pingDevice(SBMacAddress mac){
Serial.println(F("Done - Device available"));
}
else {
Serial.println("Failed - Device not responding");
Serial.println(F("Failed - Device not responding"));
}
return bSend;
}
@ -495,10 +477,6 @@ bool SBNetwork::handleCommandPackage(SBNetworkFrame *frame){
#ifdef _DEBUG
Serial.println(F("Received 'PING'"));
#endif
// Only, when the device is a paired slave, send a ping back
if (bFound) {
sendAckTo(frame->Header.FromAddress);
}
break;
}
case SB_COMMAND_SEARCH_MASTER: {
@ -506,7 +484,7 @@ bool SBNetwork::handleCommandPackage(SBNetworkFrame *frame){
// When automatic Client adding is activated
if (_EnableAutomaticClientAdding) {
Serial.print(F("Send MasterACK..."));
delay(20);
delay(100);
bool bSend = sendMasterAck(frame->Header.FromAddress);
if (bSend) {
Serial.println(F("Done"));
@ -525,7 +503,7 @@ bool SBNetwork::handleCommandPackage(SBNetworkFrame *frame){
// When automatic Client adding is activated
if (_EnableAutomaticClientAdding) {
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
bool bSend = sendPairingAck(frame->Header.FromAddress);
// If sending was successfull, then add the new slave
@ -544,19 +522,37 @@ bool SBNetwork::handleCommandPackage(SBNetworkFrame *frame){
}
break;
}
case SB_COMMAND_NO_COMMAND:
case SB_COMMAND_NO_COMMAND: {
#ifdef _DEBUG
Serial.println(F("Received 'NO_COMMAND'"));
#endif
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();
return false;
}
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.Message = (uint8_t*)&(this->NetworkDevice.NetworkKey);
frame.MessageSize = sizeof(uint32_t);
return this->sendToDeviceInternal(frame, false);
return this->sendToDeviceInternal(frame);
}
else {
return false;
@ -594,7 +590,7 @@ bool SBNetwork::sendPairingAck(SBMacAddress mac){
frame.Header = header;
frame.Message = NULL;
frame.MessageSize = 0;
return this->sendToDeviceInternal(frame, false);
return this->sendToDeviceInternal(frame);
}
else {
return false;
@ -605,13 +601,13 @@ bool SBNetwork::checkMaster(){
if (this->RunAsClient) {
if (this->pingDevice(this->NetworkDevice.MasterMAC)) {
#ifdef _DEBUG
Serial.println("Master OK");
Serial.println(F("Master OK"));
#endif
return true;
}
else {
#ifdef _DEBUG
Serial.println("Master ERROR");
Serial.println(F("Master ERROR"));
#endif
return false;
}

View File

@ -2,7 +2,7 @@
#ifndef _SB_NETWORK_
#define _SB_NETWORK_
#define SB_VERSION "1.0.4"
#define SB_VERSION "1.0.5"
#include <RF24_config.h>
#include <RF24.h>
@ -13,6 +13,8 @@
#define BROADCAST_MAC (SBMacAddress(0x9E, 0x0E, 0x9E, 0x0E, 0x9E))
#define EMPTY_MAC (SBMacAddress(0x00, 0x00, 0x00, 0x00, 0x00))
void printAddress(byte address[5]);
class SBNetwork{
private:
/*
@ -56,6 +58,10 @@ class SBNetwork{
*/
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.
This is false by default.
*/
@ -63,7 +69,7 @@ class SBNetwork{
void initializeNetworkDevice(SBNetworkDevice &device, SBMacAddress mac);
bool sendToDeviceInternal(SBNetworkFrame frame, bool waitForAck);
bool sendToDeviceInternal(SBNetworkFrame frame);
bool sendToDevice(SBNetworkFrame frame);
@ -80,10 +86,6 @@ class SBNetwork{
bool receiveMessage(void **message, uint8_t *messageSize, SBMacAddress *mac);
bool waitForAckFrom(SBMacAddress mac);
bool sendAckTo(SBMacAddress mac);
public:
/*
* Define the standard addresses for the sensor network

View File

@ -3,6 +3,7 @@
#define _SB_NETWORK_CONFIG_
// Generates details debug messages about sending and receiving data packages
//#define _DEBUG
// 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
// Waittime for an ACK package
#define ACK_WAIT 50
// Milliseconds to wait for fragmented packages
#define FRAGMENT_TIMEOUT 80
// Count of trys to send a data package
#define RETRY_COUNT 10
// Milliseconds to wait between two retries
#define RETRY_DALY 40
// Milliseconds to wait between two fragment sendings
#define FRAGMENT_DELAY 10
#endif