Arduino TinyFTP
ArduinoFTPClient.h
Go to the documentation of this file.
1 
33 #pragma once
34 
35 #include "Arduino.h"
36 #include "Client.h"
37 #include "IPAddress.h"
38 #include "Stream.h"
39 
40 #ifndef FTP_USE_NAMESPACE
41 # define FTP_USE_NAMESPACE true
42 #endif
43 
44 namespace ftp_client {
45 
46 // Common Constants
47 static const int MAXFILE_NAME_LENGTH = 512;
48 static const int COMMAND_PORT = 21;
49 static const int DATA_PORT = 1000;
50 
52 enum FileMode { READ_MODE, WRITE_MODE, WRITE_APPEND_MODE };
53 enum CurrentOperation { READ_OP, WRITE_OP, LS_OP, NOP };
54 enum LogLevel { LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR };
55 enum ObjectType { TypeFile, TypeDirectory, TypeUndefined };
56 
57 // // Allow simple constructor on ESP32
58 // #if defined(ESP32)
59 // #include "WiFi.h"
60 // #define FTP_DEFAULT_CLIENT WiFiClient
61 // #endif
62 
69 public:
70  static int findNthInStr(char *str, char ch, int n) {
71  int occur = 0;
72  // Loop to find the Nth
73  // occurence of the character
74  for (unsigned int i = 0; i < strlen(str); i++) {
75  if (str[i] == ch) {
76  occur += 1;
77  }
78  if (occur == n)
79  return i;
80  }
81  return -1;
82  }
83 
84  static int readln(Stream &stream, char *str, int maxLen) {
85  int len = 0;
86  if (maxLen > stream.available()) {
87  maxLen = stream.available();
88  }
89  for (int j = 0; j < maxLen; j++) {
90  len = j;
91  char c = stream.read();
92  if (c == 0 || c == '\n') {
93  break;
94  }
95  str[j] = c;
96  }
97  memset(str + len, 0, maxLen - len);
98  return len;
99  }
100 };
101 
107 class FTPLogger {
108 public:
109  static void setLogLevel(LogLevel level);
110  static LogLevel getLogLevel();
111  static void setOutput(Stream &out);
112  static void writeLog(LogLevel level, const char *module,
113  const char *msg = nullptr);
114 
115 protected:
116  static LogLevel min_log_level;
117  static Stream *out_ptr;
118 };
119 
127 class FTPBasicAPI {
128  friend class FTPFile;
129 
130 public:
131  FTPBasicAPI();
132  ~FTPBasicAPI();
133  virtual bool open(Client *cmd, Client *dat, IPAddress &address, int port,
134  int data_port, const char *username, const char *password);
135  virtual bool quit();
136  virtual bool connected();
137  virtual bool passv();
138  virtual bool binary();
139  virtual bool ascii();
140  virtual bool type(const char *type);
141  virtual bool del(const char *file);
142  virtual bool mkdir(const char *dir);
143  virtual bool rmd(const char *dir);
144  virtual bool abort();
145  virtual Stream *read(const char *file_name);
146  virtual Stream *write(const char *file_name, FileMode mode);
147  virtual Stream *ls(const char *file_name);
148  virtual void closeData();
149  virtual void setCurrentOperation(CurrentOperation op);
150  virtual CurrentOperation currentOperation() { return current_operation; }
151  virtual void flush();
152  virtual size_t size(const char *dir);
153  virtual ObjectType objectType(const char *file);
154 
155 protected:
156  virtual bool connect(IPAddress adr, int port, Client *client,
157  bool doCheckResult = false);
158  virtual bool cmd(const char *command, const char *par, const char *expected,
159  bool wait_for_data = true);
160  virtual bool cmd(const char *command_str, const char *par,
161  const char *expected[], bool wait_for_data = true);
162  virtual void checkClosed(Client *stream);
163  virtual bool checkResult(const char *expected[], const char *command_for_log,
164  bool wait_for_data = true);
165 
166  CurrentOperation current_operation =
167  NOP; // currently running op -> do we need to cancel ?
168 // #if defined(FTP_DEFAULT_CLIENT)
169 // FTP_DEFAULT_CLIENT default_cmd;
170 // FTP_DEFAULT_CLIENT default_data;
171 // Client *command_ptr = &default_cmd; // Client for commands
172 // Client *data_ptr = &default_data; // Client for upload and download of files
173 // #else
174  Client *command_ptr = nullptr; // Client for commands
175  Client *data_ptr = nullptr; // Client for upload and download of files
176 //#endif
177  IPAddress remote_address;
178  bool is_open;
179  char result_reply[80];
180 };
181 
190 class FTPFile : public Stream {
191 public:
192  FTPFile() = default;
193  FTPFile(FTPBasicAPI *api_ptr, const char *name, FileMode mode);
194  FTPFile(FTPFile &cpy);
195  FTPFile(FTPFile &&move);
196  ~FTPFile();
197  FTPFile &operator=(const FTPFile &);
198  virtual size_t write(uint8_t data);
199  virtual size_t write(char *data, int len);
200  virtual int read();
201  virtual int read(void *buf, size_t nbyte);
202  virtual int readln(void *buf, size_t nbyte);
203 
204  virtual int peek();
205  virtual int available();
206  virtual void flush();
207  virtual void close();
208  virtual const char *name();
209  virtual size_t size();
210  virtual void setEOL(char *eol);
211  virtual bool isDirectory();
212 
213 protected:
214  const char *file_name;
215  const char *eol = "\n";
216  FileMode mode;
217  FTPBasicAPI *api_ptr;
218  ObjectType object_type = TypeUndefined;
219 };
220 
229 public:
230  FTPFileIterator(FTPBasicAPI *api, const char *dir, FileMode mode);
233  ~FTPFileIterator();
234  virtual FTPFileIterator &begin();
235  virtual FTPFileIterator end();
236  virtual FTPFileIterator &operator++();
237  virtual FTPFileIterator &operator++(int _na);
238  virtual FTPFile operator*();
239  virtual bool operator!=(const FTPFileIterator &comp) {
240  return strcmp(this->buffer, comp.buffer) != 0;
241  }
242  virtual bool operator>(const FTPFileIterator &comp) {
243  return strcmp(this->buffer, comp.buffer) > 0;
244  }
245  virtual bool operator<(const FTPFileIterator &comp) {
246  return strcmp(this->buffer, comp.buffer) < 0;
247  }
248  virtual bool operator>=(const FTPFileIterator &comp) {
249  return strcmp(this->buffer, comp.buffer) >= 0;
250  }
251  virtual bool operator<=(const FTPFileIterator &comp) {
252  return strcmp(this->buffer, comp.buffer) <= 0;
253  }
254 
255 protected:
256  virtual void readLine();
257 
258  FTPBasicAPI *api_ptr;
259  Stream *stream_ptr;
260  FileMode file_mode;
261  const char *directory_name = "";
262  char buffer[MAXFILE_NAME_LENGTH];
263 };
264 
271 class FTPClient {
272 public:
274  FTPClient(Client &command, Client &data, int port = COMMAND_PORT,
275  int data_port = DATA_PORT);
276 // #if defined(FTP_DEFAULT_CLIENT)
277 // /// simplified constructor
278 // FTPClient(int port = COMMAND_PORT, int data_port = DATA_PORT);
279 // #endif
281  virtual bool begin(IPAddress remote_addr, const char *user = "anonymous",
282  const char *password = nullptr);
285  virtual bool end();
287  virtual FTPFile &open(const char *filename, FileMode mode = READ_MODE);
290  virtual bool mkdir(const char *filepath);
292  virtual bool remove(const char *filepath);
294  virtual bool rmdir(const char *filepath);
296  virtual FTPFileIterator ls(const char *path, FileMode mode = WRITE_MODE);
298  virtual bool binary() { return api.binary();}
300  virtual bool ascii() { return api.ascii();}
302  virtual bool type(const char *str) { return api.type(str);}
303 
304 protected:
305  void init(Client *command, Client *data, int port = COMMAND_PORT,
306  int data_port = DATA_PORT);
307  FTPBasicAPI api;
308  Client *command_ptr = nullptr;
309  Client *data_ptr = nullptr;
310  IPAddress remote_addr;
311  const char *userid = nullptr;
312  const char *password = nullptr;
313  int port;
314  int data_port;
315  bool cleanup_clients;
316 };
317 
318 } // ns
319 
320 #if FTP_USE_NAMESPACE
321 using namespace ftp_client;
322 #endif
FileMode
File Mode.
Definition: ArduinoFTPClient.h:52
CStringFunctions We implemented some missing C based string functions for character arrays.
Definition: ArduinoFTPClient.h:68
FTPBasicAPI Implementation of Low Level FTP protocol. In order to simplify the logic we always use Pa...
Definition: ArduinoFTPClient.h:127
FTPBasicAPI()
FTPBasicAPI Implementation of Low Level FTP protocol. In order to simplify the logic we always use Pa...
Definition: ArduinoFTPClient.cpp:61
FTPClient Basic FTP access class which supports directory operatations and the opening of a files.
Definition: ArduinoFTPClient.h:271
virtual bool ascii()
Switch to ascii mode.
Definition: ArduinoFTPClient.h:300
virtual bool type(const char *str)
Binary or ascii with type command.
Definition: ArduinoFTPClient.h:302
virtual bool begin(IPAddress remote_addr, const char *user="anonymous", const char *password=nullptr)
opens the ftp connection
Definition: ArduinoFTPClient.cpp:502
virtual bool end()
Definition: ArduinoFTPClient.cpp:512
virtual bool binary()
Switch to binary mode.
Definition: ArduinoFTPClient.h:298
virtual bool remove(const char *filepath)
Delete the file.
Definition: ArduinoFTPClient.cpp:531
FTPClient(Client &command, Client &data, int port=COMMAND_PORT, int data_port=DATA_PORT)
default construcotr
Definition: ArduinoFTPClient.cpp:479
virtual bool mkdir(const char *filepath)
Definition: ArduinoFTPClient.cpp:525
virtual FTPFileIterator ls(const char *path, FileMode mode=WRITE_MODE)
lists all file names in the specified directory
Definition: ArduinoFTPClient.cpp:543
virtual bool rmdir(const char *filepath)
Removes a directory.
Definition: ArduinoFTPClient.cpp:537
virtual FTPFile & open(const char *filename, FileMode mode=READ_MODE)
get the file
Definition: ArduinoFTPClient.cpp:518
FTPFile A single file which supports read and write operations. This class is implemented as an Ardui...
Definition: ArduinoFTPClient.h:190
FTPFileIterator The file name iterator can be used to list all available files and directories....
Definition: ArduinoFTPClient.h:228
FTPFileIterator(FTPBasicAPI *api, const char *dir, FileMode mode)
FTPFileIterator The file name iterator can be used to list all available files and directories....
Definition: ArduinoFTPClient.cpp:556
FTPLogger To activate logging define the output stream e.g. with FTPLogger.setOutput(Serial); and (op...
Definition: ArduinoFTPClient.h:107
static void setLogLevel(LogLevel level)
FTPLogger To activate logging define the output stream e.g. with FTPLogger.setOutput(Serial); and opt...
Definition: ArduinoFTPClient.cpp:12