aboutsummaryrefslogtreecommitdiff
path: root/libraries/Ethernet/EthernetUdp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/Ethernet/EthernetUdp.cpp')
-rw-r--r--libraries/Ethernet/EthernetUdp.cpp73
1 files changed, 54 insertions, 19 deletions
diff --git a/libraries/Ethernet/EthernetUdp.cpp b/libraries/Ethernet/EthernetUdp.cpp
index 9c752fc..3760052 100644
--- a/libraries/Ethernet/EthernetUdp.cpp
+++ b/libraries/Ethernet/EthernetUdp.cpp
@@ -52,15 +52,16 @@ uint8_t EthernetUDP::begin(uint16_t port) {
return 0;
_port = port;
+ _remaining = 0;
socket(_sock, SnMR::UDP, _port, 0);
return 1;
}
-/* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes.
- * returned value includes 8 byte UDP header!*/
+/* return number of bytes available in the current packet,
+ will return zero if parsePacket hasn't been called yet */
int EthernetUDP::available() {
- return W5100.getRXReceivedSize(_sock);
+ return _remaining;
}
/* Release any resources being used by this EthernetUDP instance */
@@ -116,11 +117,14 @@ size_t EthernetUDP::write(const uint8_t *buffer, size_t size)
int EthernetUDP::parsePacket()
{
- if (available() > 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;
+ int ret =0;
//read 8 header bytes and get IP and port from it
ret = recv(_sock,tmpBuf,8);
if (ret > 0)
@@ -128,8 +132,11 @@ int EthernetUDP::parsePacket()
_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 = available();
+ ret = _remaining;
}
return ret;
}
@@ -140,34 +147,58 @@ int EthernetUDP::parsePacket()
int EthernetUDP::read()
{
uint8_t byte;
- if (recv(_sock, &byte, 1) > 0)
+
+ 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;
}
int EthernetUDP::read(unsigned char* buffer, size_t len)
{
- /* In the readPacket that copes with truncating packets, the buffer was
- filled with this code. Not sure why it loops round reading out a byte
- at a time.
- int i;
- for(i=0;i<(int)bufLen;i++) {
- recv(_sock,tmpBuf,1);
- buf[i]=tmpBuf[0];
+
+ if (_remaining > 0)
+ {
+
+ 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 (got > 0)
+ {
+ _remaining -= got;
+ return got;
+ }
+
}
- */
- return recv(_sock, buffer, len);
+
+ // 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 (!available())
+ // 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;
@@ -175,7 +206,11 @@ int EthernetUDP::peek()
void EthernetUDP::flush()
{
- while (available())
+ // 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();
}