arduino stuffs
Diffstat (limited to 'libraries/Ethernet/src/Ethernet.h')
| -rw-r--r-- | libraries/Ethernet/src/Ethernet.h | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/libraries/Ethernet/src/Ethernet.h b/libraries/Ethernet/src/Ethernet.h new file mode 100644 index 0000000..376e6c5 --- /dev/null +++ b/libraries/Ethernet/src/Ethernet.h @@ -0,0 +1,322 @@ +/* Copyright 2018 Paul Stoffregen + * + * 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. + */ + +#ifndef ethernet_h_ +#define ethernet_h_ + +// All symbols exposed to Arduino sketches are contained in this header file +// +// Older versions had much of this stuff in EthernetClient.h, EthernetServer.h, +// and socket.h. Including headers in different order could cause trouble, so +// these "friend" classes are now defined in the same header file. socket.h +// was removed to avoid possible conflict with the C library header files. + + +// Configure the maximum number of sockets to support. W5100 chips can have +// up to 4 sockets. W5200 & W5500 can have up to 8 sockets. Several bytes +// of RAM are used for each socket. Reducing the maximum can save RAM, but +// you are limited to fewer simultaneous connections. +#if defined(RAMEND) && defined(RAMSTART) && ((RAMEND - RAMSTART) <= 2048) +#define MAX_SOCK_NUM 4 +#else +#define MAX_SOCK_NUM 8 +#endif + +// By default, each socket uses 2K buffers inside the Wiznet chip. If +// MAX_SOCK_NUM is set to fewer than the chip's maximum, uncommenting +// this will use larger buffers within the Wiznet chip. Large buffers +// can really help with UDP protocols like Artnet. In theory larger +// buffers should allow faster TCP over high-latency links, but this +// does not always seem to work in practice (maybe Wiznet bugs?) +//#define ETHERNET_LARGE_BUFFERS + + +#include <Arduino.h> +#include "Client.h" +#include "Server.h" +#include "Udp.h" + +enum EthernetLinkStatus { + Unknown, + LinkON, + LinkOFF +}; + +enum EthernetHardwareStatus { + EthernetNoHardware, + EthernetW5100, + EthernetW5200, + EthernetW5500 +}; + +class EthernetUDP; +class EthernetClient; +class EthernetServer; +class DhcpClass; + +class EthernetClass { +private: + static IPAddress _dnsServerAddress; + static DhcpClass* _dhcp; +public: + // Initialise the Ethernet shield to use the provided MAC address and + // gain the rest of the configuration through DHCP. + // Returns 0 if the DHCP configuration failed, and 1 if it succeeded + static int begin(uint8_t *mac, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + static int maintain(); + static EthernetLinkStatus linkStatus(); + static EthernetHardwareStatus hardwareStatus(); + + // Manaul configuration + static void begin(uint8_t *mac, IPAddress ip); + static void begin(uint8_t *mac, IPAddress ip, IPAddress dns); + static void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway); + static void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet); + static void init(uint8_t sspin = 10); + + static void MACAddress(uint8_t *mac_address); + static IPAddress localIP(); + static IPAddress subnetMask(); + static IPAddress gatewayIP(); + static IPAddress dnsServerIP() { return _dnsServerAddress; } + + void setMACAddress(const uint8_t *mac_address); + void setLocalIP(const IPAddress local_ip); + void setSubnetMask(const IPAddress subnet); + void setGatewayIP(const IPAddress gateway); + void setDnsServerIP(const IPAddress dns_server) { _dnsServerAddress = dns_server; } + void setRetransmissionTimeout(uint16_t milliseconds); + void setRetransmissionCount(uint8_t num); + + friend class EthernetClient; + friend class EthernetServer; + friend class EthernetUDP; +private: + // Opens a socket(TCP or UDP or IP_RAW mode) + static uint8_t socketBegin(uint8_t protocol, uint16_t port); + static uint8_t socketBeginMulticast(uint8_t protocol, IPAddress ip,uint16_t port); + static uint8_t socketStatus(uint8_t s); + // Close socket + static void socketClose(uint8_t s); + // Establish TCP connection (Active connection) + static void socketConnect(uint8_t s, uint8_t * addr, uint16_t port); + // disconnect the connection + static void socketDisconnect(uint8_t s); + // Establish TCP connection (Passive connection) + static uint8_t socketListen(uint8_t s); + // Send data (TCP) + static uint16_t socketSend(uint8_t s, const uint8_t * buf, uint16_t len); + static uint16_t socketSendAvailable(uint8_t s); + // Receive data (TCP) + static int socketRecv(uint8_t s, uint8_t * buf, int16_t len); + static uint16_t socketRecvAvailable(uint8_t s); + static uint8_t socketPeek(uint8_t s); + // sets up a UDP datagram, the data for which will be provided by one + // or more calls to bufferData and then finally sent with sendUDP. + // return true if the datagram was successfully set up, or false if there was an error + static bool socketStartUDP(uint8_t s, uint8_t* addr, uint16_t port); + // copy up to len bytes of data from buf into a UDP datagram to be + // sent later by sendUDP. Allows datagrams to be built up from a series of bufferData calls. + // return Number of bytes successfully buffered + static uint16_t socketBufferData(uint8_t s, uint16_t offset, const uint8_t* buf, uint16_t len); + // Send a UDP datagram built up from a sequence of startUDP followed by one or more + // calls to bufferData. + // return true if the datagram was successfully sent, or false if there was an error + static bool socketSendUDP(uint8_t s); + // Initialize the "random" source port number + static void socketPortRand(uint16_t n); +}; + +extern EthernetClass Ethernet; + + +#define UDP_TX_PACKET_MAX_SIZE 24 + +class EthernetUDP : public UDP { +private: + uint16_t _port; // local port to listen on + IPAddress _remoteIP; // remote IP address for the incoming packet whilst it's being processed + uint16_t _remotePort; // remote port for the incoming packet whilst it's being processed + uint16_t _offset; // offset into the packet being sent + +protected: + uint8_t sockindex; + uint16_t _remaining; // remaining bytes of incoming packet yet to be processed + +public: + EthernetUDP() : sockindex(MAX_SOCK_NUM) {} // Constructor + virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual void stop(); // Finish with the UDP socket + + // Sending UDP packets + + // Start building up a packet to send to the remote host specific in ip and port + // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port + virtual int beginPacket(IPAddress ip, uint16_t port); + // Start building up a packet to send to the remote host specific in host and port + // Returns 1 if successful, 0 if there was a problem resolving the hostname or port + virtual int beginPacket(const char *host, uint16_t port); + // Finish off this packet and send it + // Returns 1 if the packet was sent successfully, 0 if there was an error + virtual int endPacket(); + // Write a single byte into the packet + virtual size_t write(uint8_t); + // Write size bytes from buffer into the packet + virtual size_t write(const uint8_t *buffer, size_t size); + + using Print::write; + + // Start processing the next available incoming packet + // Returns the size of the packet in bytes, or 0 if no packets are available + virtual int parsePacket(); + // Number of bytes remaining in the current packet + virtual int available(); + // Read a single byte from the current packet + virtual int read(); + // Read up to len bytes from the current packet and place them into buffer + // Returns the number of bytes read, or 0 if none are available + virtual int read(unsigned char* buffer, size_t len); + // Read up to len characters from the current packet and place them into buffer + // Returns the number of characters read, or 0 if none are available + virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); }; + // Return the next byte from the current packet without moving on to the next byte + virtual int peek(); + virtual void flush(); // Finish reading the current packet + + // Return the IP address of the host who sent the current incoming packet + virtual IPAddress remoteIP() { return _remoteIP; }; + // Return the port of the host who sent the current incoming packet + virtual uint16_t remotePort() { return _remotePort; }; + virtual uint16_t localPort() { return _port; } +}; + + + + +class EthernetClient : public Client { +public: + EthernetClient() : sockindex(MAX_SOCK_NUM), _timeout(1000) { } + EthernetClient(uint8_t s) : sockindex(s), _timeout(1000) { } + + uint8_t status(); + virtual int connect(IPAddress ip, uint16_t port); + virtual int connect(const char *host, uint16_t port); + virtual int availableForWrite(void); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buf, size_t size); + virtual int available(); + virtual int read(); + virtual int read(uint8_t *buf, size_t size); + virtual int peek(); + virtual void flush(); + virtual void stop(); + virtual uint8_t connected(); + virtual operator bool() { return sockindex < MAX_SOCK_NUM; } + virtual bool operator==(const bool value) { return bool() == value; } + virtual bool operator!=(const bool value) { return bool() != value; } + virtual bool operator==(const EthernetClient&); + virtual bool operator!=(const EthernetClient& rhs) { return !this->operator==(rhs); } + uint8_t getSocketNumber() const { return sockindex; } + virtual uint16_t localPort(); + virtual IPAddress remoteIP(); + virtual uint16_t remotePort(); + virtual void setConnectionTimeout(uint16_t timeout) { _timeout = timeout; } + + friend class EthernetServer; + + using Print::write; + +private: + uint8_t sockindex; // MAX_SOCK_NUM means client not in use + uint16_t _timeout; +}; + + +class EthernetServer : public Server { +private: + uint16_t _port; +public: + EthernetServer(uint16_t port) : _port(port) { } + EthernetClient available(); + EthernetClient accept(); + virtual void begin(); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buf, size_t size); + virtual operator bool(); + using Print::write; + //void statusreport(); + + // TODO: make private when socket allocation moves to EthernetClass + static uint16_t server_port[MAX_SOCK_NUM]; +}; + + +class DhcpClass { +private: + uint32_t _dhcpInitialTransactionId; + uint32_t _dhcpTransactionId; + uint8_t _dhcpMacAddr[6]; +#ifdef __arm__ + uint8_t _dhcpLocalIp[4] __attribute__((aligned(4))); + uint8_t _dhcpSubnetMask[4] __attribute__((aligned(4))); + uint8_t _dhcpGatewayIp[4] __attribute__((aligned(4))); + uint8_t _dhcpDhcpServerIp[4] __attribute__((aligned(4))); + uint8_t _dhcpDnsServerIp[4] __attribute__((aligned(4))); +#else + uint8_t _dhcpLocalIp[4]; + uint8_t _dhcpSubnetMask[4]; + uint8_t _dhcpGatewayIp[4]; + uint8_t _dhcpDhcpServerIp[4]; + uint8_t _dhcpDnsServerIp[4]; +#endif + uint32_t _dhcpLeaseTime; + uint32_t _dhcpT1, _dhcpT2; + uint32_t _renewInSec; + uint32_t _rebindInSec; + unsigned long _timeout; + unsigned long _responseTimeout; + unsigned long _lastCheckLeaseMillis; + uint8_t _dhcp_state; + EthernetUDP _dhcpUdpSocket; + + int request_DHCP_lease(); + void reset_DHCP_lease(); + void presend_DHCP(); + void send_DHCP_MESSAGE(uint8_t, uint16_t); + void printByte(char *, uint8_t); + + uint8_t parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId); +public: + IPAddress getLocalIp(); + IPAddress getSubnetMask(); + IPAddress getGatewayIp(); + IPAddress getDhcpServerIp(); + IPAddress getDnsServerIp(); + + int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + int checkLease(); +}; + + + + + +#endif |