Skip to content

Commit a5bd6f6

Browse files
committed
change to socket esp32
1 parent d0e0779 commit a5bd6f6

2 files changed

Lines changed: 153 additions & 70 deletions

File tree

src/esp32_platform.cpp

Lines changed: 137 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
#include "knx/bits.h"
88

9+
10+
#include <string.h>
11+
912
// #ifndef KNX_SERIAL
1013
// #define KNX_SERIAL Serial1
1114
// #pragma warn "KNX_SERIAL not defined, using Serial1"
@@ -73,117 +76,184 @@ void Esp32Platform::setupMultiCast(uint32_t addr, uint16_t port)
7376
println("No network interface initialized");
7477
fatalError();
7578
}
76-
IPAddress mcastaddr(htonl(addr));
77-
IPAddress mcastaddr2(htonl(addr+1));
79+
80+
_udpSockMulticastAddr.sin_family = AF_INET;
81+
_udpSockMulticastAddr.sin_addr.s_addr = htonl(addr);
82+
_udpSockMulticastAddr.sin_port = htons(port);
7883

79-
println("Initializing KNX multicast.");
80-
print(" Bind ");
81-
print(mcastaddr.toString().c_str());
82-
print(":");
83-
println(port);
84-
uint8_t result = _udp.beginMulticast(mcastaddr, port);
85-
#ifdef TEST_MC_ONESOCKET
86-
_udp.beginMulticast(mcastaddr2, port);
87-
#else
88-
_udp2.beginMulticast(mcastaddr2, port);
89-
#endif
84+
// Create multicast socket
85+
int _udpSockMulticast = socket(AF_INET, SOCK_DGRAM, 0);
86+
if (_udpSockMulticast < 0)
87+
{
88+
println("Failed to create multicast socket");
89+
}
9090

