Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
27d36d8
Fix MacOS (case) filename clashes
manchoz Jul 6, 2021
357dba7
Add examples
manchoz Jul 6, 2021
c39cfee
Add helpers begin methods
manchoz Feb 1, 2021
05a1b80
Fix WebClient example
manchoz Feb 1, 2021
540e0ab
Add Static IP support
manchoz Jul 5, 2021
a5e512a
Manage Client status
manchoz Jul 5, 2021
d1501d0
Add support for Static Network configuration
manchoz Jul 5, 2021
b04124a
Update examples
manchoz Jul 5, 2021
817b47a
Add forgotten mac parameter
manchoz Jul 5, 2021
cf184fd
Add checks on socket validity before operations
manchoz Jul 6, 2021
9172c17
Manage sockets already connected
manchoz Jul 6, 2021
4aad72b
Add client socket management
manchoz Jul 6, 2021
5f802c1
WiFi: Cleanup libraries and error handling
facchinm Jul 7, 2021
4ded56c
WiFi: make library compliant with Arduino APIs
facchinm Jul 7, 2021
ec4109d
Initial: start moving WiFi generic classes into a standalone library
facchinm Jul 8, 2021
e0e8647
WiFi: port Client and Server to the new wrapper class
facchinm Jul 8, 2021
02b1239
TEMP: MbedClient: add horrible Client "constructor"
facchinm Jul 8, 2021
73cbc6b
WiFi: port UDP to new MbedUdp class
facchinm Jul 8, 2021
175d09f
Ethernet: port library to SocketWrapper
facchinm Jul 8, 2021
37edb74
MbedClient: fix copy constructor
facchinm Jul 8, 2021
974f4c2
Network: cleanup libraries and licenses
facchinm Jul 9, 2021
d4bb9d8
Network: apply clang-format on libraries
facchinm Jul 9, 2021
4340946
MbedUdp: make socket non blocking
facchinm Jul 9, 2021
123694b
SocketWrapper: fix download() API visibility
facchinm Jul 9, 2021
bc92047
MbedUDP: take into account write() errors
facchinm Jul 9, 2021
7fd7c9a
Remove protected leftovers
manchoz Jul 13, 2021
d9fa625
Add EthernetServer::available()
manchoz Jul 13, 2021
8c7962f
Add ::dnsServerIP
manchoz Jul 13, 2021
a175f35
Unlock mutexes before return
manchoz Jul 13, 2021
15ca271
Fix Typo
manchoz Jul 13, 2021
d3e8ee3
Manage copy and assignement
manchoz Jul 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
WiFi: port UDP to new MbedUdp class
  • Loading branch information
facchinm authored and manchoz committed Jul 14, 2021
commit 73cbc6bba45ce0eb264f11d9694dbf94c07411aa
202 changes: 1 addition & 201 deletions libraries/WiFi/src/WiFiUdp.cpp
Original file line number Diff line number Diff line change
@@ -1,201 +1 @@
#include "WiFiUdp.h"

extern WiFiClass WiFi;

#ifndef WIFI_UDP_BUFFER_SIZE
#define WIFI_UDP_BUFFER_SIZE 508
#endif

arduino::WiFiUDP::WiFiUDP() {
_packet_buffer = new uint8_t[WIFI_UDP_BUFFER_SIZE];
_current_packet = NULL;
_current_packet_size = 0;
// if this allocation fails then ::begin will fail
}

arduino::WiFiUDP::~WiFiUDP() {
delete[] _packet_buffer;
}

uint8_t arduino::WiFiUDP::begin(uint16_t port) {
// success = 1, fail = 0

nsapi_error_t rt = _socket.open(WiFi.getNetwork());
if (rt != NSAPI_ERROR_OK) {
return 0;
}

if (_socket.bind(port) < 0) {
return 0; //Failed to bind UDP Socket to port
}

if (!_packet_buffer) {
return 0;
}

_socket.set_timeout(1000);

return 1;
}

uint8_t arduino::WiFiUDP::beginMulticast(IPAddress ip, uint16_t port) {
// success = 1, fail = 0
if(begin(port) != 1){
return 0;
}

SocketAddress socketAddress = WiFi.socketAddressFromIpAddress(ip, port);

if (_socket.join_multicast_group(socketAddress) != NSAPI_ERROR_OK) {
printf("Error joining the multicast group\n");
return 0;
}

return 1;
}

void arduino::WiFiUDP::stop() {
_socket.close();
}

int arduino::WiFiUDP::beginPacket(IPAddress ip, uint16_t port) {
_host = WiFi.socketAddressFromIpAddress(ip, port);
//If IP is null and port is 0 the initialization failed
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1;
}

int arduino::WiFiUDP::beginPacket(const char *host, uint16_t port) {
_host = SocketAddress(host, port);
WiFi.getNetwork()->gethostbyname(host, &_host);
//If IP is null and port is 0 the initialization failed
return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1;
}

