Skip to content

Commit

Permalink
Better flush. And reformatting.
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasBleijendaal committed Jul 23, 2016
1 parent cd23fe1 commit f538de2
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 116 deletions.
242 changes: 126 additions & 116 deletions Arduino/libraries/Ethernet/EthernetUdp.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Udp.cpp: Library to send/receive UDP packets with the Arduino ethernet shield.
* This version only offers minimal wrapping of socket.c/socket.h
* Drop Udp.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/
* Drop Udp.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/
*
* MIT License:
* Copyright (c) 2008 Bjoern Hartmann
Expand All @@ -11,10 +11,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand All @@ -32,188 +32,198 @@
#include "Udp.h"
#include "Dns.h"

/* Constructor */
/* Constructor */
EthernetUDP::EthernetUDP() : _sock(MAX_SOCK_NUM) {}

/* Start EthernetUDP socket, listening at local port PORT */
uint8_t EthernetUDP::begin(uint16_t port) {
if (_sock != MAX_SOCK_NUM)
return 0;
if (_sock != MAX_SOCK_NUM)
return 0;

for (int i = 0; i < MAX_SOCK_NUM; i++) {
uint8_t s = W5100.readSnSR(i);
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
_sock = i;
break;
}
}
for (int i = 0; i < MAX_SOCK_NUM; i++) {
uint8_t s = W5100.readSnSR(i);
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
_sock = i;
break;
}
}

if (_sock == MAX_SOCK_NUM)
return 0;
if (_sock == MAX_SOCK_NUM)
return 0;

_port = port;
_remaining = 0;
socket(_sock, SnMR::UDP, _port, 0);
_port = port;
_remaining = 0;
socket(_sock, SnMR::UDP, _port, 0);

return 1;
return 1;
}

/* return number of bytes available in the current packet,
will return zero if parsePacket hasn't been called yet */
int EthernetUDP::available() {
return _remaining;
return _remaining;
}

/* Release any resources being used by this EthernetUDP instance */
void EthernetUDP::stop()
{
if (_sock == MAX_SOCK_NUM)
return;
if (_sock == MAX_SOCK_NUM)
return;

close(_sock);
close(_sock);

EthernetClass::_server_port[_sock] = 0;
_sock = MAX_SOCK_NUM;
EthernetClass::_server_port[_sock] = 0;
_sock = MAX_SOCK_NUM;
}

int EthernetUDP::beginPacket(const char *host, uint16_t port)
{
// Look up the host first
int ret = 0;
DNSClient dns;
IPAddress remote_addr;

dns.begin(Ethernet.dnsServerIP());
ret = dns.getHostByName(host, remote_addr);
if (ret == 1) {
return beginPacket(remote_addr, port);
} else {
return ret;
}
// Look up the host first
int ret = 0;
DNSClient dns;
IPAddress remote_addr;

dns.begin(Ethernet.dnsServerIP());
ret = dns.getHostByName(host, remote_addr);
if (ret == 1) {
return beginPacket(remote_addr, port);
}
else {
return ret;
}
}

int EthernetUDP::beginPacket(IPAddress ip, uint16_t port)
{
_offset = 0;
return startUDP(_sock, rawIPAddress(ip), port);
_offset = 0;
return startUDP(_sock, rawIPAddress(ip), port);
}

int EthernetUDP::endPacket()
{
return sendUDP(_sock);
return sendUDP(_sock);
}

size_t EthernetUDP::write(uint8_t byte)
{
return write(&byte, 1);
return write(&byte, 1);
}

size_t EthernetUDP::write(const uint8_t *buffer, size_t size)
{
uint16_t bytes_written = bufferData(_sock, _offset, buffer, size);
_offset += bytes_written;
return bytes_written;
uint16_t bytes_written = bufferData(_sock, _offset, buffer, size);
_offset += bytes_written;
return bytes_written;
}

