Skip to content
This repository has been archived by the owner on Jan 29, 2023. It is now read-only.

Commit

Permalink
v1.0.6
Browse files Browse the repository at this point in the history
### Release v1.0.6

1. Add support to PROGMEM-related commands, such as sendContent_P() and send_P()
2. Update Platform.ini to support PlatformIO 5.x owner-based dependency declaration.
3. Clean up code.
  • Loading branch information
khoih-prog authored Sep 25, 2020
1 parent 9dd2c2b commit ce52e88
Show file tree
Hide file tree
Showing 40 changed files with 690 additions and 166 deletions.
290 changes: 290 additions & 0 deletions LibraryPatches/Ethernet2/src/EthernetUdp2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,290 @@
/*
* 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/
*
* MIT License:
* Copyright (c) 2008 Bjoern Hartmann
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* 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
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* bjoern@cs.stanford.edu 12/30/2008
*
* - 10 Apr. 2015
* Added support for Arduino Ethernet Shield 2
* by Arduino.org team
*/

#include "utility/w5500.h"
#include "utility/socket.h"
#include "Ethernet2.h"
#include "Udp.h"
#include "Dns.h"

#define ETHERNET2_DEBUG 0

/* 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;

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

if (_sock == MAX_SOCK_NUM)
return 0;

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

return 1;
}

//KH, to add Multicast support
/* Start EthernetUDP socket, listening at local port PORT */
uint8_t EthernetUDP::beginMulticast(IPAddress ip, uint16_t port)
{
if (_sock != MAX_SOCK_NUM)
return 0;

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

if (_sock == MAX_SOCK_NUM)
return 0;

// Calculate MAC address from Multicast IP Address
byte mac[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 };

mac[3] = ip[1] & 0x7F;
mac[4] = ip[2];
mac[5] = ip[3];

w5500.writeSnDIPR(_sock, rawIPAddress(ip)); //239.255.0.1
w5500.writeSnDPORT(_sock, port);
w5500.writeSnDHAR(_sock,mac);

_remaining = 0;
socket(_sock, SnMR::UDP, port, SnMR::MULTI);
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;
}

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

close(_sock);

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;
}
}

int EthernetUDP::beginPacket(IPAddress ip, uint16_t port)
{
_offset = 0;

// KH debug
#if (ETHERNET2_DEBUG > 1)
Serial.print("Ethernet2UDP::beginPacket: ip=");
Serial.print(ip);
Serial.print(", port=");
Serial.println(port);
#endif

return startUDP(_sock, rawIPAddress(ip), port);
}

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

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

size_t EthernetUDP::write(const uint8_t *buffer, size_t size)
{
// KH debug
#if (ETHERNET2_DEBUG > 1)
Serial.print("Ethernet2UDP:write, size=");
Serial.println(size);
#endif

uint16_t bytes_written = bufferData(_sock, _offset, buffer, size);
_offset += bytes_written;

// KH debug
#if (ETHERNET2_DEBUG > 1)
Serial.print("Ethernet2UDP: bytes written=");
Serial.println(bytes_written);
#endif

return bytes_written;
}

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

if (w5500.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;
}

// KH debug
#if (ETHERNET2_DEBUG > 1)
Serial.print("Ethernet2UDP:parsePacket OK, datasize=");
Serial.println(ret);
#endif

return ret;
}
// There aren't any packets available
return 0;
}

int EthernetUDP::read()
{
uint8_t 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;
}

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

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;
}

}

// 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;
}

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 w5500 always behaves :)

while (_remaining)
{
read();
}
}

Loading

0 comments on commit ce52e88

Please sign in to comment.