hover-programs/rfudp/TxTunnelSender.cpp

218 lines
6.3 KiB
C++

/*
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");
}