mirror of
https://github.com/arduino/Arduino.git
synced 2025-01-30 19:52:13 +01:00
Merge branch 'master' of https://github.com/amcewen/Arduino into amcewen-master
This commit is contained in:
commit
5009fc15fa
@ -77,14 +77,25 @@ int Client::available() {
|
|||||||
|
|
||||||
int Client::read() {
|
int Client::read() {
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
if (!available())
|
if ( recv(_sock, &b, 1) > 0 )
|
||||||
return -1;
|
{
|
||||||
recv(_sock, &b, 1);
|
// recv worked
|
||||||
return b;
|
return b;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No data available
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Client::read(uint8_t *buf, size_t size) {
|
||||||
|
return recv(_sock, buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Client::peek() {
|
int Client::peek() {
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
|
// Unlike recv, peek doesn't check to see if there's any data available, so we must
|
||||||
if (!available())
|
if (!available())
|
||||||
return -1;
|
return -1;
|
||||||
::peek(_sock, &b);
|
::peek(_sock, &b);
|
||||||
|
@ -17,6 +17,7 @@ public:
|
|||||||
virtual void write(const uint8_t *buf, size_t size);
|
virtual void write(const uint8_t *buf, size_t size);
|
||||||
virtual int available();
|
virtual int available();
|
||||||
virtual int read();
|
virtual int read();
|
||||||
|
virtual int read(uint8_t *buf, size_t size);
|
||||||
virtual int peek();
|
virtual int peek();
|
||||||
virtual void flush();
|
virtual void flush();
|
||||||
void stop();
|
void stop();
|
||||||
|
@ -31,23 +31,41 @@
|
|||||||
#include "Ethernet.h"
|
#include "Ethernet.h"
|
||||||
#include "Udp.h"
|
#include "Udp.h"
|
||||||
|
|
||||||
|
/* Constructor */
|
||||||
|
UDP::UDP() : _sock(MAX_SOCK_NUM) {}
|
||||||
|
|
||||||
/* Start UDP socket, listening at local port PORT */
|
/* Start UDP socket, listening at local port PORT */
|
||||||
void UdpClass::begin(uint16_t port) {
|
uint8_t UDP::begin(uint16_t port) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_sock == MAX_SOCK_NUM)
|
||||||
|
return 0;
|
||||||
|
|
||||||
_port = port;
|
_port = port;
|
||||||
_sock = 0; //TODO: should not be hardcoded
|
|
||||||
socket(_sock, SnMR::UDP, _port, 0);
|
socket(_sock, SnMR::UDP, _port, 0);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send packet contained in buf of length len to peer at specified ip, and port */
|
/* Send packet contained in buf of length len to peer at specified ip, and port */
|
||||||
/* Use this function to transmit binary data that might contain 0x00 bytes*/
|
/* Use this function to transmit binary data that might contain 0x00 bytes*/
|
||||||
/* This function returns sent data size for success else -1. */
|
/* This function returns sent data size for success else -1. */
|
||||||
uint16_t UdpClass::sendPacket(uint8_t * buf, uint16_t len, uint8_t * ip, uint16_t port){
|
uint16_t UDP::sendPacket(uint8_t * buf, uint16_t len, uint8_t * ip, uint16_t port){
|
||||||
return sendto(_sock,(const uint8_t *)buf,len,ip,port);
|
return sendto(_sock,(const uint8_t *)buf,len,ip,port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send zero-terminated string str as packet to peer at specified ip, and port */
|
/* Send zero-terminated string str as packet to peer at specified ip, and port */
|
||||||
/* This function returns sent data size for success else -1. */
|
/* This function returns sent data size for success else -1. */
|
||||||
uint16_t UdpClass::sendPacket(const char str[], uint8_t * ip, uint16_t port){
|
uint16_t UDP::sendPacket(const char str[], uint8_t * ip, uint16_t port){
|
||||||
// compute strlen
|
// compute strlen
|
||||||
const char *s;
|
const char *s;
|
||||||
for(s = str; *s; ++s);
|
for(s = str; *s; ++s);
|
||||||
@ -57,7 +75,7 @@ uint16_t UdpClass::sendPacket(const char str[], uint8_t * ip, uint16_t port){
|
|||||||
}
|
}
|
||||||
/* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes.
|
/* Is data available in rx buffer? Returns 0 if no, number of available bytes if yes.
|
||||||
* returned value includes 8 byte UDP header!*/
|
* returned value includes 8 byte UDP header!*/
|
||||||
int UdpClass::available() {
|
int UDP::available() {
|
||||||
return W5100.getRXReceivedSize(_sock);
|
return W5100.getRXReceivedSize(_sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +85,7 @@ int UdpClass::available() {
|
|||||||
/* NOTE: I don't believe len is ever checked in implementation of recvfrom(),*/
|
/* NOTE: I don't believe len is ever checked in implementation of recvfrom(),*/
|
||||||
/* so it's easy to overflow buffer. so we check and truncate. */
|
/* so it's easy to overflow buffer. so we check and truncate. */
|
||||||
/* returns number of bytes read, or negative number of bytes we would have needed if we truncated */
|
/* returns number of bytes read, or negative number of bytes we would have needed if we truncated */
|
||||||
int UdpClass::readPacket(uint8_t * buf, uint16_t bufLen, uint8_t *ip, uint16_t *port) {
|
int UDP::readPacket(uint8_t * buf, uint16_t bufLen, uint8_t *ip, uint16_t *port) {
|
||||||
int packetLen = available()-8; //skip UDP header;
|
int packetLen = available()-8; //skip UDP header;
|
||||||
if(packetLen < 0 ) return 0; // no real data here
|
if(packetLen < 0 ) return 0; // no real data here
|
||||||
if(packetLen > (int)bufLen) {
|
if(packetLen > (int)bufLen) {
|
||||||
@ -116,21 +134,28 @@ int UdpClass::readPacket(uint8_t * buf, uint16_t bufLen, uint8_t *ip, uint16_t *
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read a received packet, throw away peer's ip and port. See note above. */
|
/* Read a received packet, throw away peer's ip and port. See note above. */
|
||||||
int UdpClass::readPacket(uint8_t * buf, uint16_t len) {
|
int UDP::readPacket(uint8_t * buf, uint16_t len) {
|
||||||
uint8_t ip[4];
|
uint8_t ip[4];
|
||||||
uint16_t port[1];
|
uint16_t port[1];
|
||||||
return recvfrom(_sock,buf,len,ip,port);
|
return recvfrom(_sock,buf,len,ip,port);
|
||||||
}
|
}
|
||||||
|
|
||||||
int UdpClass::readPacket(char * buf, uint16_t bufLen, uint8_t *ip, uint16_t &port) {
|
int UDP::readPacket(char * buf, uint16_t bufLen, uint8_t *ip, uint16_t &port) {
|
||||||
uint16_t myPort;
|
uint16_t myPort;
|
||||||
uint16_t ret = readPacket( (byte*)buf, bufLen, ip, &myPort);
|
uint16_t ret = readPacket( (byte*)buf, bufLen, ip, &myPort);
|
||||||
port = myPort;
|
port = myPort;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Release any resources being used by this UDP instance */
|
||||||
|
void UDP::stop()
|
||||||
|
{
|
||||||
|
if (_sock == MAX_SOCK_NUM)
|
||||||
|
return;
|
||||||
|
|
||||||
|
close(_sock);
|
||||||
|
|
||||||
|
EthernetClass::_server_port[_sock] = 0;
|
||||||
|
_sock = MAX_SOCK_NUM;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create one global object */
|
|
||||||
UdpClass Udp;
|
|
||||||
|
@ -39,13 +39,14 @@
|
|||||||
|
|
||||||
#define UDP_TX_PACKET_MAX_SIZE 24
|
#define UDP_TX_PACKET_MAX_SIZE 24
|
||||||
|
|
||||||
class UdpClass {
|
class UDP {
|
||||||
private:
|
private:
|
||||||
uint8_t _sock; // socket ID for Wiz5100
|
uint8_t _sock; // socket ID for Wiz5100
|
||||||
uint16_t _port; // local port to listen on
|
uint16_t _port; // local port to listen on
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void begin(uint16_t); // initialize, start listening on specified port
|
UDP();
|
||||||
|
uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
|
||||||
int available(); // has data been received?
|
int available(); // has data been received?
|
||||||
|
|
||||||
// C-style buffer-oriented functions
|
// C-style buffer-oriented functions
|
||||||
@ -56,8 +57,8 @@ public:
|
|||||||
// readPacket that fills a character string buffer
|
// readPacket that fills a character string buffer
|
||||||
int readPacket(char *, uint16_t, uint8_t *, uint16_t &);
|
int readPacket(char *, uint16_t, uint8_t *, uint16_t &);
|
||||||
|
|
||||||
|
// Finish with the UDP socket
|
||||||
|
void stop();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern UdpClass Udp;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -35,6 +35,8 @@ unsigned int remotePort; // holds received packet's originating port
|
|||||||
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
|
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
|
||||||
char ReplyBuffer[] = "acknowledged"; // a string to send back
|
char ReplyBuffer[] = "acknowledged"; // a string to send back
|
||||||
|
|
||||||
|
// A UDP instance to let us send and receive packets over UDP
|
||||||
|
UDP Udp;
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// start the Ethernet and UDP:
|
// start the Ethernet and UDP:
|
||||||
|
@ -37,6 +37,9 @@ const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the
|
|||||||
|
|
||||||
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
|
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
|
||||||
|
|
||||||
|
// A UDP instance to let us send and receive packets over UDP
|
||||||
|
UDP Udp;
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
// start Ethernet and UDP
|
// start Ethernet and UDP
|
||||||
@ -80,8 +83,16 @@ void loop()
|
|||||||
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
|
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
|
||||||
Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
|
Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
|
||||||
Serial.print(':');
|
Serial.print(':');
|
||||||
|
if ( ((epoch % 3600) / 60) < 10 ) {
|
||||||
|
// In the first 10 minutes of each hour, we'll want a leading '0'
|
||||||
|
Serial.print('0');
|
||||||
|
}
|
||||||
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
|
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
|
||||||
Serial.print(':');
|
Serial.print(':');
|
||||||
|
if ( (epoch % 60) < 10 ) {
|
||||||
|
// In the first 10 seconds of each minute, we'll want a leading '0'
|
||||||
|
Serial.print('0');
|
||||||
|
}
|
||||||
Serial.println(epoch %60); // print the second
|
Serial.println(epoch %60); // print the second
|
||||||
}
|
}
|
||||||
// wait ten seconds before asking for the time again
|
// wait ten seconds before asking for the time again
|
||||||
|
@ -146,14 +146,33 @@ uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len)
|
|||||||
*/
|
*/
|
||||||
uint16_t recv(SOCKET s, uint8_t *buf, uint16_t len)
|
uint16_t recv(SOCKET s, uint8_t *buf, uint16_t len)
|
||||||
{
|
{
|
||||||
uint16_t ret=0;
|
// Check how much data is available
|
||||||
|
uint16_t ret = W5100.getRXReceivedSize(s);
|
||||||
if ( len > 0 )
|
if ( ret == 0 )
|
||||||
|
{
|
||||||
|
// No data available.
|
||||||
|
uint8_t status = W5100.readSnSR(s);
|
||||||
|
if ( s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::CLOSE_WAIT )
|
||||||
|
{
|
||||||
|
// The remote end has closed its side of the connection, so this is the eof state
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The connection is still up, but there's no data waiting to be read
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ret > len)
|
||||||
{
|
{
|
||||||
W5100.recv_data_processing(s, buf, len);
|
|
||||||
W5100.execCmdSn(s, Sock_RECV);
|
|
||||||
ret = len;
|
ret = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ret > 0 )
|
||||||
|
{
|
||||||
|
W5100.recv_data_processing(s, buf, ret);
|
||||||
|
W5100.execCmdSn(s, Sock_RECV);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user