int arduino::WiFiUDP::endPacket() {
return 1;
}

// Write a single byte into the packet
size_t arduino::WiFiUDP::write(uint8_t byte) {
uint8_t buffer[1] = { byte };
return _socket.sendto(_host, buffer, 1);
}

// Write size bytes from buffer into the packet
size_t arduino::WiFiUDP::write(const uint8_t *buffer, size_t size) {
return _socket.sendto(_host, buffer, size);
}

int arduino::WiFiUDP::parsePacket() {
nsapi_size_or_error_t ret = _socket.recvfrom(&_remoteHost, _packet_buffer, WIFI_UDP_BUFFER_SIZE);

if (ret == NSAPI_ERROR_WOULD_BLOCK) {
// no data
return 0;
} else if(ret == NSAPI_ERROR_NO_SOCKET){
// socket was not created correctly.
return -1;
}
// error codes below zero are errors
else if (ret <= 0) {
// something else went wrong, need some tracing info...
return -1;
}

// set current packet states
_current_packet = _packet_buffer;
_current_packet_size = ret;

return _current_packet_size;
}

int arduino::WiFiUDP::available() {
return _current_packet_size;
}

// Read a single byte from the current packet
int arduino::WiFiUDP::read() {
// no current packet...
if (_current_packet == NULL) {
// try reading the next frame, if there is no data return
if (parsePacket() == 0) return -1;
}

_current_packet++;

// check for overflow
if (_current_packet > _packet_buffer + _current_packet_size) {
// try reading the next packet...
if (parsePacket() > 0) {
// if so, read first byte of next packet;
return read();
}
else {
// no new data... not sure what to return here now
return -1;
}
}

return _current_packet[0];
}

// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
int arduino::WiFiUDP::read(unsigned char* buffer, size_t len) {
// Q: does Arduino read() function handle fragmentation? I won't for now...
if (_current_packet == NULL) {
if (parsePacket() == 0) return 0;
}

// how much data do we have in the current packet?
int offset = _current_packet - _packet_buffer;
if (offset < 0) {
return 0;
}

int max_bytes = _current_packet_size - offset;
if (max_bytes < 0) {
return 0;
}

// at the end of the packet?
if (max_bytes == 0) {
// try read next packet...
if (parsePacket() > 0) {
return read(buffer, len);
}
else {
return 0;
}
}

if (len > max_bytes) len = max_bytes;

// copy to target buffer
memcpy(buffer, _current_packet, len);

_current_packet += len;

return len;
}

IPAddress arduino::WiFiUDP::remoteIP() {
nsapi_addr_t address = _remoteHost.get_addr();
return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]);
}

uint16_t arduino::WiFiUDP::remotePort() {
return _remoteHost.get_port();
}

void arduino::WiFiUDP::flush(){
// TODO: a real check to ensure transmission has been completed
}

int arduino::WiFiUDP::peek(){
if (_current_packet_size < 1){
return -1;
}

return _current_packet[0];
}
#include "WiFiUdp.h"
70 changes: 5 additions & 65 deletions libraries/WiFi/src/WiFiUdp.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,74 +21,14 @@
#define wifiudp_h

#include "WiFi.h"
#include "api/Udp.h"

#include "netsocket/SocketAddress.h"
#include "netsocket/UDPSocket.h"

#define UDP_TX_PACKET_MAX_SIZE 24
#include "MbedUdp.h"

namespace arduino {

class WiFiUDP : public UDP {
private:
UDPSocket _socket; // Mbed OS socket
SocketAddress _host; // Host to be used to send data
SocketAddress _remoteHost; // Remote host that sent incoming packets

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

// The Arduino APIs allow you to iterate through this buffer, so we need to be able to iterate over the current packet
// these two variables are used to cache the state of the current packet
uint8_t* _current_packet;
size_t _current_packet_size;

public:
WiFiUDP(); // Constructor
~WiFiUDP();
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
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
virtual void stop(); // Finish with the UDP socket

// Sending UDP packets

// Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacket(IPAddress ip, uint16_t port);
// Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
virtual int beginPacket(const char *host, uint16_t port);
// Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error
virtual int endPacket();
// Write a single byte into the packet
virtual size_t write(uint8_t);
// Write size bytes from buffer into the packet
virtual size_t write(const uint8_t *buffer, size_t size);

using Print::write;

// Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available
virtual int parsePacket();
// Number of bytes remaining in the current packet
virtual int available();
// Read a single byte from the current packet
virtual int read();
// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
virtual int read(unsigned char* buffer, size_t len);
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };
// Return the next byte from the current packet without moving on to the next byte
virtual int peek();
virtual void flush(); // Finish reading the current packet

// Return the IP address of the host who sent the current incoming packet
virtual IPAddress remoteIP();
// // Return the port of the host who sent the current incoming packet
virtual uint16_t remotePort();
class WiFiUDP : public MbedUDP {
NetworkInterface *getNetwork() {
return WiFi.getNetwork();
}
};

}
Expand Down