mirror of
https://github.com/markqvist/reticulum-cpp
synced 2026-08-12 18:35:00 -04:00
WIP: Fixes, optimizations, and more Transport
Changed all time references to use decimal seconds to match Python reference implementation. Fixed memory issues caused by storing references to objects instead of copies. More implementation of Transport logic. This is the first build that fully implements end-to-end path finding and routing.
This commit is contained in:
parent
ea7b4603ed
commit
642486ac7e
28 changed files with 958 additions and 261 deletions
|
|
@ -4,6 +4,15 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#ifndef ARDUINO
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
using namespace RNS;
|
||||
using namespace RNS::Interfaces;
|
||||
|
||||
|
|
@ -25,29 +34,53 @@ def get_broadcast_for_if(name):
|
|||
UDPInterface::UDPInterface(const char* name /*= "UDPInterface"*/) : Interface(name) {
|
||||
|
||||
IN(true);
|
||||
//OUT(false);
|
||||
OUT(true);
|
||||
bitrate(BITRATE_GUESS);
|
||||
|
||||
}
|
||||
|
||||
void UDPInterface::start() {
|
||||
UDPInterface::UDPInterface(const char* wifi_ssid, const char* wifi_password, int local_port, const char* local_host /*=nullptr*/, const char* name /*= "UDPInterface"*/) : Interface(name),
|
||||
_local_port(local_port)
|
||||
{
|
||||
|
||||
IN(true);
|
||||
OUT(true);
|
||||
bitrate(BITRATE_GUESS);
|
||||
|
||||
if (wifi_ssid != nullptr) {
|
||||
_wifi_ssid = wifi_ssid;
|
||||
}
|
||||
if (wifi_password != nullptr) {
|
||||
_wifi_password = wifi_password;
|
||||
}
|
||||
if (local_host != nullptr) {
|
||||
_local_host = local_host;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*virtual*/ UDPInterface::~UDPInterface() {
|
||||
stop();
|
||||
}
|
||||
|
||||
bool UDPInterface::start() {
|
||||
online(false);
|
||||
|
||||
#ifdef ARDUINO
|
||||
// Connect to the WiFi network
|
||||
WiFi.begin(ssid, pwd);
|
||||
WiFi.begin(_wifi_ssid.c_str(), _wifi_password.c_str());
|
||||
Serial.println("");
|
||||
|
||||
// Wait for WiFi network connection to complete
|
||||
Serial.print("Connecting to ");
|
||||
Serial.print(ssid);
|
||||
Serial.print(_wifi_ssid.c_str());
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.print("Connected to ");
|
||||
Serial.println(ssid);
|
||||
Serial.println(_wifi_ssid.c_str());
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
|
|
@ -86,10 +119,78 @@ void UDPInterface::start() {
|
|||
*/
|
||||
|
||||
// This initializes udp and transfer buffer
|
||||
udp.begin(udpPort);
|
||||
udp.begin(_local_port);
|
||||
#else
|
||||
|
||||
// resolve local host
|
||||
struct in_addr local_addr;
|
||||
if (inet_aton(_local_host.c_str(), &local_addr) == 0) {
|
||||
struct hostent* host_ent = gethostbyname(_local_host.c_str());
|
||||
if (host_ent == nullptr || host_ent->h_addr_list[0] == nullptr) {
|
||||
error("Unable to resolve local host " + std::string(_local_host));
|
||||
return false;
|
||||
}
|
||||
_local_address = *((in_addr_t*)(host_ent->h_addr_list[0]));
|
||||
}
|
||||
else {
|
||||
_local_address = local_addr.s_addr;
|
||||
}
|
||||
|
||||
// resolve remote host
|
||||
struct in_addr remote_addr;
|
||||
if (inet_aton(_remote_host.c_str(), &remote_addr) == 0) {
|
||||
struct hostent* host_ent = gethostbyname(_remote_host.c_str());
|
||||
if (host_ent == nullptr || host_ent->h_addr_list[0] == nullptr) {
|
||||
error("Unable to resolve remote host " + std::string(_remote_host));
|
||||
return false;
|
||||
}
|
||||
_remote_address = *((in_addr_t*)(host_ent->h_addr_list[0]));
|
||||
}
|
||||
else {
|
||||
_remote_address = remote_addr.s_addr;
|
||||
}
|
||||
|
||||
// open udp socket
|
||||
extreme("Opening UDP socket");
|
||||
_socket = socket( PF_INET, SOCK_DGRAM, 0 );
|
||||
if (_socket < 0) {
|
||||
error("Unable to create socket with error " + std::to_string(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
// enable broadcast
|
||||
int broadcast = 1;
|
||||
setsockopt(_socket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast));
|
||||
|
||||
// bind to udp socket for listening
|
||||
info("Binding UDP socket " + std::to_string(_socket) + " to " + std::string(_local_host) + ":" + std::to_string(_local_port));
|
||||
sockaddr_in bind_addr;
|
||||
bind_addr.sin_family = AF_INET;
|
||||
bind_addr.sin_addr.s_addr = _local_address;
|
||||
bind_addr.sin_port = htons(_local_port);
|
||||
if (bind(_socket, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) == -1) {
|
||||
close(_socket);
|
||||
_socket = -1;
|
||||
error("Unable to bind socket with error " + std::to_string(errno));
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
online(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UDPInterface::stop() {
|
||||
#ifdef ARDUINO
|
||||
#else
|
||||
if (_socket > -1) {
|
||||
close(_socket);
|
||||
_socket = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
online(false);
|
||||
}
|
||||
|
||||
void UDPInterface::loop() {
|
||||
|
|
@ -98,10 +199,22 @@ void UDPInterface::loop() {
|
|||
// Check for incoming packet
|
||||
#ifdef ARDUINO
|
||||
udp.parsePacket();
|
||||
size_t len = udp.read(buffer.writable(Type::Reticulum::MTU), Type::Reticulum::MTU);
|
||||
size_t len = udp.read(_buffer.writable(Type::Reticulum::MTU), Type::Reticulum::MTU);
|
||||
if (len > 0) {
|
||||
buffer.resize(len);
|
||||
processIncoming(buffer);
|
||||
_buffer.resize(len);
|
||||
processIncoming(_buffer);
|
||||
}
|
||||
#else
|
||||
size_t available = 0;
|
||||
ioctl(_socket, FIONREAD, &available);
|
||||
if (available > 0) {
|
||||
size_t len = read(_socket, _buffer.writable(available), available);
|
||||
if (len > 0) {
|
||||
if (len < available) {
|
||||
_buffer.resize(len);
|
||||
}
|
||||
processIncoming(_buffer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -109,20 +222,26 @@ void UDPInterface::loop() {
|
|||
|
||||
/*virtual*/ void UDPInterface::processIncoming(const Bytes& data) {
|
||||
debug("UDPInterface.processIncoming: data: " + data.toHex());
|
||||
//debug("UDPInterface.processIncoming: text: " + data.toString());
|
||||
Interface::processIncoming(data);
|
||||
}
|
||||
|
||||
/*virtual*/ void UDPInterface::processOutgoing(const Bytes& data) {
|
||||
debug("UDPInterface.processOutgoing: data: " + data.toHex());
|
||||
debug("UDPInterface.processOutgoing: text: " + data.toString());
|
||||
try {
|
||||
if (online()) {
|
||||
// Send packet
|
||||
#ifdef ARDUINO
|
||||
udp.beginPacket(udpAddress, udpPort);
|
||||
udp.beginPacket(_remote_host.c_str(), _remote_port);
|
||||
udp.write(data.data(), data.size());
|
||||
udp.endPacket();
|
||||
#else
|
||||
extreme("Sending UDP packet to " + std::string(_remote_host) + ":" + std::to_string(_remote_port));
|
||||
sockaddr_in sock_addr;
|
||||
sock_addr.sin_family = AF_INET;
|
||||
sock_addr.sin_addr.s_addr = _remote_address;
|
||||
sock_addr.sin_port = htons(_remote_port);
|
||||
int sent = sendto(_socket, data.data(), data.size(), 0, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
|
||||
extreme("Sent " + std::to_string(sent) + " bytes to " + std::string(_remote_host) + ":" + std::to_string(_remote_port));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue