diff --git a/libraries/Ethernet/examples/AdvancedChatServer/AdvancedChatServer.ino b/libraries/Ethernet/examples/AdvancedChatServer/AdvancedChatServer.ino new file mode 100644 index 000000000..630f27240 --- /dev/null +++ b/libraries/Ethernet/examples/AdvancedChatServer/AdvancedChatServer.ino @@ -0,0 +1,109 @@ +/* + 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. + You can see the client's input in the serial monitor as well. + Using an Arduino Wiznet Ethernet shield. + + Circuit: + * Ethernet shield attached to pins 10, 11, 12, 13 + + created 18 Dec 2009 + by David A. Mellis + modified 9 Apr 2012 + by Tom Igoe + redesigned to make use of operator== 25 Nov 2013 + by Norbert Truchsess + + */ + +#include +#include +#include + +// 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 +EthernetServer server(23); + +EthernetClient clients[8]; + +void setup() { + + // initialize the Ethernet device + Ethernet.begin(ip, myDns, gateway, subnet); + + // 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 + } + + // 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) + EthernetClient newClient = server.available(); + 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 000000000..6f26ef888 --- /dev/null +++ b/libraries/Ethernet/examples/BarometricPressureWebServer/BarometricPressureWebServer.ino @@ -0,0 +1,236 @@ +/* + 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 + + TODO: this hardware is long obsolete. This example program should + be rewritten to use https://www.sparkfun.com/products/9721 + + 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 + + created 31 July 2010 + by Tom Igoe + */ + +#include +#include +// 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): +EthernetServer 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 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 + } + + // 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 + EthernetClient client = server.available(); + 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/ChatServer/ChatServer.ino b/libraries/Ethernet/examples/ChatServer/ChatServer.ino new file mode 100644 index 000000000..bfc310b9c --- /dev/null +++ b/libraries/Ethernet/examples/ChatServer/ChatServer.ino @@ -0,0 +1,97 @@ +/* + Chat Server + + A simple server that distributes any incoming messages to all + connected clients. To use, telnet to your device's IP address and type. + You can see the client's input in the serial monitor as well. + Using an Arduino Wiznet Ethernet shield. + + Circuit: + * Ethernet shield attached to pins 10, 11, 12, 13 + + created 18 Dec 2009 + by David A. Mellis + modified 9 Apr 2012 + by Tom Igoe + + */ + +#include +#include +#include + +// 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, 0, 0); + + +// telnet defaults to port 23 +EthernetServer server(23); +boolean alreadyConnected = false; // whether or not the client was connected previously + +void setup() { + // You can use Ethernet.init(pin) to configure the CS pin + //Ethernet.init(10); // Most Arduino shields + //Ethernet.init(5); // MKR ETH shield + //Ethernet.init(0); // Teensy 2.0 + //Ethernet.init(20); // Teensy++ 2.0 + //Ethernet.init(15); // ESP8266 with Adafruit Featherwing Ethernet + //Ethernet.init(33); // ESP32 with Adafruit Featherwing Ethernet + + // initialize the ethernet device + Ethernet.begin(ip, myDns, gateway, subnet); + + // 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 + } + + // 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() { + // wait for a new client: + EthernetClient client = server.available(); + + // when the client sends the first byte, say hello: + if (client) { + if (!alreadyConnected) { + // clear out the input buffer: + client.flush(); + Serial.println("We have a new client"); + client.println("Hello, client!"); + alreadyConnected = true; + } + + if (client.available() > 0) { + // read the bytes incoming from the client: + char thisChar = client.read(); + // echo the bytes back to the client: + server.write(thisChar); + // echo the bytes to the server as well: + Serial.write(thisChar); + } + } +} + + + diff --git a/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino b/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino new file mode 100644 index 000000000..5cadfe2e1 --- /dev/null +++ b/libraries/Ethernet/examples/DhcpAddressPrinter/DhcpAddressPrinter.ino @@ -0,0 +1,82 @@ +/* + 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. + + Circuit: + Ethernet shield attached to pins 10, 11, 12, 13 + + created 12 April 2011 + modified 9 Apr 2012 + by Tom Igoe + modified 02 Sept 2015 + by Arturo Guadalupi + + */ + +#include +#include +#include + +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 + } + + // 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.status() != 0) { + Serial.println(Ethernet.status()); + connectEth(); + } +} + +void connectEth() +{ + // 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/DhcpChatServer/DhcpChatServer.ino b/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino new file mode 100644 index 000000000..cbf2deadd --- /dev/null +++ b/libraries/Ethernet/examples/DhcpChatServer/DhcpChatServer.ino @@ -0,0 +1,91 @@ +/* + DHCP Chat Server + + A simple server that distributes any incoming messages to all + connected clients. To use, telnet to your device's IP address and type. + You can see the client's input in the serial monitor as well. + Using an Arduino Wiznet Ethernet shield. + + THis version attempts to get an IP address using DHCP + + Circuit: + * Ethernet shield attached to pins 10, 11, 12, 13 + + created 21 May 2011 + modified 9 Apr 2012 + by Tom Igoe + modified 02 Sept 2015 + by Arturo Guadalupi + Based on ChatServer example by David A. Mellis + + */ + +#include +#include +#include + +// 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, 0, 0); + +// telnet defaults to port 23 +EthernetServer server(23); +boolean gotAMessage = false; // whether or not you got a message from the client yet + +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 + } + + // start the Ethernet connection: + Serial.println("Trying to get an IP address using 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."); + } + // initialize the Ethernet device not using DHCP: + Ethernet.begin(ip, myDns, gateway, subnet); + } + // print your local IP address: + Serial.print("My IP address: "); + Serial.println(Ethernet.localIP()); + + // start listening for clients + server.begin(); +} + +void loop() { + // wait for a new client: + EthernetClient client = server.available(); + + // when the client sends the first byte, say hello: + if (client) { + if (!gotAMessage) { + Serial.println("We have a new client"); + client.println("Hello, client!"); + gotAMessage = true; + } + + // read the bytes incoming from the client: + char thisChar = client.read(); + // echo the bytes back to the client: + server.write(thisChar); + // echo the bytes to the server as well: + Serial.print(thisChar); + } +} + diff --git a/libraries/Ethernet/examples/LinkStatus/LinkStatus.ino b/libraries/Ethernet/examples/LinkStatus/LinkStatus.ino new file mode 100644 index 000000000..b0397b7d4 --- /dev/null +++ b/libraries/Ethernet/examples/LinkStatus/LinkStatus.ino @@ -0,0 +1,36 @@ +/* + Link Status + This sketch prints the ethernet link status. When the + ethernet cable is connected the link status should go to "ON". + NOTE: Only WizNet W5200 and W5500 are capable of reporting + the link status. W5100 will report "Unknown". + Hardware: + - Ethernet shield or equivalent board/shield with WizNet 5200/5500 + Written by Cristian Maglie + This example is public domain. +*/ + +#include +#include +#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 000000000..bffb8f472 --- /dev/null +++ b/libraries/Ethernet/examples/TelnetClient/TelnetClient.ino @@ -0,0 +1,103 @@ +/* + Telnet client + + This sketch connects to a a telnet server (http://www.google.com) + using an Arduino Wiznet Ethernet shield. You'll need a telnet server + to test this with. + Processing's ChatServer example (part of the network library) works well, + running on port 10002. It can be found as part of the examples + in the Processing application, available at + http://processing.org/ + + Circuit: + * Ethernet shield attached to pins 10, 11, 12, 13 + + created 14 Sep 2010 + modified 9 Apr 2012 + by Tom Igoe + */ + +#include +#include +#include + +// The IP address will be dependent on your local network: +IPAddress ip(192, 168, 1, 177); + +// Enter the IP address of the server you're connecting to: +IPAddress server(1, 1, 1, 1); + +// 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): +EthernetClient client; + +void setup() { + + // 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 + } + + // 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); + } + + // 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, 10002)) { + 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 000000000..618869947 --- /dev/null +++ b/libraries/Ethernet/examples/UDPSendReceiveString/UDPSendReceiveString.ino @@ -0,0 +1,128 @@ +/* + 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. + + created 21 Aug 2010 + by Michael Margolis + + This code is in the public domain. + */ + +#include +#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 +EthernetUDP Udp; + +void setup() { + + // start the Ethernet + 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 + } + + // 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 000000000..627cf2cca --- /dev/null +++ b/libraries/Ethernet/examples/UdpNtpClient/UdpNtpClient.ino @@ -0,0 +1,170 @@ +/* + + 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 + + created 4 Sep 2010 + by Michael Margolis + modified 9 Apr 2012 + by Tom Igoe + modified 02 Sept 2015 + by Arturo Guadalupi + + This code is in the public domain. + + */ + +#include +#include +#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 +EthernetUDP 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 + } + + // 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.status() != 0) { + Serial.println(Ethernet.status()); + 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() +{ + // 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 000000000..62b506df8 --- /dev/null +++ b/libraries/Ethernet/examples/WebClient/WebClient.ino @@ -0,0 +1,133 @@ +/* + Web client + + This sketch connects to a website (http://www.google.com) + using an Arduino Wiznet Ethernet shield. + + Circuit: + * Ethernet shield attached to pins 10, 11, 12, 13 + + created 18 Dec 2009 + by David A. Mellis + modified 9 Apr 2012 + by Tom Igoe, based on work by Adrian McEwen + + */ + +#include +#include +#include + +// 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): +EthernetClient 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 + } + + // 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 000000000..a5ffdf1f0 --- /dev/null +++ b/libraries/Ethernet/examples/WebClientRepeating/WebClientRepeating.ino @@ -0,0 +1,120 @@ +/* + 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. + + Circuit: + * Ethernet shield attached to pins 10, 11, 12, 13 + + created 19 Apr 2012 + by Tom Igoe + modified 21 Jan 2014 + by Federico Vanzati + + http://www.arduino.cc/en/Tutorial/WebClientRepeating + This code is in the public domain. + + */ + +#include +#include +#include + +// 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: +EthernetClient 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 + } + + // 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 000000000..def9a130f --- /dev/null +++ b/libraries/Ethernet/examples/WebClientRepeatingManual/WebClientRepeatingManual.ino @@ -0,0 +1,147 @@ +/* + 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. + + Circuit: + * Ethernet shield attached to pins 10, 11, 12, 13 + + created 19 Apr 2012 + by Tom Igoe + modified 21 Jan 2014 + by Federico Vanzati + + http://www.arduino.cc/en/Tutorial/WebClientRepeating + This code is in the public domain. + + */ + +#include +#include +#include + +// 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, 0, 0); + +// initialize the library instance: +EthernetClient 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 + } + + 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/WebServer/WebServer.ino b/libraries/Ethernet/examples/WebServer/WebServer.ino new file mode 100644 index 000000000..6201495f7 --- /dev/null +++ b/libraries/Ethernet/examples/WebServer/WebServer.ino @@ -0,0 +1,113 @@ +/* + Web Server + + A simple web server that shows the value of the analog input pins. + using an Arduino Wiznet Ethernet shield. + + Circuit: + * Ethernet shield attached to pins 10, 11, 12, 13 + * Analog inputs attached to pins A0 through A5 (optional) + + created 18 Dec 2009 + by David A. Mellis + modified 9 Apr 2012 + by Tom Igoe + modified 02 Sept 2015 + by Arturo Guadalupi + + */ + +#include +#include +#include + +// 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): +EthernetServer server(80); + +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 + } + Serial.println("Ethernet WebServer Example"); + + // 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() { + // listen for incoming clients + EthernetClient client = server.available(); + if (client) { + Serial.println("new client"); + // an http request ends with a blank line + boolean currentLineIsBlank = true; + while (client.connected()) { + if (client.available()) { + char c = client.read(); + Serial.write(c); + // 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("Connection: close"); // the connection will be closed after completion of the response + client.println("Refresh: 5"); // refresh the page automatically every 5 sec + client.println(); + client.println(""); + client.println(""); + // output the value of each analog input pin + for (int analogChannel = 0; analogChannel < 6; analogChannel++) { + int sensorReading = analogRead(analogChannel); + client.print("analog input "); + client.print(analogChannel); + client.print(" is "); + client.print(sensorReading); + client.println("
"); + } + 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(); + Serial.println("client disconnected"); + } +} + diff --git a/libraries/Ethernet/src/Ethernet.cpp b/libraries/Ethernet/src/Ethernet.cpp index 92954d763..54c00ffe8 100644 --- a/libraries/Ethernet/src/Ethernet.cpp +++ b/libraries/Ethernet/src/Ethernet.cpp @@ -2,142 +2,86 @@ #define SSID_MAX_LENGTH 32 -arduino::IPAddress arduino::EthernetClass::ipAddressFromSocketAddress(SocketAddress socketAddress) { - nsapi_addr_t address = socketAddress.get_addr(); - return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]); -} - -SocketAddress arduino::EthernetClass::socketAddressFromIpAddress(arduino::IPAddress ip, uint16_t port) { - nsapi_addr_t convertedIP = {NSAPI_IPv4, {ip[0], ip[1], ip[2], ip[3]}}; - return SocketAddress(convertedIP, port); -} - int arduino::EthernetClass::begin(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) { - if (eth_if == nullptr) { - //Q: What is the callback for? - _initializerCallback(); - if(eth_if == nullptr) return 0; - } - - unsigned long start = millis(); - eth_if->set_blocking(false); - nsapi_error_t result = eth_if->connect(); + if (eth_if == nullptr) { + //Q: What is the callback for? + _initializerCallback(); + if (eth_if == nullptr) return 0; + } - while ((millis() - start < timeout) && (linkStatus() != LinkON)) { - delay(10); - } + unsigned long start = millis(); + eth_if->set_blocking(false); + eth_if->connect(); - return (linkStatus() == LinkON ? 1 : 0); -} + while ((millis() - start < timeout) && (linkStatus() != LinkON)) { + delay(10); + } -void arduino::EthernetClass::end() { - disconnect(); + return (linkStatus() == LinkON ? 1 : 0); } -EthernetLinkStatus arduino::EthernetClass::linkStatus() { - return (eth_if->get_connection_status() == NSAPI_STATUS_GLOBAL_UP ? LinkON : LinkOFF); -} +int arduino::EthernetClass::begin(uint8_t *mac, IPAddress ip) { + IPAddress dns = ip; + dns[3] = 1; -EthernetHardwareStatus arduino::EthernetClass::hardwareStatus() { - return EthernetMbed; + auto ret = begin(mac, ip, dns); + return ret; } +int arduino::EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns) { + IPAddress gateway = ip; + gateway[3] = 1; -int arduino::EthernetClass::disconnect() { - eth_if->disconnect(); + auto ret = begin(mac, ip, dns, gateway); + return ret; } -void arduino::EthernetClass::config(arduino::IPAddress local_ip){ - nsapi_addr_t convertedIP = {NSAPI_IPv4, {local_ip[0], local_ip[1], local_ip[2], local_ip[3]}}; - _ip = SocketAddress(convertedIP); +int arduino::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; } -void arduino::EthernetClass::config(const char *local_ip){ - _ip = SocketAddress(local_ip); -} +int arduino::EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) { + config(ip, dns, gateway, subnet); -void arduino::EthernetClass::config(IPAddress local_ip, IPAddress dns_server){ - config(local_ip); - setDNS(dns_server); -} - -void arduino::EthernetClass::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway){ - config(local_ip, dns_server); - nsapi_addr_t convertedGatewayIP = {NSAPI_IPv4, {gateway[0], gateway[1], gateway[2], gateway[3]}}; - _gateway = SocketAddress(convertedGatewayIP); -} + eth_if->set_dhcp(false); + eth_if->set_network(_ip, _netmask, _gateway); + eth_if->add_dns_server(_dnsServer1, nullptr); -void arduino::EthernetClass::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet){ - config(local_ip, dns_server, gateway); - nsapi_addr_t convertedSubnetMask = {NSAPI_IPv4, {subnet[0], subnet[1], subnet[2], subnet[3]}}; - _netmask = SocketAddress(convertedSubnetMask); + auto ret = begin(mac); + return ret; } -void arduino::EthernetClass::setDNS(IPAddress dns_server1){ - nsapi_addr_t convertedDNSServer = {NSAPI_IPv4, {dns_server1[0], dns_server1[1], dns_server1[2], dns_server1[3]}}; - _dnsServer1 = SocketAddress(convertedDNSServer); -} - -void arduino::EthernetClass::setDNS(IPAddress dns_server1, IPAddress dns_server2){ - setDNS(dns_server1); - nsapi_addr_t convertedDNSServer2 = {NSAPI_IPv4, {dns_server2[0], dns_server2[1], dns_server2[2], dns_server2[3]}}; - _dnsServer2 = SocketAddress(convertedDNSServer2); +void arduino::EthernetClass::end() { + disconnect(); } -uint8_t arduino::EthernetClass::status() { - return _currentNetworkStatus; +EthernetLinkStatus arduino::EthernetClass::linkStatus() { + return (eth_if->get_connection_status() == NSAPI_STATUS_GLOBAL_UP ? LinkON : LinkOFF); } -int arduino::EthernetClass::hostByName(const char* aHostname, IPAddress& aResult){ - SocketAddress socketAddress = SocketAddress(); - nsapi_error_t returnCode = getNetwork()->gethostbyname(aHostname, &socketAddress); - nsapi_addr_t address = socketAddress.get_addr(); - aResult[0] = address.bytes[0]; - aResult[1] = address.bytes[1]; - aResult[2] = address.bytes[2]; - aResult[3] = address.bytes[3]; - return returnCode == NSAPI_ERROR_OK ? 1 : 0; +EthernetHardwareStatus arduino::EthernetClass::hardwareStatus() { + return EthernetMbed; } -uint8_t* arduino::EthernetClass::macAddress(uint8_t* mac) { - const char *mac_str = getNetwork()->get_mac_address(); - for( int b = 0; b < 6; b++ ) - { - uint32_t tmp; - sscanf( &mac_str[b * 2 + (b)], "%02x", &tmp) ; - mac[5-b] = (uint8_t)tmp ; - } - //sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", &mac[5], &mac[4], &mac[3], &mac[2], &mac[1], &mac[0]); - return mac; -} -arduino::IPAddress arduino::EthernetClass::localIP() { - SocketAddress ip; - NetworkInterface *interface = getNetwork(); - interface->get_ip_address(&ip); - return ipAddressFromSocketAddress(ip); +int arduino::EthernetClass::disconnect() { + eth_if->disconnect(); + return 1; } -arduino::IPAddress arduino::EthernetClass::subnetMask() { - SocketAddress ip; - NetworkInterface *interface = getNetwork(); - interface->get_netmask(&ip); - return ipAddressFromSocketAddress(ip); -} -arduino::IPAddress arduino::EthernetClass::gatewayIP() { - SocketAddress ip; - NetworkInterface *interface = getNetwork(); - interface->get_gateway(&ip); - return ipAddressFromSocketAddress(ip); +uint8_t arduino::EthernetClass::status() { + return _currentNetworkStatus; } NetworkInterface *arduino::EthernetClass::getNetwork() { - return eth_if; + return eth_if; } unsigned long arduino::EthernetClass::getTime() { - return 0; + return 0; } arduino::EthernetClass Ethernet; diff --git a/libraries/Ethernet/src/Ethernet.h b/libraries/Ethernet/src/Ethernet.h index f1ca47a19..3b86e7601 100644 --- a/libraries/Ethernet/src/Ethernet.h +++ b/libraries/Ethernet/src/Ethernet.h @@ -1,5 +1,5 @@ /* Copyright 2018 Paul Stoffregen - * Copyright 2020 Arduino SA + * Copyright 2020-2021 Arduino SA * * 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 @@ -23,106 +23,105 @@ #define ethernet_h_ #include "Arduino.h" +#include "SocketHelpers.h" #include "api/IPAddress.h" -#include "EthernetClient.h" -#include "EthernetServer.h" -#include "EthernetUdp.h" #include "netsocket/NetworkInterface.h" #include "EthernetInterface.h" enum EthernetLinkStatus { - Unknown, - LinkON, - LinkOFF + Unknown, + LinkON, + LinkOFF }; enum EthernetHardwareStatus { - EthernetNoHardware, - EthernetMbed = 6 + EthernetNoHardware, + EthernetMbed = 6 }; namespace arduino { -typedef void* (*voidPrtFuncPtr)(void); +typedef void *(*voidPrtFuncPtr)(void); -class EthernetClass { +class EthernetClass : public MbedSocketClass { 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 - EthernetClass(EthernetInterface* _if) : eth_if(_if) {}; - EthernetClass() {}; - - EthernetClass(voidPrtFuncPtr _cb) : _initializerCallback(_cb) {}; - - int begin(uint8_t *mac, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); - int maintain(); - EthernetLinkStatus linkStatus(); - EthernetHardwareStatus hardwareStatus(); - - // Manaul configuration - void begin(uint8_t *mac, IPAddress ip) {} - void begin(uint8_t *mac, IPAddress ip, IPAddress dns) {} - void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway) {} - void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) {} - void init(uint8_t sspin = 10); - - void MACAddress(uint8_t *mac_address); - uint8_t* macAddress(uint8_t* mac); - IPAddress localIP(); - IPAddress subnetMask(); - IPAddress gatewayIP(); - IPAddress dnsServerIP() { return ipAddressFromSocketAddress(_dnsServer1); } - - void config(IPAddress local_ip); - void config(const char *local_ip); - void config(IPAddress local_ip, IPAddress dns_server); - void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway); - void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet); - void setDNS(IPAddress dns_server1); - void setDNS(IPAddress dns_server1, IPAddress dns_server2); - void setHostname(const char* name); - - int disconnect(void); - void end(void); - - uint8_t status(); - int hostByName(const char* aHostname, IPAddress& aResult); - unsigned long getTime(); - - 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) { _dnsServer1 = socketAddressFromIpAddress(dns_server, 0); } - void setRetransmissionTimeout(uint16_t milliseconds); - void setRetransmissionCount(uint8_t num); - - friend class EthernetClient; - friend class EthernetServer; - friend class EthernetUDP; - - NetworkInterface *getNetwork(); + // 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 + EthernetClass(EthernetInterface *_if) + : eth_if(_if){}; + EthernetClass(){}; + + EthernetClass(voidPrtFuncPtr _cb) + : _initializerCallback(_cb){}; + + int begin(uint8_t *mac = nullptr, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + 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); + + 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); + + void MACAddress(uint8_t *mac_address); + + void setHostname(const char *name); + + int disconnect(void); + void end(void); + + uint8_t status(); + unsigned long getTime(); + + 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) { + _dnsServer1 = socketAddressFromIpAddress(dns_server, 0); + } + void setRetransmissionTimeout(uint16_t milliseconds); + void setRetransmissionCount(uint8_t num); + + friend class EthernetClient; + friend class EthernetServer; + friend class EthernetUDP; + + NetworkInterface *getNetwork(); private: - - volatile EthernetLinkStatus _currentNetworkStatus = Unknown; - EthernetInterface net; - SocketAddress _ip = nullptr; - SocketAddress _gateway = nullptr; - SocketAddress _netmask = nullptr; - SocketAddress _dnsServer1 = nullptr; - SocketAddress _dnsServer2 = nullptr; - EthernetInterface* eth_if = &net; - voidPrtFuncPtr _initializerCallback; - arduino::IPAddress ipAddressFromSocketAddress(SocketAddress socketAddress); - SocketAddress socketAddressFromIpAddress(arduino::IPAddress ip, uint16_t port); + volatile EthernetLinkStatus _currentNetworkStatus = Unknown; + EthernetInterface net; + EthernetInterface *eth_if = &net; + voidPrtFuncPtr _initializerCallback; + arduino::IPAddress ipAddressFromSocketAddress(SocketAddress socketAddress); + SocketAddress socketAddressFromIpAddress(arduino::IPAddress ip, uint16_t port); }; } extern arduino::EthernetClass Ethernet; +#include "EthernetClient.h" +#include "EthernetServer.h" +#include "EthernetUdp.h" + #endif diff --git a/libraries/Ethernet/src/EthernetClient.cpp b/libraries/Ethernet/src/EthernetClient.cpp deleted file mode 100644 index 4a524dafd..000000000 --- a/libraries/Ethernet/src/EthernetClient.cpp +++ /dev/null @@ -1,143 +0,0 @@ -#include "EthernetClient.h" - -#ifndef SOCKET_TIMEOUT -#define SOCKET_TIMEOUT 1000 -#endif - -arduino::EthernetClient::EthernetClient() { -} - -uint8_t arduino::EthernetClient::status() { - return _status; -} - -void arduino::EthernetClient::getStatus() { - uint8_t data[256]; - int ret = sock->recv(data, rxBuffer.availableForStore()); - for (int i = 0; i < ret; i++) { - rxBuffer.store_char(data[i]); - } - if (ret < 0 && ret != NSAPI_ERROR_WOULD_BLOCK) { - _status = LinkOFF; - } -} - -int arduino::EthernetClient::connect(SocketAddress socketAddress) { - if (sock == NULL) { - sock = new TCPSocket(); - if(static_cast(sock)->open(Ethernet.getNetwork()) != NSAPI_ERROR_OK){ - return 0; - } - } - //sock->sigio(mbed::callback(this, &EthernetClient::getStatus)); - //sock->set_blocking(false); - address = socketAddress; - sock->set_timeout(SOCKET_TIMEOUT); - nsapi_error_t returnCode = static_cast(sock)->connect(socketAddress); - return returnCode == NSAPI_ERROR_OK ? 1 : 0; -} - -int arduino::EthernetClient::connect(IPAddress ip, uint16_t port) { - return connect(Ethernet.socketAddressFromIpAddress(ip, port)); -} - -int arduino::EthernetClient::connect(const char *host, uint16_t port) { - SocketAddress socketAddress = SocketAddress(); - socketAddress.set_port(port); - Ethernet.getNetwork()->gethostbyname(host, &socketAddress); - return connect(socketAddress); -} - -int arduino::EthernetClient::connectSSL(SocketAddress socketAddress){ - if (sock == NULL) { - sock = new TLSSocket(); - if(static_cast(sock)->open(Ethernet.getNetwork()) != NSAPI_ERROR_OK){ - return 0; - } - } - if (beforeConnect) { - beforeConnect(); - } - sock->set_timeout(SOCKET_TIMEOUT); - nsapi_error_t returnCode = static_cast(sock)->connect(socketAddress); - return returnCode == NSAPI_ERROR_OK ? 1 : 0; -} - -int arduino::EthernetClient::connectSSL(IPAddress ip, uint16_t port) { - return connectSSL(Ethernet.socketAddressFromIpAddress(ip, port)); -} - -int arduino::EthernetClient::connectSSL(const char *host, uint16_t port) { - SocketAddress socketAddress = SocketAddress(); - socketAddress.set_port(port); - Ethernet.getNetwork()->gethostbyname(host, &socketAddress); - return connectSSL(socketAddress); -} - -size_t arduino::EthernetClient::write(uint8_t c) { - sock->send(&c, 1); -} - -size_t arduino::EthernetClient::write(const uint8_t *buf, size_t size) { - sock->send(buf, size); -} - -int arduino::EthernetClient::available() { - if (rxBuffer.available() == 0) { - getStatus(); - } - return rxBuffer.available(); -} - -int arduino::EthernetClient::read() { - if (!available()) { - return -1; - } - - return rxBuffer.read_char(); -} - -int arduino::EthernetClient::read(uint8_t *data, size_t len) { - int avail = available(); - - if (!avail) { - return -1; - } - - if ((int)len > avail) { - len = avail; - } - - for (size_t i = 0; i < len; i++) { - data[i] = rxBuffer.read_char(); - } - - return len; -} - -int arduino::EthernetClient::peek() { - return rxBuffer.peek(); -} - -void arduino::EthernetClient::flush() { - -} - -void arduino::EthernetClient::stop() { - if (sock != NULL) { - sock->close(); - sock = NULL; - } -} - -uint8_t arduino::EthernetClient::connected() { - return _status != LinkOFF; -} - -IPAddress arduino::EthernetClient::remoteIP() { - return Ethernet.ipAddressFromSocketAddress(address); -} - -uint16_t arduino::EthernetClient::remotePort() { - return 0; -} diff --git a/libraries/Ethernet/src/EthernetClient.h b/libraries/Ethernet/src/EthernetClient.h index 0c1b1ee0f..9d9f9b77a 100644 --- a/libraries/Ethernet/src/EthernetClient.h +++ b/libraries/Ethernet/src/EthernetClient.h @@ -21,70 +21,16 @@ #define ethernetclient_h #include "Ethernet.h" -#include "api/Print.h" -#include "api/Client.h" -#include "api/IPAddress.h" -#include "TLSSocket.h" -#include "TCPSocket.h" +#include "MbedClient.h" namespace arduino { -class EthernetClient : public arduino::Client { - -public: - EthernetClient(); - ~EthernetClient() { - stop(); - } - - uint8_t status(); - int connect(SocketAddress socketAddress); - int connect(IPAddress ip, uint16_t port); - int connect(const char *host, uint16_t port); - int connectSSL(SocketAddress socketAddress); - int connectSSL(IPAddress ip, uint16_t port); - int connectSSL(const char *host, uint16_t port); - size_t write(uint8_t); - size_t write(const uint8_t *buf, size_t size); - int available(); - int read(); - int read(uint8_t *buf, size_t size); - int peek(); - void flush(); - void stop(); - uint8_t connected(); - operator bool() { - return sock != NULL; +class EthernetClient : public MbedClient { + NetworkInterface *getNetwork() { + return Ethernet.getNetwork(); } - - void setSocket(Socket* _sock) { - sock = _sock; - } - - IPAddress remoteIP(); - uint16_t remotePort(); - - friend class EthernetServer; - - using Print::write; - -protected: - - void onBeforeConnect(mbed::Callback cb) { - beforeConnect = cb; - } - -private: - static uint16_t _srcport; - Socket* sock; - RingBufferN<256> rxBuffer; - uint8_t _status; - mbed::Callback beforeConnect; - SocketAddress address; - - void getStatus(); }; } -#endif \ No newline at end of file +#endif diff --git a/libraries/Ethernet/src/EthernetServer.cpp b/libraries/Ethernet/src/EthernetServer.cpp index 1e3e260c6..94f5854b6 100644 --- a/libraries/Ethernet/src/EthernetServer.cpp +++ b/libraries/Ethernet/src/EthernetServer.cpp @@ -1,40 +1,18 @@ #include "EthernetServer.h" -#include "EthernetClient.h" - -extern arduino::EthernetClass Ethernet; - -arduino::EthernetServer::EthernetServer(uint16_t port) { - _port = port; -} - -uint8_t arduino::EthernetServer::status() { - return 0; -} - -void arduino::EthernetServer::begin() { - if (sock == NULL) { - sock = new TCPSocket(); - ((TCPSocket*)sock)->open(Ethernet.getNetwork()); - } - sock->bind(_port); - sock->listen(5); -} - -size_t arduino::EthernetServer::write(uint8_t c) { - sock->send(&c, 1); -} - -size_t arduino::EthernetServer::write(const uint8_t *buf, size_t size) { - sock->send(buf, size); -} arduino::EthernetClient arduino::EthernetServer::available(uint8_t* status) { - EthernetClient client; - nsapi_error_t error; - TCPSocket* clientSocket = sock->accept(&error); - if(status != nullptr) { - *status = error == NSAPI_ERROR_OK ? 1 : 0; - } - client.setSocket(clientSocket); - return client; + EthernetClient client; + nsapi_error_t error; + + if (sock == nullptr) { + return client; + } + TCPSocket* clientSocket = sock->accept(&error); + if (status != nullptr) { + *status = error == NSAPI_ERROR_OK ? 1 : 0; + } + if (error == NSAPI_ERROR_OK) { + client.setSocket(clientSocket); + } + return client; } diff --git a/libraries/Ethernet/src/EthernetServer.h b/libraries/Ethernet/src/EthernetServer.h index 1920ded20..3ddec326f 100644 --- a/libraries/Ethernet/src/EthernetServer.h +++ b/libraries/Ethernet/src/EthernetServer.h @@ -1,6 +1,6 @@ /* EthernetServer.h - Copyright (c) 2020 Arduino SA. All right reserved. + Copyright (c) 2021 Arduino SA. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -18,29 +18,22 @@ #define ethernetserver_h #include "Ethernet.h" -#include "api/Print.h" -#include "api/Client.h" -#include "api/IPAddress.h" -#include "TLSSocket.h" -#include "TCPSocket.h" +#include "MbedServer.h" +#include "EthernetClient.h" namespace arduino { class EthernetClient; -class EthernetServer : public arduino::Server { -private: - uint16_t _port; - TCPSocket* sock; +class EthernetServer : public MbedServer { + NetworkInterface* getNetwork() { + return Ethernet.getNetwork(); + } + public: - EthernetServer(uint16_t); - arduino::EthernetClient available(uint8_t* status = NULL); - void begin(); - virtual size_t write(uint8_t); - virtual size_t write(const uint8_t *buf, size_t size); - uint8_t status(); - - using Print::write; + EthernetServer(uint16_t port) + : MbedServer(port) {} + EthernetClient available(uint8_t* status = nullptr); }; } diff --git a/libraries/Ethernet/src/EthernetUdp.cpp b/libraries/Ethernet/src/EthernetUdp.cpp deleted file mode 100644 index 229cbcad2..000000000 --- a/libraries/Ethernet/src/EthernetUdp.cpp +++ /dev/null @@ -1,201 +0,0 @@ -#include "EthernetUdp.h" - -extern arduino::EthernetClass Ethernet; - -#ifndef ETHERNET_UDP_BUFFER_SIZE -#define ETHERNET_UDP_BUFFER_SIZE 508 -#endif - -arduino::EthernetUDP::EthernetUDP() { - _packet_buffer = new uint8_t[ETHERNET_UDP_BUFFER_SIZE]; - _current_packet = NULL; - _current_packet_size = 0; - // if this allocation fails then ::begin will fail -} - -arduino::EthernetUDP::~EthernetUDP() { - delete[] _packet_buffer; -} - -uint8_t arduino::EthernetUDP::begin(uint16_t port) { - // success = 1, fail = 0 - - nsapi_error_t rt = _socket.open(Ethernet.getNetwork()); - if (rt != NSAPI_ERROR_OK) { - return 0; - } - - if (_socket.bind(port) < 0) { - return 0; //Failed to bind UDP Socket to port - } - - if (!_packet_buffer) { - return 0; - } - - _socket.set_timeout(1000); - - return 1; -} - -uint8_t arduino::EthernetUDP::beginMulticast(IPAddress ip, uint16_t port) { - // success = 1, fail = 0 - if(begin(port) != 1){ - return 0; - } - - SocketAddress socketAddress = Ethernet.socketAddressFromIpAddress(ip, port); - - if (_socket.join_multicast_group(socketAddress) != NSAPI_ERROR_OK) { - printf("Error joining the multicast group\n"); - return 0; - } - - return 1; -} - -void arduino::EthernetUDP::stop() { - _socket.close(); -} - -int arduino::EthernetUDP::beginPacket(IPAddress ip, uint16_t port) { - _host = Ethernet.socketAddressFromIpAddress(ip, port); - //If IP is null and port is 0 the initialization failed - return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1; -} - -int arduino::EthernetUDP::beginPacket(const char *host, uint16_t port) { - _host = SocketAddress(host, port); - Ethernet.getNetwork()->gethostbyname(host, &_host); - //If IP is null and port is 0 the initialization failed - return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1; -} - -int arduino::EthernetUDP::endPacket() { - return 1; -} - -// Write a single byte into the packet -size_t arduino::EthernetUDP::write(uint8_t byte) { - uint8_t buffer[1] = { byte }; - return _socket.sendto(_host, buffer, 1); -} - -// Write size bytes from buffer into the packet -size_t arduino::EthernetUDP::write(const uint8_t *buffer, size_t size) { - return _socket.sendto(_host, buffer, size); -} - -int arduino::EthernetUDP::parsePacket() { - nsapi_size_or_error_t ret = _socket.recvfrom(&_remoteHost, _packet_buffer, ETHERNET_UDP_BUFFER_SIZE); - - if (ret == NSAPI_ERROR_WOULD_BLOCK) { - // no data - return 0; - } else if(ret == NSAPI_ERROR_NO_SOCKET){ - // socket was not created correctly. - return -1; - } - // error codes below zero are errors - else if (ret <= 0) { - // something else went wrong, need some tracing info... - return -1; - } - - // set current packet states - _current_packet = _packet_buffer; - _current_packet_size = ret; - - return _current_packet_size; -} - -int arduino::EthernetUDP::available() { - return _current_packet_size; -} - -// Read a single byte from the current packet -int arduino::EthernetUDP::read() { - // no current packet... - if (_current_packet == NULL) { - // try reading the next frame, if there is no data return - if (parsePacket() == 0) return -1; - } - - _current_packet++; - - // check for overflow - if (_current_packet > _packet_buffer + _current_packet_size) { - // try reading the next packet... - if (parsePacket() > 0) { - // if so, read first byte of next packet; - return read(); - } - else { - // no new data... not sure what to return here now - return -1; - } - } - - return _current_packet[0]; -} - -// 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 -int arduino::EthernetUDP::read(unsigned char* buffer, size_t len) { - // Q: does Arduino read() function handle fragmentation? I won't for now... - if (_current_packet == NULL) { - if (parsePacket() == 0) return 0; - } - - // how much data do we have in the current packet? - int offset = _current_packet - _packet_buffer; - if (offset < 0) { - return 0; - } - - int max_bytes = _current_packet_size - offset; - if (max_bytes < 0) { - return 0; - } - - // at the end of the packet? - if (max_bytes == 0) { - // try read next packet... - if (parsePacket() > 0) { - return read(buffer, len); - } - else { - return 0; - } - } - - if (len > max_bytes) len = max_bytes; - - // copy to target buffer - memcpy(buffer, _current_packet, len); - - _current_packet += len; - - return len; -} - -IPAddress arduino::EthernetUDP::remoteIP() { - nsapi_addr_t address = _remoteHost.get_addr(); - return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]); -} - -uint16_t arduino::EthernetUDP::remotePort() { - return _remoteHost.get_port(); -} - -void arduino::EthernetUDP::flush(){ - // TODO: a real check to ensure transmission has been completed -} - -int arduino::EthernetUDP::peek(){ - if (_current_packet_size < 1){ - return -1; - } - - return _current_packet[0]; -} diff --git a/libraries/Ethernet/src/EthernetUdp.h b/libraries/Ethernet/src/EthernetUdp.h index 73efa550d..57b69e79b 100644 --- a/libraries/Ethernet/src/EthernetUdp.h +++ b/libraries/Ethernet/src/EthernetUdp.h @@ -1,6 +1,6 @@ /* EthernetUdp.h - Copyright (c) 2020 Arduino SA. All right reserved. + Copyright (c) 2021 Arduino SA. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -21,74 +21,14 @@ #define ethernetudp_h #include "Ethernet.h" -#include "api/Udp.h" - -#include "netsocket/SocketAddress.h" -#include "netsocket/UDPSocket.h" - -#define UDP_TX_PACKET_MAX_SIZE 24 +#include "MbedUdp.h" namespace arduino { -class EthernetUDP : public UDP { -private: - UDPSocket _socket; // Mbed OS socket - SocketAddress _host; // Host to be used to send data - SocketAddress _remoteHost; // Remote host that sent incoming packets - - uint8_t* _packet_buffer; // Raw packet buffer (contains data we got from the UDPSocket) - - // The Arduino APIs allow you to iterate through this buffer, so we need to be able to iterate over the current packet - // these two variables are used to cache the state of the current packet - uint8_t* _current_packet; - size_t _current_packet_size; - -public: - EthernetUDP(); // Constructor - ~EthernetUDP(); - 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 multicast IP address and 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 the port of the host who sent the current incoming packet - virtual uint16_t remotePort(); +class EthernetUDP : public MbedUDP { + NetworkInterface *getNetwork() { + return Ethernet.getNetwork(); + } }; } diff --git a/libraries/Ethernet/src/PortentaEthernet.h b/libraries/Ethernet/src/PortentaEthernet.h new file mode 100644 index 000000000..f1349895f --- /dev/null +++ b/libraries/Ethernet/src/PortentaEthernet.h @@ -0,0 +1,3 @@ +#pragma once + +#include "Ethernet.h" \ No newline at end of file diff --git a/libraries/SocketWrapper/library.properties b/libraries/SocketWrapper/library.properties new file mode 100644 index 000000000..b872fda0e --- /dev/null +++ b/libraries/SocketWrapper/library.properties @@ -0,0 +1,9 @@ +name=SocketWrapper +version=1.0 +author=Arduino +maintainer=Arduino +sentence=Wrapper for mbed Socket classes +paragraph= +category=Other +url=http://www.arduino.cc/en/Reference/WiFi +architectures=mbed,ArduinoCore-mbed,mbed_portenta diff --git a/libraries/SocketWrapper/src/MbedClient.cpp b/libraries/SocketWrapper/src/MbedClient.cpp new file mode 100644 index 000000000..beabea18b --- /dev/null +++ b/libraries/SocketWrapper/src/MbedClient.cpp @@ -0,0 +1,282 @@ +#include "MbedClient.h" + +#ifndef SOCKET_TIMEOUT +#define SOCKET_TIMEOUT 1500 +#endif + +arduino::MbedClient::MbedClient() + : _status(false) { +} + +uint8_t arduino::MbedClient::status() { + return _status; +} + +void arduino::MbedClient::readSocket() { + while (1) { + event->wait_any(0xFF, 100); + uint8_t data[SOCKET_BUFFER_SIZE]; + int ret = NSAPI_ERROR_WOULD_BLOCK; + do { + mutex->lock(); + if (rxBuffer.availableForStore() == 0) { + yield(); + } + if (sock == nullptr || (closing && borrowed_socket)) { + goto cleanup; + } + ret = sock->recv(data, rxBuffer.availableForStore()); + if (ret < 0 && ret != NSAPI_ERROR_WOULD_BLOCK) { + goto cleanup; + } + for (int i = 0; i < ret; i++) { + rxBuffer.store_char(data[i]); + } + _status = true; + mutex->unlock(); + } while (ret == NSAPI_ERROR_WOULD_BLOCK || ret > 0); + } +cleanup: + _status = false; + mutex->unlock(); + return; +} + +void arduino::MbedClient::getStatus() { + event->set(1); +} + +void arduino::MbedClient::setSocket(Socket *_sock) { + sock = _sock; + configureSocket(sock); +} + +void arduino::MbedClient::configureSocket(Socket *_s) { + _s->set_timeout(0); + _s->set_blocking(false); + + if (event == nullptr) { + event = new rtos::EventFlags; + } + if (mutex == nullptr) { + mutex = new rtos::Mutex; + } + mutex->lock(); + if (reader_th == nullptr) { + reader_th = new rtos::Thread; + reader_th->start(mbed::callback(this, &MbedClient::readSocket)); + } + mutex->unlock(); + _s->sigio(mbed::callback(this, &MbedClient::getStatus)); + _status = true; +} + +int arduino::MbedClient::connect(SocketAddress socketAddress) { + if (sock == nullptr) { + sock = new TCPSocket(); + _own_socket = true; + } + if (sock == nullptr) { + return 0; + } + + if (static_cast(sock)->open(getNetwork()) != NSAPI_ERROR_OK) { + return 0; + } + + address = socketAddress; + nsapi_error_t returnCode = static_cast(sock)->connect(socketAddress); + int ret = 0; + + switch (returnCode) { + case NSAPI_ERROR_IS_CONNECTED: + case NSAPI_ERROR_OK: + { + ret = 1; + break; + } + } + + if (ret == 1) { + configureSocket(sock); + _status = true; + } else { + _status = false; + } + + return ret; +} + +int arduino::MbedClient::connect(IPAddress ip, uint16_t port) { + return connect(SocketHelpers::socketAddressFromIpAddress(ip, port)); +} + +int arduino::MbedClient::connect(const char *host, uint16_t port) { + SocketAddress socketAddress = SocketAddress(); + socketAddress.set_port(port); + getNetwork()->gethostbyname(host, &socketAddress); + return connect(socketAddress); +} + +int arduino::MbedClient::connectSSL(SocketAddress socketAddress) { + if (sock == nullptr) { + sock = new TLSSocket(); + _own_socket = true; + } + if (sock == nullptr) { + return 0; + } + + if (beforeConnect) { + beforeConnect(); + } + + if (static_cast(sock)->open(getNetwork()) != NSAPI_ERROR_OK) { + return 0; + } + + address = socketAddress; + +restart_connect: + nsapi_error_t returnCode = static_cast(sock)->connect(socketAddress); + int ret = 0; + + switch (returnCode) { + case NSAPI_ERROR_IS_CONNECTED: + case NSAPI_ERROR_OK: + { + ret = 1; + break; + } + case NSAPI_ERROR_IN_PROGRESS: + case NSAPI_ERROR_ALREADY: + { + delay(100); + goto restart_connect; + } + } + + if (ret == 1) { + configureSocket(sock); + _status = true; + } else { + _status = false; + } + + return ret; +} + +int arduino::MbedClient::connectSSL(IPAddress ip, uint16_t port) { + return connectSSL(SocketHelpers::socketAddressFromIpAddress(ip, port)); +} + +int arduino::MbedClient::connectSSL(const char *host, uint16_t port) { + SocketAddress socketAddress = SocketAddress(); + socketAddress.set_port(port); + getNetwork()->gethostbyname(host, &socketAddress); + return connectSSL(socketAddress); +} + +size_t arduino::MbedClient::write(uint8_t c) { + return write(&c, 1); +} + +size_t arduino::MbedClient::write(const uint8_t *buf, size_t size) { + if (sock == nullptr) + return 0; + + sock->set_blocking(true); + sock->set_timeout(SOCKET_TIMEOUT); + sock->send(buf, size); + configureSocket(sock); + return size; +} + +int arduino::MbedClient::available() { + int ret = rxBuffer.available(); + return ret; +} + +int arduino::MbedClient::read() { + mutex->lock(); + if (!available()) { + mutex->unlock(); + return -1; + } + + int ret = rxBuffer.read_char(); + mutex->unlock(); + return ret; +} + +int arduino::MbedClient::read(uint8_t *data, size_t len) { + mutex->lock(); + int avail = available(); + + if (!avail) { + mutex->unlock(); + return -1; + } + + if ((int)len > avail) { + len = avail; + } + + for (size_t i = 0; i < len; i++) { + data[i] = rxBuffer.read_char(); + } + mutex->unlock(); + + return len; +} + +int arduino::MbedClient::peek() { + return rxBuffer.peek(); +} + +void arduino::MbedClient::flush() { +} + +void arduino::MbedClient::stop() { + if (mutex != nullptr) { + mutex->lock(); + } + if (sock != nullptr && borrowed_socket == false) { + if (_own_socket) { + delete sock; + } else { + sock->close(); + } + sock = nullptr; + } + closing = true; + if (mutex != nullptr) { + mutex->unlock(); + } + if (reader_th != nullptr) { + reader_th->join(); + delete reader_th; + reader_th = nullptr; + } + if (event != nullptr) { + delete event; + event = nullptr; + } + if (mutex != nullptr) { + delete mutex; + mutex = nullptr; + } + _status = false; +} + +uint8_t arduino::MbedClient::connected() { + return _status; +} + +IPAddress arduino::MbedClient::remoteIP() { + return SocketHelpers::ipAddressFromSocketAddress(address); +} + +uint16_t arduino::MbedClient::remotePort() { + return 0; +} diff --git a/libraries/SocketWrapper/src/MbedClient.h b/libraries/SocketWrapper/src/MbedClient.h new file mode 100644 index 000000000..e8f9a0a02 --- /dev/null +++ b/libraries/SocketWrapper/src/MbedClient.h @@ -0,0 +1,129 @@ +/* + MbedClient.h - Client implementation using mbed Sockets + Copyright (c) 2021 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef MBEDCLIENT_H +#define MBEDCLIENT_H + +#include "Arduino.h" +#include "SocketHelpers.h" +#include "api/Print.h" +#include "api/Client.h" +#include "api/IPAddress.h" +#include "TLSSocket.h" +#include "TCPSocket.h" +#include "rtos.h" + +#ifndef SOCKET_BUFFER_SIZE +#define SOCKET_BUFFER_SIZE 256 +#endif + +namespace arduino { + +class MbedClient : public arduino::Client { +private: + // Helper for copy constructor and assignment operator + void copyClient(const MbedClient& orig) { + auto _sock = orig.sock; + auto _m = (MbedClient*)&orig; + _m->borrowed_socket = true; + _m->stop(); + this->setSocket(_sock); + } + +public: + MbedClient(); + + // Copy constructor, to be used when a Client returned by server.available() + // needs to "survive" event if it goes out of scope + // Sample usage: Client* new_client = new Client(existing_client) + MbedClient(const MbedClient& orig) { + copyClient(orig); + } + + MbedClient& operator=(const MbedClient& orig) { + copyClient(orig); + return *this; + } + + virtual ~MbedClient() { + stop(); + } + + uint8_t status(); + int connect(SocketAddress socketAddress); + int connect(IPAddress ip, uint16_t port); + int connect(const char* host, uint16_t port); + int connectSSL(SocketAddress socketAddress); + int connectSSL(IPAddress ip, uint16_t port); + int connectSSL(const char* host, uint16_t port); + size_t write(uint8_t); + size_t write(const uint8_t* buf, size_t size); + int available(); + int read(); + int read(uint8_t* buf, size_t size); + int peek(); + void flush(); + void stop(); + uint8_t connected(); + operator bool() { + return sock != nullptr; + } + + void setSocket(Socket* _sock); + Socket* getSocket() { return sock; }; + RingBufferN *getRxBuffer() { return &rxBuffer; }; + + void configureSocket(Socket* _s); + + IPAddress remoteIP(); + uint16_t remotePort(); + + friend class MbedServer; + friend class MbedSSLClient; + friend class MbedSocketClass; + + using Print::write; + +protected: + virtual NetworkInterface* getNetwork() = 0; + Socket* sock = nullptr; + + void onBeforeConnect(mbed::Callback cb) { + beforeConnect = cb; + } + +private: + RingBufferN rxBuffer; + bool _status = false; + bool borrowed_socket = false; + bool _own_socket = false; + bool closing = false; + mbed::Callback beforeConnect; + SocketAddress address; + rtos::Thread* reader_th = nullptr; + rtos::EventFlags* event = nullptr; + rtos::Mutex* mutex = nullptr; + + void readSocket(); + void getStatus(); +}; + +} + +#endif diff --git a/libraries/SocketWrapper/src/MbedSSLClient.cpp b/libraries/SocketWrapper/src/MbedSSLClient.cpp new file mode 100644 index 000000000..1d273c5ba --- /dev/null +++ b/libraries/SocketWrapper/src/MbedSSLClient.cpp @@ -0,0 +1,5 @@ +#include "MbedSSLClient.h" + +arduino::MbedSSLClient::MbedSSLClient() { + onBeforeConnect(mbed::callback(this, &MbedSSLClient::setRootCA)); +}; \ No newline at end of file diff --git a/libraries/SocketWrapper/src/MbedSSLClient.h b/libraries/SocketWrapper/src/MbedSSLClient.h new file mode 100644 index 000000000..a0bbbc013 --- /dev/null +++ b/libraries/SocketWrapper/src/MbedSSLClient.h @@ -0,0 +1,52 @@ +/* + MbedSSLClient.cpp - SSLClient implementation using mbed Sockets + Copyright (c) 2021 Arduino SA. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef MBEDSSLCLIENT_H +#define MBEDSSLCLIENT_H + +#include "MbedClient.h" + +extern const char CA_CERTIFICATES[]; + +namespace arduino { + +class MbedSSLClient : public arduino::MbedClient { + +public: + MbedSSLClient(); + virtual ~MbedSSLClient() { + stop(); + } + + int connect(IPAddress ip, uint16_t port) { + return connectSSL(ip, port); + } + int connect(const char* host, uint16_t port) { + return connectSSL(host, port); + } + +private: + int setRootCA() { + return ((TLSSocket*)sock)->set_root_ca_cert_path("/wlan/"); + } +}; + +} + +#endif /* MBEDSSLCLIENT_H */ \ No newline at end of file diff --git a/libraries/SocketWrapper/src/MbedServer.cpp b/libraries/SocketWrapper/src/MbedServer.cpp new file mode 100644 index 000000000..758c0208c --- /dev/null +++ b/libraries/SocketWrapper/src/MbedServer.cpp @@ -0,0 +1,55 @@ +#include "MbedServer.h" +#include "MbedClient.h" + +uint8_t arduino::MbedServer::status() { + return 0; +} + +void arduino::MbedServer::begin() { + if (sock == nullptr) { + sock = new TCPSocket(); + ((TCPSocket *)sock)->open(getNetwork()); + } + if (sock) { + sock->bind(_port); + sock->listen(5); + sock->set_blocking(false); + } +} + +size_t arduino::MbedServer::write(uint8_t c) { + if (sock) { + sock->send(&c, 1); + return 1; + } + return 0; +} + +size_t arduino::MbedServer::write(const uint8_t *buf, size_t size) { + if (sock) { + sock->send(buf, size); + return size; + } + return 0; +} + + +// MUST be reimplemented (just copy/paste and replace MbedClient to *Client) since MbedClient is abstract + +/* +arduino::MbedClient arduino::MbedServer::available(uint8_t* status) { + MbedClient client; + nsapi_error_t error; + if (sock == nullptr) { + return client; + } + TCPSocket* clientSocket = sock->accept(&error); + if(status != nullptr) { + *status = error == NSAPI_ERROR_OK ? 1 : 0; + } + if (error == NSAPI_ERROR_OK) { + client.setSocket(clientSocket); + } + return client; +} +*/ diff --git a/libraries/SocketWrapper/src/MbedServer.h b/libraries/SocketWrapper/src/MbedServer.h new file mode 100644 index 000000000..23017e296 --- /dev/null +++ b/libraries/SocketWrapper/src/MbedServer.h @@ -0,0 +1,65 @@ +/* + MbedServer.h - Server implementation using mbed Sockets + Copyright (c) 2021 Arduino SA. All right reserved. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef MBEDSERVER_H +#define MBEDSERVER_H + +#include "Arduino.h" +#include "SocketHelpers.h" +#include "mbed.h" +#include "api/Print.h" +#include "api/Client.h" +#include "api/IPAddress.h" +#include "TLSSocket.h" +#include "TCPSocket.h" + +namespace arduino { + +class MbedClient; + +class MbedServer : public arduino::Server { + +protected: + virtual NetworkInterface *getNetwork() = 0; + TCPSocket *sock = nullptr; + uint16_t _port; + +public: + MbedServer(uint16_t port) + : _port(port){}; + + virtual ~MbedServer() { + if (sock) { + delete sock; + sock = nullptr; + } + } + void begin(); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buf, size_t size); + uint8_t status(); + + //virtual MbedClient available(uint8_t* status) = 0; + + using Print::write; + + friend class MbedSocketClass; + friend class MbedClient; +}; + +} + +#endif \ No newline at end of file diff --git a/libraries/SocketWrapper/src/MbedUdp.cpp b/libraries/SocketWrapper/src/MbedUdp.cpp new file mode 100644 index 000000000..c71206a35 --- /dev/null +++ b/libraries/SocketWrapper/src/MbedUdp.cpp @@ -0,0 +1,205 @@ +#include "MbedUdp.h" + +#ifndef WIFI_UDP_BUFFER_SIZE +#define WIFI_UDP_BUFFER_SIZE 508 +#endif + +arduino::MbedUDP::MbedUDP() { + _packet_buffer = new uint8_t[WIFI_UDP_BUFFER_SIZE]; + _current_packet = NULL; + _current_packet_size = 0; + // if this allocation fails then ::begin will fail +} + +arduino::MbedUDP::~MbedUDP() { + delete[] _packet_buffer; +} + +uint8_t arduino::MbedUDP::begin(uint16_t port) { + // success = 1, fail = 0 + + nsapi_error_t rt = _socket.open(getNetwork()); + if (rt != NSAPI_ERROR_OK) { + return 0; + } + + if (_socket.bind(port) < 0) { + return 0; //Failed to bind UDP Socket to port + } + + if (!_packet_buffer) { + return 0; + } + + _socket.set_blocking(false); + _socket.set_timeout(0); + + return 1; +} + +uint8_t arduino::MbedUDP::beginMulticast(IPAddress ip, uint16_t port) { + // success = 1, fail = 0 + if (begin(port) != 1) { + return 0; + } + + SocketAddress socketAddress = SocketHelpers::socketAddressFromIpAddress(ip, port); + + if (_socket.join_multicast_group(socketAddress) != NSAPI_ERROR_OK) { + printf("Error joining the multicast group\n"); + return 0; + } + + return 1; +} + +void arduino::MbedUDP::stop() { + _socket.close(); +} + +int arduino::MbedUDP::beginPacket(IPAddress ip, uint16_t port) { + _host = SocketHelpers::socketAddressFromIpAddress(ip, port); + //If IP is null and port is 0 the initialization failed + return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1; +} + +int arduino::MbedUDP::beginPacket(const char *host, uint16_t port) { + _host = SocketAddress(host, port); + getNetwork()->gethostbyname(host, &_host); + //If IP is null and port is 0 the initialization failed + return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1; +} + +int arduino::MbedUDP::endPacket() { + return 1; +} + +// Write a single byte into the packet +size_t arduino::MbedUDP::write(uint8_t byte) { + return write(&byte, 1); +} + +// Write size bytes from buffer into the packet +size_t arduino::MbedUDP::write(const uint8_t *buffer, size_t size) { + _socket.set_blocking(true); + _socket.set_timeout(1000); + nsapi_size_or_error_t ret = _socket.sendto(_host, buffer, size); + _socket.set_blocking(false); + _socket.set_timeout(0); + if (ret < 0) { + return 0; + } + return size; +} + +int arduino::MbedUDP::parsePacket() { + nsapi_size_or_error_t ret = _socket.recvfrom(&_remoteHost, _packet_buffer, WIFI_UDP_BUFFER_SIZE); + + if (ret == NSAPI_ERROR_WOULD_BLOCK) { + // no data + return 0; + } else if (ret == NSAPI_ERROR_NO_SOCKET) { + // socket was not created correctly. + return -1; + } + // error codes below zero are errors + else if (ret <= 0) { + // something else went wrong, need some tracing info... + return -1; + } + + // set current packet states + _current_packet = _packet_buffer; + _current_packet_size = ret; + + return _current_packet_size; +} + +int arduino::MbedUDP::available() { + return _current_packet_size; +} + +// Read a single byte from the current packet +int arduino::MbedUDP::read() { + // no current packet... + if (_current_packet == NULL) { + // try reading the next frame, if there is no data return + if (parsePacket() == 0) return -1; + } + + _current_packet++; + + // check for overflow + if (_current_packet > _packet_buffer + _current_packet_size) { + // try reading the next packet... + if (parsePacket() > 0) { + // if so, read first byte of next packet; + return read(); + } else { + // no new data... not sure what to return here now + return -1; + } + } + + return _current_packet[0]; +} + +// 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 +int arduino::MbedUDP::read(unsigned char *buffer, size_t len) { + // Q: does Arduino read() function handle fragmentation? I won't for now... + if (_current_packet == NULL) { + if (parsePacket() == 0) return 0; + } + + // how much data do we have in the current packet? + int offset = _current_packet - _packet_buffer; + if (offset < 0) { + return 0; + } + + int max_bytes = _current_packet_size - offset; + if (max_bytes < 0) { + return 0; + } + + // at the end of the packet? + if (max_bytes == 0) { + // try read next packet... + if (parsePacket() > 0) { + return read(buffer, len); + } else { + return 0; + } + } + + if (len > (size_t)max_bytes) len = max_bytes; + + // copy to target buffer + memcpy(buffer, _current_packet, len); + + _current_packet += len; + + return len; +} + +IPAddress arduino::MbedUDP::remoteIP() { + nsapi_addr_t address = _remoteHost.get_addr(); + return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]); +} + +uint16_t arduino::MbedUDP::remotePort() { + return _remoteHost.get_port(); +} + +void arduino::MbedUDP::flush() { + // TODO: a real check to ensure transmission has been completed +} + +int arduino::MbedUDP::peek() { + if (_current_packet_size < 1) { + return -1; + } + + return _current_packet[0]; +} \ No newline at end of file diff --git a/libraries/SocketWrapper/src/MbedUdp.h b/libraries/SocketWrapper/src/MbedUdp.h new file mode 100644 index 000000000..45e22517e --- /dev/null +++ b/libraries/SocketWrapper/src/MbedUdp.h @@ -0,0 +1,104 @@ +/* + MbedUdp.h - UDP implementation using mbed Sockets + Copyright (c) 2021 Arduino SA. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef MBEDUDP_H +#define MBEDUDP_H + +#include "Arduino.h" +#include "SocketHelpers.h" +#include "api/Udp.h" + +#include "netsocket/SocketAddress.h" +#include "netsocket/UDPSocket.h" + +#define UDP_TX_PACKET_MAX_SIZE 24 + +namespace arduino { + +class MbedUDP : public UDP { +private: + UDPSocket _socket; // Mbed OS socket + SocketAddress _host; // Host to be used to send data + SocketAddress _remoteHost; // Remote host that sent incoming packets + + uint8_t* _packet_buffer; // Raw packet buffer (contains data we got from the UDPSocket) + + // The Arduino APIs allow you to iterate through this buffer, so we need to be able to iterate over the current packet + // these two variables are used to cache the state of the current packet + uint8_t* _current_packet; + size_t _current_packet_size; + +protected: + virtual NetworkInterface* getNetwork() = 0; + +public: + MbedUDP(); // Constructor + ~MbedUDP(); + 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 multicast IP address and 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 the port of the host who sent the current incoming packet + virtual uint16_t remotePort(); + + friend class MbedSocketClass; +}; + +} + +#endif \ No newline at end of file diff --git a/libraries/SocketWrapper/src/SocketHelpers.cpp b/libraries/SocketWrapper/src/SocketHelpers.cpp new file mode 100644 index 000000000..2e52663fa --- /dev/null +++ b/libraries/SocketWrapper/src/SocketHelpers.cpp @@ -0,0 +1,150 @@ +#include "SocketHelpers.h" + +uint8_t* arduino::MbedSocketClass::macAddress(uint8_t* mac) { + const char* mac_str = getNetwork()->get_mac_address(); + for (int b = 0; b < 6; b++) { + uint32_t tmp; + sscanf(&mac_str[b * 2 + (b)], "%02x", (unsigned int*)&tmp); + mac[5 - b] = (uint8_t)tmp; + } + //sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", &mac[5], &mac[4], &mac[3], &mac[2], &mac[1], &mac[0]); + return mac; +} + +int arduino::MbedSocketClass::hostByName(const char* aHostname, IPAddress& aResult) { + SocketAddress socketAddress = SocketAddress(); + nsapi_error_t returnCode = getNetwork()->gethostbyname(aHostname, &socketAddress); + nsapi_addr_t address = socketAddress.get_addr(); + aResult[0] = address.bytes[0]; + aResult[1] = address.bytes[1]; + aResult[2] = address.bytes[2]; + aResult[3] = address.bytes[3]; + return returnCode == NSAPI_ERROR_OK ? 1 : 0; +} + +arduino::IPAddress arduino::MbedSocketClass::localIP() { + SocketAddress ip; + NetworkInterface* interface = getNetwork(); + interface->get_ip_address(&ip); + return ipAddressFromSocketAddress(ip); +} + +arduino::IPAddress arduino::MbedSocketClass::subnetMask() { + SocketAddress ip; + NetworkInterface* interface = getNetwork(); + interface->get_netmask(&ip); + return ipAddressFromSocketAddress(ip); +} + +arduino::IPAddress arduino::MbedSocketClass::gatewayIP() { + SocketAddress ip; + NetworkInterface* interface = getNetwork(); + interface->get_gateway(&ip); + return ipAddressFromSocketAddress(ip); +} + +arduino::IPAddress arduino::MbedSocketClass::dnsServerIP() { + SocketAddress ip; + NetworkInterface* interface = getNetwork(); + interface->get_dns_server(0, &ip, nullptr); + return ipAddressFromSocketAddress(ip); +} + +void arduino::MbedSocketClass::config(arduino::IPAddress local_ip) { + nsapi_addr_t convertedIP = { NSAPI_IPv4, { local_ip[0], local_ip[1], local_ip[2], local_ip[3] } }; + _ip = SocketAddress(convertedIP); +} + +void arduino::MbedSocketClass::config(const char* local_ip) { + _ip = SocketAddress(local_ip); +} + +void arduino::MbedSocketClass::config(IPAddress local_ip, IPAddress dns_server) { + config(local_ip); + setDNS(dns_server); +} + +void arduino::MbedSocketClass::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway) { + config(local_ip, dns_server); + nsapi_addr_t convertedGatewayIP = { NSAPI_IPv4, { gateway[0], gateway[1], gateway[2], gateway[3] } }; + _gateway = SocketAddress(convertedGatewayIP); +} + +void arduino::MbedSocketClass::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet) { + config(local_ip, dns_server, gateway); + nsapi_addr_t convertedSubnetMask = { NSAPI_IPv4, { subnet[0], subnet[1], subnet[2], subnet[3] } }; + _netmask = SocketAddress(convertedSubnetMask); +} + +void arduino::MbedSocketClass::setDNS(IPAddress dns_server1) { + nsapi_addr_t convertedDNSServer = { NSAPI_IPv4, { dns_server1[0], dns_server1[1], dns_server1[2], dns_server1[3] } }; + _dnsServer1 = SocketAddress(convertedDNSServer); +} + +void arduino::MbedSocketClass::setDNS(IPAddress dns_server1, IPAddress dns_server2) { + setDNS(dns_server1); + nsapi_addr_t convertedDNSServer2 = { NSAPI_IPv4, { dns_server2[0], dns_server2[1], dns_server2[2], dns_server2[3] } }; + _dnsServer2 = SocketAddress(convertedDNSServer2); +} + +arduino::IPAddress arduino::MbedSocketClass::ipAddressFromSocketAddress(SocketAddress socketAddress) { + nsapi_addr_t address = socketAddress.get_addr(); + return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]); +} + +SocketAddress arduino::MbedSocketClass::socketAddressFromIpAddress(arduino::IPAddress ip, uint16_t port) { + nsapi_addr_t convertedIP = { NSAPI_IPv4, { ip[0], ip[1], ip[2], ip[3] } }; + return SocketAddress(convertedIP, port); +} + + +// Download helper + +#include "utility/http_request.h" +#include "utility/https_request.h" + +void MbedSocketClass::setFeedWatchdogFunc(voidFuncPtr func) { + _feed_watchdog_func = func; +} + +void MbedSocketClass::feedWatchdog() { + if (_feed_watchdog_func) + _feed_watchdog_func(); +} + +void MbedSocketClass::body_callback(const char* data, uint32_t data_len) { + feedWatchdog(); + fwrite(data, 1, data_len, download_target); +} + +int MbedSocketClass::download(char* url, const char* target_file, bool const is_https) { + download_target = fopen(target_file, "wb"); + + HttpRequest* req_http = nullptr; + HttpsRequest* req_https = nullptr; + HttpResponse* rsp = nullptr; + + if (is_https) { + req_https = new HttpsRequest(getNetwork(), nullptr, HTTP_GET, url, mbed::callback(this, &MbedSocketClass::body_callback)); + rsp = req_https->send(NULL, 0); + if (rsp == NULL) { + fclose(download_target); + return req_https->get_error(); + } + } else { + req_http = new HttpRequest(getNetwork(), HTTP_GET, url, mbed::callback(this, &MbedSocketClass::body_callback)); + rsp = req_http->send(NULL, 0); + if (rsp == NULL) { + fclose(download_target); + return req_http->get_error(); + } + } + + while (!rsp->is_message_complete()) { + delay(10); + } + + int const size = ftell(download_target); + fclose(download_target); + return size; +} diff --git a/libraries/SocketWrapper/src/SocketHelpers.h b/libraries/SocketWrapper/src/SocketHelpers.h new file mode 100644 index 000000000..6934cf888 --- /dev/null +++ b/libraries/SocketWrapper/src/SocketHelpers.h @@ -0,0 +1,138 @@ +/* + SocketHelpers.h - Utility wrappers for mbed Sockets and NetworkInterfaces + Copyright (c) 2021 Arduino SA. All right reserved. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef MBEDSOCKETCLASS_H +#define MBEDSOCKETCLASS_H + +#include "Arduino.h" +#include "netsocket/NetworkInterface.h" + +namespace arduino { + +class MbedSocketClass { + +public: + void config(IPAddress local_ip); + + /* Change Ip configuration settings disabling the dhcp client + * + * param local_ip: Static ip configuration as string + */ + void config(const char* local_ip); + + /* Change Ip configuration settings disabling the dhcp client + * + * param local_ip: Static ip configuration + * param dns_server: IP configuration for DNS server 1 + */ + void config(IPAddress local_ip, IPAddress dns_server); + + /* Change Ip configuration settings disabling the dhcp client + * + * param local_ip: Static ip configuration + * param dns_server: IP configuration for DNS server 1 + * param gateway : Static gateway configuration + */ + void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway); + + /* Change Ip configuration settings disabling the dhcp client + * + * param local_ip: Static ip configuration + * param dns_server: IP configuration for DNS server 1 + * param gateway: Static gateway configuration + * param subnet: Static Subnet mask + */ + void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet); + + /* Change DNS Ip configuration + * + * param dns_server1: ip configuration for DNS server 1 + */ + void setDNS(IPAddress dns_server1); + + /* Change DNS Ip configuration + * + * param dns_server1: ip configuration for DNS server 1 + * param dns_server2: ip configuration for DNS server 2 + * + */ + void setDNS(IPAddress dns_server1, IPAddress dns_server2); + + /* + * Get the interface IP address. + * + * return: Ip address value + */ + IPAddress localIP(); + + /* + * Get the interface subnet mask address. + * + * return: subnet mask address value + */ + IPAddress subnetMask(); + + /* + * Get the gateway ip address. + * + * return: gateway ip address value + */ + IPAddress gatewayIP(); + + /* + * Get the DNS Server ip address. + * + * return: DNS Server ip address value + */ + IPAddress dnsServerIP(); + + virtual NetworkInterface* getNetwork() = 0; + + int download(char* url, const char* target, bool const is_https = false); + + int hostByName(const char* aHostname, IPAddress& aResult); + + uint8_t* macAddress(uint8_t* mac); + + void setFeedWatchdogFunc(voidFuncPtr func); + void feedWatchdog(); + + friend class MbedUDP; + friend class MbedServer; + friend class MbedClient; + +protected: + SocketAddress _ip = nullptr; + SocketAddress _gateway = nullptr; + SocketAddress _netmask = nullptr; + SocketAddress _dnsServer1 = nullptr; + SocketAddress _dnsServer2 = nullptr; + + voidFuncPtr _feed_watchdog_func = nullptr; + + FILE* download_target; + + void body_callback(const char* data, uint32_t data_len); + + static arduino::IPAddress ipAddressFromSocketAddress(SocketAddress socketAddress); + static SocketAddress socketAddressFromIpAddress(arduino::IPAddress ip, uint16_t port); +}; + +using SocketHelpers = MbedSocketClass; + +} + +#endif diff --git a/libraries/WiFi/src/utility/http_parsed_url.h b/libraries/SocketWrapper/src/utility/http_parsed_url.h similarity index 100% rename from libraries/WiFi/src/utility/http_parsed_url.h rename to libraries/SocketWrapper/src/utility/http_parsed_url.h diff --git a/libraries/WiFi/src/utility/http_parser/LICENSE b/libraries/SocketWrapper/src/utility/http_parser/LICENSE similarity index 100% rename from libraries/WiFi/src/utility/http_parser/LICENSE rename to libraries/SocketWrapper/src/utility/http_parser/LICENSE diff --git a/libraries/WiFi/src/utility/http_parser/http_parser.c b/libraries/SocketWrapper/src/utility/http_parser/http_parser.c similarity index 100% rename from libraries/WiFi/src/utility/http_parser/http_parser.c rename to libraries/SocketWrapper/src/utility/http_parser/http_parser.c diff --git a/libraries/WiFi/src/utility/http_parser/http_parser.h b/libraries/SocketWrapper/src/utility/http_parser/http_parser.h similarity index 100% rename from libraries/WiFi/src/utility/http_parser/http_parser.h rename to libraries/SocketWrapper/src/utility/http_parser/http_parser.h diff --git a/libraries/WiFi/src/utility/http_request.h b/libraries/SocketWrapper/src/utility/http_request.h similarity index 100% rename from libraries/WiFi/src/utility/http_request.h rename to libraries/SocketWrapper/src/utility/http_request.h diff --git a/libraries/WiFi/src/utility/http_request_base.h b/libraries/SocketWrapper/src/utility/http_request_base.h similarity index 98% rename from libraries/WiFi/src/utility/http_request_base.h rename to libraries/SocketWrapper/src/utility/http_request_base.h index 2b981c32d..df7f75015 100644 --- a/libraries/WiFi/src/utility/http_request_base.h +++ b/libraries/SocketWrapper/src/utility/http_request_base.h @@ -255,7 +255,7 @@ class HttpRequestBase { nsapi_size_or_error_t send_buffer(char* buffer, uint32_t buffer_size) { nsapi_size_or_error_t total_send_count = 0; - while (total_send_count < buffer_size) { + while ((uint32_t)total_send_count < buffer_size) { // get a slice of the buffer char *buffer_slice = buffer + total_send_count; @@ -299,7 +299,7 @@ class HttpRequestBase { // Pass the chunk into the http_parser uint32_t nparsed = parser.execute((const char*)recv_buffer, recv_ret); - if (nparsed != recv_ret) { + if (nparsed != (uint32_t)recv_ret) { // printf("Parsing failed... parsed %d bytes, received %d bytes\n", nparsed, recv_ret); _error = -2101; free(recv_buffer); diff --git a/libraries/WiFi/src/utility/http_request_builder.h b/libraries/SocketWrapper/src/utility/http_request_builder.h similarity index 100% rename from libraries/WiFi/src/utility/http_request_builder.h rename to libraries/SocketWrapper/src/utility/http_request_builder.h diff --git a/libraries/WiFi/src/utility/http_request_parser.h b/libraries/SocketWrapper/src/utility/http_request_parser.h similarity index 100% rename from libraries/WiFi/src/utility/http_request_parser.h rename to libraries/SocketWrapper/src/utility/http_request_parser.h diff --git a/libraries/WiFi/src/utility/http_response.h b/libraries/SocketWrapper/src/utility/http_response.h similarity index 100% rename from libraries/WiFi/src/utility/http_response.h rename to libraries/SocketWrapper/src/utility/http_response.h diff --git a/libraries/WiFi/src/utility/https_request.h b/libraries/SocketWrapper/src/utility/https_request.h similarity index 100% rename from libraries/WiFi/src/utility/https_request.h rename to libraries/SocketWrapper/src/utility/https_request.h diff --git a/libraries/SocketWrapper/src/utility/wl_definitions.h b/libraries/SocketWrapper/src/utility/wl_definitions.h new file mode 100644 index 000000000..bbf3fd8fc --- /dev/null +++ b/libraries/SocketWrapper/src/utility/wl_definitions.h @@ -0,0 +1,78 @@ +/* + wl_definitions.h - Library for Arduino Wifi shield. + Copyright (c) 2011-2014 Arduino. All right reserved. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +/* + * wl_definitions.h + * + * Created on: Mar 6, 2011 + * Author: dlafauci + */ + +#ifndef WL_DEFINITIONS_H_ +#define WL_DEFINITIONS_H_ + +// Maximum size of a SSID +#define WL_SSID_MAX_LENGTH 32 +// Length of passphrase. Valid lengths are 8-63. +#define WL_WPA_KEY_MAX_LENGTH 63 +// Length of key in bytes. Valid values are 5 and 13. +#define WL_WEP_KEY_MAX_LENGTH 13 +// Size of a MAC-address or BSSID +#define WL_MAC_ADDR_LENGTH 6 +// Size of a MAC-address or BSSID +#define WL_IPV4_LENGTH 4 +// Maximum size of a SSID list +#define WL_NETWORKS_LIST_MAXNUM 10 +// Maxmium number of socket +#define MAX_SOCK_NUM 4 +// Socket not available constant +#define SOCK_NOT_AVAIL 255 +// Default state value for Wifi state field +#define NA_STATE -1 +//Maximum number of attempts to establish wifi connection +#define WL_MAX_ATTEMPT_CONNECTION 10 + +typedef enum { + WL_NO_SHIELD = 255, + WL_NO_MODULE = 255, + WL_IDLE_STATUS = 0, + WL_NO_SSID_AVAIL, + WL_SCAN_COMPLETED, + WL_CONNECTED, + WL_CONNECT_FAILED, + WL_CONNECTION_LOST, + WL_DISCONNECTED, + WL_AP_LISTENING, + WL_AP_CONNECTED, + WL_AP_FAILED +} wl_status_t; + +/* Encryption modes */ +enum wl_enc_type { /* Values map to 802.11 encryption suites... */ + ENC_TYPE_WEP = 5, + ENC_TYPE_TKIP = 2, + ENC_TYPE_CCMP = 4, + /* ... except these two, 7 and 8 are reserved in 802.11-2007 */ + ENC_TYPE_NONE = 7, + ENC_TYPE_UNKNOWN = 9, + ENC_TYPE_AUTO = 8 +}; + +#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) +#include "whd_version.h" +#define WIFI_FIRMWARE_LATEST_VERSION WHD_VERSION +#endif + +#endif /* WL_DEFINITIONS_H_ */ \ No newline at end of file diff --git a/libraries/SocketWrapper/src/utility/wl_types.h b/libraries/SocketWrapper/src/utility/wl_types.h new file mode 100644 index 000000000..65f8caae2 --- /dev/null +++ b/libraries/SocketWrapper/src/utility/wl_types.h @@ -0,0 +1,53 @@ +/* + wl_types.h - Library for Arduino Wifi shield. + Copyright (c) 2011-2014 Arduino. All right reserved. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +/* + * wl_types.h + * + * Created on: Jul 30, 2010 + * Author: dlafauci + */ + + +#ifndef _WL_TYPES_H_ +#define _WL_TYPES_H_ + +#include + +typedef enum { + WL_FAILURE = -1, + WL_SUCCESS = 1, +} wl_error_code_t; + +/* Authentication modes */ +enum wl_auth_mode { + AUTH_MODE_INVALID, + AUTH_MODE_AUTO, + AUTH_MODE_OPEN_SYSTEM, + AUTH_MODE_SHARED_KEY, + AUTH_MODE_WPA, + AUTH_MODE_WPA2, + AUTH_MODE_WPA_PSK, + AUTH_MODE_WPA2_PSK +}; + +typedef enum { + WL_PING_DEST_UNREACHABLE = -1, + WL_PING_TIMEOUT = -2, + WL_PING_UNKNOWN_HOST = -3, + WL_PING_ERROR = -4 +} wl_ping_result_t; + +#endif //_WL_TYPES_H_ \ No newline at end of file diff --git a/libraries/WiFi/src/WiFi.cpp b/libraries/WiFi/src/WiFi.cpp index 8ff342b62..3ba76ab1b 100644 --- a/libraries/WiFi/src/WiFi.cpp +++ b/libraries/WiFi/src/WiFi.cpp @@ -3,329 +3,206 @@ #define SSID_MAX_LENGTH 32 bool arduino::WiFiClass::isVisible(const char* ssid) { - for (int i=0; i<10; i++) { - if (strncmp(ap_list[i].get_ssid(), ssid, SSID_MAX_LENGTH) == 0) { - connected_ap = i; - return true; - } + for (int i = 0; i < 10; i++) { + if (strncmp(ap_list[i].get_ssid(), ssid, SSID_MAX_LENGTH) == 0) { + connected_ap = i; + return true; } - return false; + } + return false; } -arduino::IPAddress arduino::WiFiClass::ipAddressFromSocketAddress(SocketAddress socketAddress) { - nsapi_addr_t address = socketAddress.get_addr(); - return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]); -} +int arduino::WiFiClass::begin(const char* ssid, const char* passphrase) { + if (wifi_if == nullptr) { + return 0; + } -SocketAddress arduino::WiFiClass::socketAddressFromIpAddress(arduino::IPAddress ip, uint16_t port) { - nsapi_addr_t convertedIP = {NSAPI_IPv4, {ip[0], ip[1], ip[2], ip[3]}}; - return SocketAddress(convertedIP, port); -} + scanNetworks(); + // use scan result to populate security field + if (!isVisible(ssid)) { + _currentNetworkStatus = WL_CONNECT_FAILED; + return _currentNetworkStatus; + } -int arduino::WiFiClass::begin(const char* ssid, const char *passphrase) { - if (wifi_if == nullptr) { - //Q: What is the callback for? - _initializerCallback(); - if(wifi_if == nullptr) return WL_CONNECT_FAILED; - } - - scanNetworks(); - // use scan result to populate security field - if (!isVisible(ssid)) { - _currentNetworkStatus = WL_CONNECT_FAILED; - return _currentNetworkStatus; - } + nsapi_error_t result = wifi_if->connect(ssid, passphrase, ap_list[connected_ap].get_security()); - nsapi_error_t result = wifi_if->connect(ssid, passphrase, ap_list[connected_ap].get_security()); - - _currentNetworkStatus = (result == NSAPI_ERROR_OK && setSSID(ssid)) ? WL_CONNECTED : WL_CONNECT_FAILED; - return _currentNetworkStatus; + _currentNetworkStatus = (result == NSAPI_ERROR_OK && setSSID(ssid)) ? WL_CONNECTED : WL_CONNECT_FAILED; + return _currentNetworkStatus; } -int arduino::WiFiClass::beginAP(const char* ssid, const char *passphrase, uint8_t channel) { +int arduino::WiFiClass::beginAP(const char* ssid, const char* passphrase, uint8_t channel) { - #if defined(COMPONENT_4343W_FS) - _softAP = WhdSoftAPInterface::get_default_instance(); - #endif +#if defined(COMPONENT_4343W_FS) + _softAP = WhdSoftAPInterface::get_default_instance(); +#endif - if (_softAP == NULL) { - return (_currentNetworkStatus = WL_AP_FAILED); - } + if (_softAP == NULL) { + _currentNetworkStatus = WL_AP_FAILED; + return _currentNetworkStatus; + } - ensureDefaultAPNetworkConfiguration(); + ensureDefaultAPNetworkConfiguration(); - WhdSoftAPInterface* softAPInterface = static_cast(_softAP); + WhdSoftAPInterface* softAPInterface = static_cast(_softAP); - //Set ap ssid, password and channel - softAPInterface->set_network(_ip, _netmask, _gateway); - nsapi_error_t result = softAPInterface->start(ssid, passphrase, NSAPI_SECURITY_WPA2, channel, true /* dhcp server */, NULL, true /* cohexistance */); - - nsapi_error_t registrationResult; - softAPInterface->unregister_event_handler(); - registrationResult = softAPInterface->register_event_handler(arduino::WiFiClass::handleAPEvents); + //Set ap ssid, password and channel + softAPInterface->set_network(_ip, _netmask, _gateway); + nsapi_error_t result = softAPInterface->start(ssid, passphrase, NSAPI_SECURITY_WPA2, channel, true /* dhcp server */, NULL, true /* cohexistance */); - if (registrationResult != NSAPI_ERROR_OK) { - return (_currentNetworkStatus = WL_AP_FAILED); - } + nsapi_error_t registrationResult; + softAPInterface->unregister_event_handler(); + registrationResult = softAPInterface->register_event_handler(arduino::WiFiClass::handleAPEvents); - _currentNetworkStatus = (result == NSAPI_ERROR_OK && setSSID(ssid)) ? WL_AP_LISTENING : WL_AP_FAILED; + if (registrationResult != NSAPI_ERROR_OK) { + _currentNetworkStatus = WL_AP_FAILED; return _currentNetworkStatus; -} - -void * arduino::WiFiClass::handleAPEvents(whd_interface_t ifp, const whd_event_header_t *event_header, const uint8_t *event_data, void *handler_user_data){ - if(event_header->event_type == WLC_E_ASSOC_IND){ - WiFi._currentNetworkStatus = WL_AP_CONNECTED; - } else if(event_header->event_type == WLC_E_DISASSOC_IND){ - WiFi._currentNetworkStatus = WL_AP_LISTENING; - } - - // Default Event Handler - whd_driver_t whd_driver = ifp->whd_driver; - WHD_IOCTL_LOG_ADD_EVENT(whd_driver, event_header->event_type, event_header->flags, event_header->reason); - - if ((event_header->event_type == (whd_event_num_t)WLC_E_LINK) || (event_header->event_type == WLC_E_IF)) { - if (osSemaphoreGetCount(whd_driver->ap_info.whd_wifi_sleep_flag) < 1) { - osStatus_t result = osSemaphoreRelease(whd_driver->ap_info.whd_wifi_sleep_flag); - if (result != osOK) { - printf("Release whd_wifi_sleep_flag ERROR: %d", result); - } - } - } + } - return handler_user_data; + _currentNetworkStatus = (result == NSAPI_ERROR_OK && setSSID(ssid)) ? WL_AP_LISTENING : WL_AP_FAILED; + return _currentNetworkStatus; } -void arduino::WiFiClass::ensureDefaultAPNetworkConfiguration() { - if(_ip == nullptr){ - _ip = SocketAddress(DEFAULT_IP_ADDRESS); - } - if(_gateway == nullptr){ - _gateway = _ip; - } - if(_netmask == nullptr){ - _netmask = SocketAddress(DEFAULT_NETMASK); - } -} +void* arduino::WiFiClass::handleAPEvents(whd_interface_t ifp, const whd_event_header_t* event_header, const uint8_t* event_data, void* handler_user_data) { + if (event_header->event_type == WLC_E_ASSOC_IND) { + WiFi._currentNetworkStatus = WL_AP_CONNECTED; + } else if (event_header->event_type == WLC_E_DISASSOC_IND) { + WiFi._currentNetworkStatus = WL_AP_LISTENING; + } -void arduino::WiFiClass::end() { - disconnect(); -} + // Default Event Handler + whd_driver_t whd_driver = ifp->whd_driver; + WHD_IOCTL_LOG_ADD_EVENT(whd_driver, event_header->event_type, event_header->flags, event_header->reason); -int arduino::WiFiClass::disconnect() { - if (_softAP != nullptr) { - WhdSoftAPInterface* softAPInterface = static_cast(_softAP); - softAPInterface->unregister_event_handler(); - _currentNetworkStatus = (softAPInterface->stop() == NSAPI_ERROR_OK ? WL_DISCONNECTED : WL_AP_FAILED); - } else { - wifi_if->disconnect(); - _currentNetworkStatus = WL_DISCONNECTED; + if ((event_header->event_type == (whd_event_num_t)WLC_E_LINK) || (event_header->event_type == WLC_E_IF)) { + if (osSemaphoreGetCount(whd_driver->ap_info.whd_wifi_sleep_flag) < 1) { + osStatus_t result = osSemaphoreRelease(whd_driver->ap_info.whd_wifi_sleep_flag); + if (result != osOK) { + printf("Release whd_wifi_sleep_flag ERROR: %d", result); + } } - - return _currentNetworkStatus; -} - -void arduino::WiFiClass::config(arduino::IPAddress local_ip){ - nsapi_addr_t convertedIP = {NSAPI_IPv4, {local_ip[0], local_ip[1], local_ip[2], local_ip[3]}}; - _ip = SocketAddress(convertedIP); -} - -void arduino::WiFiClass::config(const char *local_ip){ - _ip = SocketAddress(local_ip); -} + } -void arduino::WiFiClass::config(IPAddress local_ip, IPAddress dns_server){ - config(local_ip); - setDNS(dns_server); + return handler_user_data; } -void arduino::WiFiClass::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway){ - config(local_ip, dns_server); - nsapi_addr_t convertedGatewayIP = {NSAPI_IPv4, {gateway[0], gateway[1], gateway[2], gateway[3]}}; - _gateway = SocketAddress(convertedGatewayIP); +void arduino::WiFiClass::ensureDefaultAPNetworkConfiguration() { + if (_ip == nullptr) { + _ip = SocketAddress(DEFAULT_IP_ADDRESS); + } + if (_gateway == nullptr) { + _gateway = _ip; + } + if (_netmask == nullptr) { + _netmask = SocketAddress(DEFAULT_NETMASK); + } } -void arduino::WiFiClass::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet){ - config(local_ip, dns_server, gateway); - nsapi_addr_t convertedSubnetMask = {NSAPI_IPv4, {subnet[0], subnet[1], subnet[2], subnet[3]}}; - _netmask = SocketAddress(convertedSubnetMask); +void arduino::WiFiClass::end() { + disconnect(); } -void arduino::WiFiClass::setDNS(IPAddress dns_server1){ - nsapi_addr_t convertedDNSServer = {NSAPI_IPv4, {dns_server1[0], dns_server1[1], dns_server1[2], dns_server1[3]}}; - _dnsServer1 = SocketAddress(convertedDNSServer); -} +int arduino::WiFiClass::disconnect() { + if (_softAP != nullptr) { + WhdSoftAPInterface* softAPInterface = static_cast(_softAP); + softAPInterface->unregister_event_handler(); + _currentNetworkStatus = (softAPInterface->stop() == NSAPI_ERROR_OK ? WL_DISCONNECTED : WL_AP_FAILED); + } else { + wifi_if->disconnect(); + _currentNetworkStatus = WL_DISCONNECTED; + } -void arduino::WiFiClass::setDNS(IPAddress dns_server1, IPAddress dns_server2){ - setDNS(dns_server1); - nsapi_addr_t convertedDNSServer2 = {NSAPI_IPv4, {dns_server2[0], dns_server2[1], dns_server2[2], dns_server2[3]}}; - _dnsServer2 = SocketAddress(convertedDNSServer2); + return _currentNetworkStatus; } char* arduino::WiFiClass::SSID() { - return _ssid; + return _ssid; } -int arduino::WiFiClass::setSSID(const char* ssid){ - if (_ssid) free(_ssid); - - _ssid = (char*)malloc(SSID_MAX_LENGTH + 1); - if (!_ssid) { - //tr_error("Could not allocate ssid buffer"); - return 0; - } - - memcpy(_ssid, ssid, SSID_MAX_LENGTH + 1); - // too long? break it off - if (strlen(ssid) > SSID_MAX_LENGTH) _ssid[SSID_MAX_LENGTH] = 0; - return 1; -} - -static const char *sec2str(nsapi_security_t sec) -{ - switch (sec) { - case NSAPI_SECURITY_NONE: - return "None"; - case NSAPI_SECURITY_WEP: - return "WEP"; - case NSAPI_SECURITY_WPA: - return "WPA"; - case NSAPI_SECURITY_WPA2: - return "WPA2"; - case NSAPI_SECURITY_WPA_WPA2: - return "WPA/WPA2"; - case NSAPI_SECURITY_UNKNOWN: - default: - return "Unknown"; - } -} +int arduino::WiFiClass::setSSID(const char* ssid) { + if (_ssid) free(_ssid); -static uint8_t sec2enum(nsapi_security_t sec) -{ - switch (sec) { - case NSAPI_SECURITY_NONE: - return ENC_TYPE_NONE; - case NSAPI_SECURITY_WEP: - return ENC_TYPE_WEP; - case NSAPI_SECURITY_WPA: - return ENC_TYPE_TKIP; - case NSAPI_SECURITY_WPA2: - return ENC_TYPE_CCMP; - case NSAPI_SECURITY_WPA_WPA2: - return ENC_TYPE_CCMP; - case NSAPI_SECURITY_UNKNOWN: - default: - return ENC_TYPE_AUTO; - } + _ssid = (char*)malloc(SSID_MAX_LENGTH + 1); + if (!_ssid) { + //tr_error("Could not allocate ssid buffer"); + return 0; + } + + memcpy(_ssid, ssid, SSID_MAX_LENGTH + 1); + // too long? break it off + if (strlen(ssid) > SSID_MAX_LENGTH) _ssid[SSID_MAX_LENGTH] = 0; + return 1; +} + +static uint8_t sec2enum(nsapi_security_t sec) { + switch (sec) { + case NSAPI_SECURITY_NONE: + return ENC_TYPE_NONE; + case NSAPI_SECURITY_WEP: + return ENC_TYPE_WEP; + case NSAPI_SECURITY_WPA: + return ENC_TYPE_TKIP; + case NSAPI_SECURITY_WPA2: + return ENC_TYPE_CCMP; + case NSAPI_SECURITY_WPA_WPA2: + return ENC_TYPE_CCMP; + case NSAPI_SECURITY_UNKNOWN: + default: + return ENC_TYPE_AUTO; + } } int8_t arduino::WiFiClass::scanNetworks() { - uint8_t count = 10; - if (ap_list == nullptr) { - ap_list = new WiFiAccessPoint[count]; - } - return wifi_if->scan(ap_list, count); + uint8_t count = 10; + if (ap_list == nullptr) { + ap_list = new WiFiAccessPoint[count]; + } + return wifi_if->scan(ap_list, count); } char* arduino::WiFiClass::SSID(uint8_t networkItem) { - return (char*)ap_list[networkItem].get_ssid(); + return (char*)ap_list[networkItem].get_ssid(); } int32_t arduino::WiFiClass::RSSI(uint8_t networkItem) { - return ap_list[networkItem].get_rssi(); + return ap_list[networkItem].get_rssi(); } uint8_t arduino::WiFiClass::encryptionType(uint8_t networkItem) { - return sec2enum(ap_list[networkItem].get_security()); + return sec2enum(ap_list[networkItem].get_security()); } int32_t arduino::WiFiClass::RSSI() { - return wifi_if->get_rssi(); + return wifi_if->get_rssi(); } -uint8_t arduino::WiFiClass::status() { - return _currentNetworkStatus; -} - -int arduino::WiFiClass::hostByName(const char* aHostname, IPAddress& aResult){ - SocketAddress socketAddress = SocketAddress(); - nsapi_error_t returnCode = getNetwork()->gethostbyname(aHostname, &socketAddress); - nsapi_addr_t address = socketAddress.get_addr(); - aResult[0] = address.bytes[0]; - aResult[1] = address.bytes[1]; - aResult[2] = address.bytes[2]; - aResult[3] = address.bytes[3]; - return returnCode == NSAPI_ERROR_OK ? 1 : 0; +uint8_t arduino::WiFiClass::status() { + return _currentNetworkStatus; } uint8_t arduino::WiFiClass::encryptionType() { - return sec2enum(ap_list[connected_ap].get_security()); + return sec2enum(ap_list[connected_ap].get_security()); } uint8_t* arduino::WiFiClass::BSSID(unsigned char* bssid) { - const uint8_t* reverse_bssid = ap_list[connected_ap].get_bssid(); - for( int b = 0; b < 6; b++ ) { - bssid[b] = reverse_bssid[5-b]; - } - return bssid; + const uint8_t* reverse_bssid = ap_list[connected_ap].get_bssid(); + for (int b = 0; b < 6; b++) { + bssid[b] = reverse_bssid[5 - b]; + } + return bssid; } -uint8_t* arduino::WiFiClass::macAddress(uint8_t* mac) { - const char *mac_str = getNetwork()->get_mac_address(); - for( int b = 0; b < 6; b++ ) - { - uint32_t tmp; - sscanf( &mac_str[b * 2 + (b)], "%02x", &tmp) ; - mac[5-b] = (uint8_t)tmp ; - } - //sscanf(mac_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", &mac[5], &mac[4], &mac[3], &mac[2], &mac[1], &mac[0]); - return mac; -} - -arduino::IPAddress arduino::WiFiClass::localIP() { - SocketAddress ip; - NetworkInterface *interface = getNetwork(); - interface->get_ip_address(&ip); - return ipAddressFromSocketAddress(ip); -} - -arduino::IPAddress arduino::WiFiClass::subnetMask() { - SocketAddress ip; - NetworkInterface *interface = getNetwork(); - interface->get_netmask(&ip); - return ipAddressFromSocketAddress(ip); -} - -arduino::IPAddress arduino::WiFiClass::gatewayIP() { - SocketAddress ip; - NetworkInterface *interface = getNetwork(); - interface->get_gateway(&ip); - return ipAddressFromSocketAddress(ip); -} - -NetworkInterface *arduino::WiFiClass::getNetwork() { - if (_softAP != nullptr) { - return _softAP; - } else { - return wifi_if; - } +NetworkInterface* arduino::WiFiClass::getNetwork() { + if (_softAP != nullptr) { + return _softAP; + } else { + return wifi_if; + } } unsigned long arduino::WiFiClass::getTime() { - return 0; + return 0; } -void arduino::WiFiClass::setFeedWatchdogFunc(ArduinoPortentaH7WiFiFeedWatchdogFuncPtr func) -{ - _feed_watchdog_func = func; -} - -void arduino::WiFiClass::feedWatchdog() -{ - if (_feed_watchdog_func) - _feed_watchdog_func(); -} - - #if defined(COMPONENT_4343W_FS) #define WIFI_FIRMWARE_PATH "/wlan/4343WA1.BIN" @@ -336,53 +213,52 @@ bool firmware_available = false; #include "resources.h" void wiced_filesystem_mount_error(void) { - Serial.println("Failed to mount the filesystem containing the WiFi firmware."); - Serial.println("Usually that means that the WiFi firmware has not been installed yet" - " or was overwritten with another firmware."); - whd_print_logbuffer(); - while (1) {} + Serial.println("Failed to mount the filesystem containing the WiFi firmware."); + Serial.println("Usually that means that the WiFi firmware has not been installed yet" + " or was overwritten with another firmware."); + whd_print_logbuffer(); + while (1) {} } void wiced_filesystem_firmware_error(void) { - Serial.println("Please run the \"PortentaWiFiFirmwareUpdater\" sketch once to install the WiFi firmware."); - whd_print_logbuffer(); - while (1) {} -} - -wiced_result_t whd_firmware_check_hook(const char *mounted_name, int mount_err) -{ - DIR *dir; - struct dirent *ent; - String dir_name(mounted_name); - if(mount_err) { - wiced_filesystem_mount_error(); - } else { - if ((dir = opendir(mounted_name)) != NULL) { - // print all the files and directories within directory - while ((ent = readdir(dir)) != NULL) { - String fullname = "/" + dir_name + "/" + String(ent->d_name); - if (fullname == WIFI_FIRMWARE_PATH) { - closedir(dir); - firmware_available = true; - return WICED_SUCCESS; - } - } - Serial.println("File not found"); - closedir(dir); + Serial.println("Please run the \"PortentaWiFiFirmwareUpdater\" sketch once to install the WiFi firmware."); + whd_print_logbuffer(); + while (1) {} +} + +wiced_result_t whd_firmware_check_hook(const char* mounted_name, int mount_err) { + DIR* dir; + struct dirent* ent; + String dir_name(mounted_name); + if (mount_err) { + wiced_filesystem_mount_error(); + } else { + if ((dir = opendir(mounted_name)) != NULL) { + // print all the files and directories within directory + while ((ent = readdir(dir)) != NULL) { + String fullname = "/" + dir_name + "/" + String(ent->d_name); + if (fullname == WIFI_FIRMWARE_PATH) { + closedir(dir); + firmware_available = true; + return WICED_SUCCESS; } - wiced_filesystem_firmware_error(); + } + Serial.println("File not found"); + closedir(dir); } - return WICED_ERROR; + wiced_filesystem_firmware_error(); + } + return WICED_ERROR; } #include "whd_version.h" -char* arduino::WiFiClass::firmwareVersion() { - if (firmware_available) { - return WHD_VERSION; - } else { - return "v0.0.0"; - } +const char* arduino::WiFiClass::firmwareVersion() { + if (firmware_available) { + return WHD_VERSION; + } else { + return "v0.0.0"; + } } arduino::WiFiClass WiFi(WiFiInterface::get_default_instance()); diff --git a/libraries/WiFi/src/WiFi.h b/libraries/WiFi/src/WiFi.h index 482426a92..cbbaab42e 100644 --- a/libraries/WiFi/src/WiFi.h +++ b/libraries/WiFi/src/WiFi.h @@ -1,6 +1,6 @@ /* - WiFi.h - Library for Arduino Wifi shield. - Copyright (c) 2011-2014 Arduino LLC. All right reserved. + WiFi.h - Library for Wifi on mbed platforms. + Copyright (c) 2011-2021 Arduino LLC. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -20,18 +20,11 @@ #include extern "C" { - #include "utility/wl_definitions.h" - #include "utility/wl_types.h" +#include "utility/wl_definitions.h" +#include "utility/wl_types.h" } -#include "Arduino.h" -#include "api/IPAddress.h" -#include "WiFiClient.h" -//#include "WiFiSSLClient.h" -#include "WiFiServer.h" -#include "WiFiUdp.h" - -#include "netsocket/NetworkInterface.h" +#include "SocketHelpers.h" #if defined(COMPONENT_4343W_FS) #include "WhdSoftAPInterface.h" @@ -54,36 +47,27 @@ extern "C" { namespace arduino { typedef void* (*voidPrtFuncPtr)(void); -typedef void (*ArduinoPortentaH7WiFiFeedWatchdogFuncPtr)(void); -class WiFiClass -{ +class WiFiClass : public MbedSocketClass { public: - static int16_t _state[MAX_SOCK_NUM]; - static uint16_t _server_port[MAX_SOCK_NUM]; + static int16_t _state[MAX_SOCK_NUM]; + static uint16_t _server_port[MAX_SOCK_NUM]; - WiFiClass(WiFiInterface* _if) : wifi_if(_if) {}; + WiFiClass(WiFiInterface* _if) + : wifi_if(_if){}; - WiFiClass(voidPrtFuncPtr _cb) : _initializerCallback(_cb) {}; - - /* - * Get the first socket available - */ - static uint8_t getSocket(); - - /* + /* * Get firmware version */ - static char* firmwareVersion(); - + static const char* firmwareVersion(); - /* Start Wifi connection for OPEN networks + /* Start Wifi connection for OPEN networks * * param ssid: Pointer to the SSID string. */ - int begin(const char* ssid); + int begin(const char* ssid); - /* Start Wifi connection with WEP encryption. + /* Start Wifi connection with WEP encryption. * Configure a key into the device. The key type (WEP-40, WEP-104) * is determined by the size of the key (5 bytes for WEP-40, 13 bytes for WEP-104). * @@ -91,242 +75,150 @@ class WiFiClass * param key_idx: The key index to set. Valid values are 0-3. * param key: Key input buffer. */ - int begin(const char* ssid, uint8_t key_idx, const char* key); + int begin(const char* ssid, uint8_t key_idx, const char* key); - /* Start Wifi connection with passphrase + /* Start Wifi connection with passphrase * the most secure supported mode will be automatically selected * * param ssid: Pointer to the SSID string. * param passphrase: Passphrase. Valid characters in a passphrase * must be between ASCII 32-126 (decimal). */ - int begin(const char* ssid, const char *passphrase); - - int beginAP(const char *ssid, const char* passphrase, uint8_t channel = DEFAULT_AP_CHANNEL); - - /* Change Ip configuration settings disabling the dhcp client - * - * param local_ip: Static ip configuration - */ - void config(IPAddress local_ip); - - /* Change Ip configuration settings disabling the dhcp client - * - * param local_ip: Static ip configuration as string - */ - void config(const char *local_ip); - - /* Change Ip configuration settings disabling the dhcp client - * - * param local_ip: Static ip configuration - * param dns_server: IP configuration for DNS server 1 - */ - void config(IPAddress local_ip, IPAddress dns_server); - - /* Change Ip configuration settings disabling the dhcp client - * - * param local_ip: Static ip configuration - * param dns_server: IP configuration for DNS server 1 - * param gateway : Static gateway configuration - */ - void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway); - - /* Change Ip configuration settings disabling the dhcp client - * - * param local_ip: Static ip configuration - * param dns_server: IP configuration for DNS server 1 - * param gateway: Static gateway configuration - * param subnet: Static Subnet mask - */ - void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet); - - /* Change DNS Ip configuration - * - * param dns_server1: ip configuration for DNS server 1 - */ - void setDNS(IPAddress dns_server1); - - /* Change DNS Ip configuration - * - * param dns_server1: ip configuration for DNS server 1 - * param dns_server2: ip configuration for DNS server 2 - * - */ - void setDNS(IPAddress dns_server1, IPAddress dns_server2); + int begin(const char* ssid, const char* passphrase); + int beginAP(const char* ssid, const char* passphrase, uint8_t channel = DEFAULT_AP_CHANNEL); - /* Set the hostname used for DHCP requests + /* Set the hostname used for DHCP requests * * param name: hostname to set * */ - void setHostname(const char* name); + void setHostname(const char* name); - /* + /* * Disconnect from the network * * return: one value of wl_status_t enum */ - int disconnect(void); + int disconnect(void); - void end(void); + void end(void); - /* + /* * Get the interface MAC address. * * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH */ - uint8_t* macAddress(uint8_t* mac); + uint8_t* macAddress(uint8_t* mac); - /* - * Get the interface IP address. - * - * return: Ip address value - */ - IPAddress localIP(); - - /* - * Get the interface subnet mask address. - * - * return: subnet mask address value - */ - IPAddress subnetMask(); - - /* - * Get the gateway ip address. - * - * return: gateway ip address value - */ - IPAddress gatewayIP(); - - /* + /* * Return the current SSID associated with the network * * return: ssid string */ - char* SSID(); + char* SSID(); - /* + /* * Return the current BSSID associated with the network. * It is the MAC address of the Access Point * * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH */ - uint8_t* BSSID(uint8_t* bssid); + uint8_t* BSSID(uint8_t* bssid); - /* + /* * Return the current RSSI /Received Signal Strength in dBm) * associated with the network * * return: signed value */ - int32_t RSSI(); + int32_t RSSI(); - /* + /* * Return the Encryption Type associated with the network * * return: one value of wl_enc_type enum */ - uint8_t encryptionType(); + uint8_t encryptionType(); - /* + /* * Start scan WiFi networks available * * return: Number of discovered networks */ - int8_t scanNetworks(); + int8_t scanNetworks(); - /* + /* * Return the SSID discovered during the network scan. * * param networkItem: specify from which network item want to get the information * * return: ssid string of the specified item on the networks scanned list */ - char* SSID(uint8_t networkItem); + char* SSID(uint8_t networkItem); - /* + /* * Return the encryption type of the networks discovered during the scanNetworks * * param networkItem: specify from which network item want to get the information * * return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list */ - uint8_t encryptionType(uint8_t networkItem); + uint8_t encryptionType(uint8_t networkItem); - uint8_t* BSSID(uint8_t networkItem, uint8_t* bssid); - uint8_t channel(uint8_t networkItem); + uint8_t* BSSID(uint8_t networkItem, uint8_t* bssid); + uint8_t channel(uint8_t networkItem); - /* + /* * Return the RSSI of the networks discovered during the scanNetworks * * param networkItem: specify from which network item want to get the information * * return: signed value of RSSI of the specified item on the networks scanned list */ - int32_t RSSI(uint8_t networkItem); + int32_t RSSI(uint8_t networkItem); - /* + /* * Return Connection status. * * return: one of the value defined in wl_status_t */ - uint8_t status(); - - /* - * Resolve the given hostname to an IP address. - * param aHostname: Name to be resolved - * param aResult: IPAddress structure to store the returned IP address - * result: 1 if aIPAddrString was successfully converted to an IP address, - * else error code - */ - int hostByName(const char* aHostname, IPAddress& aResult); + uint8_t status(); - unsigned long getTime(); + unsigned long getTime(); - void lowPowerMode(); - void noLowPowerMode(); + void lowPowerMode(); + void noLowPowerMode(); - int ping(const char* hostname, uint8_t ttl = 128); - int ping(const String &hostname, uint8_t ttl = 128); - int ping(IPAddress host, uint8_t ttl = 128); + int ping(const char* hostname, uint8_t ttl = 128); + int ping(const String& hostname, uint8_t ttl = 128); + int ping(IPAddress host, uint8_t ttl = 128); - int download(char* url, const char* target, bool const is_https = false); + friend class WiFiClient; + friend class WiFiServer; + friend class WiFiUDP; - friend class WiFiClient; - friend class WiFiServer; - friend class WiFiUDP; - - NetworkInterface *getNetwork(); - - void setFeedWatchdogFunc(ArduinoPortentaH7WiFiFeedWatchdogFuncPtr func); - void feedWatchdog(); + NetworkInterface* getNetwork(); private: - - EMACInterface* _softAP = nullptr; - SocketAddress _ip = nullptr; - SocketAddress _gateway = nullptr; - SocketAddress _netmask = nullptr; - SocketAddress _dnsServer1 = nullptr; - SocketAddress _dnsServer2 = nullptr; - char* _ssid = nullptr; - volatile wl_status_t _currentNetworkStatus = WL_IDLE_STATUS; - WiFiInterface* wifi_if = nullptr; - voidPrtFuncPtr _initializerCallback; - WiFiAccessPoint* ap_list = nullptr; - uint8_t connected_ap; - int setSSID(const char* ssid); - void ensureDefaultAPNetworkConfiguration(); - static void * handleAPEvents(whd_interface_t ifp, const whd_event_header_t *event_header, const uint8_t *event_data, void *handler_user_data); - bool isVisible(const char* ssid); - arduino::IPAddress ipAddressFromSocketAddress(SocketAddress socketAddress); - SocketAddress socketAddressFromIpAddress(arduino::IPAddress ip, uint16_t port); - ArduinoPortentaH7WiFiFeedWatchdogFuncPtr _feed_watchdog_func = 0; + EMACInterface* _softAP = nullptr; + char* _ssid = nullptr; + volatile wl_status_t _currentNetworkStatus = WL_IDLE_STATUS; + WiFiInterface* wifi_if = nullptr; + WiFiAccessPoint* ap_list = nullptr; + uint8_t connected_ap; + int setSSID(const char* ssid); + void ensureDefaultAPNetworkConfiguration(); + static void* handleAPEvents(whd_interface_t ifp, const whd_event_header_t* event_header, const uint8_t* event_data, void* handler_user_data); + bool isVisible(const char* ssid); }; } extern WiFiClass WiFi; +#include "WiFiClient.h" +#include "WiFiServer.h" +#include "WiFiUdp.h" + #endif diff --git a/libraries/WiFi/src/WiFiClient.cpp b/libraries/WiFi/src/WiFiClient.cpp deleted file mode 100644 index 175cb24d2..000000000 --- a/libraries/WiFi/src/WiFiClient.cpp +++ /dev/null @@ -1,149 +0,0 @@ -#include "WiFiClient.h" - -extern WiFiClass WiFi; - -#ifndef WIFI_TCP_BUFFER_SIZE -#define WIFI_TCP_BUFFER_SIZE 1508 -#endif - -#ifndef SOCKET_TIMEOUT -#define SOCKET_TIMEOUT 1000 -#endif - -arduino::WiFiClient::WiFiClient() { -} - -uint8_t arduino::WiFiClient::status() { - return _status; -} - -void arduino::WiFiClient::getStatus() { - uint8_t data[256]; - int ret = sock->recv(data, rxBuffer.availableForStore()); - for (int i = 0; i < ret; i++) { - rxBuffer.store_char(data[i]); - } - if (ret < 0 && ret != NSAPI_ERROR_WOULD_BLOCK) { - _status = WL_CONNECTION_LOST; - } -} - -int arduino::WiFiClient::connect(SocketAddress socketAddress) { - if (sock == NULL) { - sock = new TCPSocket(); - if(static_cast(sock)->open(WiFi.getNetwork()) != NSAPI_ERROR_OK){ - return 0; - } - } - //sock->sigio(mbed::callback(this, &WiFiClient::getStatus)); - //sock->set_blocking(false); - address = socketAddress; - sock->set_timeout(SOCKET_TIMEOUT); - nsapi_error_t returnCode = static_cast(sock)->connect(socketAddress); - return returnCode == NSAPI_ERROR_OK ? 1 : 0; -} - -int arduino::WiFiClient::connect(IPAddress ip, uint16_t port) { - return connect(WiFi.socketAddressFromIpAddress(ip, port)); -} - -int arduino::WiFiClient::connect(const char *host, uint16_t port) { - SocketAddress socketAddress = SocketAddress(); - socketAddress.set_port(port); - WiFi.getNetwork()->gethostbyname(host, &socketAddress); - return connect(socketAddress); -} - -int arduino::WiFiClient::connectSSL(SocketAddress socketAddress){ - if (sock == NULL) { - sock = new TLSSocket(); - if(static_cast(sock)->open(WiFi.getNetwork()) != NSAPI_ERROR_OK){ - return 0; - } - } - if (beforeConnect) { - beforeConnect(); - } - sock->set_timeout(SOCKET_TIMEOUT); - nsapi_error_t returnCode = static_cast(sock)->connect(socketAddress); - return returnCode == NSAPI_ERROR_OK ? 1 : 0; -} - -int arduino::WiFiClient::connectSSL(IPAddress ip, uint16_t port) { - return connectSSL(WiFi.socketAddressFromIpAddress(ip, port)); -} - -int arduino::WiFiClient::connectSSL(const char *host, uint16_t port) { - SocketAddress socketAddress = SocketAddress(); - socketAddress.set_port(port); - WiFi.getNetwork()->gethostbyname(host, &socketAddress); - return connectSSL(socketAddress); -} - -size_t arduino::WiFiClient::write(uint8_t c) { - sock->send(&c, 1); -} - -size_t arduino::WiFiClient::write(const uint8_t *buf, size_t size) { - sock->send(buf, size); -} - -int arduino::WiFiClient::available() { - if (rxBuffer.available() == 0) { - getStatus(); - } - return rxBuffer.available(); -} - -int arduino::WiFiClient::read() { - if (!available()) { - return -1; - } - - return rxBuffer.read_char(); -} - -int arduino::WiFiClient::read(uint8_t *data, size_t len) { - int avail = available(); - - if (!avail) { - return -1; - } - - if ((int)len > avail) { - len = avail; - } - - for (size_t i = 0; i < len; i++) { - data[i] = rxBuffer.read_char(); - } - - return len; -} - -int arduino::WiFiClient::peek() { - return rxBuffer.peek(); -} - -void arduino::WiFiClient::flush() { - -} - -void arduino::WiFiClient::stop() { - if (sock != NULL) { - sock->close(); - sock = NULL; - } -} - -uint8_t arduino::WiFiClient::connected() { - return _status != WL_CONNECTION_LOST; -} - -IPAddress arduino::WiFiClient::remoteIP() { - return WiFi.ipAddressFromSocketAddress(address); -} - -uint16_t arduino::WiFiClient::remotePort() { - return 0; -} diff --git a/libraries/WiFi/src/WiFiClient.h b/libraries/WiFi/src/WiFiClient.h index c8b3bce69..f60a978d3 100644 --- a/libraries/WiFi/src/WiFiClient.h +++ b/libraries/WiFi/src/WiFiClient.h @@ -1,6 +1,6 @@ /* - WiFiClient.cpp - Library for Arduino Wifi shield. - Copyright (c) 2011-2014 Arduino LLC. All right reserved. + WiFiClient.h + Copyright (c) 2021 Arduino SA. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -21,71 +21,16 @@ #define wificlient_h #include "WiFi.h" -#include "api/Print.h" -#include "api/Client.h" -#include "api/IPAddress.h" -#include "TLSSocket.h" -#include "TCPSocket.h" +#include "MbedClient.h" namespace arduino { -class WiFiClient : public arduino::Client { - -public: - WiFiClient(); - ~WiFiClient() { - stop(); - } - - uint8_t status(); - int connect(SocketAddress socketAddress); - int connect(IPAddress ip, uint16_t port); - int connect(const char *host, uint16_t port); - int connectSSL(SocketAddress socketAddress); - int connectSSL(IPAddress ip, uint16_t port); - int connectSSL(const char *host, uint16_t port); - size_t write(uint8_t); - size_t write(const uint8_t *buf, size_t size); - int available(); - int read(); - int read(uint8_t *buf, size_t size); - int peek(); - void flush(); - void stop(); - uint8_t connected(); - operator bool() { - return sock != NULL; +class WiFiClient : public MbedClient { + NetworkInterface *getNetwork() { + return WiFi.getNetwork(); } - - void setSocket(Socket* _sock) { - sock = _sock; - } - - IPAddress remoteIP(); - uint16_t remotePort(); - - friend class WiFiServer; - friend class WiFiSSLClient; - - using Print::write; - -protected: - - void onBeforeConnect(mbed::Callback cb) { - beforeConnect = cb; - } - -private: - static uint16_t _srcport; - Socket* sock; - RingBufferN<256> rxBuffer; - uint8_t _status; - mbed::Callback beforeConnect; - SocketAddress address; - - void getStatus(); }; } -#endif \ No newline at end of file +#endif diff --git a/libraries/WiFi/src/WiFiHelpers.cpp b/libraries/WiFi/src/WiFiHelpers.cpp deleted file mode 100644 index ed9301233..000000000 --- a/libraries/WiFi/src/WiFiHelpers.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - WiFi.h - Library for Arduino Wifi shield. - Copyright (c) 2011-2014 Arduino LLC. All right reserved. - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "WiFi.h" -#include "mbed.h" -#include "utility/http_request.h" -#include "utility/https_request.h" - -static FILE* target; - -void body_callback(const char* data, uint32_t data_len) -{ - WiFi.feedWatchdog(); - fwrite(data, 1, data_len, target); -} - -int WiFiClass::download(char* url, const char* target_file, bool const is_https) -{ - target = fopen(target_file, "wb"); - - HttpRequest * req_http = nullptr; - HttpsRequest * req_https = nullptr; - HttpResponse * rsp = nullptr; - - if (is_https) - { - req_https = new HttpsRequest(getNetwork(), nullptr, HTTP_GET, url, &body_callback); - rsp = req_https->send(NULL, 0); - if (rsp == NULL) { - fclose(target); - return req_https->get_error(); - } - } - else - { - req_http = new HttpRequest(getNetwork(), HTTP_GET, url, &body_callback); - rsp = req_http->send(NULL, 0); - if (rsp == NULL) { - fclose(target); - return req_http->get_error(); - } - } - - while (!rsp->is_message_complete()) { - delay(10); - } - - int const size = ftell(target); - fclose(target); - return size; -} diff --git a/libraries/WiFi/src/WiFiSSLClient.cpp b/libraries/WiFi/src/WiFiSSLClient.cpp index 338982285..cb1396b4d 100644 --- a/libraries/WiFi/src/WiFiSSLClient.cpp +++ b/libraries/WiFi/src/WiFiSSLClient.cpp @@ -1,5 +1,5 @@ #include "WiFiSSLClient.h" arduino::WiFiSSLClient::WiFiSSLClient() { - onBeforeConnect(mbed::callback(this, &WiFiSSLClient::setRootCA)); + onBeforeConnect(mbed::callback(this, &WiFiSSLClient::setRootCA)); }; \ No newline at end of file diff --git a/libraries/WiFi/src/WiFiSSLClient.h b/libraries/WiFi/src/WiFiSSLClient.h index 25bf49a33..61e484a69 100644 --- a/libraries/WiFi/src/WiFiSSLClient.h +++ b/libraries/WiFi/src/WiFiSSLClient.h @@ -1,6 +1,6 @@ /* - WiFiSSLClient.cpp - Library for Arduino Wifi shield. - Copyright (c) 2011-2014 Arduino. All right reserved. + WiFiSSLClient.h + Copyright (c) 2021 Arduino SA. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -30,6 +30,9 @@ class WiFiSSLClient : public arduino::WiFiClient { public: WiFiSSLClient(); + virtual ~WiFiSSLClient() { + stop(); + } int connect(IPAddress ip, uint16_t port) { return connectSSL(ip, port); @@ -37,13 +40,6 @@ class WiFiSSLClient : public arduino::WiFiClient { int connect(const char* host, uint16_t port) { return connectSSL(host, port); } - void stop() { - if (sock != NULL) { - sock->close(); - delete ((TLSSocket*)sock); - sock = NULL; - } - } private: int setRootCA() { diff --git a/libraries/WiFi/src/WiFiServer.cpp b/libraries/WiFi/src/WiFiServer.cpp index c54ebe8ad..cefbd0214 100644 --- a/libraries/WiFi/src/WiFiServer.cpp +++ b/libraries/WiFi/src/WiFiServer.cpp @@ -1,44 +1,17 @@ #include "WiFiServer.h" -#include "WiFiClient.h" - -extern WiFiClass WiFi; - -#ifndef WIFI_TCP_BUFFER_SIZE -#define WIFI_TCP_BUFFER_SIZE 1508 -#endif - -arduino::WiFiServer::WiFiServer(uint16_t port) { - _port = port; -} - -uint8_t arduino::WiFiServer::status() { - return 0; -} - -void arduino::WiFiServer::begin() { - if (sock == NULL) { - sock = new TCPSocket(); - ((TCPSocket*)sock)->open(WiFi.getNetwork()); - } - sock->bind(_port); - sock->listen(5); -} - -size_t arduino::WiFiServer::write(uint8_t c) { - sock->send(&c, 1); -} - -size_t arduino::WiFiServer::write(const uint8_t *buf, size_t size) { - sock->send(buf, size); -} arduino::WiFiClient arduino::WiFiServer::available(uint8_t* status) { - WiFiClient client; - nsapi_error_t error; - TCPSocket* clientSocket = sock->accept(&error); - if(status != nullptr) { - *status = error == NSAPI_ERROR_OK ? 1 : 0; - } - client.setSocket(clientSocket); - return client; -} + WiFiClient client; + nsapi_error_t error; + if (sock == nullptr) { + return client; + } + TCPSocket* clientSocket = sock->accept(&error); + if (status != nullptr) { + *status = error == NSAPI_ERROR_OK ? 1 : 0; + } + if (error == NSAPI_ERROR_OK) { + client.setSocket(clientSocket); + } + return client; +} \ No newline at end of file diff --git a/libraries/WiFi/src/WiFiServer.h b/libraries/WiFi/src/WiFiServer.h index 41b2088b5..ae293b374 100644 --- a/libraries/WiFi/src/WiFiServer.h +++ b/libraries/WiFi/src/WiFiServer.h @@ -1,6 +1,6 @@ /* - WiFiServer.h - Library for Arduino Wifi shield. - Copyright (c) 2011-2014 Arduino LLC. All right reserved. + WiFiServer.h + Copyright (c) 2021 Arduino SA. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -18,29 +18,22 @@ #define wifiserver_h #include "WiFi.h" -#include "api/Print.h" -#include "api/Client.h" -#include "api/IPAddress.h" -#include "TLSSocket.h" -#include "TCPSocket.h" +#include "MbedServer.h" +#include "WiFiClient.h" namespace arduino { class WiFiClient; -class WiFiServer : public arduino::Server { -private: - uint16_t _port; - TCPSocket* sock; +class WiFiServer : public MbedServer { + NetworkInterface* getNetwork() { + return WiFi.getNetwork(); + } + public: - WiFiServer(uint16_t); - arduino::WiFiClient available(uint8_t* status = NULL); - void begin(); - virtual size_t write(uint8_t); - virtual size_t write(const uint8_t *buf, size_t size); - uint8_t status(); - - using Print::write; + WiFiServer(uint16_t port) + : MbedServer(port) {} + WiFiClient available(uint8_t* status = nullptr); }; } diff --git a/libraries/WiFi/src/WiFiUdp.cpp b/libraries/WiFi/src/WiFiUdp.cpp deleted file mode 100644 index a2d48e213..000000000 --- a/libraries/WiFi/src/WiFiUdp.cpp +++ /dev/null @@ -1,201 +0,0 @@ -#include "WiFiUdp.h" - -extern WiFiClass WiFi; - -#ifndef WIFI_UDP_BUFFER_SIZE -#define WIFI_UDP_BUFFER_SIZE 508 -#endif - -arduino::WiFiUDP::WiFiUDP() { - _packet_buffer = new uint8_t[WIFI_UDP_BUFFER_SIZE]; - _current_packet = NULL; - _current_packet_size = 0; - // if this allocation fails then ::begin will fail -} - -arduino::WiFiUDP::~WiFiUDP() { - delete[] _packet_buffer; -} - -uint8_t arduino::WiFiUDP::begin(uint16_t port) { - // success = 1, fail = 0 - - nsapi_error_t rt = _socket.open(WiFi.getNetwork()); - if (rt != NSAPI_ERROR_OK) { - return 0; - } - - if (_socket.bind(port) < 0) { - return 0; //Failed to bind UDP Socket to port - } - - if (!_packet_buffer) { - return 0; - } - - _socket.set_timeout(1000); - - return 1; -} - -uint8_t arduino::WiFiUDP::beginMulticast(IPAddress ip, uint16_t port) { - // success = 1, fail = 0 - if(begin(port) != 1){ - return 0; - } - - SocketAddress socketAddress = WiFi.socketAddressFromIpAddress(ip, port); - - if (_socket.join_multicast_group(socketAddress) != NSAPI_ERROR_OK) { - printf("Error joining the multicast group\n"); - return 0; - } - - return 1; -} - -void arduino::WiFiUDP::stop() { - _socket.close(); -} - -int arduino::WiFiUDP::beginPacket(IPAddress ip, uint16_t port) { - _host = WiFi.socketAddressFromIpAddress(ip, port); - //If IP is null and port is 0 the initialization failed - return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1; -} - -int arduino::WiFiUDP::beginPacket(const char *host, uint16_t port) { - _host = SocketAddress(host, port); - WiFi.getNetwork()->gethostbyname(host, &_host); - //If IP is null and port is 0 the initialization failed - return (_host.get_ip_address() == nullptr && _host.get_port() == 0) ? 0 : 1; -} - -int arduino::WiFiUDP::endPacket() { - return 1; -} - -// Write a single byte into the packet -size_t arduino::WiFiUDP::write(uint8_t byte) { - uint8_t buffer[1] = { byte }; - return _socket.sendto(_host, buffer, 1); -} - -// Write size bytes from buffer into the packet -size_t arduino::WiFiUDP::write(const uint8_t *buffer, size_t size) { - return _socket.sendto(_host, buffer, size); -} - -int arduino::WiFiUDP::parsePacket() { - nsapi_size_or_error_t ret = _socket.recvfrom(&_remoteHost, _packet_buffer, WIFI_UDP_BUFFER_SIZE); - - if (ret == NSAPI_ERROR_WOULD_BLOCK) { - // no data - return 0; - } else if(ret == NSAPI_ERROR_NO_SOCKET){ - // socket was not created correctly. - return -1; - } - // error codes below zero are errors - else if (ret <= 0) { - // something else went wrong, need some tracing info... - return -1; - } - - // set current packet states - _current_packet = _packet_buffer; - _current_packet_size = ret; - - return _current_packet_size; -} - -int arduino::WiFiUDP::available() { - return _current_packet_size; -} - -// Read a single byte from the current packet -int arduino::WiFiUDP::read() { - // no current packet... - if (_current_packet == NULL) { - // try reading the next frame, if there is no data return - if (parsePacket() == 0) return -1; - } - - _current_packet++; - - // check for overflow - if (_current_packet > _packet_buffer + _current_packet_size) { - // try reading the next packet... - if (parsePacket() > 0) { - // if so, read first byte of next packet; - return read(); - } - else { - // no new data... not sure what to return here now - return -1; - } - } - - return _current_packet[0]; -} - -// 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 -int arduino::WiFiUDP::read(unsigned char* buffer, size_t len) { - // Q: does Arduino read() function handle fragmentation? I won't for now... - if (_current_packet == NULL) { - if (parsePacket() == 0) return 0; - } - - // how much data do we have in the current packet? - int offset = _current_packet - _packet_buffer; - if (offset < 0) { - return 0; - } - - int max_bytes = _current_packet_size - offset; - if (max_bytes < 0) { - return 0; - } - - // at the end of the packet? - if (max_bytes == 0) { - // try read next packet... - if (parsePacket() > 0) { - return read(buffer, len); - } - else { - return 0; - } - } - - if (len > max_bytes) len = max_bytes; - - // copy to target buffer - memcpy(buffer, _current_packet, len); - - _current_packet += len; - - return len; -} - -IPAddress arduino::WiFiUDP::remoteIP() { - nsapi_addr_t address = _remoteHost.get_addr(); - return IPAddress(address.bytes[0], address.bytes[1], address.bytes[2], address.bytes[3]); -} - -uint16_t arduino::WiFiUDP::remotePort() { - return _remoteHost.get_port(); -} - -void arduino::WiFiUDP::flush(){ - // TODO: a real check to ensure transmission has been completed -} - -int arduino::WiFiUDP::peek(){ - if (_current_packet_size < 1){ - return -1; - } - - return _current_packet[0]; -} \ No newline at end of file diff --git a/libraries/WiFi/src/WiFiUdp.h b/libraries/WiFi/src/WiFiUdp.h index 3796c5f9b..8fbeba079 100644 --- a/libraries/WiFi/src/WiFiUdp.h +++ b/libraries/WiFi/src/WiFiUdp.h @@ -1,6 +1,6 @@ /* - WiFiUdp.h - Library for Arduino Wifi shield. - Copyright (c) 2011-2014 Arduino LLC. All right reserved. + WiFiUdp.h + Copyright (c) 2021 Arduino SA. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -21,74 +21,14 @@ #define wifiudp_h #include "WiFi.h" -#include "api/Udp.h" - -#include "netsocket/SocketAddress.h" -#include "netsocket/UDPSocket.h" - -#define UDP_TX_PACKET_MAX_SIZE 24 +#include "MbedUdp.h" namespace arduino { -class WiFiUDP : public UDP { -private: - UDPSocket _socket; // Mbed OS socket - SocketAddress _host; // Host to be used to send data - SocketAddress _remoteHost; // Remote host that sent incoming packets - - uint8_t* _packet_buffer; // Raw packet buffer (contains data we got from the UDPSocket) - - // The Arduino APIs allow you to iterate through this buffer, so we need to be able to iterate over the current packet - // these two variables are used to cache the state of the current packet - uint8_t* _current_packet; - size_t _current_packet_size; - -public: - WiFiUDP(); // Constructor - ~WiFiUDP(); - 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 multicast IP address and 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 the port of the host who sent the current incoming packet - virtual uint16_t remotePort(); +class WiFiUDP : public MbedUDP { + NetworkInterface *getNetwork() { + return WiFi.getNetwork(); + } }; }