Did some changes in ping process. A ping now must get an answer from the destination device, otherwise the ping returns false. The master device now must be available and must know the device as a slave before it answers with a return ping. This prevents a slave to send data to master but the master doesn't know the slave (maybe because of a reset). This makes finding errors much easier than before.

This commit is contained in:
Marcel Schulz 2017-12-14 23:38:46 +01:00
parent b73eff4bec
commit bb6da7e5d7
8 changed files with 57 additions and 34 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
extras/key_visual.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 KiB

View File

@ -1,5 +1,5 @@
name=SBNetwork name=SBNetwork
version=1.0.2 version=1.0.3
author=Schullebernd,schullebernd@googlemail.com author=Schullebernd,schullebernd@googlemail.com
maintainer=Schullebernd,schullebernd@googlemail.com maintainer=Schullebernd,schullebernd@googlemail.com
sentence=Build simple master/client networks with nRF24L01 transmitter. sentence=Build simple master/client networks with nRF24L01 transmitter.

View File

@ -141,7 +141,7 @@ bool SBNetwork::sendToDevice(SBMacAddress mac, void* message, uint8_t messageSiz
SBNetworkHeader header; SBNetworkHeader header;
header.ToAddress = mac; header.ToAddress = mac;
header.FromAddress = this->NetworkDevice.MAC; header.FromAddress = this->NetworkDevice.MAC;
header.CommandType = SBS_COMMAND_NO_COMMAND; header.CommandType = SB_COMMAND_NO_COMMAND;
SBNetworkFrame frame = SBNetworkFrame(); SBNetworkFrame frame = SBNetworkFrame();
frame.Header = header; frame.Header = header;
@ -225,32 +225,38 @@ bool SBNetwork::sendToDevice(SBNetworkFrame frame){
return bSuccess; return bSuccess;
} }
bool SBNetwork::receive(SBNetworkFrame *frame){ bool SBNetwork::receiveInternal(SBNetworkFrame *frame) {
uint8_t pipe = -1; uint8_t pipe = -1;
if (radio.available(&pipe)){ if (radio.available(&pipe)) {
// Variable for the received timestamp // Variable for the received timestamp
uint8_t size = radio.getDynamicPayloadSize(); uint8_t size = radio.getDynamicPayloadSize();
if (size == 0){ if (size == 0) {
return false; return false;
} }
else{ else {
byte buffer[32]; byte buffer[32];
radio.read(buffer, size); radio.read(buffer, size);
// We cant use the target address of frame, because the first element in frame is the header // We cant use the target address of frame, because the first element in frame is the header
memcpy(frame, buffer, sizeof(SBNetworkHeader)); memcpy(frame, buffer, sizeof(SBNetworkHeader));
frame->MessageSize = size - sizeof(SBNetworkHeader); frame->MessageSize = size - sizeof(SBNetworkHeader);
if (frame->MessageSize > 0){ if (frame->MessageSize > 0) {
//uint8_t *payload = (uint8_t*)malloc(frame->MessageSize); //uint8_t *payload = (uint8_t*)malloc(frame->MessageSize);
memcpy(_ReceiveBuffer, buffer + sizeof(SBNetworkHeader), frame->MessageSize); memcpy(_ReceiveBuffer, buffer + sizeof(SBNetworkHeader), frame->MessageSize);
frame->Message = _ReceiveBuffer; frame->Message = _ReceiveBuffer;
} }
// We must check, if the received package is a NO_COMMAND_PACKAGE otherwise we have to handle it internally return true;
return this->handleCommandPackage(frame);
} }
} }
return false; return false;
} }
bool SBNetwork::receive(SBNetworkFrame *frame){
if (receiveInternal(frame)) {
// We must check, if the received package is a NO_COMMAND_PACKAGE otherwise we have to handle it internally
return this->handleCommandPackage(frame);
}
}
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;
@ -325,7 +331,7 @@ bool SBNetwork::connectToNetwork(){
SBNetworkHeader header; SBNetworkHeader header;
header.ToAddress = this->_BroadcastAddress; header.ToAddress = this->_BroadcastAddress;
header.FromAddress = this->NetworkDevice.MAC; header.FromAddress = this->NetworkDevice.MAC;
header.CommandType = SBS_COMMAND_SEARCH_MASTER; header.CommandType = SB_COMMAND_SEARCH_MASTER;
header.FragmentCount = 1; header.FragmentCount = 1;
header.PackageId = millis(); header.PackageId = millis();
@ -348,7 +354,7 @@ bool SBNetwork::connectToNetwork(){
return false; return false;
} }
else { else {
if (frame.Header.CommandType != SBS_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);
} }
@ -362,7 +368,7 @@ bool SBNetwork::connectToNetwork(){
Serial.println(); Serial.println();
Serial.print(F("Try to pair with master...")); Serial.print(F("Try to pair with master..."));
SBNetworkFrame conFrame; SBNetworkFrame conFrame;
conFrame.Header.CommandType = SBS_COMMAND_REQUEST_PAIRING; conFrame.Header.CommandType = SB_COMMAND_REQUEST_PAIRING;
conFrame.Header.FragmentCount = 1; conFrame.Header.FragmentCount = 1;
conFrame.Header.FragmentNr = 0; conFrame.Header.FragmentNr = 0;
conFrame.Header.FromAddress = this->NetworkDevice.MAC; conFrame.Header.FromAddress = this->NetworkDevice.MAC;
@ -383,7 +389,7 @@ bool SBNetwork::connectToNetwork(){
Serial.println(F("Timeout")); Serial.println(F("Timeout"));
return false; return false;
} }
if (frame.Header.CommandType != SBS_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"));
return false; return false;
} }
@ -403,12 +409,20 @@ bool SBNetwork::connectToNetwork(){
bool bMasterAvailable = this->pingDevice(this->NetworkDevice.MasterMAC); bool bMasterAvailable = this->pingDevice(this->NetworkDevice.MasterMAC);
if (bMasterAvailable) { if (bMasterAvailable) {
Serial.println(F("Done - Master available")); long lNow = millis();
} SBNetworkFrame pingAckFrame;
else { while ((lNow + 100) > millis()) {
if (this->receiveInternal(&pingAckFrame)) {
if (pingAckFrame.Header.CommandType == SB_COMMAND_PING) {
Serial.println(F("Done - Master available"));
return true;
}
}
}
Serial.println(F("Failed - Master not responding")); Serial.println(F("Failed - Master not responding"));
} }
return bMasterAvailable; Serial.println("Error - Sending Ping to Master");
return false;
} }
else { else {
return false; return false;
@ -419,7 +433,7 @@ bool SBNetwork::pingDevice(SBMacAddress mac){
SBNetworkHeader header; SBNetworkHeader header;
header.ToAddress = mac; header.ToAddress = mac;
header.FromAddress = this->NetworkDevice.MAC; header.FromAddress = this->NetworkDevice.MAC;
header.CommandType = SBS_COMMAND_PING; header.CommandType = SB_COMMAND_PING;
header.FragmentCount = 1; header.FragmentCount = 1;
header.FragmentNr = 0; header.FragmentNr = 0;
header.PackageId = millis(); header.PackageId = millis();
@ -454,13 +468,16 @@ bool SBNetwork::handleCommandPackage(SBNetworkFrame *frame){
//return false; //return false;
} }
switch (frame->Header.CommandType) { switch (frame->Header.CommandType) {
case SBS_COMMAND_PING: { case SB_COMMAND_PING: {
#ifdef _DEBUG #ifdef _DEBUG
Serial.println(F("Received 'PING'")); Serial.println(F("Received 'PING'"));
#endif #endif
if (bFound) {
pingDevice(frame->Header.FromAddress);
}
break; break;
} }
case SBS_COMMAND_SEARCH_MASTER: { case SB_COMMAND_SEARCH_MASTER: {
#ifdef _DEBUG #ifdef _DEBUG
Serial.print(F("Received 'SEARCH_MASTER' Package. ")); Serial.print(F("Received 'SEARCH_MASTER' Package. "));
#endif #endif
@ -468,7 +485,7 @@ bool SBNetwork::handleCommandPackage(SBNetworkFrame *frame){
#ifdef _DEBUG #ifdef _DEBUG
Serial.println(F("Send MasterACK...")); Serial.println(F("Send MasterACK..."));
#endif #endif
delay(100); delay(20);
bool bSend = sendMasterAck(frame->Header.FromAddress); bool bSend = sendMasterAck(frame->Header.FromAddress);
if (bSend) { if (bSend) {
return false; return false;
@ -482,7 +499,7 @@ bool SBNetwork::handleCommandPackage(SBNetworkFrame *frame){
#endif #endif
break; break;
} }
case SBS_COMMAND_REQUEST_PAIRING: { case SB_COMMAND_REQUEST_PAIRING: {
#ifdef _DEBUG #ifdef _DEBUG
Serial.print(F("Received 'PAIRING_REQUEST' Package. ")); Serial.print(F("Received 'PAIRING_REQUEST' Package. "));
#endif #endif
@ -490,7 +507,7 @@ bool SBNetwork::handleCommandPackage(SBNetworkFrame *frame){
#ifdef _DEBUG #ifdef _DEBUG
Serial.println(F("Send MasterACK...")); Serial.println(F("Send MasterACK..."));
#endif #endif
delay(100); delay(20);
// This is the point where we could stop orpcessing 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 orpcessing 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 (bSend) { if (bSend) {
@ -504,7 +521,7 @@ bool SBNetwork::handleCommandPackage(SBNetworkFrame *frame){
#endif #endif
break; break;
} }
case SBS_COMMAND_NO_COMMAND: case SB_COMMAND_NO_COMMAND:
default: { default: {
//Serial.println("No Command received. Passing through transport layer."); //Serial.println("No Command received. Passing through transport layer.");
return bFound; return bFound;
@ -524,7 +541,7 @@ bool SBNetwork::sendMasterAck(SBMacAddress mac){
SBNetworkHeader header; SBNetworkHeader header;
header.ToAddress = mac; header.ToAddress = mac;
header.FromAddress = this->NetworkDevice.MAC; header.FromAddress = this->NetworkDevice.MAC;
header.CommandType = SBS_COMMAND_MASTER_ACK; header.CommandType = SB_COMMAND_MASTER_ACK;
header.FragmentCount = 1; header.FragmentCount = 1;
header.PackageId = millis(); header.PackageId = millis();
@ -545,7 +562,7 @@ bool SBNetwork::sendPairingAck(SBMacAddress mac){
SBNetworkHeader header; SBNetworkHeader header;
header.ToAddress = mac; header.ToAddress = mac;
header.FromAddress = this->NetworkDevice.MAC; header.FromAddress = this->NetworkDevice.MAC;
header.CommandType = SBS_COMMAND_PAIRING_ACK; header.CommandType = SB_COMMAND_PAIRING_ACK;
header.FragmentCount = 1; header.FragmentCount = 1;
header.PackageId = millis(); header.PackageId = millis();
@ -553,7 +570,6 @@ 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->sendToDevice(frame); return this->sendToDevice(frame);
} }
else { else {

View File

@ -2,7 +2,7 @@
#ifndef _SB_NETWORK_ #ifndef _SB_NETWORK_
#define _SB_NETWORK_ #define _SB_NETWORK_
#define SB_VERSION "1.0.2" #define SB_VERSION "1.0.3"
#include <RF24_config.h> #include <RF24_config.h>
#include <RF24.h> #include <RF24.h>
@ -74,6 +74,8 @@ class SBNetwork{
bool sendPairingAck(SBMacAddress mac); bool sendPairingAck(SBMacAddress mac);
bool receiveInternal(SBNetworkFrame *frame);
bool receive(SBNetworkFrame *frame); bool receive(SBNetworkFrame *frame);
bool receiveMessage(void **message, uint8_t *messageSize, SBMacAddress *mac); bool receiveMessage(void **message, uint8_t *messageSize, SBMacAddress *mac);

View File

@ -15,4 +15,6 @@
#define FLASH_SIZE 512 #define FLASH_SIZE 512
#define ACK_WAIT 100
#endif #endif

View File

@ -4,14 +4,17 @@
#include <arduino.h> #include <arduino.h>
// Will be sent to check, if a device is available // Will be sent to check, if a device is available
#define SBS_COMMAND_PING 0 #define SB_COMMAND_PING 0
#define SBS_COMMAND_NO_COMMAND 1 // Will be sent, if normal data is transported
#define SB_COMMAND_NO_COMMAND 1
// Will be sent from a slave to find search a master // Will be sent from a slave to find search a master
#define SBS_COMMAND_SEARCH_MASTER 2 #define SB_COMMAND_SEARCH_MASTER 2
// Will be sent from a master after receiving a search master request // Will be sent from a master after receiving a search master request
#define SBS_COMMAND_MASTER_ACK 3 #define SB_COMMAND_MASTER_ACK 3
#define SBS_COMMAND_REQUEST_PAIRING 4 // Will be sent from a new client, in case he wants to join the network
#define SBS_COMMAND_PAIRING_ACK 5 #define SB_COMMAND_REQUEST_PAIRING 4
// Will be sent from the master after successfule adding a new client
#define SB_COMMAND_PAIRING_ACK 5
class SBMacAddress{ class SBMacAddress{
public: public: