Skip to content

Commit

Permalink
#79: add udp writer
Browse files Browse the repository at this point in the history
  • Loading branch information
andreas committed Nov 4, 2024
1 parent d0dee36 commit 490a5b9
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/api/GwApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ class GwApi{
unsigned long ser2Tx=0;
unsigned long tcpSerRx=0;
unsigned long tcpSerTx=0;
unsigned long udpwTx=0;
int tcpClients=0;
unsigned long tcpClRx=0;
unsigned long tcpClTx=0;
Expand Down
26 changes: 26 additions & 0 deletions lib/channel/GwChannelList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "GwSocketServer.h"
#include "GwSerial.h"
#include "GwTcpClient.h"
#include "GwUdpWriter.h"
class SerInit{
public:
int serial=-1;
Expand Down Expand Up @@ -241,6 +242,24 @@ static ChannelParam channelParameters[]={
.maxId=-1,
.rxstatus=offsetof(GwApi::Status,GwApi::Status::tcpClRx),
.txstatus=offsetof(GwApi::Status,GwApi::Status::tcpClTx)
},
{
.id=UDPW_CHANNEL_ID,
.baud="",
.receive="",
.send=GwConfigDefinitions::udpwEnabled,
.direction="",
.toN2K="",
.readF="",
.writeF=GwConfigDefinitions::udpwWriteFilter,
.preventLog="",
.readAct="",
.writeAct="",
.sendSeasmart=GwConfigDefinitions::udpwSeasmart,
.name="UDPWriter",
.maxId=-1,
.rxstatus=0,
.txstatus=offsetof(GwApi::Status,GwApi::Status::udpwTx)
}

};
Expand Down Expand Up @@ -425,6 +444,13 @@ void GwChannelList::begin(bool fallbackSerial){
);
}
addChannel(createChannel(logger,config,TCP_CLIENT_CHANNEL_ID,client));

//udp writer
if (config->getBool(GwConfigDefinitions::udpwEnabled)){
GwUdpWriter *writer=new GwUdpWriter(config,logger,UDPW_CHANNEL_ID);
writer->begin();
addChannel(createChannel(logger,config,UDPW_CHANNEL_ID,writer));
}
logger->flush();
}
String GwChannelList::getMode(int id){
Expand Down
1 change: 1 addition & 0 deletions lib/channel/GwChannelList.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define SERIAL2_CHANNEL_ID 3
#define TCP_CLIENT_CHANNEL_ID 4
#define MIN_TCP_CHANNEL_ID 5
#define UDPW_CHANNEL_ID 20

#define MIN_USER_TASK 200
class GwSocketServer;
Expand Down
59 changes: 59 additions & 0 deletions lib/socketserver/GwUdpWriter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "GwUdpWriter.h"
#include <ESPmDNS.h>
#include <errno.h>
#include "GwBuffer.h"
#include "GwSocketConnection.h"
#include "GwSocketHelper.h"

GwUdpWriter::GwUdpWriter(const GwConfigHandler *config, GwLog *logger, int minId)
{
this->config = config;
this->logger = logger;
this->minId = minId;
}

void GwUdpWriter::begin()
{
fd=socket(AF_INET,SOCK_DGRAM,IPPROTO_IP);
if (fd < 0){
LOG_ERROR("unable to create udp socket");
return;
}
int enable = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &enable, sizeof(int));
port=config->getInt(GwConfigDefinitions::udpwPort);
//TODO: check port
address=config->getString(GwConfigDefinitions::udpwAddress);
LOG_INFO("UDP writer created, address=%s, port=%d",
address.c_str(),port);
inet_pton(AF_INET, address.c_str(), &destination.sin_addr);
destination.sin_family = AF_INET;
destination.sin_port = htons(port);
}

void GwUdpWriter::loop(bool handleRead, bool handleWrite)
{

}

void GwUdpWriter::readMessages(GwMessageFetcher *writer)
{

}
size_t GwUdpWriter::sendToClients(const char *buf, int source,bool partial)
{
if (source == minId) return 0;
size_t len=strlen(buf);
ssize_t err = sendto(fd,buf,len,0,(struct sockaddr *)&destination, sizeof(destination));
if (err < 0){
LOG_DEBUG(GwLog::DEBUG,"UDP writer error sending: %d",errno);
return 0;
}
return err;
}


GwUdpWriter::~GwUdpWriter()
{
}
28 changes: 28 additions & 0 deletions lib/socketserver/GwUdpWriter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef _GWUDPWRITER_H
#define _GWUDPWRITER_H
#include "GWConfig.h"
#include "GwLog.h"
#include "GwBuffer.h"
#include "GwChannelInterface.h"
#include <memory>
#include <sys/socket.h>
#include <arpa/inet.h>

class GwUdpWriter: public GwChannelInterface{
private:
const GwConfigHandler *config;
GwLog *logger;
int fd=-1;
int minId;
int port;
String address;
struct sockaddr_in destination;
public:
GwUdpWriter(const GwConfigHandler *config,GwLog *logger,int minId);
~GwUdpWriter();
void begin();
virtual void loop(bool handleRead=true,bool handleWrite=true);
virtual size_t sendToClients(const char *buf,int sourceId, bool partialWrite=false);
virtual void readMessages(GwMessageFetcher *writer);
};
#endif
41 changes: 41 additions & 0 deletions web/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,47 @@
"description": "send NMEA2000 as seasmart to remote TCP server",
"category": "TCP client"
},
{
"name": "udpwEnabled",
"label": "enable",
"type": "boolean",
"default": "false",
"description":"enable the UDP writer",
"category":"UDP writer"
},
{
"name": "udpwPort",
"label": "remote port",
"type": "number",
"default": "10110",
"description": "the UDP port we send to",
"category": "UDP writer"
},
{
"name": "udpwAddress",
"label": "remote address",
"type": "string",
"default": "",
"check": "checkIpAddress",
"description": "the IP address we connect to in the form 192.168.1.2",
"category": "UDP writer"
},
{
"name": "udpwWriteFilter",
"label": "NMEA write Filter",
"type": "filter",
"default": "",
"description": "filter for NMEA0183 data when writing to remote UDP server\nselect aison|aisoff, set a whitelist or a blacklist with NMEA sentences like RMC,RMB",
"category": "UDP writer"
},
{
"name": "udpwSeasmart",
"label": "Seasmart out",
"type": "boolean",
"default": "false",
"description": "send NMEA2000 as seasmart to remote UDP server",
"category": "UDP writer"
},
{
"name": "wifiClient",
"label": "wifi client",
Expand Down

0 comments on commit 490a5b9

Please sign in to comment.