Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify interrupt handling #32

Merged
merged 7 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 56 additions & 83 deletions RF24Gateway.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
template<class mesh_t, class network_t, class radio_t>
ESBGateway<mesh_t, network_t, radio_t>::ESBGateway(radio_t& _radio, network_t& _network, mesh_t& _mesh) : radio(_radio), network(_network), mesh(_mesh)
{
interruptInProgress = 0;
interruptsEnabled = 1;
gotInterrupt = false;
}

/***************************************************************************************/
Expand Down Expand Up @@ -44,9 +43,9 @@ bool ESBGateway<mesh_t, network_t, radio_t>::begin(bool configTUN, bool meshEnab
#endif
config_TUN = configTUN;

///FIX
/// FIX

channel = _channel; //97;
channel = _channel; // 97;

dataRate = data_rate;

Expand All @@ -68,7 +67,7 @@ bool ESBGateway<mesh_t, network_t, radio_t>::begin(bool configTUN, bool meshEnab
if (!mesh_nodeID) {
mesh_nodeID = 253;
}
mesh.setNodeID(mesh_nodeID); //Try not to conflict with any low-numbered node-ids
mesh.setNodeID(mesh_nodeID); // Try not to conflict with any low-numbered node-ids
}
mesh.begin(channel, data_rate);
thisNodeAddress = mesh.mesh_address;
Expand Down Expand Up @@ -143,9 +142,9 @@ void ESBGateway<mesh_t, network_t, radio_t>::loadRoutingTable()
}
routingTableSize = count;

//for(int i=0; i<count; i++){
// std::cout << inet_ntoa(routingStruct[i].ip) << ";" << inet_ntoa(routingStruct[i].mask) << ";" << inet_ntoa(routingStruct[i].gw) << std::endl;
//}
// for(int i=0; i<count; i++){
// std::cout << inet_ntoa(routingStruct[i].ip) << ";" << inet_ntoa(routingStruct[i].mask) << ";" << inet_ntoa(routingStruct[i].gw) << std::endl;
// }
}