91-
91+
// Set socket options for multicast
92+
int opt = 1;
93+
setsockopt(_udpSockMulticast, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
9294

95+
// Bind the socket to the multicast address
96+
if (bind(_udpSockMulticast, (struct sockaddr*)&_udpSockMulticastAddr, sizeof(_udpSockMulticastAddr)) < 0)
97+
{
98+
println("Failed to bind multicast socket");
99+
close(_udpSockMulticast);
100+
}
93101

102+
// Join multicast group
103+
ip_mreq mreq;
104+
mreq.imr_multiaddr.s_addr = htonl(addr);
105+
mreq.imr_interface.s_addr = INADDR_ANY;
106+
if (setsockopt(_udpSockMulticast, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
107+
{
108+
println("Failed to join multicast group");
109+
close(_udpSockMulticast);
110+
}
94111

112+
// Create unicast socket
113+
int _udpSockUnicast = socket(AF_INET, SOCK_DGRAM, 0);
114+
if (_udpSockUnicast < 0)
115+
{
116+
println("Failed to create unicast socket");
117+
}
95118

119+
// Bind the unicast socket to the same port
120+
struct sockaddr_in unicast_addr;
121+
unicast_addr.sin_family = AF_INET;
122+
unicast_addr.sin_addr.s_addr = INADDR_ANY; // or specific unicast address
123+
unicast_addr.sin_port = htons(port); // use the same port as multicast
124+
if (bind(_udpSockUnicast, (struct sockaddr*)&unicast_addr, sizeof(unicast_addr)) < 0)
125+
{
126+
println("Failed to bind unicast socket");
127+
close(_udpSockUnicast);
128+
}
96129

97-
(void)result; // Suppress unused variable warning
98-
// KNX_DEBUG_SERIAL.printf("result %d\n", result);
130+
println("Initializing KNX multicast.");
131+
print(" Bind ");
132+
print(IPAddress(htonl(addr)).toString().c_str());
133+
print(":");
134+
println(port);
99135
}
100136

101137
void Esp32Platform::closeMultiCast()
102138
{
103-
_udp.stop();
139+
if (_udpSockMulticast >= 0)
140+
{
141+
close(_udpSockMulticast);
142+
_udpSockMulticast = -1; // Mark as closed
143+
println("Multicast socket closed");
144+
}
145+
146+
if (_udpSockUnicast >= 0)
147+
{
148+
close(_udpSockUnicast);
149+
_udpSockUnicast = -1; // Mark as closed
150+
println("Unicast socket closed");
151+
}
104152
}
105153

106154
bool Esp32Platform::sendBytesMultiCast(uint8_t * buffer, uint16_t len)
107155
{
108-
//printHex("<- ",buffer, len);
109-
_udp.beginMulticastPacket();
110-
_udp.write(buffer, len);
111-
_udp.endPacket();
156+
if (_udpSockMulticast < 0)
157+
{
158+
println("Multicast socket not initialized");
159+
return false;
160+
}
161+
162+
ssize_t sentBytes = sendto(_udpSockMulticast, buffer, len, 0, (struct sockaddr*)&_udpSockMulticastAddr, sizeof(_udpSockMulticastAddr));
163+
if (sentBytes < 0)
164+
{
165+
println("Failed to send multicast data");
166+
return false;
167+
}
168+
112169
return true;
113170
}
114171

115172
int Esp32Platform::readBytesMultiCast(uint8_t * buffer, uint16_t maxLen, uint32_t& src_addr, uint16_t& src_port)
116173
{
117-
int len = _udp.parsePacket();
118-
if (len == 0)
174+
struct sockaddr_in src_addr_struct;
175+
socklen_t addrlen = sizeof(src_addr_struct);
176+
ssize_t len = recvfrom(_udpSockMulticast, buffer, maxLen, 0, (struct sockaddr*)&src_addr_struct, &addrlen);
177+
178+
if (len < 0)
119179
{
120-
// check second socket for test purposes
121-
#ifndef TEST_MC_ONESOCKET
122-
len = _udp2.parsePacket();
123-
if (len == 0)
124-
{
125-
return 0;
126-
}
127-
else
128-
{
129-
_remoteIP = _udp2.remoteIP();
130-
_remotePort = _udp2.remotePort();
131-
src_addr = htonl(_remoteIP);
132-
src_port = _remotePort;
133-
134-
print("Receive UDP2 ");
135-
print(_udp2.remoteIP().toString().c_str());
136-
print(":");
137-
println(_udp2.remotePort());
138-
printHex("-> ", buffer, len);
139-
_udp2.read(buffer, len);
140-
return len;
141-
}
142-
#else
143180
return 0;
144-
#endif
145181
}
146182

147183
if (len > maxLen)
148184
{
149185
println("Unexpected UDP data packet length - drop packet");
150-
for (size_t i = 0; i < len; i++)
151-
_udp.read();
152186
return 0;
153187
}
154188

155-
_udp.read(buffer, len);
156-
_remoteIP = _udp.remoteIP();
157-
_remotePort = _udp.remotePort();
158-
src_addr = htonl(_remoteIP);
159-
src_port = _remotePort;
189+
src_addr = ntohl(src_addr_struct.sin_addr.s_addr);
190+
src_port = ntohs(src_addr_struct.sin_port);
160191

161-
print("Receive UDP ");
162-
print(_udp.remoteIP().toString().c_str());
192+
_remoteIP = src_addr;
193+
_remotePort = src_port;
194+
195+
print("Receive Multicast UDP ");
196+
print(IPAddress(src_addr).toString().c_str());
163197
print(":");
164-
println(_udp.remotePort());
198+
println(src_port);
165199
printHex("-> ", buffer, len);
166200

167201
return len;
168202
}
169203

170-
bool Esp32Platform::sendBytesUniCast(uint32_t addr, uint16_t port, uint8_t* buffer, uint16_t len)
204+
int Esp32Platform::readBytesUniCast(uint8_t * buffer, uint16_t maxLen, uint32_t& src_addr, uint16_t& src_port)
171205
{
172-
IPAddress ucastaddr(htonl(addr));
206+
struct sockaddr_in src_addr_struct;
207+
socklen_t addrlen = sizeof(src_addr_struct);
208+
ssize_t len = recvfrom(_udpSockUnicast, buffer, maxLen, 0, (struct sockaddr*)&src_addr_struct, &addrlen);
209+
210+
if (len < 0)
211+
{
212+
return 0;
213+
}
173214

174-
if(!addr)
175-
ucastaddr = _remoteIP;
215+
if (len > maxLen)
216+
{
217+
println("Unexpected UDP data packet length - drop packet");
218+
return 0;
219+
}
220+
221+
src_addr = ntohl(src_addr_struct.sin_addr.s_addr);
222+
src_port = ntohs(src_addr_struct.sin_port);
223+
224+
_remoteIP = src_addr;
225+
_remotePort = src_port;
226+
227+
print("Receive Unicast UDP ");
228+
print(IPAddress(src_addr).toString().c_str());
229+
print(":");
230+
println(src_port);
231+
printHex("-> ", buffer, len);
232+
233+
return len;
234+
}
235+
236+
bool Esp32Platform::sendBytesUniCast(uint32_t addr, uint16_t port, uint8_t* buffer, uint16_t len)
237+
{
238+
struct sockaddr_in dest_addr;
239+
dest_addr.sin_family = AF_INET;
240+
dest_addr.sin_addr.s_addr = htonl(addr);
176241

177-
if(!port)
242+
if (!addr)
243+
dest_addr.sin_addr.s_addr = htonl(_remoteIP);
244+
245+
if (!port)
178246
port = _remotePort;
179247

180-
if(_udp.beginPacket(ucastaddr, port) == 1)
248+
dest_addr.sin_port = htons(port);
249+
250+
ssize_t sentBytes = sendto(_udpSockUnicast, buffer, len, 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
251+
if (sentBytes < 0)
181252
{
182-
_udp.write(buffer, len);
183-
if(_udp.endPacket() == 0) println("sendBytesUniCast endPacket fail");
253+
println("Failed to send unicast data");
254+
return false;
184255
}
185-
else
186-
println("sendBytesUniCast beginPacket fail");
256+
187257
return true;
188258
}
189259

src/esp32_platform.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55

66
#include <WiFiUdp.h>
7+
#include <netinet/in.h>
8+
#include <sys/socket.h>
9+
#include <arpa/inet.h>
710

811
class Esp32Platform : public ArduinoPlatform
912
{
@@ -28,6 +31,7 @@ class Esp32Platform : public ArduinoPlatform
2831
void closeMultiCast() override;
2932
bool sendBytesMultiCast(uint8_t* buffer, uint16_t len) override;
3033
int readBytesMultiCast(uint8_t* buffer, uint16_t maxLen, uint32_t& src_addr, uint16_t& src_port) override;
34+
int readBytesUniCast(uint8_t* buffer, uint16_t maxLen, uint32_t& src_addr, uint16_t& src_port);
3135

3236
//unicast
3337
bool sendBytesUniCast(uint32_t addr, uint16_t port, uint8_t* buffer, uint16_t len) override;
@@ -36,12 +40,21 @@ class Esp32Platform : public ArduinoPlatform
3640
uint8_t* getEepromBuffer(uint32_t size);
3741
void commitToEeprom();
3842

39-
protected: IPAddress _remoteIP;
43+
protected: uint32_t _remoteIP;
4044
protected: uint16_t _remotePort;
4145

4246
private:
43-
WiFiUDP _udp;
44-
WiFiUDP _udp2;
47+
//WiFiUDP _udp;
48+
//WiFiUDP _udp2;
49+
50+
int _udpSockUnicast = -1;
51+
52+
int _udpSockMulticast = -1;
53+
struct sockaddr_in _udpSockMulticastAddr;
54+
55+
56+
//int _udpSockMulticast2 = -1;
57+
//uint32_t _multicastAddr2 = 0;
4558
// int8_t _rxPin = -1;
4659
// int8_t _txPin = -1;
4760
};

0 commit comments

Comments
 (0)