From edc4cff11ea3c5f5704fd7922a2f04e61bd74d32 Mon Sep 17 00:00:00 2001 From: Khoi Hoang <57012152+khoih-prog@users.noreply.github.com> Date: Sat, 8 Oct 2022 01:29:15 -0400 Subject: [PATCH] v1.2.0 to add support to `WiFiNINA` ### Releases v1.2.0 1. Add support to `WiFiNINA`, such as `Adafruit Airlift Featherwing` 2. Configurable `user_name` length to 63 and `user_password` to 127. Check [Setting FTP_CRED_SIZE on the fly like with FTP_BUF_SIZE #4](https://github.com/khoih-prog/FTP_Server_Teensy41/issues/4) --- CONTRIBUTING.md | 12 +- changelog.md | 6 + .../FTP_Server_SDFAT2/FTP_Server_SDFAT2.ino | 8 +- examples/FTP_Server_SDFAT2/defines.h | 2 +- .../FTP_Server_SDFAT2_NINA.ino | 402 ++++++++++++++++++ .../FTP_Server_SDFAT2_NINA/arduino_secrets.h | 2 + .../WiFiNINA/FTP_Server_SDFAT2_NINA/defines.h | 147 +++++++ .../multiFileProject/multiFileProject.ino | 4 +- library.json | 6 +- library.properties | 2 +- platformio/platformio.ini | 11 +- src/FTP_Server_Teensy41.h | 13 +- src/FTP_Server_Teensy41.hpp | 78 +++- src/FTP_Server_Teensy41_Config.h | 23 +- src/FTP_Server_Teensy41_Debug.h | 4 +- src/FTP_Server_Teensy41_Impl.h | 168 +++++++- 16 files changed, 841 insertions(+), 47 deletions(-) create mode 100644 examples/WiFiNINA/FTP_Server_SDFAT2_NINA/FTP_Server_SDFAT2_NINA.ino create mode 100644 examples/WiFiNINA/FTP_Server_SDFAT2_NINA/arduino_secrets.h create mode 100644 examples/WiFiNINA/FTP_Server_SDFAT2_NINA/defines.h diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 32f3ef2..fc421c4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,8 +15,8 @@ If you don't find anything, please [open a new issue](https://github.com/khoih-p Please ensure to specify the following: * Arduino IDE version (e.g. 1.8.19) or Platform.io version -* `Teensyduino` Core Version (e.g. `Teensyduino core v1.56`) -* `QNEthernet` library version (e.g. `QNEthernet v0.14.0`) or +* `Teensyduino` Core Version (e.g. `Teensyduino core v1.57`) +* `QNEthernet` library version (e.g. `QNEthernet v0.15.0`) or * `NativeEthernet` library version or * `Ethernet_Generic` library version * Board type and relevant info @@ -31,13 +31,13 @@ Please ensure to specify the following: ``` Arduino IDE version: 1.8.19 -Teensyduino core v1.56 -Teensy 4.1 using QNEthernet v0.14.0 +Teensyduino core v1.57 +Teensy 4.1 using QNEthernet v0.15.0 OS: Ubuntu 20.04 LTS -Linux xy-Inspiron-3593 5.13.0-41-generic #46~20.04.1-Ubuntu SMP Wed Apr 20 13:16:21 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux +Linux xy-Inspiron-3593 5.15.0-48-generic #54~20.04.1-Ubuntu SMP Thu Sep 1 16:17:26 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux Context: -I encountered a crash while using TimerInterrupt. +I encountered a crash while using this library Steps to reproduce: 1. ... diff --git a/changelog.md b/changelog.md index c4cfa94..c0eb8ba 100644 --- a/changelog.md +++ b/changelog.md @@ -13,6 +13,7 @@ * [Changelog](#changelog) + * [Releases v1.2.0](#releases-v120) * [Releases v1.1.0](#releases-v110) * [Releases v1.0.0](#releases-v100) @@ -21,6 +22,11 @@ ## Changelog +### Releases v1.2.0 + +1. Add support to `WiFiNINA`, such as `Adafruit Airlift Featherwing` +2. Configurable `user_name` length to 63 and `user_password` to 127. Check [Setting FTP_CRED_SIZE on the fly like with FTP_BUF_SIZE #4](https://github.com/khoih-prog/FTP_Server_Teensy41/issues/4) + ### Releases v1.1.0 1. Fix bug incomplete downloads from server to client. Check [Incomplete downloads from server to client. #2](https://github.com/khoih-prog/FTP_Server_Teensy41/pull/2) diff --git a/examples/FTP_Server_SDFAT2/FTP_Server_SDFAT2.ino b/examples/FTP_Server_SDFAT2/FTP_Server_SDFAT2.ino index 0e13332..d322c3f 100644 --- a/examples/FTP_Server_SDFAT2/FTP_Server_SDFAT2.ino +++ b/examples/FTP_Server_SDFAT2/FTP_Server_SDFAT2.ino @@ -12,10 +12,14 @@ #include #include -#define FTP_FILESYST FTP_SDFAT2 +#define PASV_RESPONSE_STYLE_NEW true +#define FTP_FILESYST FTP_SDFAT2 // Default 2048 -#define FTP_BUF_SIZE 8192 +#define FTP_BUF_SIZE 8192 + +#define FTP_USER_NAME_LEN 64 // Max permissible and default are 64 +#define FTP_USER_PWD_LEN 128 // Max permissible and default are 128 #include diff --git a/examples/FTP_Server_SDFAT2/defines.h b/examples/FTP_Server_SDFAT2/defines.h index 2a622ee..9c92b39 100644 --- a/examples/FTP_Server_SDFAT2/defines.h +++ b/examples/FTP_Server_SDFAT2/defines.h @@ -13,7 +13,7 @@ #define TEENSY41_DEBUG_PORT Serial // Debug Level from 0 to 4 -#define _FTP_SERVER_LOGLEVEL_ 2 +#define _FTP_SERVER_LOGLEVEL_ 1 #if ( defined(CORE_TEENSY) && defined(__IMXRT1062__)) #if (defined(ARDUINO_TEENSY41)) diff --git a/examples/WiFiNINA/FTP_Server_SDFAT2_NINA/FTP_Server_SDFAT2_NINA.ino b/examples/WiFiNINA/FTP_Server_SDFAT2_NINA/FTP_Server_SDFAT2_NINA.ino new file mode 100644 index 0000000..a7a21fa --- /dev/null +++ b/examples/WiFiNINA/FTP_Server_SDFAT2_NINA/FTP_Server_SDFAT2_NINA.ino @@ -0,0 +1,402 @@ +/********************************************************************************************************************** + FTP_Server_SDFAT2.ino + + FTP_Server_Teensy41 is an FTP Server for Teensy 4.1 using SD, FS, etc. with QNEthernet or NativeEthernet + + Based on and modified from Arduino-Ftp-Server Library (https://github.com/gallegojm/Arduino-Ftp-Server) + Built by Khoi Hoang https://github.com/khoih-prog/FTP_Server_Teensy41 + ***********************************************************************************************************************/ + +#include "defines.h" + +#include +#include + +#define FTP_FILESYST FTP_SDFAT2 + +// Default 2048 +#define FTP_BUF_SIZE 4096 + +#define FTP_USER_NAME_LEN 64 // Max permissible and default are 64 +#define FTP_USER_PWD_LEN 128 // Max permissible and default are 128 + +#include + +// Object for FtpServer +// Command port and Data port in passive mode can be defined here +// FtpServer ftpSrv( 221, 25000 ); +// FtpServer ftpSrv( 421 ); // Default data port in passive mode is 55600 +FtpServer ftpSrv; // Default command port is 21 ( !! without parenthesis !! ) + +File myFile; + +// change this to match your SD shield or module; +// Arduino Ethernet shield: pin 4 +// Adafruit SD shields and modules: pin 10 +// Sparkfun SD shield: pin 8 +// Teensy audio board: pin 10 +// Teensy 3.5 & 3.6 & 4.1 on-board: BUILTIN_SDCARD +// Wiz820+SD board: pin 4 +// Teensy 2.0: pin 0 +// Teensy++ 2.0: pin 20 +const int chipSelect = BUILTIN_SDCARD; //10; + +SDClass myfs; + +// set up variables using the SD utility library functions: +Sd2Card card; +SdVolume volume; +SdFile root; + +/******************************************************************************* +** ** +** INITIALISATION ** +** ** +*******************************************************************************/ + +#define FTP_ACCOUNT "teensy4x" +#define FTP_PASSWORD "ftp_test" + +void initNetwork() +{ +#if USE_QN_ETHERNET + Serial.println(F("=========== USE_QN_ETHERNET ===========")); +#elif USE_NATIVE_ETHERNET + Serial.println(F("========= USE_NATIVE_ETHERNET =========")); +#elif USE_ETHERNET_GENERIC + Serial.println(F("========= USE_ETHERNET_GENERIC ========")); +#elif USE_WIFI_NINA + Serial.println(F("============ USE_WIFI_NINA ============")); +#else + Serial.println(F("=======================================")); +#endif + +#if USE_WIFI_NINA + // check for the WiFi module: + // Using this setPins() with Adafruit WiFiNINA library + //WiFi.setPins(SPIWIFI_SS, SPIWIFI_ACK, ESP32_RESETN, ESP32_GPIO0, &SPIWIFI); + + if (WiFi.status() == WL_NO_MODULE) + { + Serial.println("Communication with WiFi module failed!"); + // don't continue + while (true); + } + + // Start the Ethernet connection, using DHCP + Serial.print("Initialize WiFi using DHCP => "); + WiFi.begin(ssid, pass); + Serial.println(""); + + // Wait for connection + while (WiFi.status() != WL_CONNECTED) + { + delay(500); + Serial.print("."); + } + + Serial.println(""); + Serial.print("Connected to "); Serial.println(ssid); + Serial.print("IP address: "); Serial.println(WiFi.localIP()); + +#elif USE_NATIVE_ETHERNET + + // start the ethernet connection and the server: + // Use DHCP dynamic IP and random mac + uint16_t index = millis() % NUMBER_OF_MAC; + // Use Static IP + //Ethernet.begin(mac[index], ip); + Ethernet.begin(mac[index]); + + Serial.print(F("Using mac index = ")); + Serial.println(index); + + Serial.print(F("Connected! IP address: ")); + Serial.println(Ethernet.localIP()); + +#elif USE_QN_ETHERNET + +#if USING_DHCP + // Start the Ethernet connection, using DHCP + Serial.print("Initialize Ethernet using DHCP => "); + Ethernet.begin(); + // give the Ethernet shield minimum 1 sec for DHCP and 2 secs for staticP to initialize: + delay(1000); +#else + // Start the Ethernet connection, using static IP + Serial.print("Initialize Ethernet using static IP => "); + Ethernet.begin(myIP, myNetmask, myGW); + Ethernet.setDNSServerIP(mydnsServer); +#endif + + if (!Ethernet.waitForLocalIP(5000)) + { + Serial.println("Failed to configure Ethernet"); + + if (!Ethernet.linkStatus()) + { + Serial.println("Ethernet cable is not connected."); + } + + // Stay here forever + while (true) + { + delay(1); + } + } + else + { + Serial.print("IP Address = "); + Serial.println(Ethernet.localIP()); + } + + // give the Ethernet shield minimum 1 sec for DHCP and 2 secs for staticP to initialize: + //delay(2000); + +#else + + FTP_LOGWARN(F("Default SPI pinout:")); + FTP_LOGWARN1(F("MOSI:"), MOSI); + FTP_LOGWARN1(F("MISO:"), MISO); + FTP_LOGWARN1(F("SCK:"), SCK); + FTP_LOGWARN1(F("SS:"), SS); + FTP_LOGWARN(F("=========================")); + + // unknown board, do nothing, use default SS = 10 + #ifndef USE_THIS_SS_PIN + #define USE_THIS_SS_PIN 10 // For other boards + #endif + + #if defined(BOARD_NAME) + FTP_LOGWARN3(F("Board :"), BOARD_NAME, F(", setCsPin:"), USE_THIS_SS_PIN); + #else + FTP_LOGWARN1(F("Unknown board setCsPin:"), USE_THIS_SS_PIN); + #endif + + // For other boards, to change if necessary + Ethernet.init (USE_THIS_SS_PIN); + + // start the ethernet connection and the server: + // Use DHCP dynamic IP and random mac + uint16_t index = millis() % NUMBER_OF_MAC; + // Use Static IP + //Ethernet.begin(mac[index], ip); + Ethernet.begin(mac[index]); + + Serial.print("IP Address = "); + Serial.println(Ethernet.localIP()); + +#endif +} + +void cardInit() +{ + // we'll use the initialization code from the utility libraries + // since we're just testing if the card is working! + if (!card.init(SPI_HALF_SPEED, chipSelect)) + { + Serial.println("Initialization failed. Things to check:"); + Serial.println("* is a card inserted?"); + Serial.println("* is your wiring correct?"); + Serial.println("* did you change the chipSelect pin to match your shield or module?"); + return; + } + else + { + Serial.println("Wiring is correct and a card is present."); + } + + // print the type of card + Serial.print("\nCard type: "); + + switch (card.type()) + { + case SD_CARD_TYPE_SD1: + Serial.println("SD1"); + break; + case SD_CARD_TYPE_SD2: + Serial.println("SD2"); + break; + case SD_CARD_TYPE_SDHC: + Serial.println("SDHC"); + break; + default: + Serial.println("Unknown"); + } + + // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32 + if (!volume.init(card)) + { + Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card"); + + return; + } + + // print the type and size of the first FAT-type volume + uint32_t volumesize; + + Serial.print("\nVolume type is FAT"); Serial.println(volume.fatType(), DEC); Serial.println(); + + volumesize = volume.blocksPerCluster(); // clusters are collections of blocks + volumesize *= volume.clusterCount(); // we'll have a lot of clusters + + if (volumesize < 8388608ul) + { + Serial.print("Volume size (bytes): "); + Serial.println(volumesize * 512); // SD card blocks are always 512 bytes + } + + Serial.print("Volume size (Kbytes): "); volumesize /= 2; Serial.println(volumesize); + Serial.print("Volume size (Mbytes): "); volumesize /= 1024; Serial.println(volumesize); +} + +void printDirectory(File dir, int numSpaces) +{ + while (true) + { + File entry = dir.openNextFile(); + + if (! entry) + { + //Serial.println("** no more files **"); + break; + } + + printSpaces(numSpaces); + Serial.print(entry.name()); + + if (entry.isDirectory()) + { + Serial.println("/"); + printDirectory(entry, numSpaces + 2); + } + else + { + // files have sizes, directories do not + unsigned int n = log10(entry.size()); + + if (n > 10) + n = 10; + + printSpaces(50 - numSpaces - strlen(entry.name()) - n); + Serial.print(" "); Serial.print(entry.size(), DEC); + + DateTimeFields datetime; + + if (entry.getModifyTime(datetime)) + { + printSpaces(4); + printTime(datetime); + } + + Serial.println(); + } + + entry.close(); + } +} + +void printSpaces(int num) +{ + for (int i = 0; i < num; i++) + { + Serial.print(" "); + } +} + +void printTime(const DateTimeFields tm) +{ + const char *months[12] = + { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + }; + + if (tm.hour < 10) + Serial.print('0'); + + Serial.print(tm.hour); + Serial.print(':'); + + if (tm.min < 10) + Serial.print('0'); + + Serial.print(tm.min); + Serial.print(" "); + Serial.print(months[tm.mon]); + Serial.print(" "); + Serial.print(tm.mday); + Serial.print(", "); + Serial.print(tm.year + 1900); +} + +void SDCardTest() +{ + Serial.println("\n==============================="); + Serial.print("SDCard Initialization : "); + + + if (!SD.begin(chipSelect)) + { + Serial.println("failed!"); + return; + } + + Serial.println("done."); + + File root = SD.open("/"); + + printDirectory(root, 0); + + Serial.println("done!"); +} + +void setup() +{ + Serial.begin(115200); + while (!Serial && millis() < 5000); + + delay(500); + + Serial.print(F("\nStarting FTP_Server_SDFAT2_NINA on ")); Serial.print(BOARD_NAME); + Serial.print(F(" with ")); Serial.println(SHIELD_TYPE); + Serial.println(FTP_SERVER_TEENSY41_VERSION); + +// Uncomment this if Teensy 4.0 has SD card +#if (defined(ARDUINO_TEENSY41)) + + Serial.println("Initializing SD card..."); + + ////////////////////////////////////////////////////////////////// + + cardInit(); + + //////////////////////////////////////////////////////////////// + +// SDCardTest(); + + ////////////////////////////////////////////////////////////////// +#endif + + initNetwork(); + + // Initialize the FTP server + ftpSrv.init(); + ftpSrv.credentials( FTP_ACCOUNT, FTP_PASSWORD ); + + Serial.print("FTP Server Credentials => account = "); Serial.print(FTP_ACCOUNT); + Serial.print(", password = "); Serial.println(FTP_PASSWORD); +} + +/******************************************************************************* +** ** +** MAIN LOOP ** +** ** +*******************************************************************************/ + +void loop() +{ + ftpSrv.service(); + + // more processes... +} diff --git a/examples/WiFiNINA/FTP_Server_SDFAT2_NINA/arduino_secrets.h b/examples/WiFiNINA/FTP_Server_SDFAT2_NINA/arduino_secrets.h new file mode 100644 index 0000000..41951b9 --- /dev/null +++ b/examples/WiFiNINA/FTP_Server_SDFAT2_NINA/arduino_secrets.h @@ -0,0 +1,2 @@ +#define SECRET_SSID "your_ssid" +#define SECRET_PASS "12345678" diff --git a/examples/WiFiNINA/FTP_Server_SDFAT2_NINA/defines.h b/examples/WiFiNINA/FTP_Server_SDFAT2_NINA/defines.h new file mode 100644 index 0000000..157f7e6 --- /dev/null +++ b/examples/WiFiNINA/FTP_Server_SDFAT2_NINA/defines.h @@ -0,0 +1,147 @@ +/**************************************************************************************************************************** + defines.h + + FTP_Server_Teensy41 is an FTP Server for Teensy 4.1 using SD, FS, etc. with QNEthernet or NativeEthernet + + Based on and modified from Arduino-Ftp-Server Library (https://github.com/gallegojm/Arduino-Ftp-Server) + Built by Khoi Hoang https://github.com/khoih-prog/FTP_Server_Teensy41 + ***************************************************************************************************************************************/ + +#ifndef defines_h +#define defines_h + +#define TEENSY41_DEBUG_PORT Serial + +// Debug Level from 0 to 4 +#define _FTP_SERVER_LOGLEVEL_ 1 + +#if ( defined(CORE_TEENSY) && defined(__IMXRT1062__)) + #if (defined(ARDUINO_TEENSY41)) + // For Teensy 4.1 + #define BOARD_TYPE "TEENSY 4.1" + // Use true for QNEthernet or NativeEthernet Library, and false to use other Ethernet_Generic library + #define USE_QN_ETHERNET false + #define USE_NATIVE_ETHERNET false + #define USE_WIFI_NINA true // Added 05-17-22 WEW + #else + // For Teensy 4.0 + #define BOARD_TYPE "TEENSY 4.0" + // Use false for QNEthernet and NativeEthernet Library, and to use other Ethernet_Generic library + #define USE_QN_ETHERNET false + #define USE_NATIVE_ETHERNET false + #define USE_WIFI_NINA false // Added 05-17-22 WEW + #endif +#else + #error Only Teensy 4.1 supported +#endif + +#ifndef BOARD_NAME + #define BOARD_NAME BOARD_TYPE +#endif + +// Use true for ENC28J60 and UIPEthernet library (https://github.com/UIPEthernet/UIPEthernet) +// Use false for W5x00 and Ethernetx library (https://www.arduino.cc/en/Reference/Ethernet) + +#define USE_UIP_ETHERNET false +#define USE_ETHERNET_GENERIC false +#define USE_ETHERNET_ESP8266 false +#define USE_ETHERNET_ENC false +#define USE_CUSTOM_ETHERNET false + +#if USE_QN_ETHERNET + #include "QNEthernet.h" // https://github.com/ssilverman/QNEthernet + using namespace qindesign::network; + //#warning Using QNEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error + #define SHIELD_TYPE "QNEthernet" + +#elif USE_NATIVE_ETHERNET + #include "NativeEthernet.h" + //#warning Using NativeEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error + #define SHIELD_TYPE "NativeEthernet" + +#elif USE_WIFI_NINA + //#include "WiFiNINA.h" + #include "WiFiNINA_Generic.h" + #include "SPI.h" + #include "arduino_secrets.h" + + // T4.1 SPI pin defs for WiFiNINA AirLift. To update WiFiNINA_Pinout_Generic.h using this info + //#warning Using WiFiNINA_Generic lib for Teensy 4.1. Must also update WiFiNINA_Pinout_Generic.h or error + + //#define SPIWIFI SPI // The SPI port + //#define SPIWIFI_SS 5 // Chip select pin + //#define ESP32_RESETN 6 // Reset pin + //#define SPIWIFI_ACK 9 // a.k.a BUSY or READY pin + //#define ESP32_GPIO0 -1 + ///////please enter your sensitive data in the Secret tab/arduino_secrets.h + char ssid[] = SECRET_SSID; // your network SSID (name) + char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) + #define SHIELD_TYPE "WiFiNINA" + +#elif USE_ETHERNET_GENERIC + + #include + + /////////////////////////////////////////////////////////// + + // W5100 chips can have up to 4 sockets. W5200 & W5500 can have up to 8 sockets. + // Use EthernetLarge feature, Larger buffers, but reduced number of simultaneous connections/sockets (MAX_SOCK_NUM == 2) + #define ETHERNET_LARGE_BUFFERS + + ////////////////////////////////////////////////////////// + + #include "Ethernet_Generic.h" + + #if defined(ETHERNET_LARGE_BUFFERS) + #define SHIELD_TYPE "W5x00 using Ethernet_Generic Library with Large Buffer" + #else + #define SHIELD_TYPE "W5x00 using Ethernet_Generic Library" + #endif + +#endif + + +#if (USE_NATIVE_ETHERNET || USE_ETHERNET_GENERIC) + // Enter a MAC address and IP address for your controller below. + #define NUMBER_OF_MAC 20 + + byte mac[][NUMBER_OF_MAC] = + { + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x14 }, + }; + +#else + + #define USING_DHCP true //true + + #if !USING_DHCP + // Set the static IP address to use if the DHCP fails to assign + IPAddress myIP(192, 168, 0, 114); + IPAddress myNetmask(255, 255, 255, 0); + IPAddress myGW(192, 168, 0, 1); + //IPAddress mydnsServer(192, 168, 2, 1); + IPAddress mydnsServer(192, 168, 0, 1); + #endif + +#endif + +#endif //defines_h diff --git a/examples/multiFileProject/multiFileProject.ino b/examples/multiFileProject/multiFileProject.ino index 4fe7011..0dbce75 100644 --- a/examples/multiFileProject/multiFileProject.ino +++ b/examples/multiFileProject/multiFileProject.ino @@ -20,8 +20,8 @@ #error Only Teensy 4.1 supported #endif -#define FTP_SERVER_TEENSY41_VERSION_MIN_TARGET "FTP_Server_Teensy41 v1.0.0" -#define FTP_SERVER_TEENSY41_VERSION_MIN 1000000 +#define FTP_SERVER_TEENSY41_VERSION_MIN_TARGET "FTP_Server_Teensy41 v1.2.1" +#define FTP_SERVER_TEENSY41_VERSION_MIN 1002001 #define FTP_FILESYST FTP_SDFAT2 diff --git a/library.json b/library.json index 9646c47..571e2d9 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name":"FTP_Server_Teensy41", - "version": "1.1.0", + "version": "1.2.0", "description":"FTP Server for Teensy 4.x using SD, LittleFS, etc. with QNEthernet, NativeEthernet or W5x00 using Ethernet_Generic Library", "keywords":"communication, data, ftp, server, ftp-server, ethernet, teensy, teensy41, teensy40, qnethernet, lwip, native-ethernet, w5x00, w5100, w5500, ethernet-generic", "authors": [ @@ -30,12 +30,12 @@ { "owner": "khoih-prog", "name": "Ethernet_Generic", - "version": "^2.3.0" + "version": "^2.6.1" }, { "owner": "ssilverman", "name": "QNEthernet", - "version": ">=0.14.0", + "version": ">=0.15.0", "platforms": ["teensy"] } ], diff --git a/library.properties b/library.properties index ba38023..54ff260 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=FTP_Server_Teensy41 -version=1.1.0 +version=1.2.0 author=Jean-Michel Gallego, Khoi Hoang maintainer=Khoi Hoang sentence=FTP Server for Teensy 4.1 using SD, FS, etc. diff --git a/platformio/platformio.ini b/platformio/platformio.ini index 376f7f5..9a9c448 100644 --- a/platformio/platformio.ini +++ b/platformio/platformio.ini @@ -27,14 +27,21 @@ upload_speed = 921600 ;monitor_port = COM11 ; Checks for the compatibility with frameworks and dev/platforms +; Adjust as necessary lib_compat_mode = strict +lib_ldf_mode = chain+ +;lib_ldf_mode = deep+ lib_deps = ; PlatformIO 4.x -; QNEthernet@>=0.14.0 +; QNEthernet@>=0.15.0 +; Functional-Vlpp@~1.0.2 +; Ethernet_Generic@>=2.6.1 ; PlatformIO 5.x -ssilverman/QNEthernet@>=0.14.0 + ssilverman/QNEthernet@>=0.15.0 + khoih-prog/Functional-Vlpp@~1.0.2 + khoih-prog/Ethernet_Generic@~2.6.1 build_flags = ; set your build_flags diff --git a/src/FTP_Server_Teensy41.h b/src/FTP_Server_Teensy41.h index 15cda55..3183bc5 100644 --- a/src/FTP_Server_Teensy41.h +++ b/src/FTP_Server_Teensy41.h @@ -6,12 +6,14 @@ Based on and modified from Arduino-Ftp-Server Library (https://github.com/gallegojm/Arduino-Ftp-Server) Built by Khoi Hoang https://github.com/khoih-prog/FTP_Server_Teensy41 - Version: 1.1.0 + Version: 1.2.0 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 30/04/2022 Initial porting and coding for Teensy 4.1 using built-in QNEthernet, NativeEthernet 1.1.0 K Hoang 16/05/2022 Fix bug incomplete downloads from server to client + 1.2.0 K Hoang 08/10/2022 Add support to WiFiNINA, such as Adafruit Airlift Featherwing. + Configurable user_name length to 63 and user_password to 127 ***********************************************************************************************************************/ /* @@ -54,10 +56,11 @@ #endif // Default to QNEthernet if nothing pre-selected - #if !(USE_QN_ETHERNET || USE_NATIVE_ETHERNET || USE_ETHERNET_GENERIC) + #if !(USE_QN_ETHERNET || USE_NATIVE_ETHERNET || USE_ETHERNET_GENERIC || USE_WIFI_NINA) #define USE_QN_ETHERNET true #define USE_NATIVE_ETHERNET false #define USE_ETHERNET_GENERIC false + #define USE_WIFI_NINA false // Added 05-17-22 WEW #endif #else //#error Only Teensy 4.1 supported @@ -65,13 +68,13 @@ //////////////////////////////////////////////////////////////////////////// -#define FTP_SERVER_TEENSY41_VERSION "FTP_Server_Teensy41 v1.1.0" +#define FTP_SERVER_TEENSY41_VERSION "FTP_Server_Teensy41 v1.2.0" #define FTP_SERVER_TEENSY41_VERSION_MAJOR 1 -#define FTP_SERVER_TEENSY41_VERSION_MINOR 1 +#define FTP_SERVER_TEENSY41_VERSION_MINOR 2 #define FTP_SERVER_TEENSY41_VERSION_PATCH 0 -#define FTP_SERVER_TEENSY41_VERSION_INT 1001000 +#define FTP_SERVER_TEENSY41_VERSION_INT 1002000 //////////////////////////////////////////////////////////////////////////// diff --git a/src/FTP_Server_Teensy41.hpp b/src/FTP_Server_Teensy41.hpp index 99d7f59..5570b30 100644 --- a/src/FTP_Server_Teensy41.hpp +++ b/src/FTP_Server_Teensy41.hpp @@ -6,12 +6,14 @@ Based on and modified from Arduino-Ftp-Server Library (https://github.com/gallegojm/Arduino-Ftp-Server) Built by Khoi Hoang https://github.com/khoih-prog/FTP_Server_Teensy41 - Version: 1.1.0 + Version: 1.2.0 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 30/04/2022 Initial porting and coding for Teensy 4.1 using built-in QNEthernet, NativeEthernet 1.1.0 K Hoang 16/05/2022 Fix bug incomplete downloads from server to client + 1.2.0 K Hoang 24/05/2022 Add support to WiFiNINA, such as Adafruit Airlift Featherwing. + Configurable user_name length to 63 and user_password to 127 ***********************************************************************************************************************/ /* @@ -66,7 +68,16 @@ #warning Using NativeEthernet lib for Teensy 4.1. Must also use Teensy Packages Patch or error #endif - //#define SHIELD_TYPE "using NativeEthernet" + //#define SHIELD_TYPE "using NativeEthernet" + +#elif USE_WIFI_NINA + #include "WiFiNINA_Generic.h" + + #if (_FTP_SERVER_LOGLEVEL_>2) + //#warning Using WiFiNINA_Generic lib for Teensy 4.1. Must also use Teensy Packages Patch or error + #warning Using WiFiNINA_Generic lib for Teensy 4.1. Must also update WiFiNINA_Pinout_Generic.h or error + #endif + #elif USE_ETHERNET_GENERIC #include "Ethernet_Generic.hpp" #else @@ -79,7 +90,7 @@ #if (FTP_FILESYST == FTP_SDFAT1) - #include + #include #include #define FTP_FS SD #define FTP_FILE SdFile @@ -88,7 +99,7 @@ #elif (FTP_FILESYST == FTP_SDFAT2) - #include + #include #include #define FTP_FS SD.sdfs #define FTP_FILE SdFile @@ -100,6 +111,8 @@ #if USE_QN_ETHERNET using namespace qindesign::network; + + #define FTP_NETWORK Ethernet #define FTP_SERVER EthernetServer #define FTP_CLIENT EthernetClient #define FTP_LOCALIP() Ethernet.localIP() @@ -108,14 +121,25 @@ #elif USE_NATIVE_ETHERNET + #define FTP_NETWORK Ethernet #define FTP_SERVER EthernetServer #define FTP_CLIENT EthernetClient #define FTP_LOCALIP() Ethernet.localIP() #define CommandIs( a ) ( ! strcmp_PF( command, PSTR( a ))) #define ParameterIs( a ) ( ! strcmp_PF( parameter, PSTR( a ))) - + +#elif USE_WIFI_NINA + + #define FTP_NETWORK WiFi + #define FTP_SERVER WiFiServer + #define FTP_CLIENT WiFiClient + #define FTP_LOCALIP() WiFi.localIP() + #define CommandIs( a ) ( ! strcmp_PF( command, PSTR( a ))) + #define ParameterIs( a ) ( ! strcmp_PF( parameter, PSTR( a ))) + #else + #define FTP_NETWORK Ethernet #define FTP_SERVER EthernetServer #define FTP_CLIENT EthernetClient #define FTP_LOCALIP() Ethernet.localIP() @@ -136,8 +160,40 @@ #define FF_MAX_LFN 255 // max size of a long file name #define FTP_CMD_SIZE FF_MAX_LFN+8 // max size of a command #define FTP_CWD_SIZE FF_MAX_LFN+8 // max size of a directory name -#define FTP_FIL_SIZE FF_MAX_LFN // max size of a file name -#define FTP_CRED_SIZE 16 // max size of username and password +#define FTP_FIL_SIZE FF_MAX_LFN // max size of a file name + +#ifndef FTP_USER_NAME_LEN + #define FTP_USER_NAME_LEN 64 + + #if (_FTP_SERVER_LOGLEVEL_ > 2) + #warning Using default FTP_USER_NAME_LEN == 64 + #endif +#else + #if (FTP_USER_NAME_LEN > 64) + #undef FTP_USER_NAME_LEN + + #define FTP_USER_NAME_LEN 64 + + #warning Forcing FTP_USER_NAME_LEN == 64 + #endif +#endif + +#ifndef FTP_USER_PWD_LEN + #define FTP_USER_PWD_LEN 128 + + #if (_FTP_SERVER_LOGLEVEL_ > 2) + #warning Using default FTP_USER_PWD_LEN == 128 + #endif +#else + #if (FTP_USER_PWD_LEN > 128) + #undef FTP_USER_PWD_LEN + + #define FTP_USER_PWD_LEN 128 + + #warning Forcing FTP_USER_PWD_LEN == 128 + #endif +#endif + #define FTP_NULLIP() IPAddress(0,0,0,0) //////////////////////////////////////////////////////////////////////////// @@ -205,8 +261,10 @@ class FtpServer uint8_t * phour, uint8_t * pminute, uint8_t * second ); char * makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ); + bool timeStamp( char * path, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second ); + bool getFileModTime( char * path, uint16_t * pdate, uint16_t * ptime ); #if FTP_FILESYST != FTP_FATFS @@ -325,8 +383,10 @@ class FtpServer char cmdLine [ FTP_CMD_SIZE ]; // where to store incoming char from client char cwdName [ FTP_CWD_SIZE ]; // name of current directory char rnfrName[ FTP_CWD_SIZE ]; // name of file for RNFR command - char user[ FTP_CRED_SIZE ]; // user name - char pass[ FTP_CRED_SIZE ]; // password + + char user[ FTP_USER_NAME_LEN ]; // user name + char pass[ FTP_USER_PWD_LEN ]; // password + char command[ 5 ]; // command sent by client bool rnfrCmd; // previous command was RNFR char * parameter; // point to begin of parameters sent by client diff --git a/src/FTP_Server_Teensy41_Config.h b/src/FTP_Server_Teensy41_Config.h index fcdca91..54048f7 100644 --- a/src/FTP_Server_Teensy41_Config.h +++ b/src/FTP_Server_Teensy41_Config.h @@ -6,12 +6,14 @@ Based on and modified from Arduino-Ftp-Server Library (https://github.com/gallegojm/Arduino-Ftp-Server) Built by Khoi Hoang https://github.com/khoih-prog/FTP_Server_Teensy41 - Version: 1.1.0 + Version: 1.2.0 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 30/04/2022 Initial porting and coding for Teensy 4.1 using built-in QNEthernet, NativeEthernet 1.1.0 K Hoang 16/05/2022 Fix bug incomplete downloads from server to client + 1.2.0 K Hoang 24/05/2022 Add support to WiFiNINA, such as Adafruit Airlift Featherwing. + Configurable user_name length to 63 and user_password to 127 ***********************************************************************************************************************/ /* @@ -56,7 +58,7 @@ // Select one of the previous files system as default #if !defined(FTP_FILESYST) - #define FTP_FILESYST FTP_SDFAT2 + #define FTP_FILESYST FTP_SDFAT2 #endif // Redirect debug info to console or other port @@ -64,19 +66,28 @@ // #define FTP_SERIAL SerialUSB // Disconnect client after 5 minutes of inactivity (expressed in seconds) -#define FTP_TIME_OUT (5 * 60) +#define FTP_TIME_OUT (5 * 60) // Wait for authentication for 10 seconds (expressed in seconds) //#define FTP_AUTH_TIME_OUT 10 -#define FTP_AUTH_TIME_OUT 60 +#define FTP_AUTH_TIME_OUT 60 // Size of file buffer for read/write // Transfer speed depends of this value // Best value depends on many factors: SD card, client side OS, ... // But it can be reduced to 512 if memory usage is critical. #if ( !defined(FTP_BUF_SIZE) || (FTP_BUF_SIZE < 2048) ) - #warning Using default FTP_BUF_SIZE = 2048 - #define FTP_BUF_SIZE 2048 //1024 // 512 + #if(_FTP_SERVER_LOGLEVEL_>2) + #warning Using default FTP_BUF_SIZE = 2048 + #endif + + #define FTP_BUF_SIZE 2048 //1024 // 512 +#endif + +#if !defined(PASV_RESPONSE_STYLE_NEW) + // True => "227 Entering Passive Mode (192,168,2,112,157,218)" + // False => "227 Entering Passive Mode (4043483328, port 55600)" + #define PASV_RESPONSE_STYLE_NEW true #endif #endif // FTP_SERVER_TEENSY41_CONFIG_H diff --git a/src/FTP_Server_Teensy41_Debug.h b/src/FTP_Server_Teensy41_Debug.h index 7619f17..97ff874 100644 --- a/src/FTP_Server_Teensy41_Debug.h +++ b/src/FTP_Server_Teensy41_Debug.h @@ -6,12 +6,14 @@ Based on and modified from Arduino-Ftp-Server Library (https://github.com/gallegojm/Arduino-Ftp-Server) Built by Khoi Hoang https://github.com/khoih-prog/FTP_Server_Teensy41 - Version: 1.1.0 + Version: 1.2.0 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 30/04/2022 Initial porting and coding for Teensy 4.1 using built-in QNEthernet, NativeEthernet 1.1.0 K Hoang 16/05/2022 Fix bug incomplete downloads from server to client + 1.2.0 K Hoang 24/05/2022 Add support to WiFiNINA, such as Adafruit Airlift Featherwing. + Configurable user_name length to 63 and user_password to 127 *****************************************************************************************************************************/ #pragma once diff --git a/src/FTP_Server_Teensy41_Impl.h b/src/FTP_Server_Teensy41_Impl.h index 8c19800..11481f3 100644 --- a/src/FTP_Server_Teensy41_Impl.h +++ b/src/FTP_Server_Teensy41_Impl.h @@ -6,12 +6,14 @@ Based on and modified from Arduino-Ftp-Server Library (https://github.com/gallegojm/Arduino-Ftp-Server) Built by Khoi Hoang https://github.com/khoih-prog/FTP_Server_Teensy41 - Version: 1.1.0 + Version: 1.2.0 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 30/04/2022 Initial porting and coding for Teensy 4.1 using built-in QNEthernet, NativeEthernet 1.1.0 K Hoang 16/05/2022 Fix bug incomplete downloads from server to client + 1.2.0 K Hoang 24/05/2022 Add support to WiFiNINA, such as Adafruit Airlift Featherwing. + Configurable user_name length to 63 and user_password to 127 ***********************************************************************************************************************/ /* @@ -139,10 +141,10 @@ void FtpServer::init( IPAddress _localIP ) void FtpServer::credentials( const char * _user, const char * _pass ) { - if ( strlen( _user ) > 0 && strlen( _user ) < FTP_CRED_SIZE ) + if ( strlen( _user ) > 0 && strlen( _user ) < FTP_USER_NAME_LEN ) strcpy( user, _user ); - if ( strlen( _pass ) > 0 && strlen( _pass ) < FTP_CRED_SIZE ) + if ( strlen( _pass ) > 0 && strlen( _pass ) < FTP_USER_PWD_LEN ) strcpy( pass, _pass ); } @@ -172,7 +174,10 @@ uint8_t FtpServer::service() if ( cmdStage == FTP_Stop ) { if ( client.connected()) + { + FTP_LOGDEBUG(F(" Client disconnected!")); disconnectClient(); + } cmdStage = FTP_Init; } @@ -188,7 +193,13 @@ uint8_t FtpServer::service() else if ( cmdStage == FTP_Client ) // Ftp server idle { if ( client && ! client.connected()) + { + FTP_LOGDEBUG(F(" Client stopped!")); + client.stop(); + } + + //FTP_LOGDEBUG(F("Accepting Client")); client = ftpServer.accept(); @@ -201,42 +212,86 @@ uint8_t FtpServer::service() } else if ( readChar() > 0 ) // got response { + FTP_LOGDEBUG(F("processCommand")); + processCommand(); if ( cmdStage == FTP_Stop ) + { + FTP_LOGDEBUG(F("Stage: FTP_Stop")); + millisEndConnection = millis() + 1000L * FTP_AUTH_TIME_OUT; // wait authentication for 10 s. + } else if ( cmdStage < FTP_Cmd ) + { + FTP_LOGDEBUG(F("Stage: cmdStage < FTP_Cmd => unrecognized command")); + millisDelay = millis() + 200; // delay of 100 ms + } else + { + FTP_LOGDEBUG(F("Stage: Connection OK, FTP_TIME_OUT = 5 minutes")); + millisEndConnection = millis() + 1000L * FTP_TIME_OUT; + } } else if ( ! client.connected() ) + { + FTP_LOGDEBUG(F("Stage: FTP_Init")); + cmdStage = FTP_Init; + } if ( transferStage == FTP_Retrieve ) // Retrieve data { + FTP_LOGDEBUG(F("transferStage: FTP_Retrieve")); + if ( ! doRetrieve()) + { + FTP_LOGDEBUG(F("transferStage: FTP_Retrieve error or done, FTP_Close")); + transferStage = FTP_Close; + } } else if ( transferStage == FTP_Store ) // Store data { + FTP_LOGDEBUG(F("transferStage: FTP_Store")); + if ( ! doStore()) + { + FTP_LOGDEBUG(F("transferStage: FTP_Store error or done, FTP_Close")); + transferStage = FTP_Close; + } } else if ( transferStage == FTP_List || transferStage == FTP_Nlst) // LIST or NLST { + FTP_LOGDEBUG(F("transferStage: FTP_List or FTP_NList")); + if ( ! doList()) + { + FTP_LOGDEBUG(F("transferStage: FTP_List error or done, FTP_Close")); + transferStage = FTP_Close; + } } else if ( transferStage == FTP_Mlsd ) // MLSD listing { + FTP_LOGDEBUG(F("transferStage: FTP_Mlsd")); + if ( ! doMlsd()) + { + FTP_LOGDEBUG(F("transferStage: FTP_Mlsd error or done, FTP_Close")); + transferStage = FTP_Close; + } } else if ( cmdStage > FTP_Client && ! ((int32_t) ( millisEndConnection - millis() ) > 0 )) { + FTP_LOGDEBUG(F("Timeout => FTP_Stop")); + FtpOutCli << F("530 Timeout") << endl; millisDelay = millis() + 200; // delay of 200 ms cmdStage = FTP_Stop; @@ -262,7 +317,7 @@ void FtpServer::clientConnected() void FtpServer::disconnectClient() { - FTP_LOGWARN(F(" Disconnecting client")); + FTP_LOGWARN(F(" Disconnecting client")); abortTransfer(); @@ -290,6 +345,8 @@ bool FtpServer::processCommand() // if ( CommandIs( "USER" )) { + FTP_LOGDEBUG(F("Got USER")); + if ( ! strcmp( parameter, user )) { FtpOutCli << F("331 Ok. Password required") << endl; @@ -307,6 +364,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "PASS" )) { + FTP_LOGDEBUG(F("Got PASS")); + if ( cmdStage != FTP_Pass ) { FtpOutCli << F("503 ") << endl; @@ -331,6 +390,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "FEAT" )) { + FTP_LOGDEBUG(F("Got FEAT")); + FtpOutCli << F("211-Extensions supported:") << endl; FtpOutCli << F(" MLST type*;modify*;size*;") << endl; FtpOutCli << F(" MLSD") << endl; @@ -344,12 +405,18 @@ bool FtpServer::processCommand() // AUTH - Not implemented // else if ( CommandIs( "AUTH" )) + { + FTP_LOGDEBUG(F("Got AUTH")); + FtpOutCli << F("502 ") << endl; + } // // Unrecognized commands at stage of authentication // else if ( cmdStage < FTP_Cmd ) { + FTP_LOGDEBUG(F("Got Unrecognized conmmand")); + FtpOutCli << F("530 ") << endl; cmdStage = FTP_Stop; @@ -366,6 +433,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "PWD" ) || ( CommandIs( "CWD" ) && ParameterIs( "." ))) { + FTP_LOGDEBUG(F("Got PWD or CWD .")); + FtpOutCli << F("257 \"") << cwdName << F("\"") << F(" is your current directory") << endl; } // @@ -373,6 +442,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "CDUP" ) || ( CommandIs( "CWD" ) && ParameterIs( ".." ))) { + FTP_LOGDEBUG(F("Got CDUP or CWD ..")); + bool ok = false; if ( strlen( cwdName ) > 1 ) // do nothing if cwdName is root @@ -404,6 +475,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "CWD" )) { + FTP_LOGDEBUG(F("Got CWD")); + char path[ FTP_CWD_SIZE ]; if ( haveParameter() && makeExistsPath( path )) @@ -418,6 +491,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "QUIT" )) { + FTP_LOGDEBUG(F("Got QUIT")); + FtpOutCli << F("221 Goodbye") << endl; disconnectClient(); @@ -435,6 +510,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "MODE" )) { + FTP_LOGDEBUG(F("Got MODE")); + if ( ParameterIs( "S" )) FtpOutCli << F("200 S Ok") << endl; else @@ -445,11 +522,13 @@ bool FtpServer::processCommand() // else if ( CommandIs( "PASV" )) { + FTP_LOGDEBUG(F("Got PASV")); + data.stop(); dataServer.begin(); - if ((((uint32_t) FTP_LOCALIP()) & ((uint32_t) Ethernet.subnetMask())) == - (((uint32_t) client.remoteIP()) & ((uint32_t) Ethernet.subnetMask()))) + if ((((uint32_t) FTP_LOCALIP()) & ((uint32_t) FTP_NETWORK.subnetMask())) == + (((uint32_t) client.remoteIP()) & ((uint32_t) FTP_NETWORK.subnetMask()))) dataIp = FTP_LOCALIP(); else dataIp = localIp; @@ -459,8 +538,27 @@ bool FtpServer::processCommand() FTP_LOGWARN(F(" Connection management set to passive")); FTP_LOGWARN3(F(" Listening at "), dataIp, F(":"), dataPort); - FtpOutCli << F("227 Entering Passive Mode") << F(" (") +#if PASV_RESPONSE_STYLE_NEW + // "227 Entering Passive Mode (192,168,2,241,217,48)" + //uint8_t* rawDataIP = dataIp.raw_address(); + FTP_LOGDEBUG0(F("227 Entering Passive Mode (")); + FTP_LOGDEBUG0(dataIp[0]); FTP_LOGDEBUG0(','); + FTP_LOGDEBUG0(dataIp[1]); FTP_LOGDEBUG0(','); + FTP_LOGDEBUG0(dataIp[2]); FTP_LOGDEBUG0(','); + FTP_LOGDEBUG0(dataIp[3]); FTP_LOGDEBUG0(','); + FTP_LOGDEBUG0(dataPort >> 8); FTP_LOGDEBUG0(','); + FTP_LOGDEBUG0(dataPort & 0xFF); FTP_LOGDEBUG0(")\n"); + + FtpOutCli << F("227 Entering Passive Mode (") + << dataIp[0] << ',' << dataIp[1] << ',' << dataIp[2] << ',' << dataIp[3] << ',' + << (dataPort >> 8) << ',' << (dataPort & 0xFF) << F(")") << endl; +#else + + // "227 Entering Passive Mode (4043483328, port 55600)" + FtpOutCli << F("227 Entering Passive Mode (") << dataIp << F(", port ") << dataPort << F(")") << endl; + +#endif dataConn = FTP_Pasive; } @@ -469,6 +567,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "PORT" )) { + FTP_LOGDEBUG(F("Got PORT")); + data.stop(); // get IP of data client dataIp[ 0 ] = atoi( parameter ); @@ -500,6 +600,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "STRU" )) { + FTP_LOGDEBUG(F("Got STRU")); + if ( ParameterIs( "F" )) FtpOutCli << F("200 F Ok") << endl; // else if( ParameterIs( "R" )) @@ -512,6 +614,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "TYPE" )) { + FTP_LOGDEBUG(F("Got TYPE")); + if ( ParameterIs( "A" )) FtpOutCli << F("200 TYPE is now ASCII") << endl; else if ( ParameterIs( "I" )) @@ -531,6 +635,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "ABOR" )) { + FTP_LOGDEBUG(F("Got ABOR")); + abortTransfer(); FtpOutCli << F("226 Data connection closed") << endl; } @@ -539,6 +645,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "DELE" )) { + FTP_LOGDEBUG(F("Got DELE")); + char path[ FTP_CWD_SIZE ]; if ( haveParameter() && makeExistsPath( path )) @@ -556,6 +664,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "LIST" ) || CommandIs( "NLST" ) || CommandIs( "MLSD" )) { + FTP_LOGDEBUG(F("Got LIST or NLST or MLSD")); + if ( dataConnect()) { if ( openDir( & dir )) @@ -578,6 +688,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "MLST" )) { + FTP_LOGDEBUG(F("Got MLST")); + char path[ FTP_CWD_SIZE ]; uint16_t dat, tim; char dtStr[ 15 ]; @@ -612,12 +724,18 @@ bool FtpServer::processCommand() // NOOP // else if ( CommandIs( "NOOP" )) + { + FTP_LOGDEBUG(F("Got NOOP")); + FtpOutCli << F("200 Zzz...") << endl; + } // // RETR - Retrieve // else if ( CommandIs( "RETR" )) { + FTP_LOGDEBUG(F("Got RETR")); + char path[ FTP_CWD_SIZE ]; if ( haveParameter() && makeExistsPath( path )) @@ -643,6 +761,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "STOR" ) || CommandIs( "APPE" )) { + FTP_LOGDEBUG(F("Got STOR or APPE")); + char path[ FTP_CWD_SIZE ]; if ( haveParameter() && makePath( path )) @@ -673,6 +793,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "MKD" )) { + FTP_LOGDEBUG(F("Got MKD")); + char path[ FTP_CWD_SIZE ]; if ( haveParameter() && makePath( path )) @@ -695,6 +817,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "RMD" )) { + FTP_LOGDEBUG(F("Got RMD")); + char path[ FTP_CWD_SIZE ]; if ( haveParameter() && makeExistsPath( path )) @@ -714,6 +838,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "RNFR" )) { + FTP_LOGDEBUG(F("Got RNFR")); + rnfrName[ 0 ] = 0; if ( haveParameter() && makeExistsPath( rnfrName )) @@ -729,6 +855,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "RNTO" )) { + FTP_LOGDEBUG(F("Got RNTO")); + char path[ FTP_CWD_SIZE ]; char dirp[ FTP_FIL_SIZE ]; @@ -791,6 +919,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "MDTM" ) || CommandIs( "MFMT" )) { + FTP_LOGDEBUG(F("Got MDTM or MFTM")); + if ( haveParameter()) { char path[ FTP_CWD_SIZE ]; @@ -833,6 +963,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "SIZE" )) { + FTP_LOGDEBUG(F("Got SIZE")); + char path[ FTP_CWD_SIZE ]; if ( haveParameter() && makeExistsPath( path )) @@ -851,6 +983,8 @@ bool FtpServer::processCommand() // else if ( CommandIs( "SITE" )) { + FTP_LOGDEBUG(F("Got SITE")); + if ( ParameterIs( "FREE" )) { uint32_t capa = capacity(); @@ -869,7 +1003,11 @@ bool FtpServer::processCommand() // Unrecognized commands ... // else + { + FTP_LOGDEBUG(F("Got Unknown Command")); + FtpOutCli << F("500 Unknown command") << endl; + } return true; } @@ -909,7 +1047,9 @@ bool FtpServer::dataConnected() { if ( data.connected()) return true; - + + FTP_LOGDEBUG(F("dataConnected: error, stop => FTP_Close")); + data.stop(); FtpOutCli << F("426 Data connection closed. Transfer aborted") << endl; transferStage = FTP_Close; @@ -1069,6 +1209,8 @@ bool FtpServer::doMlsd() { if ( ! dataConnected()) { + FTP_LOGDEBUG(F("doMlsd: !dataConnected")); + dir.close(); return false; } @@ -1078,6 +1220,7 @@ bool FtpServer::doMlsd() if ( dir.nextFile()) { char dtStr[ 15 ]; + FtpOutData << F("Type=") << ( dir.isDir() ? F("dir") : F("file")) << F(";Modify=") << makeDateTimeStr( dtStr, dir.fileModDate(), dir.fileModTime()) << F(";Size=") << long( dir.fileSize()) @@ -1106,6 +1249,8 @@ bool FtpServer::doMlsd() } file.close(); + + FTP_LOGDEBUG1(F("doMlsd: done, return gfmt = "), gfmt? "true" : "false"); return gfmt; } @@ -1116,6 +1261,8 @@ bool FtpServer::doMlsd() FtpOutCli << F("226 ") << nbMatch << F(" matches total") << endl; dir.close(); data.stop(); + + FTP_LOGDEBUG(F("doMlsd: done, stop data connection")); return false; } @@ -1149,6 +1296,7 @@ void FtpServer::abortTransfer() { file.close(); dir.close(); + FtpOutCli << F("426 Transfer aborted") << endl; FTP_LOGWARN(F(" Transfer aborted!")); @@ -1398,7 +1546,7 @@ uint8_t FtpServer::getDateTime( char * dt, uint16_t * pyear, uint8_t * pmonth, u strncpy( dt, parameter, 14 ); - FTP_LOGWARN1(F(" File: "), (char *) ( parameter + i )); + FTP_LOGWARN1(F(" File: "), (char *) ( parameter + i )); FTP_LOGWARN5(F(" Modification time yy/mm/dd: "), int (* pyear), F("/"), int (* pmonth), F("/"), int (* pday)); FTP_LOGWARN5(F(" Modification time hh:mm:ss: "), int (* phour), F(":"), int (* pminute), F(":"), int (* psecond)); @@ -1425,6 +1573,8 @@ char * FtpServer::makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ) return tstr; } +//////////////////////////////////////////////////////////////////////////// + // Return true if path points to a directory bool FtpServer::isDir( char * path )