diff --git a/libraries/Ethernet/README.md b/libraries/Ethernet/README.md new file mode 100644 index 00000000..872a6637 --- /dev/null +++ b/libraries/Ethernet/README.md @@ -0,0 +1,11 @@ +# Ethernet Library for Arduino + +Provides Ethernet connectivity for Arduino boards using the Arduino Zephyr core, together with a shield or carrier featuring an Ethernet connector. + +📖 For more information about this library please read the documentation [here](http://www.arduino.cc/en/Reference/Ethernet). + +## License + +Copyright (c) 2025 Arduino SA. All rights reserved. + +This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. \ No newline at end of file diff --git a/libraries/Ethernet/examples/AdvancedChatServer/AdvancedChatServer.ino b/libraries/Ethernet/examples/AdvancedChatServer/AdvancedChatServer.ino new file mode 100644 index 00000000..28781ff6 --- /dev/null +++ b/libraries/Ethernet/examples/AdvancedChatServer/AdvancedChatServer.ino @@ -0,0 +1,125 @@ +/* + Advanced Chat Server + + A more advanced server that distributes any incoming messages + to all connected clients but the client the message comes from. + To use, telnet to your device's IP address and type. + + Usage: + 1. Upload this sketch to your board. + 2. Make sure your board is connected to the network and note its IP address. + 3. From a computer on the same network, open a terminal and connect via Telnet: + + - On macOS or Linux (using netcat if telnet is not available): + telnet 23 + # or, if telnet is missing: + nc 23 + + - On Windows (Command Prompt): + telnet 23 + # If 'telnet' is not recognized, enable it in "Windows Features". + + 4. Type a message and press Enter. + Your message will be broadcast to all connected clients except you. + + Example: + telnet 192.168.1.177 23 + + Press CTRL + ] then 'quit' to exit Telnet. + + */ + +#include "ZephyrServer.h" +#include "ZephyrClient.h" +#include "ZephyrEthernet.h" + +// The IP address will be dependent on your local network. +// gateway and subnet are optional: +IPAddress ip(192, 168, 1, 177); +IPAddress myDns(192, 168, 1, 1); +IPAddress gateway(192, 168, 1, 1); +IPAddress subnet(255, 255, 255, 0); + +// telnet defaults to port 23 +ZephyrServer server(23); + +ZephyrClient clients[8]; + +void setup() { + // start serial port: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // in Zephyr system check if Ethernet is ready before proceeding to initialize + Serial.print("Waiting for link on"); + while (Ethernet.linkStatus() != LinkON) { + Serial.print("."); + delay(100); + } + Serial.println(); + + // initialize the Ethernet device + Ethernet.begin(ip, myDns, gateway, subnet); + + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + + // start listening for clients + server.begin(); + + Serial.print("Chat server address:"); + Serial.println(Ethernet.localIP()); +} + +void loop() { + // check for any new client connecting, and say hello (before any incoming data) + ZephyrClient newClient = server.accept(); + if (newClient) { + for (byte i=0; i < 8; i++) { + if (!clients[i]) { + Serial.print("We have a new client #"); + Serial.println(i); + newClient.print("Hello, client number: "); + newClient.println(i); + // Once we "accept", the client is no longer tracked by EthernetServer + // so we must store it into our list of clients + clients[i] = newClient; + break; + } + } + } + + // check for incoming data from all clients + for (byte i=0; i < 8; i++) { + if (clients[i] && clients[i].available() > 0) { + // read bytes from a client + byte buffer[80]; + int count = clients[i].read(buffer, 80); + // write the bytes to all other connected clients + for (byte j=0; j < 8; j++) { + if (j != i && clients[j].connected()) { + clients[j].write(buffer, count); + } + } + } + } + + // stop any clients which disconnect + for (byte i=0; i < 8; i++) { + if (clients[i] && !clients[i].connected()) { + Serial.print("disconnect client #"); + Serial.println(i); + clients[i].stop(); + } + } +} diff --git a/libraries/Ethernet/examples/BarometricPressureWebServer/BarometricPressureWebServer.ino b/libraries/Ethernet/examples/BarometricPressureWebServer/BarometricPressureWebServer.ino new file mode 100644 index 00000000..acbcec36 --- /dev/null +++ b/libraries/Ethernet/examples/BarometricPressureWebServer/BarometricPressureWebServer.ino @@ -0,0 +1,244 @@ +/* + SCP1000 Barometric Pressure Sensor Display + + Serves the output of a Barometric Pressure Sensor as a web page. + Uses the SPI library. For details on the sensor, see: + http://www.sparkfun.com/commerce/product_info.php?products_id=8161 + + This sketch adapted from Nathan Seidle's SCP1000 example for PIC: + http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip + + Circuit: + SCP1000 sensor attached to pins 6,7, and 11 - 13: + DRDY: pin 6 + CSB: pin 7 + MOSI: pin 11 + MISO: pin 12 + SCK: pin 13 + + How it works: + 1. The board reads temperature and pressure data from the SCP1000 sensor. + 2. It hosts a simple HTTP server on port 80 that serves the current readings as a web page. + 3. You can view the readings from any device on the same network via a browser. + Open a web browser and go to: http://192.168.1.20/ (Replace with your board's IP address if changed) + + Note: The SCP1000 sensor is long obsolete. For modern projects, consider replacing it + with the BMP085/BMP180/BMP280 or similar (e.g. https://www.sparkfun.com/products/9721). + */ + +#include "ZephyrServer.h" +#include "ZephyrEthernet.h" +// the sensor communicates using SPI, so include the library: +#include + +// assign an IP address for the controller: +IPAddress ip(192, 168, 1, 20); + +// Initialize the Ethernet server library +// with the IP address and port you want to use +// (port 80 is default for HTTP): +ZephyrServer server(80); + +//Sensor's memory register addresses: +const int PRESSURE = 0x1F; //3 most significant bits of pressure +const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure +const int TEMPERATURE = 0x21; //16 bit temperature reading + +// pins used for the connection with the sensor +// the others you need are controlled by the SPI library): +const int dataReadyPin = 6; +const int chipSelectPin = 7; + +float temperature = 0.0; +long pressure = 0; +long lastReadingTime = 0; + +void setup() { + + // start the SPI library: + SPI.begin(); + + // start serial port: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // in Zephyr system check if Ethernet is ready before proceeding to initialize + Serial.print("Waiting for link on"); + while (Ethernet.linkStatus() != LinkON) { + Serial.print("."); + delay(100); + } + Serial.println(); + + // start the Ethernet connection + Ethernet.begin(ip); + + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + + // start listening for clients + server.begin(); + + // initalize the data ready and chip select pins: + pinMode(dataReadyPin, INPUT); + pinMode(chipSelectPin, OUTPUT); + + //Configure SCP1000 for low noise configuration: + writeRegister(0x02, 0x2D); + writeRegister(0x01, 0x03); + writeRegister(0x03, 0x02); + + // give the sensor and Ethernet shield time to set up: + delay(1000); + + //Set the sensor to high resolution mode tp start readings: + writeRegister(0x03, 0x0A); + +} + +void loop() { + // check for a reading no more than once a second. + if (millis() - lastReadingTime > 1000) { + // if there's a reading ready, read it: + // don't do anything until the data ready pin is high: + if (digitalRead(dataReadyPin) == HIGH) { + getData(); + // timestamp the last time you got a reading: + lastReadingTime = millis(); + } + } + + // listen for incoming Ethernet connections: + listenForEthernetClients(); +} + + +void getData() { + Serial.println("Getting reading"); + //Read the temperature data + int tempData = readRegister(0x21, 2); + + // convert the temperature to celsius and display it: + temperature = (float)tempData / 20.0; + + //Read the pressure data highest 3 bits: + byte pressureDataHigh = readRegister(0x1F, 1); + pressureDataHigh &= 0b00000111; //you only needs bits 2 to 0 + + //Read the pressure data lower 16 bits: + unsigned int pressureDataLow = readRegister(0x20, 2); + //combine the two parts into one 19-bit number: + pressure = ((pressureDataHigh << 16) | pressureDataLow) / 4; + + Serial.print("Temperature: "); + Serial.print(temperature); + Serial.println(" degrees C"); + Serial.print("Pressure: " + String(pressure)); + Serial.println(" Pa"); +} + +void listenForEthernetClients() { + // listen for incoming clients + ZephyrClient client = server.accept(); + if (client) { + Serial.println("Got a client"); + // an http request ends with a blank line + boolean currentLineIsBlank = true; + while (client.connected()) { + if (client.available()) { + char c = client.read(); + // if you've gotten to the end of the line (received a newline + // character) and the line is blank, the http request has ended, + // so you can send a reply + if (c == '\n' && currentLineIsBlank) { + // send a standard http response header + client.println("HTTP/1.1 200 OK"); + client.println("Content-Type: text/html"); + client.println(); + // print the current readings, in HTML format: + client.print("Temperature: "); + client.print(temperature); + client.print(" degrees C"); + client.println("
"); + client.print("Pressure: " + String(pressure)); + client.print(" Pa"); + client.println("
"); + break; + } + if (c == '\n') { + // you're starting a new line + currentLineIsBlank = true; + } else if (c != '\r') { + // you've gotten a character on the current line + currentLineIsBlank = false; + } + } + } + // give the web browser time to receive the data + delay(1); + // close the connection: + client.stop(); + } +} + + +//Send a write command to SCP1000 +void writeRegister(byte registerName, byte registerValue) { + // SCP1000 expects the register name in the upper 6 bits + // of the byte: + registerName <<= 2; + // command (read or write) goes in the lower two bits: + registerName |= 0b00000010; //Write command + + // take the chip select low to select the device: + digitalWrite(chipSelectPin, LOW); + + SPI.transfer(registerName); //Send register location + SPI.transfer(registerValue); //Send value to record into register + + // take the chip select high to de-select: + digitalWrite(chipSelectPin, HIGH); +} + + +//Read register from the SCP1000: +unsigned int readRegister(byte registerName, int numBytes) { + byte inByte = 0; // incoming from the SPI read + unsigned int result = 0; // result to return + + // SCP1000 expects the register name in the upper 6 bits + // of the byte: + registerName <<= 2; + // command (read or write) goes in the lower two bits: + registerName &= 0b11111100; //Read command + + // take the chip select low to select the device: + digitalWrite(chipSelectPin, LOW); + // send the device the register you want to read: + int command = SPI.transfer(registerName); + // send a value of 0 to read the first byte returned: + inByte = SPI.transfer(0x00); + + result = inByte; + // if there's more than one byte returned, + // shift the first byte then get the second byte: + if (numBytes > 1) { + result = inByte << 8; + inByte = SPI.transfer(0x00); + result = result | inByte; + } + // take the chip select high to de-select: + digitalWrite(chipSelectPin, HIGH); + // return the result: + return (result); +} diff --git a/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino b/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino new file mode 100644 index 00000000..a7e60e99 --- /dev/null +++ b/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino @@ -0,0 +1,86 @@ +/* + DHCP-based IP printer + + This sketch uses the DHCP extensions to the Ethernet library + to get an IP address via DHCP and print the address obtained. + using an Arduino Wiznet Ethernet shield. + + */ + +#include "ZephyrEthernet.h" + +void setup() +{ + // start serial port: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // in Zephyr system check if Ethernet is ready before proceeding to initialize + Serial.print("Waiting for link on"); + while (Ethernet.linkStatus() != LinkON) { + Serial.print("."); + delay(100); + } + Serial.println(); + + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin() == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + } else if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // no point in carrying on, so do nothing forevermore: + while (true) { + delay(1); + } + } + // print your local IP address: + Serial.print("My IP address: "); + Serial.println(Ethernet.localIP()); +} + +void loop() +{ + if (Ethernet.linkStatus() != LinkON) { + Serial.println(Ethernet.linkStatus()); + connectEth(); + } +} + +void connectEth() +{ + // in Zephyr system check if Ethernet is ready before proceeding to initialize + Serial.print("Waiting for link on"); + while (Ethernet.linkStatus() != LinkON) { + Serial.print("."); + delay(100); + } + Serial.println(); + + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin() == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + } else { + Serial.print(" DHCP assigned IP "); + Serial.println(Ethernet.localIP()); + } + + Serial.println("You're connected to the network"); + Serial.println(); +} diff --git a/libraries/Ethernet/examples/LinkStatus/LinkStatus.ino b/libraries/Ethernet/examples/LinkStatus/LinkStatus.ino new file mode 100644 index 00000000..a38e005d --- /dev/null +++ b/libraries/Ethernet/examples/LinkStatus/LinkStatus.ino @@ -0,0 +1,28 @@ +/* + Link Status + This sketch prints the ethernet link status. When the + ethernet cable is connected the link status should go to "ON". +*/ + +#include + +void setup() { + Serial.begin(9600); +} + +void loop() { + auto link = Ethernet.linkStatus(); + Serial.print("Link status: "); + switch (link) { + case Unknown: + Serial.println("Unknown"); + break; + case LinkON: + Serial.println("ON"); + break; + case LinkOFF: + Serial.println("OFF"); + break; + } + delay(1000); +} diff --git a/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino b/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino new file mode 100644 index 00000000..97f55814 --- /dev/null +++ b/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino @@ -0,0 +1,96 @@ + /* + Telnet client + + This sketch connects to a telnet server. + You need a telnet server to test this. +*/ + +#include "ZephyrClient.h" +#include "ZephyrEthernet.h" + +// The IP address will be dependent on your local network: +IPAddress ip(192, 168, 1, 177); + +// Example: To get the IP address of telehack.com (an example telnet server), run in a terminal: +// ping telehack.com +// or +// nslookup telehack.com +// Then use the returned IP address in the code. + +// Enter the IP address of the server you're connecting to: +IPAddress server(1, 1, 1, 1); +int port = 23; // Telnet port + +// Initialize the Ethernet client library +// with the IP address and port of the server +// that you want to connect to (port 23 is default for telnet; +// if you're using Processing's ChatServer, use port 10002): +ZephyrClient client; + +void setup() { + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + while (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + delay(500); + } + + // start the Ethernet connection: + Ethernet.begin(ip); + + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // give the Ethernet shield a second to initialize: + delay(1000); + Serial.println("connecting..."); + + // if you get a connection, report back via serial: + if (client.connect(server, port)) { + Serial.println("connected"); + } else { + // if you didn't get a connection to the server: + Serial.println("connection failed"); + } +} + +void loop() { + // if there are incoming bytes available + // from the server, read them and print them: + if (client.available()) { + char c = client.read(); + Serial.print(c); + } + + // as long as there are bytes in the serial queue, + // read them and send them out the socket if it's open: + while (Serial.available() > 0) { + char inChar = Serial.read(); + if (client.connected()) { + client.print(inChar); + } + } + + // if the server's disconnected, stop the client: + if (!client.connected()) { + Serial.println(); + Serial.println("disconnecting."); + client.stop(); + // do nothing: + while (true) { + delay(1); + } + } +} + + + + diff --git a/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.ino b/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.ino new file mode 100644 index 00000000..c733e15b --- /dev/null +++ b/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.ino @@ -0,0 +1,129 @@ +/* + UDPSendReceiveString: + This sketch receives UDP message strings, prints them to the serial port + and sends an "acknowledge" string back to the sender + + A Processing sketch is included at the end of file that can be used to send + and received messages for testing with a computer. + */ + +#include +#include + +// The IP address will be dependent on your local network: +IPAddress ip(192, 168, 1, 177); + +unsigned int localPort = 8888; // local port to listen on + +// buffers for receiving and sending data +char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // buffer to hold incoming packet, +char ReplyBuffer[] = "acknowledged"; // a string to send back + +// An EthernetUDP instance to let us send and receive packets over UDP +ZephyrUDP Udp; + +void setup() { + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // in Zephyr system check if Ethernet is ready before proceeding to initialize + Serial.print("Waiting for link on"); + while (Ethernet.linkStatus() != LinkON) { + Serial.print("."); + delay(100); + } + Serial.println(); + + // start the Ethernet + Ethernet.begin(ip); + + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + + // start UDP + Udp.begin(localPort); +} + +void loop() { + // if there's data available, read a packet + int packetSize = Udp.parsePacket(); + if (packetSize) { + Serial.print("Received packet of size "); + Serial.println(packetSize); + Serial.print("From "); + IPAddress remote = Udp.remoteIP(); + for (int i=0; i < 4; i++) { + Serial.print(remote[i], DEC); + if (i < 3) { + Serial.print("."); + } + } + Serial.print(", port "); + Serial.println(Udp.remotePort()); + + // read the packet into packetBufffer + Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); + Serial.println("Contents:"); + Serial.println(packetBuffer); + + // send a reply to the IP address and port that sent us the packet we received + Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); + Udp.write(ReplyBuffer); + Udp.endPacket(); + } + delay(10); +} + + +/* + Processing sketch to run with this example + ===================================================== + + // Processing UDP example to send and receive string data from Arduino + // press any key to send the "Hello Arduino" message + + + import hypermedia.net.*; + + UDP udp; // define the UDP object + + + void setup() { + udp = new UDP( this, 6000 ); // create a new datagram connection on port 6000 + //udp.log( true ); // <-- printout the connection activity + udp.listen( true ); // and wait for incoming message + } + + void draw() + { + } + + void keyPressed() { + String ip = "192.168.1.177"; // the remote IP address + int port = 8888; // the destination port + + udp.send("Hello World", ip, port ); // the message to send + + } + + void receive( byte[] data ) { // <-- default handler + //void receive( byte[] data, String ip, int port ) { // <-- extended handler + + for(int i=0; i < data.length; i++) + print(char(data[i])); + println(); + } + */ + + diff --git a/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino b/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino new file mode 100644 index 00000000..41e39859 --- /dev/null +++ b/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino @@ -0,0 +1,174 @@ +/* + + Udp NTP Client + + Get the time from a Network Time Protocol (NTP) time server + Demonstrates use of UDP sendPacket and ReceivePacket + For more on NTP time servers and the messages needed to communicate with them, + see http://en.wikipedia.org/wiki/Network_Time_Protocol + + */ + +#include +#include + +unsigned int localPort = 8888; // local port to listen for UDP packets + +const char timeServer[] = "time.nist.gov"; // time.nist.gov NTP server + +const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message + +byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets + +// A UDP instance to let us send and receive packets over UDP +ZephyrUDP Udp; + +void setup() { + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // in Zephyr system check if Ethernet is ready before proceeding to initialize + Serial.print("Waiting for link on"); + while (Ethernet.linkStatus() != LinkON) { + Serial.print("."); + delay(100); + } + Serial.println(); + + // start Ethernet and UDP + if (Ethernet.begin() == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + } else if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // no point in carrying on, so do nothing forevermore: + while (true) { + delay(1); + } + } + Udp.begin(localPort); +} + +void loop() { + if (Ethernet.linkStatus() != LinkON) { + Serial.println(Ethernet.linkStatus()); + connectEth(); + } + sendNTPpacket(timeServer); // send an NTP packet to a time server + + // wait to see if a reply is available + delay(1000); + if (Udp.parsePacket()) { + // We've received a packet, read the data from it + Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer + + // the timestamp starts at byte 40 of the received packet and is four bytes, + // or two words, long. First, extract the two words: + + unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); + unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); + // combine the four bytes (two words) into a long integer + // this is NTP time (seconds since Jan 1 1900): + unsigned long secsSince1900 = highWord << 16 | lowWord; + Serial.print("Seconds since Jan 1 1900 = "); + Serial.println(secsSince1900); + + // now convert NTP time into everyday time: + Serial.print("Unix time = "); + // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: + const unsigned long seventyYears = 2208988800UL; + // subtract seventy years: + unsigned long epoch = secsSince1900 - seventyYears; + // print Unix time: + Serial.println(epoch); + + + // print the hour, minute and second: + 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(':'); + 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(':'); + 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 + } + // wait ten seconds before asking for the time again + delay(10000); +} + +// send an NTP request to the time server at the given address +void sendNTPpacket(const char * address) { + // set all bytes in the buffer to 0 + memset(packetBuffer, 0, NTP_PACKET_SIZE); + // Initialize values needed to form NTP request + // (see URL above for details on the packets) + packetBuffer[0] = 0b11100011; // LI, Version, Mode + packetBuffer[1] = 0; // Stratum, or type of clock + packetBuffer[2] = 6; // Polling Interval + packetBuffer[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + packetBuffer[12] = 49; + packetBuffer[13] = 0x4E; + packetBuffer[14] = 49; + packetBuffer[15] = 52; + + // all NTP fields have been given values, now + // you can send a packet requesting a timestamp: + Udp.beginPacket(address, 123); // NTP requests are to port 123 + Udp.write(packetBuffer, NTP_PACKET_SIZE); + Udp.endPacket(); +} + +void connectEth() +{ + // in Zephyr system check if Ethernet is ready before proceeding to initialize + Serial.print("Waiting for link on"); + while (Ethernet.linkStatus() != LinkON) { + Serial.print("."); + delay(100); + } + Serial.println(); + + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin(nullptr) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + } else { + Serial.print(" DHCP assigned IP "); + Serial.println(Ethernet.localIP()); + } + + Serial.println("You're connected to the network"); + Serial.println(); +} + + + + + + + + diff --git a/libraries/Ethernet/examples/WebClient/WebClient.ino b/libraries/Ethernet/examples/WebClient/WebClient.ino new file mode 100644 index 00000000..6f92a963 --- /dev/null +++ b/libraries/Ethernet/examples/WebClient/WebClient.ino @@ -0,0 +1,128 @@ +/* + Web client + + This sketch connects to a website (http://www.google.com) + */ + +#include +#include "ZephyrEthernet.h" + +// Enter a MAC address for your controller below. +// Newer Ethernet shields have a MAC address printed on a sticker on the shield +// byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; + +// if you don't want to use DNS (and reduce your sketch size) +// use the numeric IP instead of the name for the server: +//IPAddress server(74,125,232,128); // numeric IP for Google (no DNS) +char server[] = "www.google.com"; // name address for Google (using DNS) + +// Set the static IP address to use if the DHCP fails to assign +IPAddress ip(192, 168, 2, 177); +IPAddress myDns(192, 168, 2, 1); + +// Initialize the Ethernet client library +// with the IP address and port of the server +// that you want to connect to (port 80 is default for HTTP): +ZephyrClient client; + +// Variables to measure the speed +unsigned long beginMicros, endMicros; +unsigned long byteCount = 0; +bool printWebData = true; // set to false for better speed measurement + +void setup() +{ + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // in Zephyr system check if Ethernet is ready before proceeding to initialize + while (Ethernet.linkStatus() != LinkON) { + Serial.println("Waiting for link on"); + delay(100); + } + + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin() == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // try to congifure using IP address instead of DHCP: + Ethernet.begin(ip, myDns); + } else { + Serial.print(" DHCP assigned IP "); + Serial.println(Ethernet.localIP()); + } + + // give the Ethernet shield a second to initialize: + delay(1000); + Serial.print("connecting to "); + Serial.print(server); + Serial.println("..."); + + // if you get a connection, report back via serial: + if (client.connect(server, 80)) { + Serial.print("connected to "); + Serial.println(client.remoteIP()); + // Make a HTTP request: + client.println("GET /search?q=arduino HTTP/1.1"); + client.println("Host: www.google.com"); + client.println("Connection: close"); + client.println(); + } else { + // if you didn't get a connection to the server: + Serial.println("connection failed"); + } + beginMicros = micros(); +} + +void loop() +{ + // if there are incoming bytes available + // from the server, read them and print them: + int len = client.available(); + if (len > 0) { + byte buffer[80]; + if (len > 80) + len = 80; + client.read(buffer, len); + if (printWebData) { + Serial.write(buffer, len); // show in the serial monitor (slows some boards) + } + byteCount = byteCount + len; + } + + // if the server's disconnected, stop the client: + if (!client.connected()) { + endMicros = micros(); + Serial.println(); + Serial.println("disconnecting."); + client.stop(); + Serial.print("Received "); + Serial.print(byteCount); + Serial.print(" bytes in "); + float seconds = (float)(endMicros - beginMicros) / 1000000.0; + Serial.print(seconds, 4); + float rate = (float)byteCount / seconds / 1000.0; + Serial.print(", rate = "); + Serial.print(rate); + Serial.print(" kbytes/second"); + Serial.println(); + + // do nothing forevermore: + while (true) { + delay(1); + } + } +} diff --git a/libraries/Ethernet/examples/WebClientRepeating/WebClientRepeating.ino b/libraries/Ethernet/examples/WebClientRepeating/WebClientRepeating.ino new file mode 100644 index 00000000..8b37198f --- /dev/null +++ b/libraries/Ethernet/examples/WebClientRepeating/WebClientRepeating.ino @@ -0,0 +1,114 @@ +/* + Repeating Web client + + This sketch connects to a a web server and makes a request + using a Wiznet Ethernet shield. You can use the Arduino Ethernet shield, or + the Adafruit Ethernet shield, either one will work, as long as it's got + a Wiznet Ethernet module on board. + + This example uses DNS, by assigning the Ethernet client with a MAC address, + IP address, and DNS address. + + */ + +#include +#include "ZephyrEthernet.h" + +// Set the static IP address to use if the DHCP fails to assign +IPAddress ip(192, 168, 0, 177); +IPAddress myDns(192, 168, 0, 1); + +// initialize the library instance: +ZephyrClient client; + +char server[] = "www.arduino.cc"; // also change the Host line in httpRequest() +//IPAddress server(64,131,82,241); + +unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds +const unsigned long postingInterval = 10*1000; // delay between updates, in milliseconds + +void setup() { + // start serial port: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // in Zephyr system check if Ethernet is ready before proceeding to initialize + Serial.print("Waiting for link on"); + while (Ethernet.linkStatus() != LinkON) { + Serial.print("."); + delay(100); + } + Serial.println(); + + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin() == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // try to congifure using IP address instead of DHCP: + Ethernet.begin(ip, myDns); + Serial.print("My IP address: "); + Serial.println(Ethernet.localIP()); + } else { + Serial.print(" DHCP assigned IP "); + Serial.println(Ethernet.localIP()); + } + // give the Ethernet shield a second to initialize: + delay(1000); +} + +void loop() { + // if there's incoming data from the net connection. + // send it out the serial port. This is for debugging + // purposes only: + if (client.available()) { + char c = client.read(); + Serial.write(c); + } + + // if ten seconds have passed since your last connection, + // then connect again and send data: + if (millis() - lastConnectionTime > postingInterval) { + httpRequest(); + } + +} + +// this method makes a HTTP connection to the server: +void httpRequest() { + // close any connection before send a new request. + // This will free the socket on the WiFi shield + client.stop(); + + // if there's a successful connection: + if (client.connect(server, 80)) { + Serial.println("connecting..."); + // send the HTTP GET request: + client.println("GET /latest.txt HTTP/1.1"); + client.println("Host: www.arduino.cc"); + client.println("User-Agent: arduino-ethernet"); + client.println("Connection: close"); + client.println(); + + // note the time that the connection was made: + lastConnectionTime = millis(); + } else { + // if you couldn't make a connection: + Serial.println("connection failed"); + } +} + + + + diff --git a/libraries/Ethernet/examples/WebClientRepeatingManual/WebClientRepeatingManual.ino b/libraries/Ethernet/examples/WebClientRepeatingManual/WebClientRepeatingManual.ino new file mode 100644 index 00000000..de8e9266 --- /dev/null +++ b/libraries/Ethernet/examples/WebClientRepeatingManual/WebClientRepeatingManual.ino @@ -0,0 +1,142 @@ +/* + Repeating Web client + + This sketch connects to a a web server and makes a request + using a Wiznet Ethernet shield. You can use the Arduino Ethernet shield, or + the Adafruit Ethernet shield, either one will work, as long as it's got + a Wiznet Ethernet module on board. + + This example uses DNS, by assigning the Ethernet client with a MAC address, + IP address, and DNS address. + */ + +#include +#include "ZephyrEthernet.h" + +// The IP address will be dependent on your local network. +// DNS, gateway and subnet are optional: +IPAddress ip(192, 168, 1, 177); +IPAddress myDns(192, 168, 1, 1); +IPAddress gateway(192, 168, 1, 1); +IPAddress subnet(255, 255, 255, 0); + +// initialize the library instance: +ZephyrClient client; + +char server[] = "www.arduino.cc"; // also change the Host line in httpRequest() +//IPAddress server(64,131,82,241); + +unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds +const unsigned long postingInterval = 10 * 1000; // delay between updates, in milliseconds + +void setup() +{ + // start serial port: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // in Zephyr system check if Ethernet is ready before proceeding to initialize + Serial.print("Waiting for link on"); + while (Ethernet.linkStatus() != LinkON) { + Serial.print("."); + delay(100); + } + Serial.println(); + + delay(2500); + + // start the Ethernet connection: + Serial.println("Initialize Ethernet with Static IP Address:"); + if (Ethernet.begin(ip, myDns, gateway, subnet) == 0) { + Serial.println("Failed to configure Ethernet with Static IP Address"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + } + + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // try to congifure using IP address instead of DHCP: + Serial.print("My IP address: "); + Serial.println(Ethernet.localIP()); + Serial.print("My Gateway IP address: "); + Serial.println(Ethernet.gatewayIP()); + Serial.print("My DNS Server IP address: "); + Serial.println(Ethernet.dnsServerIP()); + // give the Ethernet shield a second to initialize: + delay(2500); +} + +void loop() +{ + // if there's incoming data from the net connection. + // send it out the serial port. This is for debugging + // purposes only: + if (client.available()) { + char c = client.read(); + Serial.write(c); + } + + // if ten seconds have passed since your last connection, + // then connect again and send data: + if (millis() - lastConnectionTime > postingInterval) { + httpRequest(); + } +} + +// this method makes a HTTP connection to the server: +void httpRequest() +{ + // close any connection before send a new request. + // This will free the socket on the WiFi shield + client.stop(); + + // if there's a successful connection: + if (client.connect(server, 80)) { + Serial.println("connecting..."); + // send the HTTP GET request: + client.println("GET /latest.txt HTTP/1.1"); + client.println("Host: www.arduino.cc"); + client.println("User-Agent: arduino-ethernet"); + client.println("Connection: close"); + client.println(); + + // note the time that the connection was made: + lastConnectionTime = millis(); + } else { + // if you couldn't make a connection: + Serial.println("connection failed"); + } +} + +void connectEth() +{ + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin(nullptr) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + } else { + Serial.print(" DHCP assigned IP "); + Serial.println(Ethernet.localIP()); + } + + Serial.println("You're connected to the network"); + Serial.println(); +} diff --git a/libraries/Ethernet/examples/WebClientRepeatingSSL/WebClientRepeatingSSL.ino b/libraries/Ethernet/examples/WebClientRepeatingSSL/WebClientRepeatingSSL.ino new file mode 100644 index 00000000..748f63c1 --- /dev/null +++ b/libraries/Ethernet/examples/WebClientRepeatingSSL/WebClientRepeatingSSL.ino @@ -0,0 +1,110 @@ +/* + Repeating TLS/SSL Ethernet Web client. + + Remeber to update the CA certificates using WiFiFirmwareUpdater sketch + before using this sketch. + + */ + +#include +#include "ZephyrEthernet.h" + +// initialize the library instance: +ZephyrSSLClient client; + +char server[] = "www.arduino.cc"; +int port = 443; +// IPAddress server(64,131,82,241); + +// Set the static IP address to use if the DHCP fails to assign +IPAddress ip(192, 168, 0, 177); +IPAddress myDns(192, 168, 0, 1); + +unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds +const unsigned long postingInterval = 10 * 1000; // delay between updates, in milliseconds + +void setup() +{ + // start serial port: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // in Zephyr system check if Ethernet is ready before proceeding to initialize + Serial.print("Waiting for link on"); + while (Ethernet.linkStatus() != LinkON) { + Serial.print("."); + delay(100); + } + Serial.println(); + + // start the Ethernet connection: + Serial.println("Initialize Ethernet with DHCP:"); + if (Ethernet.begin() == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + // try to congifure using IP address instead of DHCP: + Ethernet.begin(ip, myDns); + Serial.print("My IP address: "); + Serial.println(Ethernet.localIP()); + } else { + Serial.print(" DHCP assigned IP "); + Serial.println(Ethernet.localIP()); + } + // give the Ethernet shield a second to initialize: + delay(1000); +} + +void loop() +{ + // if there's incoming data from the net connection. + // send it out the serial port. This is for debugging + // purposes only: + if (client.available()) { + char c = client.read(); + Serial.write(c); + } + + // if ten seconds have passed since your last connection, + // then connect again and send data: + if (millis() - lastConnectionTime > postingInterval) { + httpRequest(); + } +} + +// this method makes a HTTP connection to the server: +void httpRequest() +{ + // close any connection before send a new request. + // This will free the socket on the WiFi shield + client.stop(); + + // if there's a successful connection: + if (client.connect(server, port)) { + Serial.println("connecting..."); + // send the HTTP GET request: + client.println("GET /latest.txt HTTP/1.1"); + client.print("Host: "); + client.println(server); + client.println("User-Agent: arduino-ethernet"); + client.println("Accept: *"); + client.println("Connection: close"); + client.println(); + + // note the time that the connection was made: + lastConnectionTime = millis(); + } else { + // if you couldn't make a connection: + Serial.println("connection failed"); + } +} diff --git a/libraries/SocketWrapper/examples/TestServer/TestServer.ino b/libraries/Ethernet/examples/WebServer/WebServer.ino similarity index 56% rename from libraries/SocketWrapper/examples/TestServer/TestServer.ino rename to libraries/Ethernet/examples/WebServer/WebServer.ino index b74e6ce3..81b7dcb9 100644 --- a/libraries/SocketWrapper/examples/TestServer/TestServer.ino +++ b/libraries/Ethernet/examples/WebServer/WebServer.ino @@ -1,27 +1,65 @@ +/* + Web Server + + A simple web server that shows the value of the analog input pins. + To view the page, open a web browser and type the server’s IP address in the address bar. + */ + #include "ZephyrServer.h" -#include "Ethernet.h" +#include "ZephyrClient.h" +#include "ZephyrEthernet.h" + +// The IP address will be dependent on your local network: +IPAddress ip(192, 168, 1, 177); +// Initialize the Ethernet server library +// with the IP address and port you want to use +// (port 80 is default for HTTP): ZephyrServer server(80); void setup() { - Serial.begin(115200); + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + Serial.println("Ethernet WebServer Example"); + + // in Zephyr system check if Ethernet is ready before proceeding to initialize while (Ethernet.linkStatus() != LinkON) { - Serial.println("waiting for link on"); + Serial.println("Waiting for link on"); delay(100); } - Ethernet.begin(); - Serial.println(Ethernet.localIP()); + + // start the Ethernet connection and the server: + Ethernet.begin(ip); + + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + + // start the server server.begin(); + Serial.print("server is at "); + Serial.println(Ethernet.localIP()); } -void loop() { - ZephyrClient client = server.available(); +void loop() { + // listen for incoming clients + ZephyrClient client = server.accept(); if (client) { Serial.println("new client"); // an http request ends with a blank line - bool currentLineIsBlank = true; + boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); @@ -40,7 +78,7 @@ void loop() { client.println(""); // output the value of each analog input pin for (int analogChannel = 0; analogChannel < 6; analogChannel++) { - int sensorReading = random(analogChannel, 100); + int sensorReading = analogRead(analogChannel); client.print("analog input "); client.print(analogChannel); client.print(" is "); @@ -50,11 +88,9 @@ void loop() { client.println(""); break; } - if (c == '\n') { // you're starting a new line currentLineIsBlank = true; - } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; @@ -66,7 +102,6 @@ void loop() { // close the connection: client.stop(); Serial.println("client disconnected"); - } else { - delay(100); } -} \ No newline at end of file +} + diff --git a/libraries/Ethernet/keywords.txt b/libraries/Ethernet/keywords.txt new file mode 100644 index 00000000..3c4ed937 --- /dev/null +++ b/libraries/Ethernet/keywords.txt @@ -0,0 +1,64 @@ +####################################### +# Syntax Coloring Map For Ethernet +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +Ethernet KEYWORD1 Ethernet +EthernetClient KEYWORD1 EthernetClient +EthernetServer KEYWORD1 EthernetServer +IPAddress KEYWORD1 EthernetIPAddress + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +status KEYWORD2 +connect KEYWORD2 +write KEYWORD2 +available KEYWORD2 +availableForWrite KEYWORD2 +read KEYWORD2 +peek KEYWORD2 +flush KEYWORD2 +stop KEYWORD2 +connected KEYWORD2 +accept KEYWORD2 +begin KEYWORD2 +beginMulticast KEYWORD2 +beginPacket KEYWORD2 +endPacket KEYWORD2 +parsePacket KEYWORD2 +remoteIP KEYWORD2 +remotePort KEYWORD2 +getSocketNumber KEYWORD2 +localIP KEYWORD2 +localPort KEYWORD2 +maintain KEYWORD2 +linkStatus KEYWORD2 +hardwareStatus KEYWORD2 +MACAddress KEYWORD2 +subnetMask KEYWORD2 +gatewayIP KEYWORD2 +dnsServerIP KEYWORD2 +setMACAddress KEYWORD2 +setLocalIP KEYWORD2 +setSubnetMask KEYWORD2 +setGatewayIP KEYWORD2 +setDnsServerIP KEYWORD2 +setRetransmissionTimeout KEYWORD2 +setRetransmissionCount KEYWORD2 +setConnectionTimeout KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + +EthernetLinkStatus LITERAL1 +Unknown LITERAL1 +LinkON LITERAL1 +LinkOFF LITERAL1 +EthernetHardwareStatus LITERAL1 +EthernetNoHardware LITERAL1 \ No newline at end of file diff --git a/libraries/Ethernet/library.properties b/libraries/Ethernet/library.properties new file mode 100644 index 00000000..cae314d2 --- /dev/null +++ b/libraries/Ethernet/library.properties @@ -0,0 +1,10 @@ +name=Ethernet +version=0.1.0 +author=Arduino +maintainer=Arduino +sentence=Enables network connection (local and Internet) using Ethernet on Zephyr enabled boards +paragraph=With this library you can connect to Internet via Ethernet. The library provides both Client and server functionalities. The library permits you to connect to a local network also with DHCP and to resolve DNS. +category=Communication +url=http://www.arduino.cc/en/Reference/Ethernet +architectures=zephyr,zephyr_portenta,zephyr_nicla,zephyr_giga +includes=Ethernet.h diff --git a/libraries/Ethernet/src/Ethernet.cpp b/libraries/Ethernet/src/Ethernet.cpp new file mode 100644 index 00000000..8618b4b1 --- /dev/null +++ b/libraries/Ethernet/src/Ethernet.cpp @@ -0,0 +1,120 @@ +#include "Ethernet.h" + +#if DT_HAS_COMPAT_STATUS_OKAY(ethernet_phy) + +int EthernetClass::begin(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) { + setMACAddress(mac); + return NetworkInterface::begin(true, 0); +} + +int EthernetClass::begin(uint8_t *mac, IPAddress ip) { + IPAddress dns = ip; + dns[3] = 1; + + auto ret = begin(mac, ip, dns); + return ret; +} + +int EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns) { + IPAddress gateway = ip; + gateway[3] = 1; + + auto ret = begin(mac, ip, dns, gateway); + return ret; +} + +int EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway) { + IPAddress subnet(255, 255, 255, 0); + auto ret = begin(mac, ip, dns, gateway, subnet); + return ret; +} + +int EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet, unsigned long timeout, unsigned long responseTimeout) { + setMACAddress(mac); + + if (!NetworkInterface::setLocalIPFull(ip, subnet, gateway)) { + return 0; + } + + if (!net_if_is_up(netif)) { + net_if_up(netif); + } + + return 1; +} + +EthernetLinkStatus EthernetClass::linkStatus() { + if ((hardwareStatus() == EthernetOk) && net_if_is_up(netif)) { + return LinkON; + } + return LinkOFF; +} + +EthernetHardwareStatus EthernetClass::hardwareStatus() { + const struct device *const dev = DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(ethernet_phy)); + if (device_is_ready(dev)) { + for (int i = 1; i < 3; i++) { + auto _if = net_if_get_by_index(i); + if (!net_eth_type_is_wifi(_if)) { + netif = _if; + break; + } + } + return EthernetOk; + } else { + return EthernetNoHardware; + } +} + +int EthernetClass::disconnect() { + return NetworkInterface::disconnect(); +} + +void EthernetClass::end() { + disconnect(); +} + +void EthernetClass::setMACAddress(const uint8_t *mac_address) { + if (mac_address != nullptr) { + NetworkInterface::setMACAddress(mac_address); + } +} + +void EthernetClass::MACAddress(uint8_t *mac_address) { + setMACAddress(mac_address); +} + +IPAddress EthernetClass::localIP() { + return NetworkInterface::localIP(); +} + +IPAddress EthernetClass::subnetMask() { + return NetworkInterface::subnetMask(); +} + +IPAddress EthernetClass::gatewayIP() { + return NetworkInterface::gatewayIP(); +} + +IPAddress EthernetClass::dnsServerIP() { + return NetworkInterface::dnsServerIP(); +} + +void EthernetClass::setLocalIP(const IPAddress local_ip) { + NetworkInterface::setLocalIP(local_ip); +} + +void EthernetClass::setSubnetMask(const IPAddress subnet) { + NetworkInterface::setSubnetMask(subnet); +} + +void EthernetClass::setGatewayIP(const IPAddress gateway) { + NetworkInterface::setGatewayIP(gateway); +} + +void EthernetClass::setDnsServerIP(const IPAddress dns_server) { + NetworkInterface::setDnsServerIP(dns_server); +} + +EthernetClass Ethernet; +#endif diff --git a/libraries/Ethernet/src/Ethernet.h b/libraries/Ethernet/src/Ethernet.h new file mode 100644 index 00000000..52913e6a --- /dev/null +++ b/libraries/Ethernet/src/Ethernet.h @@ -0,0 +1,70 @@ +#include "SocketHelpers.h" + +#include + +#if DT_HAS_COMPAT_STATUS_OKAY(ethernet_phy) + +enum EthernetLinkStatus { + Unknown, + LinkON, + LinkOFF +}; + +enum EthernetHardwareStatus { + EthernetNoHardware, + EthernetOk +}; + +class EthernetClass: public NetworkInterface +{ +public: + EthernetClass() {} + virtual ~EthernetClass() {} + + int begin(uint8_t *mac = nullptr, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + int maintain(); + EthernetLinkStatus linkStatus(); + EthernetHardwareStatus hardwareStatus(); + + // Manual configuration + int begin(uint8_t *mac, IPAddress ip); + int begin(uint8_t *mac, IPAddress ip, IPAddress dns); + int begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway); + int begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + + int begin(IPAddress ip) { + return begin(nullptr, ip); + } + int begin(IPAddress ip, IPAddress dns) { + return begin(nullptr, ip, dns); + } + int begin(IPAddress ip, IPAddress dns, IPAddress gateway) { + return begin(nullptr, ip, dns, gateway); + } + int begin(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) { + return begin(nullptr, ip, dns, gateway, subnet); + } + void init(uint8_t sspin = 10); + + int disconnect(void); + void end(void); + + void MACAddress(uint8_t *mac_address); + IPAddress localIP(); + IPAddress subnetMask(); + IPAddress gatewayIP(); + IPAddress dnsServerIP(); + + 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); + + void setRetransmissionTimeout(uint16_t milliseconds); + void setRetransmissionCount(uint8_t num); +}; + +extern EthernetClass Ethernet; + +#endif diff --git a/libraries/Ethernet/src/ZephyrEthernet.h b/libraries/Ethernet/src/ZephyrEthernet.h new file mode 100644 index 00000000..6ada64df --- /dev/null +++ b/libraries/Ethernet/src/ZephyrEthernet.h @@ -0,0 +1,3 @@ +#pragma once + +#include "Ethernet.h" diff --git a/libraries/Ethernet/src/Zephyr_Ethernet.h b/libraries/Ethernet/src/Zephyr_Ethernet.h new file mode 100644 index 00000000..61aaa315 --- /dev/null +++ b/libraries/Ethernet/src/Zephyr_Ethernet.h @@ -0,0 +1 @@ +// placeholder to allow the discovery of this library diff --git a/libraries/SocketWrapper/Ethernet.cpp b/libraries/SocketWrapper/Ethernet.cpp deleted file mode 100644 index 94802bb3..00000000 --- a/libraries/SocketWrapper/Ethernet.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Ethernet.h" - -#if DT_HAS_COMPAT_STATUS_OKAY(ethernet_phy) -EthernetClass Ethernet; -#endif \ No newline at end of file diff --git a/libraries/SocketWrapper/Ethernet.h b/libraries/SocketWrapper/Ethernet.h deleted file mode 100644 index 989420ab..00000000 --- a/libraries/SocketWrapper/Ethernet.h +++ /dev/null @@ -1,64 +0,0 @@ -#include "SocketHelpers.h" - -#include - -#if DT_HAS_COMPAT_STATUS_OKAY(ethernet_phy) - -enum EthernetLinkStatus { - Unknown, - LinkON, - LinkOFF -}; - -enum EthernetHardwareStatus { - EthernetNoHardware, - EthernetOk -}; - -class EthernetClass: public NetworkInterface -{ -public: - EthernetClass() {} - virtual ~EthernetClass() {} - - EthernetLinkStatus linkStatus() { - hardwareStatus(); - if (net_if_is_up(netif)) { - return LinkON; - } else { - return LinkOFF; - } - } - - bool begin(bool blocking = true, uint32_t additional_event_mask = 0) { - hardwareStatus(); - return NetworkInterface::begin(blocking, additional_event_mask); - } - - bool begin(uint8_t* mac_address, int _timeout, int _response_timeout) { - return begin(); - } - - bool begin(uint8_t* mac_address, IPAddress _ip, IPAddress _dns, IPAddress _gateway, IPAddress _netmask, int _timeout, int _response_timeout) { - return begin(); - } - - EthernetHardwareStatus hardwareStatus() { - const struct device *const dev = DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(ethernet_phy)); - if (device_is_ready(dev)) { - for (int i = 1; i < 3; i++) { - auto _if = net_if_get_by_index(i); - if (!net_eth_type_is_wifi(_if)) { - netif = _if; - break; - } - } - return EthernetOk; - } else { - return EthernetNoHardware; - } - } -}; -extern EthernetClass Ethernet; - -#endif \ No newline at end of file diff --git a/libraries/SocketWrapper/SocketHelpers.cpp b/libraries/SocketWrapper/SocketHelpers.cpp index aa4d59ab..8c94efa4 100644 --- a/libraries/SocketWrapper/SocketHelpers.cpp +++ b/libraries/SocketWrapper/SocketHelpers.cpp @@ -1,4 +1,211 @@ #include "SocketHelpers.h" +#include +LOG_MODULE_DECLARE(sketch, LOG_LEVEL_NONE); + struct net_mgmt_event_callback NetworkInterface::mgmt_cb; struct net_dhcpv4_option_callback NetworkInterface::dhcp_cb; + +void NetworkInterface::event_handler(struct net_mgmt_event_callback *cb, + uint64_t mgmt_event, + struct net_if *iface) +{ + int i = 0; + + if (mgmt_event != NET_EVENT_IPV4_ADDR_ADD) { + return; + } + + for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { + char buf[NET_IPV4_ADDR_LEN]; + + if (iface->config.ip.ipv4->unicast[i].ipv4.addr_type != + NET_ADDR_DHCP) { + continue; + } + + LOG_INF(" Address[%d]: %s", net_if_get_by_iface(iface), + net_addr_ntop(AF_INET, + &iface->config.ip.ipv4->unicast[i].ipv4.address.in_addr, + buf, sizeof(buf))); + LOG_INF(" Subnet[%d]: %s", net_if_get_by_iface(iface), + net_addr_ntop(AF_INET, + &iface->config.ip.ipv4->unicast[i].netmask, + buf, sizeof(buf))); + LOG_INF(" Router[%d]: %s", net_if_get_by_iface(iface), + net_addr_ntop(AF_INET, + &iface->config.ip.ipv4->gw, + buf, sizeof(buf))); + LOG_INF("Lease time[%d]: %u seconds", net_if_get_by_iface(iface), + iface->config.dhcpv4.lease_time); + } +} + +void NetworkInterface::option_handler(struct net_dhcpv4_option_callback *cb, + size_t length, + enum net_dhcpv4_msg_type msg_type, + struct net_if *iface) +{ + char buf[NET_IPV4_ADDR_LEN]; + + LOG_INF("DHCP Option %d: %s", cb->option, + net_addr_ntop(AF_INET, cb->data, buf, sizeof(buf))); +} + +int NetworkInterface::dhcp() +{ + net_mgmt_init_event_callback(&mgmt_cb, event_handler, NET_EVENT_IPV4_ADDR_ADD | NET_EVENT_IF_UP | NET_EVENT_IF_DOWN); + net_mgmt_add_event_callback(&mgmt_cb); + + net_dhcpv4_init_option_callback(&dhcp_cb, option_handler, + DHCP_OPTION_NTP, ntp_server, + sizeof(ntp_server)); + + net_dhcpv4_add_option_callback(&dhcp_cb); + + net_dhcpv4_start(netif); + + LOG_INF("DHCPv4 started...\n"); + + return 0; +} + +void NetworkInterface::enable_dhcpv4_server(struct net_if *netif, char* _netmask) +{ + static struct in_addr addr; + static struct in_addr netmaskAddr; + + if (net_addr_pton(AF_INET, String(localIP()).c_str(), &addr)) { + LOG_ERR("Invalid address: %s", String(localIP()).c_str()); + return; + } + + if (net_addr_pton(AF_INET, _netmask, &netmaskAddr)) { + LOG_ERR("Invalid netmask: %s", _netmask); + return; + } + + net_if_ipv4_set_gw(netif, &addr); + + if (net_if_ipv4_addr_add(netif, &addr, NET_ADDR_MANUAL, 0) == NULL) { + LOG_ERR("unable to set IP address for AP interface"); + } + + if (!net_if_ipv4_set_netmask_by_addr(netif, &addr, &netmaskAddr)) { + LOG_ERR("Unable to set netmask for AP interface: %s", _netmask); + } + + addr.s4_addr[3] += 10; /* Starting IPv4 address for DHCPv4 address pool. */ + + if (net_dhcpv4_server_start(netif, &addr) != 0) { + LOG_ERR("DHCP server is not started for desired IP"); + return; + } + + LOG_INF("DHCPv4 server started...\n"); +} + +IPAddress NetworkInterface::localIP() { + return IPAddress(netif->config.ip.ipv4->unicast[0].ipv4.address.in_addr.s_addr); +} + +IPAddress NetworkInterface::subnetMask() { + return IPAddress(netif->config.ip.ipv4->unicast[0].netmask.s_addr); +} +IPAddress NetworkInterface::gatewayIP() { + return IPAddress(netif->config.ip.ipv4->gw.s_addr); +} +IPAddress NetworkInterface::dnsServerIP() { + return arduino::INADDR_NONE; +} + +void NetworkInterface::setMACAddress(const uint8_t* mac) { + struct net_eth_addr new_mac; + struct ethernet_req_params params = { 0 }; + + memcpy(¶ms.mac_address, &new_mac, sizeof(struct net_eth_addr)); + + net_if_down(netif); // Ensure the interface is down before changing the MAC address + + int ret = net_mgmt(NET_REQUEST_ETHERNET_SET_MAC_ADDRESS, netif, + ¶ms, sizeof(params)); + if (ret != 0) { + LOG_ERR("Failed to set MAC address via net_mgmt, ret=%d", ret); + } else { + LOG_INF("MAC address set successfully via net_mgmt"); + } + + net_if_up(netif); // Bring the interface back up after changing the MAC address +} + +int NetworkInterface::begin(bool blocking, uint32_t additional_event_mask) { + dhcp(); + int ret = net_mgmt_event_wait_on_iface(netif, NET_EVENT_IPV4_ADDR_ADD | additional_event_mask, + NULL, NULL, NULL, blocking ? K_FOREVER : K_SECONDS(1)); + return (ret == 0) ? 1 : 0; +} + +bool NetworkInterface::disconnect() { + return (net_if_down(netif) == 0); +} + +bool NetworkInterface::setLocalIPFull(IPAddress ip, IPAddress subnet, IPAddress gateway) { + struct in_addr ip_addr, subnet_addr, gw_addr; + + ip_addr.s_addr = ip; + subnet_addr.s_addr = subnet; + gw_addr.s_addr = gateway; + + if (!net_if_ipv4_addr_add(netif, &ip_addr, NET_ADDR_MANUAL, 0)) { + LOG_ERR("Failed to set static IP address"); + return false; + } + + if (!net_if_ipv4_set_netmask_by_addr(netif, &ip_addr, &subnet_addr)) { + LOG_ERR("Failed to set subnet mask"); + return false; + } + + net_if_ipv4_set_gw(netif, &gw_addr); + LOG_INF("Static IP configured"); + return true; +} + +bool NetworkInterface::setLocalIP(IPAddress ip) { + struct in_addr addr; + addr.s_addr = ip; + + if (!net_if_ipv4_addr_add(netif, &addr, NET_ADDR_MANUAL, 0)) { + LOG_ERR("Failed to set local IP address"); + return false; + } + + LOG_INF("Local IP address set: %s", ip.toString().c_str()); + return true; +} + +bool NetworkInterface::setSubnetMask(IPAddress subnet) { + struct in_addr netmask_addr; + netmask_addr.s_addr = subnet; + + if (!net_if_ipv4_set_netmask_by_addr(netif, &netmask_addr, &netmask_addr)) { + LOG_ERR("Failed to set subnet mask"); + return false; + } + + LOG_INF("Subnet mask set: %s", subnet.toString().c_str()); + return true; +} + +bool NetworkInterface::setGatewayIP(IPAddress gateway) { + struct in_addr gw_addr; + gw_addr.s_addr = gateway; + + net_if_ipv4_set_gw(netif, &gw_addr); + LOG_INF("Gateway IP set: %s", gateway.toString().c_str()); + return true; +} + +bool NetworkInterface::setDnsServerIP(IPAddress dns_server) { + return false; // DNS server dynamic configuration is not supported +} diff --git a/libraries/SocketWrapper/SocketHelpers.h b/libraries/SocketWrapper/SocketHelpers.h index cf15fefe..b407c077 100644 --- a/libraries/SocketWrapper/SocketHelpers.h +++ b/libraries/SocketWrapper/SocketHelpers.h @@ -12,157 +12,51 @@ #include #include #include +#include +#include #include #define DHCP_OPTION_NTP (42) -#undef LOG_INF -#define LOG_INF(...) -#undef LOG_ERR -#define LOG_ERR(...) - class NetworkInterface { -private: - - uint8_t ntp_server[4]; - static struct net_mgmt_event_callback mgmt_cb; - static struct net_dhcpv4_option_callback dhcp_cb; - - static void event_handler(struct net_mgmt_event_callback *cb, - uint32_t mgmt_event, - struct net_if *iface) - { - int i = 0; - - if (mgmt_event != NET_EVENT_IPV4_ADDR_ADD) { - return; - } - - for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - char buf[NET_IPV4_ADDR_LEN]; - - if (iface->config.ip.ipv4->unicast[i].ipv4.addr_type != - NET_ADDR_DHCP) { - continue; - } - - LOG_INF(" Address[%d]: %s", net_if_get_by_iface(iface), - net_addr_ntop(AF_INET, - &iface->config.ip.ipv4->unicast[i].ipv4.address.in_addr, - buf, sizeof(buf))); - LOG_INF(" Subnet[%d]: %s", net_if_get_by_iface(iface), - net_addr_ntop(AF_INET, - &iface->config.ip.ipv4->unicast[i].netmask, - buf, sizeof(buf))); - LOG_INF(" Router[%d]: %s", net_if_get_by_iface(iface), - net_addr_ntop(AF_INET, - &iface->config.ip.ipv4->gw, - buf, sizeof(buf))); - LOG_INF("Lease time[%d]: %u seconds", net_if_get_by_iface(iface), - iface->config.dhcpv4.lease_time); - } - } - - static void option_handler(struct net_dhcpv4_option_callback *cb, - size_t length, - enum net_dhcpv4_msg_type msg_type, - struct net_if *iface) - { - char buf[NET_IPV4_ADDR_LEN]; - - LOG_INF("DHCP Option %d: %s", cb->option, - net_addr_ntop(AF_INET, cb->data, buf, sizeof(buf))); - } - -protected: - - struct net_if *netif = nullptr; - int dhcp() - { - net_mgmt_init_event_callback(&mgmt_cb, event_handler, NET_EVENT_IPV4_ADDR_ADD | NET_EVENT_IF_UP | NET_EVENT_IF_DOWN); - net_mgmt_add_event_callback(&mgmt_cb); - - net_dhcpv4_init_option_callback(&dhcp_cb, option_handler, - DHCP_OPTION_NTP, ntp_server, - sizeof(ntp_server)); - - net_dhcpv4_add_option_callback(&dhcp_cb); - - net_dhcpv4_start(netif); - - return 0; - } - - void enable_dhcpv4_server(struct net_if *netif, char* _netmask = "255.255.255.0") - { - static struct in_addr addr; - static struct in_addr netmaskAddr; - - if (net_addr_pton(AF_INET, String(localIP()).c_str(), &addr)) { - LOG_ERR("Invalid address: %s", String(localIP()).c_str()); - return; - } - - if (net_addr_pton(AF_INET, _netmask, &netmaskAddr)) { - LOG_ERR("Invalid netmask: %s", _netmask); - return; - } - - net_if_ipv4_set_gw(netif, &addr); - - if (net_if_ipv4_addr_add(netif, &addr, NET_ADDR_MANUAL, 0) == NULL) { - LOG_ERR("unable to set IP address for AP interface"); - } - - if (!net_if_ipv4_set_netmask_by_addr(netif, &addr, &netmaskAddr)) { - LOG_ERR("Unable to set netmask for AP interface: %s", _netmask); - } - - addr.s4_addr[3] += 10; /* Starting IPv4 address for DHCPv4 address pool. */ - - if (net_dhcpv4_server_start(netif, &addr) != 0) { - LOG_ERR("DHCP server is not started for desired IP"); - return; - } + private: + uint8_t ntp_server[4]; + static struct net_mgmt_event_callback mgmt_cb; + static struct net_dhcpv4_option_callback dhcp_cb; - LOG_INF("DHCPv4 server started...\n"); - } + static void event_handler(struct net_mgmt_event_callback *cb, + uint64_t mgmt_event, + struct net_if *iface); + static void option_handler(struct net_dhcpv4_option_callback *cb, + size_t length, + enum net_dhcpv4_msg_type msg_type, + struct net_if *iface); -public: - NetworkInterface() {} - ~NetworkInterface() {} - IPAddress localIP() { - return IPAddress(netif->config.ip.ipv4->unicast[0].ipv4.address.in_addr.s_addr); - } + protected: + struct net_if *netif = nullptr; + int dhcp(); + void enable_dhcpv4_server(struct net_if *netif, char* _netmask = "255.255.255.0"); - IPAddress subnetMask() { - return IPAddress(netif->config.ip.ipv4->unicast[0].netmask.s_addr); - } - IPAddress gatewayIP() { - return IPAddress(netif->config.ip.ipv4->gw.s_addr); - } - IPAddress dnsServerIP() { - return arduino::INADDR_NONE; - } + public: + NetworkInterface() {} + ~NetworkInterface() {} - IPAddress dnsIP(int n = 0); + IPAddress localIP(); - void setMACAddress(const uint8_t* mac); + IPAddress subnetMask(); + IPAddress gatewayIP(); + IPAddress dnsServerIP(); - bool begin(bool blocking = true, uint32_t additional_event_mask = 0) { - dhcp(); - int ret = net_mgmt_event_wait_on_iface(netif, NET_EVENT_IPV4_ADDR_ADD | additional_event_mask, - NULL, NULL, NULL, blocking ? K_FOREVER : K_SECONDS(1)); - return (ret == 0); - } + void setMACAddress(const uint8_t* mac); + bool setLocalIPFull(IPAddress ip, IPAddress subnet, IPAddress gateway); + bool setLocalIP(IPAddress ip); + bool setSubnetMask(IPAddress subnet); + bool setGatewayIP(IPAddress gateway); + bool setDnsServerIP(IPAddress dns_server); - bool disconnect() { - return (net_if_down(netif) == 0); - } + int begin(bool blocking = true, uint32_t additional_event_mask = 0); - // TODO: manual functions for setting IP address, subnet mask, gateway, etc. - // net_if_ipv4_set_netmask_by_addr(iface, &addr4, &nm); - // net_if_ipv4_addr_add(iface, &addr4, NET_ADDR_MANUAL, 0); + bool disconnect(); }; diff --git a/libraries/SocketWrapper/SocketWrapper.h b/libraries/SocketWrapper/SocketWrapper.h index ad5c36db..ce58ec8d 100644 --- a/libraries/SocketWrapper/SocketWrapper.h +++ b/libraries/SocketWrapper/SocketWrapper.h @@ -265,5 +265,27 @@ class ZephyrSocketWrapper { return ::accept(sock_fd, nullptr, nullptr); } + String remoteIP() { + if (sock_fd == -1) { + return {}; + } + + struct sockaddr_storage addr; + socklen_t addr_len = sizeof(addr); + char ip_str[INET6_ADDRSTRLEN] = {0}; + + if (::getpeername(sock_fd, (struct sockaddr*)&addr, &addr_len) == 0) { + if (addr.ss_family == AF_INET) { + struct sockaddr_in *s = (struct sockaddr_in*)&addr; + ::inet_ntop(AF_INET, &s->sin_addr, ip_str, sizeof(ip_str)); + } else if (addr.ss_family == AF_INET6) { + struct sockaddr_in6 *s6 = (struct sockaddr_in6*)&addr; + ::inet_ntop(AF_INET6, &s6->sin6_addr, ip_str, sizeof(ip_str)); + } + return String(ip_str); + } + + return {}; + } friend class ZephyrClient; }; diff --git a/libraries/SocketWrapper/ZephyrClient.h b/libraries/SocketWrapper/ZephyrClient.h index 8d947963..8332665b 100644 --- a/libraries/SocketWrapper/ZephyrClient.h +++ b/libraries/SocketWrapper/ZephyrClient.h @@ -85,5 +85,8 @@ class ZephyrClient : public arduino::Client, ZephyrSocketWrapper { operator bool() { return sock_fd != -1; } + String remoteIP() { + return ZephyrSocketWrapper::remoteIP(); + } friend class ZephyrServer; -}; \ No newline at end of file +}; diff --git a/libraries/SocketWrapper/ZephyrSSLClient.h b/libraries/SocketWrapper/ZephyrSSLClient.h index 71f47aed..e44c12d1 100644 --- a/libraries/SocketWrapper/ZephyrSSLClient.h +++ b/libraries/SocketWrapper/ZephyrSSLClient.h @@ -17,4 +17,4 @@ class ZephyrSSLClient : public ZephyrClient { return connectSSL(host, port, cert); } }; -#endif \ No newline at end of file +#endif diff --git a/libraries/SocketWrapper/ZephyrServer.h b/libraries/SocketWrapper/ZephyrServer.h index 286f9cc5..7ad0568e 100644 --- a/libraries/SocketWrapper/ZephyrServer.h +++ b/libraries/SocketWrapper/ZephyrServer.h @@ -53,4 +53,4 @@ class ZephyrServer : public arduino::Server, ZephyrSocketWrapper { } friend class ZephyrClient; -}; \ No newline at end of file +}; diff --git a/libraries/SocketWrapper/ZephyrUDP.h b/libraries/SocketWrapper/ZephyrUDP.h index d0620205..c12b26f0 100644 --- a/libraries/SocketWrapper/ZephyrUDP.h +++ b/libraries/SocketWrapper/ZephyrUDP.h @@ -29,6 +29,8 @@ #include #include +#define UDP_TX_PACKET_MAX_SIZE 24 + class ZephyrUDP : public arduino::UDP { private: int _socket; @@ -327,4 +329,4 @@ class ZephyrUDP : public arduino::UDP { }; std::list _rx_pkt_list; UdpRxPacket::SharedPtr _rx_pkt; -}; \ No newline at end of file +}; diff --git a/libraries/SocketWrapper/examples/TestClient/TestClient.ino b/libraries/SocketWrapper/examples/TestClient/TestClient.ino deleted file mode 100755 index dc5b98c3..00000000 --- a/libraries/SocketWrapper/examples/TestClient/TestClient.ino +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include "Ethernet.h" - -ZephyrClient client; -IPAddress addr(93, 184, 215, 14); - -void setup() { - - pinMode(LED_BUILTIN, OUTPUT); - Serial.begin(115200); - - while (Ethernet.linkStatus() != LinkON) { - Serial.println("waiting for link on"); - delay(100); - } - Ethernet.begin(); - Serial.println(Ethernet.localIP()); - - auto res = client.connect("example.com", 80); - res = client.println("GET / HTTP/1.0"); - client.println("Host: example.com"); - client.println("Connection: close"); - client.println(); -} - -// the loop function runs over and over again forever -void loop() { - while (client.available()) { - Serial.write(client.read()); - } -} diff --git a/libraries/SocketWrapper/utility/wl_definitions.h b/libraries/SocketWrapper/utility/wl_definitions.h index 1c49a7af..45f26fa9 100644 --- a/libraries/SocketWrapper/utility/wl_definitions.h +++ b/libraries/SocketWrapper/utility/wl_definitions.h @@ -74,4 +74,4 @@ enum wl_enc_type { /* Values map to 802.11 Cipher Algorithm Identifier */ ENC_TYPE_AUTO = 8 }; -#endif /* WL_DEFINITIONS_H_ */ \ No newline at end of file +#endif /* WL_DEFINITIONS_H_ */ diff --git a/loader/llext_exports.c b/loader/llext_exports.c index f1370a92..a76672ab 100644 --- a/loader/llext_exports.c +++ b/loader/llext_exports.c @@ -66,9 +66,12 @@ EXPORT_SYMBOL(usb_disable); EXPORT_SYMBOL(z_log_msg_runtime_vcreate); +FORCE_EXPORT_SYM(log_dynamic_sketch) + #if defined(CONFIG_NETWORKING) FORCE_EXPORT_SYM(net_if_foreach); FORCE_EXPORT_SYM(net_if_down); +FORCE_EXPORT_SYM(net_if_up); FORCE_EXPORT_SYM(net_if_get_by_iface); FORCE_EXPORT_SYM(net_if_ipv4_maddr_add); FORCE_EXPORT_SYM(net_if_ipv4_maddr_join); @@ -80,6 +83,7 @@ FORCE_EXPORT_SYM(net_if_lookup_by_dev); #if defined(CONFIG_NET_L2_ETHERNET) FORCE_EXPORT_SYM(_net_l2_ETHERNET); +FORCE_EXPORT_SYM(net_mgmt_NET_REQUEST_ETHERNET_SET_MAC_ADDRESS); #endif #if defined(CONFIG_NET_DHCPV4) @@ -157,6 +161,8 @@ FORCE_EXPORT_SYM(inet_pton); FORCE_EXPORT_SYM(sendto); FORCE_EXPORT_SYM(recvfrom); FORCE_EXPORT_SYM(setsockopt); +FORCE_EXPORT_SYM(getpeername); +FORCE_EXPORT_SYM(inet_ntop); #endif #if defined(CONFIG_CDC_ACM_DTE_RATE_CALLBACK_SUPPORT) @@ -239,4 +245,4 @@ FORCE_EXPORT_SYM(__aeabi_dcmpge); #if defined (CONFIG_CPP) FORCE_EXPORT_SYM(__cxa_pure_virtual); -#endif \ No newline at end of file +#endif diff --git a/loader/main.c b/loader/main.c index 643da9d7..0e68e970 100644 --- a/loader/main.c +++ b/loader/main.c @@ -6,7 +6,7 @@ #include "zephyr/sys/printk.h" #include -LOG_MODULE_REGISTER(app); +LOG_MODULE_REGISTER(sketch); #include #include