Skip to content

Commit b081c5a

Browse files
authored
Merge pull request #14 from sbhklr/wifi-udp
WiFi UDP & Multicast Functionality
2 parents e27b2f1 + 203af56 commit b081c5a

File tree

2 files changed

+84
-31
lines changed

2 files changed

+84
-31
lines changed

Diff for: libraries/WiFi/src/WiFiUdp.cpp

+74-22
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@ extern WiFiClass WiFi;
77
#endif
88

99
arduino::WiFiUDP::WiFiUDP() {
10-
_packet_buffer = (uint8_t*)malloc(WIFI_UDP_BUFFER_SIZE);
10+
_packet_buffer = new uint8_t[WIFI_UDP_BUFFER_SIZE];
1111
_current_packet = NULL;
1212
_current_packet_size = 0;
13-
// if this malloc fails then ::begin will fail
13+
// if this allocation fails then ::begin will fail
14+
}
15+
16+
arduino::WiFiUDP::~WiFiUDP() {
17+
delete[] _packet_buffer;
1418
}
1519

1620
uint8_t arduino::WiFiUDP::begin(uint16_t port) {
@@ -21,6 +25,10 @@ uint8_t arduino::WiFiUDP::begin(uint16_t port) {
2125
return 0;
2226
}
2327

28+
if (_socket.bind(port) < 0) {
29+
return 0; //Failed to bind UDP Socket to port
30+
}
31+
2432
if (!_packet_buffer) {
2533
return 0;
2634
}
@@ -31,56 +39,79 @@ uint8_t arduino::WiFiUDP::begin(uint16_t port) {
3139
return 1;
3240
}
3341

34-
void arduino::WiFiUDP::stop() {
35-
_socket.close();
36-
}
42+
uint8_t arduino::WiFiUDP::beginMulticast(IPAddress ip, uint16_t port) {
43+
// success = 1, fail = 0
44+
if(begin(port) != 1){
45+
return 0;
46+
}
3747

38-
// we should get the octets out of the IPAddress... there's nothing for it right now
39-
// int arduino::WiFiUDP::beginPacket(IPAddress ip, uint16_t port) {
40-
// }
48+
nsapi_addr_t multicastGroup = {NSAPI_IPv4, {ip[0], ip[1], ip[2], ip[3]}};
4149

42-
int arduino::WiFiUDP::beginPacket(const char *host, uint16_t port) {
43-
_host = host;
44-
_port = port;
50+
if (_socket.join_multicast_group(SocketAddress(multicastGroup)) != NSAPI_ERROR_OK) {
51+
printf("Error joining the multicast group\n");
52+
return 0;
53+
}
4554

4655
return 1;
4756
}
4857

58+
void arduino::WiFiUDP::stop() {
59+
_socket.close();
60+
}
61+
62+
int arduino::WiFiUDP::beginPacket(IPAddress ip, uint16_t port) {
63+
nsapi_addr_t convertedIP = {NSAPI_IPv4, {ip[0], ip[1], ip[2], ip[3]}};
64+
_host = SocketAddress(convertedIP, port);
65+
//If IP is null and port is 0 the initialization failed
66+
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1;
67+
}
68+
69+
int arduino::WiFiUDP::beginPacket(const char *host, uint16_t port) {
70+
_host = SocketAddress(host, port);
71+
//If IP is null and port is 0 the initialization failed
72+
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1;
73+
}
74+
4975
int arduino::WiFiUDP::endPacket() {
5076
return 1;
5177
}
5278

5379
// Write a single byte into the packet
5480
size_t arduino::WiFiUDP::write(uint8_t byte) {
55-
uint8_t buffer[1] = { byte };
56-
SocketAddress addr(_host, _port);
57-
return _socket.sendto(addr, buffer, 1);
81+
uint8_t buffer[1] = { byte };
82+
return _socket.sendto(_host, buffer, 1);
5883
}
5984

6085
// Write size bytes from buffer into the packet
61-
size_t arduino::WiFiUDP::write(const uint8_t *buffer, size_t size) {
62-
SocketAddress addr(_host, _port);
63-
return _socket.sendto(addr, buffer, size);
86+
size_t arduino::WiFiUDP::write(const uint8_t *buffer, size_t size) {
87+
return _socket.sendto(_host, buffer, size);
6488
}
6589

6690
int arduino::WiFiUDP::parsePacket() {
67-
nsapi_size_or_error_t ret = _socket.recvfrom(NULL, _packet_buffer, WIFI_UDP_BUFFER_SIZE);
91+
nsapi_size_or_error_t ret = _socket.recvfrom(&_remoteHost, _packet_buffer, WIFI_UDP_BUFFER_SIZE);
6892

6993
if (ret == NSAPI_ERROR_WOULD_BLOCK) {
7094
// no data
7195
return 0;
96+
} else if(ret == NSAPI_ERROR_NO_SOCKET){
97+
// socket was not created correctly.
98+
return -1;
7299
}
73100
// error codes below zero are errors
74101
else if (ret <= 0) {
75102
// something else went wrong, need some tracing info...
76-
return 0;
103+
return -1;
77104
}
78105

79106
// set current packet states
80107
_current_packet = _packet_buffer;
81108
_current_packet_size = ret;
82109

83-
return 1;
110+
return _current_packet_size;
111+
}
112+
113+
int arduino::WiFiUDP::available() {
114+
return _current_packet_size;
84115
}
85116

86117
// Read a single byte from the current packet
@@ -96,7 +127,7 @@ int arduino::WiFiUDP::read() {
96127
// check for overflow
97128
if (_current_packet > _packet_buffer + _current_packet_size) {
98129
// try reading the next packet...
99-
if (parsePacket() == 1) {
130+
if (parsePacket() > 0) {
100131
// if so, read first byte of next packet;
101132
return read();
102133
}
@@ -131,7 +162,7 @@ int arduino::WiFiUDP::read(unsigned char* buffer, size_t len) {
131162
// at the end of the packet?
132163
if (max_bytes == 0) {
133164
// try read next packet...
134-
if (parsePacket() == 1) {
165+
if (parsePacket() > 0) {
135166
return read(buffer, len);
136167
}
137168
else {
@@ -147,4 +178,25 @@ int arduino::WiFiUDP::read(unsigned char* buffer, size_t len) {
147178
_current_packet += len;
148179

149180
return len;
181+
}
182+
183+
IPAddress arduino::WiFiUDP::remoteIP() {
184+
nsapi_addr_t address = _remoteHost.get_addr();
185+
return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]);
186+
}
187+
188+
uint16_t arduino::WiFiUDP::remotePort() {
189+
return _remoteHost.get_port();
190+
}
191+
192+
void arduino::WiFiUDP::flush(){
193+
// TODO: a real check to ensure transmission has been completed
194+
}
195+
196+
int arduino::WiFiUDP::peek(){
197+
if (_current_packet_size < 1){
198+
return -1;
199+
}
200+
201+
return _current_packet[0];
150202
}

Diff for: libraries/WiFi/src/WiFiUdp.h

+10-9
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ namespace arduino {
3333
class WiFiUDP : public UDP {
3434
private:
3535
UDPSocket _socket; // Mbed OS socket
36-
const char *_host; // Host to be used to send data (todo: switch to SocketAddress)
37-
uint16_t _port; // Port to be used to send data (^)
36+
SocketAddress _host; // Host to be used to send data
37+
SocketAddress _remoteHost; // Remote host that sent incoming packets
3838

3939
uint8_t* _packet_buffer; // Raw packet buffer (contains data we got from the UDPSocket)
4040

@@ -45,15 +45,16 @@ class WiFiUDP : public UDP {
4545

4646
public:
4747
WiFiUDP(); // Constructor
48+
~WiFiUDP();
4849
virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
49-
// virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 if there are no sockets available to use
50+
virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 if there are no sockets available to use
5051
virtual void stop(); // Finish with the UDP socket
5152

5253
// Sending UDP packets
5354

5455
// Start building up a packet to send to the remote host specific in ip and port
5556
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
56-
// virtual int beginPacket(IPAddress ip, uint16_t port);
57+
virtual int beginPacket(IPAddress ip, uint16_t port);
5758
// Start building up a packet to send to the remote host specific in host and port
5859
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
5960
virtual int beginPacket(const char *host, uint16_t port);
@@ -71,7 +72,7 @@ class WiFiUDP : public UDP {
7172
// Returns the size of the packet in bytes, or 0 if no packets are available
7273
virtual int parsePacket();
7374
// Number of bytes remaining in the current packet
74-
// virtual int available();
75+
virtual int available();
7576
// Read a single byte from the current packet
7677
virtual int read();
7778
// Read up to len bytes from the current packet and place them into buffer
@@ -81,13 +82,13 @@ class WiFiUDP : public UDP {
8182
// Returns the number of characters read, or 0 if none are available
8283
virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };
8384
// Return the next byte from the current packet without moving on to the next byte
84-
// virtual int peek();
85-
// virtual void flush(); // Finish reading the current packet
85+
virtual int peek();
86+
virtual void flush(); // Finish reading the current packet
8687

8788
// Return the IP address of the host who sent the current incoming packet
88-
// virtual IPAddress remoteIP();
89+
virtual IPAddress remoteIP();
8990
// // Return the port of the host who sent the current incoming packet
90-
// virtual uint16_t remotePort();
91+
virtual uint16_t remotePort();
9192
};
9293

9394
}

0 commit comments

Comments
 (0)