summaryrefslogtreecommitdiffstats
path: root/espFtpServer.h
blob: 2f3e329e31602738a80d30dfd97f74cc0b3e467a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
 * FTP SERVER FOR ESP8266/ESP32
 * based on FTP Serveur for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200)
 * based on Jean-Michel Gallego's work
 * modified to work with esp8266 SPIFFS by David Paiva (david@nailbuster.com)
 * modified to work with esp8266 LitteFS by Daniel Plasa dplasa@gmail.com
 * Also done some code reworks and all string contants are now in flash memory 
 * by using F(), PSTR() ... on the string literals.  
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef ESP_FTP_SERVER_H
#define ESP_FTP_SERVER_H

#include <WiFiClient.h>
#include <FS.h>

/*******************************************************************************
 **                                                                            **
 **                       DEFINITIONS FOR FTP SERVER                           **
 **                                                                            **
 *******************************************************************************/

//
// DEBUG via Serial Console
//  Please select in your Arduino IDE menu Tools->Debug Port to enable debugging.
//  (This will provide DEBUG_ESP_PORT at compile time.)
//

// Use ESP8266 Core Debug functionality
#ifdef DEBUG_ESP_PORT
#define FTP_DEBUG_MSG(fmt, ...)                                      \
  do                                                                 \
  {                                                                  \
    DEBUG_ESP_PORT.printf_P(PSTR("[FTP] " fmt "\n"), ##__VA_ARGS__); \
    yield();                                                         \
  } while (0)
#else
#define FTP_DEBUG_MSG(...)
#endif

#define FTP_SERVER_VERSION "0.9-20200525"

#define FTP_CTRL_PORT 21         // Command port on wich server is listening
#define FTP_DATA_PORT_PASV 50009 // Data port in passive mode
#define FTP_TIME_OUT 5           // Disconnect client after 5 minutes of inactivity
#define FTP_CMD_SIZE 127         // allow max. 127 chars in a received command

class FtpServer
{
public:
  // contruct an instance of the FTP server using a
  // given FS object, e.g. SPIFFS or LittleFS
  FtpServer(FS &_FSImplementation);

  // starts the FTP server with username and password,
  // either one can be empty to enable anonymous ftp
  void begin(const String &uname, const String &pword);

  // stops the FTP server
  void stop();

  // set the FTP server's timeout in seconds
  void setTimeout(uint16_t timeout = FTP_TIME_OUT * 60);

  // needs to be called frequently (e.g. in loop() )
  // to process ftp requests
  void handleFTP();

private:
  FS &THEFS;

  enum internalState
  {
    cInit = 0,
    cWait,
    cCheck,
    cUserId,
    cPassword,
    cLoginOk,
    cProcess,

    tIdle,
    tRetrieve,
    tStore
  };
  void iniVariables();
  void disconnectClient(bool gracious = true);
  int8_t processCommand();
  int8_t dataConnect();

  bool doRetrieve();
  bool doStore();
  void closeTransfer();
  void abortTransfer();
  int32_t allocateBuffer(int32_t desiredBytes);
  void freeBuffer();

  String getPathName(const String& param, bool includeLast = false);
  String getFileName(const String &param, bool fullFilePath = false);
  String makeDateTimeStr(time_t fileTime);
  int8_t readChar();
  void updateTimeout(uint16_t timeout);

  WiFiClient control;
  WiFiClient data;

  File file;

  bool dataPassiveConn = true; // PASV (passive) mode is our default
  IPAddress dataIP;            // IP address for PORT (active) mode
  uint16_t dataPort =          // holds our PASV port number or the port number provided by PORT
      FTP_DATA_PORT_PASV;

  uint32_t command;       // numeric command code of command sent by the client
  String cmdLine;         // command line as read from client
  String cmdString;       // command as textual representation
  String parameters;      // parameters sent by client
  String cwd;             // the current directory
  String rnFrom;          // previous command was RNFR, this is the source file name

  internalState cmdState, // state of ftp control connection
      transferState;      // state of ftp data connection
  uint16_t sTimeOut =     // disconnect after 5 min of inactivity
      FTP_TIME_OUT * 60;
  uint32_t millisEndConnection, //
      millisBeginTrans,         // store time of beginning of a transaction
      bytesTransfered;          //
  uint8_t *fileBuffer = NULL;   // pointer to buffer for file transfer (by allocateBuffer)
  int32_t fileBufferSize;       // size of buffer
  String _FTP_USER;             // usename
  String _FTP_PASS;             // password
};

#endif // ESP_FTP_SERVER_H