From 151b5160d2b5a73e04d9b5035be3f0b8932e6a82 Mon Sep 17 00:00:00 2001 From: Angel Garcia Date: Tue, 21 May 2019 03:54:27 +0200 Subject: [PATCH] Tunnel server and first receiver Sin transmision mediante ACKs gestor vacio --- hover-controller/Makefile | 37 +++++ hover-controller/hover-controller.cpp | 137 ++++++++++++++++ rfudp/Makefile | 41 +++++ rfudp/TxTunnel.h | 51 ++++++ rfudp/TxTunnelSender.cpp | 217 ++++++++++++++++++++++++++ rfudp/client_test.cpp | 67 ++++++++ rfudp/doSUID.sh | 9 ++ 7 files changed, 559 insertions(+) create mode 100644 hover-controller/Makefile create mode 100644 hover-controller/hover-controller.cpp create mode 100644 rfudp/Makefile create mode 100644 rfudp/TxTunnel.h create mode 100644 rfudp/TxTunnelSender.cpp create mode 100644 rfudp/client_test.cpp create mode 100755 rfudp/doSUID.sh diff --git a/hover-controller/Makefile b/hover-controller/Makefile new file mode 100644 index 0000000..d941e09 --- /dev/null +++ b/hover-controller/Makefile @@ -0,0 +1,37 @@ +############################################################################# +# +# Makefile for Raspberry Pi NRF24L01/NRF24L01+ hover controller +# +# Run: +# make clean; make +# sudo ./receiver +############################################################################# +prefix := /usr/local + +# The recommended compiler flags for the Raspberry Pi +#CCFLAGS=-Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s +CPUFLAGS=-march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard +CFLAGS=-march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -Ofast -Wall -pthread + +RF_LIB=rf24 +RF_LIB_DIR=/usr/local/lib +RF_HEADER_DIR=/usr/local/include/RF24 + +# define all programs +PROGRAMS = hover-controller +SOURCES = ${PROGRAMS:=.cpp} + + +all: ${PROGRAMS} tests + + +${PROGRAMS}: ${SOURCES} + $(CXX) $(CFLAGS) -I$(RF_HEADER_DIR) -L$(RF_LIB_DIR) -l$(RF_LIB) $@.cpp -o $@ + + +tests: + + +.PHONY: clean +clean: + rm -rf $(PROGRAMS) *.o diff --git a/hover-controller/hover-controller.cpp b/hover-controller/hover-controller.cpp new file mode 100644 index 0000000..ed66007 --- /dev/null +++ b/hover-controller/hover-controller.cpp @@ -0,0 +1,137 @@ +/* +TMRh20 2014 + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. + */ + +/** General Data Transfer Rate Test + * This example demonstrates basic data transfer functionality with the + updated library. This example will display the transfer rates acheived using + the slower form of high-speed transfer using blocking-writes. + */ + +#include "../rfudp/TxTunnel.h" + +using namespace std; +// +// Hardware configuration +// + +/****************** Raspberry Pi ***********************/ + +// Radio CE Pin, CSN Pin, SPI Speed +// See http://www.airspayce.com/mikem/bcm2835/group__constants.html#ga63c029bd6500167152db4e57736d0939 and the related enumerations for pin information. + +// Setup for GPIO 15 CE and CE0 CSN with SPI Speed @ 8Mhz +RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_32MHZ); + + +// Radio pipe addresses for the 2 nodes to communicate. From "TxTunnel.h" +//const uint8_t addresses[][5] = {"2RPi","0RPi"}; + +// loop condition +sig_atomic_t loop_on = TRUE; + +void signal_handler(int sig){ + loop_on = FALSE; +} + +int main(int argc, char** argv){ + + + char buffer[MAX_MSG_SZ+1]; + + // SIGNAL handler + struct sigaction sa; + sa.sa_handler = &signal_handler; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(SIGINT, &sa, NULL); + sigaction(SIGQUIT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + + +/* RF setup */ + radio.begin(); // Setup and configure rf radio + radio.powerUp(); + #ifdef RF_CHANNEL + #if RF_CHANNEL != 0 + radio.setChannel(RF_CHANNEL); // If is definned and not 0, set channel + #endif + #endif + radio.setPALevel(RF24_PA_MAX); // Set Power Amplification to MAX + radio.setDataRate(RF24_2MBPS); // Set maximun datarate + radio.setAutoAck(1); // Ensure autoACK is enabled + radio.enableAckPayload(); // Allow optional ack payloads + radio.enableDynamicPayloads(); + radio.setRetries(2,10); // Optionally, increase the delay between retries & # of retries + radio.setCRCLength(RF24_CRC_8); // Use 8-bit CRC for performance + + + + // This opens two pipes for these two nodes to communicate + // back and forth. + if ( 0 == 1 ) + { + radio.openWritingPipe(addresses[1]); + radio.openReadingPipe(1,addresses[0]); + radio.stopListening(); + } else { + radio.openWritingPipe(addresses[0]); + radio.openReadingPipe(1,addresses[1]); + radio.startListening(); + } + + + // + int n; + uint8_t pipeNo; + memset(buffer, 0, sizeof(buffer)); + + do{ + // GET DATA FROM CLIENT + if(radio.available(&pipeNo)){ + n = radio.getDynamicPayloadSize(); + if(n < 1){ + // Corrupt payload has been flushed + continue; + }else + radio.read(buffer, n); + }else{ + continue; + } + buffer[n] = '\0'; + + // Print info about msg + eprintf("MSG: \'%s\'\n", buffer); + + + /* START process Part */ + + + /* END process Part */ + + // Answer the client + #if ACK_MODE //ACK MODE + radio.writeAckPayload(pipeNo, buffer, n ); + #else + radio.stopListening(); + if ( radio.write(buffer,n) ) + printf("sending correct\n"); + else + eprintf("error\n"); + radio.startListening(); + #endif + + + + }while(loop_on); + + // Power down the antenna + eprintf("Powering down the antenna"); + radio.powerDown(); + eprintf("\n"); +} + diff --git a/rfudp/Makefile b/rfudp/Makefile new file mode 100644 index 0000000..4a2d220 --- /dev/null +++ b/rfudp/Makefile @@ -0,0 +1,41 @@ +############################################################################# +# +# Makefile for Raspberry Pi NRF24L01/NRF24L01+ udp tunnel server +# +# Run: +# make clean; make +# sudo ./TxTunnelSender +############################################################################# +prefix := /usr/local + +# The recommended compiler flags for the Raspberry Pi +#CCFLAGS=-Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s +CPUFLAGS=-march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard +CFLAGS=-march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -Ofast -Wall -pthread + +RF_LIB=rf24 +RF_LIB_DIR=/usr/local/lib +RF_HEADER_DIR=/usr/local/include/RF24 + +# define all programs +PROGRAMS = TxTunnelSender +SOURCES = ${PROGRAMS:=.cpp} + + +all: ${PROGRAMS} tests + + +${PROGRAMS}: ${SOURCES} + $(CXX) $(CFLAGS) -I$(RF_HEADER_DIR) -L$(RF_LIB_DIR) -l$(RF_LIB) $@.cpp -o $@ + ./doSUID.sh $@ + + +tests: client_test + +client_test: client_test.cpp + $(CXX) $(CFLAGS) $@.cpp -o $@ + + +.PHONY: clean +clean: + rm -rf $(PROGRAMS) *.o client_test diff --git a/rfudp/TxTunnel.h b/rfudp/TxTunnel.h new file mode 100644 index 0000000..5acd3db --- /dev/null +++ b/rfudp/TxTunnel.h @@ -0,0 +1,51 @@ +#ifndef __TX_TUNNEL_H__ +#define __TX_TUNNEL_H__ + +// Basic headers +#include +#include +#include +#include +#include + +// RF libs +#include +#include +#include +#include +#include +#include + +// UDP libs +#include +#include +#include +#include + +// Signal handling +#include + +// Error handling +#include + + +// various functions and definitions +#define eprintf(...) fprintf(stderr, __VA_ARGS__); + +#define FALSE (1 != 1) +#define TRUE (!FALSE) + + +// TxTunnel Congif +#define SERVER_IP "192.168.1.149" +#define SERVER_PORT 8080 +#define MAX_MSG_SZ 32 +#define RF_CHANNEL 0 + +#define ACK_MODE FALSE + +// Radio pipe addresses for the 2 nodes to communicate. +const uint8_t addresses[][5] = {"2RPi","0RPi"}; + + +#endif // __TX_TUNNEL_H__ diff --git a/rfudp/TxTunnelSender.cpp b/rfudp/TxTunnelSender.cpp new file mode 100644 index 0000000..01787b4 --- /dev/null +++ b/rfudp/TxTunnelSender.cpp @@ -0,0 +1,217 @@ +/* +TMRh20 2014 + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. + */ + +/** General Data Transfer Rate Test + * This example demonstrates basic data transfer functionality with the + updated library. This example will display the transfer rates acheived using + the slower form of high-speed transfer using blocking-writes. + */ + +#include "TxTunnel.h" + +using namespace std; +// +// Hardware configuration +// + +/****************** Raspberry Pi ***********************/ + +// Radio CE Pin, CSN Pin, SPI Speed +// See http://www.airspayce.com/mikem/bcm2835/group__constants.html#ga63c029bd6500167152db4e57736d0939 and the related enumerations for pin information. + +// Setup for GPIO 15 CE and CE0 CSN with SPI Speed @ 8Mhz +RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_32MHZ); + + +// Radio pipe addresses for the 2 nodes to communicate. From "TxTunnel.h" +//const uint8_t addresses[][5] = {"2RPi","0RPi"}; + +// loop condition +sig_atomic_t loop_on = TRUE; + +void signal_handler(int sig){ + loop_on = FALSE; +} + +int main(int argc, char** argv){ + + // here we define a socket address to be used and a buffer to store data + int sockfd; + char buffer[MAX_MSG_SZ+1]; + // Here are defined both sockets structs from server and sender + struct sockaddr_in servaddr, cliaddr; + + // SIGNAL handler + struct sigaction sa; + sa.sa_handler = &signal_handler; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(SIGINT, &sa, NULL); + sigaction(SIGQUIT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + + +/* UDP LISTENER setup */ + + // Creating socket file descriptor + if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { + perror("socket creation failed"); + //eprintf("socket creation failed: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + + // set both struct to 0s before initialization + memset(&servaddr, 0, sizeof(servaddr)); + memset(&cliaddr, 0, sizeof(cliaddr)); + + // Filling server information + servaddr.sin_family = AF_INET; // IPv4 + servaddr.sin_addr.s_addr = INADDR_ANY; // Listen on any interface + servaddr.sin_port = htons(SERVER_PORT); // Port + + // Bind the socket with the server address + if ( bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 ) + { + perror("bind failed"); + //eprintf("bind failed: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + + +/* RF setup */ + radio.begin(); // Setup and configure rf radio + radio.powerUp(); + #ifdef RF_CHANNEL + #if RF_CHANNEL != 0 + radio.setChannel(RF_CHANNEL); // If is definned and not 0, set channel + #endif + #endif + radio.setPALevel(RF24_PA_MAX); // Set Power Amplification to MAX + radio.setDataRate(RF24_2MBPS); // Set maximun datarate + radio.setAutoAck(1); // Ensure autoACK is enabled + radio.enableDynamicPayloads(); + radio.setRetries(2,10); // Optionally, increase the delay between retries & # of retries + radio.setRetries(15,15); + radio.setCRCLength(RF24_CRC_8); // Use 8-bit CRC for performance + + +/* Print setup details*/ + printf("================ UDP Configuration ================\n"); + printf("SERVER IP = %s\n", inet_ntoa(servaddr.sin_addr)); + printf("SERVER PORT = %i\n", ntohs(servaddr.sin_port)); + printf("MSG MAX SIZE = %i\n", MAX_MSG_SZ); + printf("ACK MODE = %s\n", ACK_MODE? "true":"false"); + radio.printDetails(); + printf("\n"); + + + + // This opens two pipes for these two nodes to communicate + // back and forth. + if ( 0 == 0 ) + { + radio.openWritingPipe(addresses[1]); + radio.openReadingPipe(1,addresses[0]); + radio.stopListening(); + } else { + radio.openWritingPipe(addresses[0]); + radio.openReadingPipe(1,addresses[1]); + radio.startListening(); + } + + + // + int n; + #if !ACK_MODE + unsigned long loop_start; + #endif + unsigned int cliaddr_len = sizeof(cliaddr); + memset(buffer, 0, sizeof(buffer)); + + printf("Starting listenning for messages\n"); + + do{ + // GET DATA FROM CLIENT + n = recvfrom( + sockfd, (char *) buffer, MAX_MSG_SZ, MSG_WAITALL, + ( struct sockaddr *) &cliaddr, &cliaddr_len + ); + if(n == -1){ // Test for error + //fprintf(stderr, "some error ocurred: %s\n", strerror(errno)); + perror("[UDP Listen] some error ocurred"); + continue; + } + buffer[n] = '\0'; + + // Print info about client + printf("Client addrr: %s, port: %i\n", + inet_ntoa(cliaddr.sin_addr), // addrress + ntohs(cliaddr.sin_port) // port + ); + printf("MSG: \'%s\'\n", buffer); + + + /* START RF Part */ + #if ACK_MODE + if ( radio.write(buffer,n) ){ + //usleep(10000); + if(!radio.available()){ + // If nothing in the buffer, we got an ack but it is blank + strcpy(buffer,"ACK"); + }else{ + n = radio.getDynamicPayloadSize(); + radio.read(buffer, MAX_MSG_SZ); + } + }else{ + // If no ack response, sending failed + eprintf("Sending failed.\n\r"); + strcpy(buffer,"TxERR\0"); + n=strlen(buffer); + } + #else + radio.write(buffer,n); + + loop_start = millis(); + radio.startListening(); + while ( !radio.available() && (millis() - loop_start) < 100) { + // Serial.println(F("waiting.")); + } + if (millis() - loop_start >= 100) { + eprintf("Not Response.\n\r"); + strcpy(buffer,"TxERR\0"); + n=strlen(buffer); + } else { + n = radio.getDynamicPayloadSize(); + radio.read(buffer, MAX_MSG_SZ); + } + radio.stopListening(); + #endif + buffer[n] = '\0'; + + /* END RF Part */ + + printf("ANS: \'%s\'\n", buffer); + + // Answer the client + sendto( + sockfd, (char *) buffer, strlen(buffer), MSG_CONFIRM, + (const struct sockaddr *) &cliaddr, cliaddr_len + ); + + }while(loop_on); + + // Power down the antenna + eprintf("Powering down the antenna"); + radio.powerDown(); + eprintf("\n"); + // Close the socket + eprintf("Closing scockets"); + close(sockfd); + eprintf("\n"); +} + diff --git a/rfudp/client_test.cpp b/rfudp/client_test.cpp new file mode 100644 index 0000000..1571890 --- /dev/null +++ b/rfudp/client_test.cpp @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "TxTunnel.h" + +// loop condition +sig_atomic_t loop_on = TRUE; + +void signal_handler(int sig){ + loop_on = FALSE; +} + +int main(){ + + int sockfd, n; + unsigned int len; + char buffer[MAX_MSG_SZ]; + struct sockaddr_in servaddr, direccion; + + // SIGNAL handler + struct sigaction sa; + sa.sa_handler = &signal_handler; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(SIGINT, &sa, NULL); + sigaction(SIGQUIT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + + if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { + perror("fallo creacion del socket"); + exit(EXIT_FAILURE); + } + + memset(&servaddr, 0, sizeof(servaddr)); + memset(&direccion, 0, sizeof(direccion)); + + direccion.sin_family = AF_INET; + direccion.sin_port = htons(SERVER_PORT); + direccion.sin_addr.s_addr = inet_addr(SERVER_IP); + +do{ + printf("Introduce el mssg: "); + fgets(buffer, MAX_MSG_SZ, stdin); + + sendto( + sockfd, (const char *) buffer, strlen(buffer), MSG_CONFIRM, + (const struct sockaddr *)&direccion, sizeof(direccion) + ); + + len = sizeof(servaddr); + n = recvfrom( + sockfd, (char *) buffer, MAX_MSG_SZ, MSG_WAITALL, + (struct sockaddr *) &servaddr, &len + ); + + buffer[n] = '\0'; + printf("ANS: \'%s\'\n", buffer); +}while(loop_on); +} diff --git a/rfudp/doSUID.sh b/rfudp/doSUID.sh new file mode 100755 index 0000000..d0757a2 --- /dev/null +++ b/rfudp/doSUID.sh @@ -0,0 +1,9 @@ +#!/bin/bash +SUDO="" + +if [ $UID != 0 ]; then + SUDO="sudo" +fi + +${SUDO} chown root: "$@" +${SUDO} chmod u+s "$@"