Skip to content

Commit 5009fc1

Browse files
committed
Merge branch 'master' of https://github.com/amcewen/Arduino into amcewen-master
2 parents 300f5e2 + 983d8af commit 5009fc1

File tree

7 files changed

+91
-21
lines changed

7 files changed

+91
-21
lines changed

libraries/Ethernet/Client.cpp

+14-3
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,25 @@ int Client::available() {
7777

7878
int Client::read() {
7979
uint8_t b;
80-
if (!available())
80+
if ( recv(_sock, &b, 1) > 0 )
81+
{
82+
// recv worked
83+
return b;
84+
}
85+
else
86+
{
87+
// No data available
8188
return -1;
82-
recv(_sock, &b, 1);
83-
return b;
89+
}
90+
}
91+
92+
int Client::read(uint8_t *buf, size_t size) {
93+
return recv(_sock, buf, size);
8494
}
8595

8696
int Client::peek() {
8797
uint8_t b;
98+
// Unlike recv, peek doesn't check to see if there's any data available, so we must
8899
if (!available())
89100
return -1;
90101
::peek(_sock, &b);

libraries/Ethernet/Client.h

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class Client : public Stream {
1717
virtual void write(const uint8_t *buf, size_t size);
1818
virtual int available();
1919
virtual int read();
20+
virtual int read(uint8_t *buf, size_t size);
2021
virtual int peek();
2122
virtual void flush();
2223
void stop();

libraries/Ethernet/Udp.cpp

+35-10
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,41 @@
3131
#include "Ethernet.h"
3232
#include "Udp.h"
3333

34+
/* Constructor */
35+
UDP::UDP() : _sock(MAX_SOCK_NUM) {}
36+
3437
/* Start UDP socket, listening at local port PORT */
35-
void UdpClass::begin(uint16_t port) {
38+
uint8_t UDP::begin(uint16_t port) {
39+
if (_sock != MAX_SOCK_NUM)
40+
return 0;
41+
42+
for (int i = 0; i < MAX_SOCK_NUM; i++) {
43+
uint8_t s = W5100.readSnSR(i);
44+
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
45+
_sock = i;
46+
break;
47+
}
48+
}
49+
50+
if (_sock == MAX_SOCK_NUM)
51+
return 0;
52+
3653
_port = port;
37-
_sock = 0; //TODO: should not be hardcoded
3854
socket(_sock, SnMR::UDP, _port, 0);
55+
56+
return 1;
3957
}
4058

4159
/* Send packet contained in buf of length len to peer at specified ip, and port */
4260
/* Use this function to transmit binary data that might contain 0x00 bytes*/
4361
/* This function returns sent data size for success else -1. */
44-
uint16_t UdpClass::sendPacket(uint8_t * buf, uint16_t len, uint8_t * ip, uint16_t port){
62+
uint16_t UDP::sendPacket(uint8_t * buf, uint16_t len, uint8_t * ip, uint16_t port){
4563
return sendto(_sock,(const uint8_t *)buf,len,ip,port);
4664
}
4765

4866
/* Send zero-terminated string str as packet to peer at specified ip, and port */
4967
/* This function returns sent data size for success else -1. */
50-
uint16_t UdpClass::sendPacket(const char str[], uint8_t * ip, uint16_t port){
68+
uint16_t UDP::sendPacket(const char str[], uint8_t * ip, uint16_t port){
5169
// compute strlen
5270
const char *s;
5371
for(s = str; *s; ++s);
@@ -57,7 +75,7 @@ uint16_t UdpClass::sendPacket(const char str[], uint8_t * ip, uint16_t port){
5775
}
5876
/* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes.
5977
* returned value includes 8 byte UDP header!*/
60-
int UdpClass::available() {
78+
int UDP::available() {
6179
return W5100.getRXReceivedSize(_sock);
6280
}
6381

@@ -67,7 +85,7 @@ int UdpClass::available() {
6785
/* NOTE: I don't believe len is ever checked in implementation of recvfrom(),*/
6886
/* so it's easy to overflow buffer. so we check and truncate. */
6987
/* returns number of bytes read, or negative number of bytes we would have needed if we truncated */
70-
int UdpClass::readPacket(uint8_t * buf, uint16_t bufLen, uint8_t *ip, uint16_t *port) {
88+
int UDP::readPacket(uint8_t * buf, uint16_t bufLen, uint8_t *ip, uint16_t *port) {
7189
int packetLen = available()-8; //skip UDP header;
7290
if(packetLen < 0 ) return 0; // no real data here
7391
if(packetLen > (int)bufLen) {
@@ -116,21 +134,28 @@ int UdpClass::readPacket(uint8_t * buf, uint16_t bufLen, uint8_t *ip, uint16_t *
116134
}
117135

118136
/* Read a received packet, throw away peer's ip and port. See note above. */
119-
int UdpClass::readPacket(uint8_t * buf, uint16_t len) {
137+
int UDP::readPacket(uint8_t * buf, uint16_t len) {
120138
uint8_t ip[4];
121139
uint16_t port[1];
122140
return recvfrom(_sock,buf,len,ip,port);
123141
}
124142

125-
int UdpClass::readPacket(char * buf, uint16_t bufLen, uint8_t *ip, uint16_t &port) {
143+
int UDP::readPacket(char * buf, uint16_t bufLen, uint8_t *ip, uint16_t &port) {
126144
uint16_t myPort;
127145
uint16_t ret = readPacket( (byte*)buf, bufLen, ip, &myPort);
128146
port = myPort;
129147
return ret;
130148
}
131149

150+
/* Release any resources being used by this UDP instance */
151+
void UDP::stop()
152+
{
153+
if (_sock == MAX_SOCK_NUM)
154+
return;
132155

156+
close(_sock);
133157

158+
EthernetClass::_server_port[_sock] = 0;
159+
_sock = MAX_SOCK_NUM;
160+
}
134161

135-
/* Create one global object */
136-
UdpClass Udp;

libraries/Ethernet/Udp.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,14 @@
3939

4040
#define UDP_TX_PACKET_MAX_SIZE 24
4141

42-
class UdpClass {
42+
class UDP {
4343
private:
4444
uint8_t _sock; // socket ID for Wiz5100
4545
uint16_t _port; // local port to listen on
4646

4747
public:
48-
void begin(uint16_t); // initialize, start listening on specified port
48+
UDP();
49+
uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
4950
int available(); // has data been received?
5051

5152
// C-style buffer-oriented functions
@@ -56,8 +57,8 @@ class UdpClass {
5657
// readPacket that fills a character string buffer
5758
int readPacket(char *, uint16_t, uint8_t *, uint16_t &);
5859

60+
// Finish with the UDP socket
61+
void stop();
5962
};
6063

61-
extern UdpClass Udp;
62-
6364
#endif

libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.pde

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ unsigned int remotePort; // holds received packet's originating port
3535
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
3636
char ReplyBuffer[] = "acknowledged"; // a string to send back
3737

38+
// A UDP instance to let us send and receive packets over UDP
39+
UDP Udp;
3840

3941
void setup() {
4042
// start the Ethernet and UDP:

libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.pde

+11
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the
3737

3838
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
3939

40+
// A UDP instance to let us send and receive packets over UDP
41+
UDP Udp;
42+
4043
void setup()
4144
{
4245
// start Ethernet and UDP
@@ -80,8 +83,16 @@ void loop()
8083
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
8184
Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
8285
Serial.print(':');
86+
if ( ((epoch % 3600) / 60) < 10 ) {
87+
// In the first 10 minutes of each hour, we'll want a leading '0'
88+
Serial.print('0');
89+
}
8390
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
8491
Serial.print(':');
92+
if ( (epoch % 60) < 10 ) {
93+
// In the first 10 seconds of each minute, we'll want a leading '0'
94+
Serial.print('0');
95+
}
8596
Serial.println(epoch %60); // print the second
8697
}
8798
// wait ten seconds before asking for the time again

libraries/Ethernet/utility/socket.cpp

+23-4
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,32 @@ uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len)
146146
*/
147147
uint16_t recv(SOCKET s, uint8_t *buf, uint16_t len)
148148
{
149-
uint16_t ret=0;
149+
// Check how much data is available
150+
uint16_t ret = W5100.getRXReceivedSize(s);
151+
if ( ret == 0 )
152+
{
153+
// No data available.
154+
uint8_t status = W5100.readSnSR(s);
155+
if ( s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::CLOSE_WAIT )
156+
{
157+
// The remote end has closed its side of the connection, so this is the eof state
158+
ret = 0;
159+
}
160+
else
161+
{
162+
// The connection is still up, but there's no data waiting to be read
163+
ret = -1;
164+
}
165+
}
166+
else if (ret > len)
167+
{
168+
ret = len;
169+
}
150170

151-
if ( len > 0 )
171+
if ( ret > 0 )
152172
{
153-
W5100.recv_data_processing(s, buf, len);
173+
W5100.recv_data_processing(s, buf, ret);
154174
W5100.execCmdSn(s, Sock_RECV);
155-
ret = len;
156175
}
157176
return ret;
158177
}

0 commit comments

Comments
 (0)