int EthernetUDP::parsePacket()
{
// discard any remaining bytes in the last packet
flush();

if (W5100.getRXReceivedSize(_sock) > 0)
{
//HACK - hand-parse the UDP packet using TCP recv method
uint8_t tmpBuf[8];
int ret =0;
//read 8 header bytes and get IP and port from it
ret = recv(_sock,tmpBuf,8);
if (ret > 0)
{
_remoteIP = tmpBuf;
_remotePort = tmpBuf[4];
_remotePort = (_remotePort << 8) + tmpBuf[5];
_remaining = tmpBuf[6];
_remaining = (_remaining << 8) + tmpBuf[7];

// When we get here, any remaining bytes are the data
ret = _remaining;
}
return ret;
}
// There aren't any packets available
return 0;
// discard any remaining bytes in the last packet
flush();

if (W5100.getRXReceivedSize(_sock) > 0)
{
//HACK - hand-parse the UDP packet using TCP recv method
uint8_t tmpBuf[8];
int ret = 0;
//read 8 header bytes and get IP and port from it
ret = recv(_sock, tmpBuf, 8);
if (ret > 0)
{
_remoteIP = tmpBuf;
_remotePort = tmpBuf[4];
_remotePort = (_remotePort << 8) + tmpBuf[5];
_remaining = tmpBuf[6];
_remaining = (_remaining << 8) + tmpBuf[7];

// When we get here, any remaining bytes are the data
ret = _remaining;
}
return ret;
}
// There aren't any packets available
return 0;
}

int EthernetUDP::read()
{
uint8_t byte;
uint8_t byte;

if ((_remaining > 0) && (recv(_sock, &byte, 1) > 0))
{
// We read things without any problems
_remaining--;
return byte;
}
if ((_remaining > 0) && (recv(_sock, &byte, 1) > 0))
{
// We read things without any problems
_remaining--;
return byte;
}

// If we get here, there's no data available
return -1;
// If we get here, there's no data available
return -1;
}

int EthernetUDP::read(unsigned char* buffer, size_t len)
{

if (_remaining > 0)
{
if (_remaining > 0)
{

int got;
int got;

if (_remaining <= len)
{
// data should fit in the buffer
got = recv(_sock, buffer, _remaining);
}
else
{
// too much data for the buffer,
// grab as much as will fit
got = recv(_sock, buffer, len);
}
if (_remaining <= len)
{
// data should fit in the buffer
got = recv(_sock, buffer, _remaining);
}
else
{
// too much data for the buffer,
// grab as much as will fit
got = recv(_sock, buffer, len);
}

if (got > 0)
{
_remaining -= got;
return got;
}
if (got > 0)
{
_remaining -= got;
return got;
}

}
}

// If we get here, there's no data available or recv failed
return -1;
// If we get here, there's no data available or recv failed
return -1;

}

int EthernetUDP::peek()
{
uint8_t b;
// Unlike recv, peek doesn't check to see if there's any data available, so we must.
// If the user hasn't called parsePacket yet then return nothing otherwise they
// may get the UDP header
if (!_remaining)
return -1;
::peek(_sock, &b);
return b;
uint8_t b;
// Unlike recv, peek doesn't check to see if there's any data available, so we must.
// If the user hasn't called parsePacket yet then return nothing otherwise they
// may get the UDP header
if (!_remaining)
return -1;
::peek(_sock, &b);
return b;
}

void EthernetUDP::flush()
{
// could this fail (loop endlessly) if _remaining > 0 and recv in read fails?
// should only occur if recv fails after telling us the data is there, lets
// hope the w5100 always behaves :)

while (_remaining)
{
read();
}

#ifdef BETTERFLUSH
// suggestion by steckel @ https://forum.pjrc.com/threads/28628-Slow-performance-with-Arduino-Ethernet-shield

byte test[_remaining];
read(test, _remaining);
_remaining = 0;
#else
// could this fail (loop endlessly) if _remaining > 0 and recv in read fails?
// should only occur if recv fails after telling us the data is there, lets
// hope the w5100 always behaves :)

while (_remaining)
{
read();
}
#endif
}

/* Start EthernetUDP socket, listening at local port PORT */
Expand Down
1 change: 1 addition & 0 deletions Arduino/libraries/Ethernet/EthernetUdp.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

#include <Udp.h>

#define BETTERFLUSH
#define UDP_TX_PACKET_MAX_SIZE 24

class EthernetUDP : public UDP {
Expand Down

0 comments on commit f538de2

Please sign in to comment.