/***************************************************************************************/
Expand Down Expand Up @@ -192,7 +191,7 @@ int ESBGateway<mesh_t, network_t, radio_t>::allocateTunDevice(char* dev, int fla
struct ifreq ifr;
int fd;

//open the device
// open the device
if ((fd = open("/dev/net/tun", O_RDWR)) < 0) {
return fd;
}
Expand All @@ -207,15 +206,15 @@ int ESBGateway<mesh_t, network_t, radio_t>::allocateTunDevice(char* dev, int fla

// Create device
if (ioctl(fd, TUNSETIFF, (void*)&ifr) < 0) {
//close(fd);
// close(fd);
2bndy5 marked this conversation as resolved.
Show resolved Hide resolved
//#if (DEBUG_LEVEL >= 1)
std::cerr << "RF24Gw: Error: enabling TUNSETIFF" << std::endl;
std::cerr << "RF24Gw: If changing from TAP/TUN, run 'sudo ip link delete tun_nrf24' to remove the interface" << std::endl;
return -1;
//#endif
}

//Make persistent
// Make persistent
if (ioctl(fd, TUNSETPERSIST, 1) < 0) {
#if (DEBUG_LEVEL >= 1)
std::cerr << "RF24Gw: Error: enabling TUNSETPERSIST" << std::endl;
Expand All @@ -233,7 +232,7 @@ int ESBGateway<mesh_t, network_t, radio_t>::allocateTunDevice(char* dev, int fla
((char*)sap.sa_data)[2] = 0x32;
((char*)sap.sa_data)[3] = 0x34;

//printf("Address 0%o first %u last %u\n",address,sap.sa_data[0],sap.sa_data[1]);
// printf("Address 0%o first %u last %u\n",address,sap.sa_data[0],sap.sa_data[1]);
memcpy((char*)&ifr.ifr_hwaddr, (char*)&sap, sizeof(struct sockaddr));

if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) {
Expand Down Expand Up @@ -261,7 +260,7 @@ int ESBGateway<mesh_t, network_t, radio_t>::setIP(char* ip_addr, char* mask)
}

sin.sin_family = AF_INET;
//inet_aton(ip_addr,&sin.sin_addr.s_addr);
// inet_aton(ip_addr,&sin.sin_addr.s_addr);
inet_aton(ip_addr, &sin.sin_addr);
strncpy(ifr.ifr_name, tunName, IFNAMSIZ);

Expand All @@ -278,7 +277,7 @@ int ESBGateway<mesh_t, network_t, radio_t>::setIP(char* ip_addr, char* mask)
#endif

if (!(ifr.IRFFLAGS & IFF_UP)) {
//fprintf(stdout, "Device is currently down..setting up.-- %u\n", ifr.IRFFLAGS);
// fprintf(stdout, "Device is currently down..setting up.-- %u\n", ifr.IRFFLAGS);
ifr.IRFFLAGS |= IFF_UP;
if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
fprintf(stderr, "ifup: failed ");
Expand Down Expand Up @@ -314,18 +313,7 @@ int ESBGateway<mesh_t, network_t, radio_t>::setIP(char* ip_addr, char* mask)
template<class mesh_t, class network_t, class radio_t>
void ESBGateway<mesh_t, network_t, radio_t>::interrupts(bool enable)
{
if (enable) {
interruptsEnabled = enable;
}
else {
while (interruptInProgress) {
usleep(100);
}
interruptsEnabled = 0;
while (interruptInProgress) {
usleep(500);
}
}
// No longer required
}

/***************************************************************************************/
Expand All @@ -335,18 +323,7 @@ void ESBGateway<mesh_t, network_t, radio_t>::update(bool interrupts)
{

if (interrupts) {
interruptInProgress = 1;
uint32_t intTimer = millis();
while (!interruptsEnabled) {
usleep(750);
if (millis() - intTimer > 1000) { //Wait up to 1s for interrupts to be re-enabled
interruptInProgress = 0;
return;
}
}
handleRadioIn();
handleTX();
interruptInProgress = 0;
gotInterrupt = true;
}
else {
handleRadioIn();
Expand All @@ -362,25 +339,21 @@ template<class mesh_t, class network_t, class radio_t>
void ESBGateway<mesh_t, network_t, radio_t>::poll(uint32_t waitDelay)
{

handleRX(waitDelay);

while (interruptInProgress) {
usleep(100);
}
interruptsEnabled = 0;
while (interruptInProgress) {
usleep(500);
if (gotInterrupt) {
gotInterrupt = false;
handleRadioIn();
handleTX();
}

//gateway.poll() is called manually when using interrupts, so if the radio RX buffer is full, or interrupts have been missed, check for it here.
if (radio.rxFifoFull()) {
else if (radio.rxFifoFull()) {
fifoCleared = true;
handleRadioIn();
interruptsEnabled = 1;
return;
handleRadioOut();
}
else {
delay(waitDelay);
}
handleRX();
handleRadioOut();
interruptsEnabled = 1;
}

/***************************************************************************************/
Expand Down Expand Up @@ -416,10 +389,10 @@ void ESBGateway<mesh_t, network_t, radio_t>::handleRadioIn()
std::cout << "Radio: Received " << bytesRead << " bytes ... " << std::endl;
#endif
#if (DEBUG_LEVEL >= 3)
//printPayload(msg.getPayloadStr(),"radio RX");
// printPayload(msg.getPayloadStr(),"radio RX");
std::cout << "TunRead: " << std::endl;
for (size_t i = 0; i < msg.size; i++) {
//std::cout << std::hex << buffer[i];
// std::cout << std::hex << buffer[i];
printf(":%0x :", msg.message[i]);
}
std::cout << std::endl;
Expand All @@ -429,7 +402,7 @@ void ESBGateway<mesh_t, network_t, radio_t>::handleRadioIn()
rxQueue.push(msg);
}
else {
//std::cerr << "Radio: Error reading data from radio. Read '" << bytesRead << "' Bytes." << std::endl;
// std::cerr << "Radio: Error reading data from radio. Read '" << bytesRead << "' Bytes." << std::endl;
}
network.external_queue.pop();
}
Expand Down Expand Up @@ -458,7 +431,7 @@ struct in_addr ESBGateway<mesh_t, network_t, radio_t>::getLocalIP()

family = ifa->ifa_addr->sa_family;

//This is an IPv4 interface, get the IP
// This is an IPv4 interface, get the IP
if (family == AF_INET) {
s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if (s == 0) {
Expand Down Expand Up @@ -489,16 +462,16 @@ void ESBGateway<mesh_t, network_t, radio_t>::handleRadioOut()
#endif
#if (DEBUG_LEVEL >= 3)

//PrintDebug == 1 does not have an endline.
//printPayload(msg.getPayloadStr(),"radio TX");
// PrintDebug == 1 does not have an endline.
// printPayload(msg.getPayloadStr(),"radio TX");
#endif

std::uint8_t* tmp = msgTx->message;

if (!config_TUN) { //TAP can use RF24Mesh for address assignment, but will still use ARP for address resolution
if (!config_TUN) { // TAP can use RF24Mesh for address assignment, but will still use ARP for address resolution

uint32_t RF24_STR = 0x34324652; //Identifies the mac as an RF24 mac
uint32_t ARP_BC = 0xFFFFFFFF; //Broadcast address
uint32_t RF24_STR = 0x34324652; // Identifies the mac as an RF24 mac
uint32_t ARP_BC = 0xFFFFFFFF; // Broadcast address
struct macStruct
{
uint32_t rf24_Verification;
Expand All @@ -515,22 +488,22 @@ void ESBGateway<mesh_t, network_t, radio_t>::handleRadioOut()
ok = network.write(header, &msgTx->message, msgTx->size);
}
else if (macData.rf24_Verification == ARP_BC) {
RF24NetworkHeader header(/*to node*/ 00, EXTERNAL_DATA_TYPE); //Set to master node, will be modified by RF24Network if multi-casting
RF24NetworkHeader header(/*to node*/ 00, EXTERNAL_DATA_TYPE); // Set to master node, will be modified by RF24Network if multi-casting
if (msgTx->size <= 42) {
if (thisNodeAddress == 00) { //Master Node
if (thisNodeAddress == 00) { // Master Node

uint32_t arp_timeout = millis();

ok = network.multicast(header, &msgTx->message, msgTx->size, 1); //Send to Level 1
ok = network.multicast(header, &msgTx->message, msgTx->size, 1); // Send to Level 1
while (millis() - arp_timeout < 5) {
network.update();
}
network.multicast(header, &msgTx->message, msgTx->size, 1); //Send to Level 1
network.multicast(header, &msgTx->message, msgTx->size, 1); // Send to Level 1
arp_timeout = millis();
while (millis() - arp_timeout < 15) {
network.update();
}
network.multicast(header, &msgTx->message, msgTx->size, 1); //Send to Level 1
network.multicast(header, &msgTx->message, msgTx->size, 1); // Send to Level 1
}
else {
ok = network.write(header, &msgTx->message, msgTx->size);
Expand All @@ -549,19 +522,19 @@ void ESBGateway<mesh_t, network_t, radio_t>::handleRadioOut()
struct in_addr ipDestination;
memcpy(&ipDestination.s_addr, &tmp[16], 4);

if ((getLocalIP().s_addr & 0x00FFFFFF) == (ipDestination.s_addr & 0x00FFFFFF)) { //Is inside the RF24Mesh network
if ((getLocalIP().s_addr & 0x00FFFFFF) == (ipDestination.s_addr & 0x00FFFFFF)) { // Is inside the RF24Mesh network
if ((meshAddr = mesh.getAddress(lastOctet)) > 0) {
header.to_node = meshAddr;
sendData = true;
}
else {
if (thisNodeID > 0) { //If IP is in mesh range, address lookup fails, and this is not master,
sendData = true; //send to 00 anyway in case destination is master, or the lookup just failed
if (thisNodeID > 0) { // If IP is in mesh range, address lookup fails, and this is not master,
sendData = true; // send to 00 anyway in case destination is master, or the lookup just failed
}
//printf("Could not find matching mesh nodeID for IP ending in %d\n",lastOctet);
// printf("Could not find matching mesh nodeID for IP ending in %d\n",lastOctet);
}
}
else if (thisNodeID > 0) { //If not master, send to master for routing etc. if target not within mesh
else if (thisNodeID > 0) { // If not master, send to master for routing etc. if target not within mesh
sendData = true;
}
else if (routingTableSize > 0) {
Expand All @@ -570,7 +543,7 @@ void ESBGateway<mesh_t, network_t, radio_t>::handleRadioOut()
network.s_addr = routingStruct[i].ip.s_addr & routingStruct[i].mask.s_addr;
struct in_addr destNet;
destNet.s_addr = ipDestination.s_addr & routingStruct[i].mask.s_addr;
//printf("network %s destNet: %s\n",inet_ntoa(network),inet_ntoa(destNet));
// printf("network %s destNet: %s\n",inet_ntoa(network),inet_ntoa(destNet));
if (destNet.s_addr == network.s_addr) {
uint8_t toNode = routingStruct[i].gw.s_addr >> 24;
int16_t netAddr = 0;
Expand All @@ -585,22 +558,22 @@ void ESBGateway<mesh_t, network_t, radio_t>::handleRadioOut()

if (sendData) {
ok = network.write(header, msgTx->message, msgTx->size);
//std::cout << "SendData " << header.to_node << std::endl;
// std::cout << "SendData " << header.to_node << std::endl;
}
}
//delay( rf24_min(msgTx->size/48,20));
// delay( rf24_min(msgTx->size/48,20));
txQueue.pop();

//printf("Addr: 0%#x\n",macData.rf24_Addr);
//printf("Verif: 0%#x\n",macData.rf24_Verification);
// printf("Addr: 0%#x\n",macData.rf24_Addr);
// printf("Verif: 0%#x\n",macData.rf24_Verification);
if (ok) {
// std::cout << "ok." << std::endl;
}
else {
// std::cerr << "failed." << std::endl;
}

} //End Tx
} // End Tx
}

/***************************************************************************************/
Expand Down Expand Up @@ -637,7 +610,7 @@ void ESBGateway<mesh_t, network_t, radio_t>::handleRX(uint32_t waitDelay)
msgStruct msg;
memcpy(&msg.message, &buffer, nread);
msg.size = nread;
if (txQueue.size() < 2) {
if (txQueue.size() < 10) {
txQueue.push(msg);
}
else {
Expand Down Expand Up @@ -667,7 +640,7 @@ void ESBGateway<mesh_t, network_t, radio_t>::handleTX()

if (msg->size > MAX_PAYLOAD_SIZE)
{
//printf("*****WTF OVER *****");
// printf("*****WTF OVER *****");
2bndy5 marked this conversation as resolved.
Show resolved Hide resolved
rxQueue.pop();
return;
}
Expand All @@ -678,7 +651,7 @@ void ESBGateway<mesh_t, network_t, radio_t>::handleTX()
size_t writtenBytes = write(tunFd, &msg->message, msg->size);
if (writtenBytes != msg->size)
{
//std::cerr << "Tun: Less bytes written to tun/tap device then requested." << std::endl;
// std::cerr << "Tun: Less bytes written to tun/tap device then requested." << std::endl;
#if DEBUG_LEVEL >= 1
printf("Tun: Less bytes written %d to tun/tap device then requested %d.", writtenBytes, msg->size);
#endif
Expand All @@ -691,10 +664,10 @@ void ESBGateway<mesh_t, network_t, radio_t>::handleTX()
}

#if (DEBUG_LEVEL >= 3)
//printPayload(msg.message,"tun write");
// printPayload(msg.message,"tun write");
std::cout << "TunRead: " << std::endl;
for (size_t i = 0; i < msg->size; i++) {
//printf(":%0x :",msg->message[i]);
// printf(":%0x :",msg->message[i]);
}
std::cout << std::endl;
#endif
Expand Down Expand Up @@ -732,7 +705,7 @@ void ESBGateway<mesh_t, network_t, radio_t>::setupSocket()
exit(1);
}
addr.sin_port = htons(32001);
//buf = "Hello UDP";
// buf = "Hello UDP";
s = socket(PF_INET, SOCK_DGRAM, 0);
if (s == -1) {
perror("socket");
Expand Down
6 changes: 2 additions & 4 deletions RF24Gateway.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,7 @@ class ESBGateway
void handleRadioIn();
void handleRX(uint32_t waitDelay = 0);
void handleTX();
volatile bool interruptInProgress;
volatile bool interruptsEnabled;

volatile bool gotInterrupt;
int configDevice(uint16_t address);
int allocateTunDevice(char* dev, int flags, uint16_t address);

Expand All @@ -263,7 +261,7 @@ class ESBGateway
// void printPayload(std::string buffer, std::string debugMsg = "");
// void printPayload(char* buffer, int nread, std::string debugMsg = "");

int s; //Socket variable for sending UDP
int s; // Socket variable for sending UDP
void setupSocket();
struct sockaddr_in addr;
struct in_addr getLocalIP();
Expand Down
Loading