21 FTPBasicAPI() { FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI"); }
23 ~
FTPBasicAPI() { FTPLogger::writeLog(LOG_DEBUG,
"~FTPBasicAPI"); }
25 bool begin(Client *cmdPar, Client *dataPar, IPAddress &address,
int port,
26 const char *username,
const char *password) {
27 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI ",
"open");
30 remote_address = address;
32 if (!connect(address, port, command_ptr,
true))
return false;
33 if (username !=
nullptr) {
34 const char *ok_result[] = {
"331",
"230",
"530",
nullptr};
35 if (!cmd(
"USER", username, ok_result))
return false;
37 if (password !=
nullptr) {
38 const char *ok_result[] = {
"230",
"202",
nullptr};
39 if (!cmd(
"PASS", password, ok_result))
return false;
48 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"quit");
49 const char *ok_result[] = {
"221",
"226",
nullptr};
50 bool result = cmd(
"QUIT",
nullptr, ok_result,
false);
52 result = cmd(
"BYE",
nullptr, ok_result,
false);
55 result = cmd(
"DISCONNECT",
nullptr, ok_result,
false);
60 bool connected() {
return is_open; }
62 operator bool() {
return is_open; }
65 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"passv");
66 bool ok = cmd(
"PASV",
nullptr,
"227");
69 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::passv", result_reply);
71 int start1 = CStringFunctions::findNthInStr(result_reply,
',', 4) + 1;
72 int p1 = atoi(result_reply + start1);
74 sprintf(buffer,
"*** port1 -> %d ", p1);
75 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::passv", buffer);
77 int start2 = CStringFunctions::findNthInStr(result_reply,
',', 5) + 1;
78 int p2 = atoi(result_reply + start2);
80 sprintf(buffer,
"*** port2 -> %d ", p2);
81 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::passv", buffer);
83 int dataPort = (p1 * 256) + p2;
84 sprintf(buffer,
"*** data port: %d", dataPort);
85 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::passv", buffer);
87 ok = connect(remote_address, dataPort, data_ptr) == 1;
92 bool del(
const char *file) {
93 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"del");
94 return cmd(
"DELE", file,
"250");
97 bool mkdir(
const char *dir) {
98 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"mkdir");
99 return cmd(
"MKD", dir,
"257");
102 bool rmd(
const char *dir) {
103 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"rd");
104 return cmd(
"RMD", dir,
"250");
107 size_t size(
const char *file) {
108 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"size");
109 if (cmd(
"SIZE", file,
"213")) {
110 return atol(result_reply + 4);
115 ObjectType objectType(
const char *file) {
116 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"objectType");
117 const char *ok_result[] = {
"213",
"550",
nullptr};
118 ObjectType result = TypeDirectory;
119 if (cmd(
"SIZE", file, ok_result)) {
120 if (strncmp(result_reply,
"213", 3) == 0) {
129 if (current_operation == READ_OP || current_operation == WRITE_OP ||
130 current_operation == LS_OP) {
131 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"abort");
134 const char *ok[] = {
"426",
"226",
"225",
nullptr};
135 setCurrentOperation(NOP);
136 rc = cmd(
"ABOR",
nullptr, ok);
137 delay(FTP_ABORT_DELAY_MS);
138 while (command_ptr->available() > 0) {
146 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"binary");
147 return cmd(
"BIN",
nullptr,
"200");
151 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"ascii");
152 return cmd(
"ASC",
nullptr,
"200");
155 bool type(
const char *txt) {
156 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"type");
157 return cmd(
"TYPE", txt,
"200");
160 Stream *read(
const char *file_name) {
161 if (current_operation != READ_OP) {
162 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"read");
163 const char *ok[] = {
"150",
"125",
nullptr};
164 cmd(
"RETR", file_name, ok);
165 setCurrentOperation(READ_OP);
170 Stream *write(
const char *file_name, FileMode mode) {
171 if (current_operation != WRITE_OP) {
172 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"write");
173 const char *ok_write[] = {
"125",
"150",
nullptr};
174 cmd(mode == WRITE_APPEND_MODE ?
"APPE" :
"STOR", file_name, ok_write);
175 setCurrentOperation(WRITE_OP);
180 Stream *ls(
const char *file_name) {
181 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"ls");
182 const char *ok[] = {
"125",
"150",
nullptr};
183 cmd(
"NLST", file_name, ok);
184 setCurrentOperation(LS_OP);
189 FTPLogger::writeLog(LOG_INFO,
"FTPBasicAPI",
"closeData");
196 void setCurrentOperation(CurrentOperation op) {
198 sprintf(msg,
"setCurrentOperation: %d", (
int)op);
199 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI", msg);
200 current_operation = op;
203 CurrentOperation currentOperation() {
return current_operation; }
206 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"flush");
210 bool checkResult(
const char *expected[],
const char *command,
211 bool wait_for_data =
true) {
214 result_reply[0] =
'\0';
215 Stream *stream_ptr = command_ptr;
217 char result_str[FTP_RESULT_BUFFER_SIZE];
218 if (wait_for_data || stream_ptr->available()) {
220 while (stream_ptr->available() == 0) {
225 CStringFunctions::readln(*stream_ptr, result_str, FTP_RESULT_BUFFER_SIZE);
227 if (strlen(result_str) > 3) {
228 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::checkResult", result_str);
229 strncpy(result_reply, result_str,
sizeof(result_reply) - 1);
231 if (expected[0] ==
nullptr) {
233 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::checkResult",
234 "success because of not expected result codes");
238 for (
int j = 0; expected[j] !=
nullptr; j++) {
239 sprintf(msg,
"- checking with %s", expected[j]);
240 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::checkResult", msg);
241 if (strncmp(result_str, expected[j], 3) == 0) {
242 sprintf(msg,
" -> success with %s", expected[j]);
243 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::checkResult", msg);
251 if (!wait_for_data) ok =
true;
259 FTPLogger::writeLog(LOG_ERROR,
"FTPBasicAPI::checkResult", command);
260 FTPLogger::writeLog(LOG_ERROR,
"FTPBasicAPI::checkResult", result_reply);
265 bool cmd(
const char *command,
const char *par,
const char *expected,
266 bool wait_for_data =
true) {
267 const char *expected_array[] = {expected,
nullptr};
268 return cmd(command, par, expected_array, wait_for_data);
271 bool cmd(
const char *command_str,
const char *par,
const char *expected[],
272 bool wait_for_data =
true) {
273 char command_buffer[FTP_COMMAND_BUFFER_SIZE];
274 Stream *stream_ptr = command_ptr;
275 if (par ==
nullptr) {
276 strncpy(command_buffer, command_str, FTP_COMMAND_BUFFER_SIZE);
277 stream_ptr->println(command_buffer);
279 snprintf(command_buffer, FTP_COMMAND_BUFFER_SIZE,
"%s %s", command_str,
281 stream_ptr->println(command_buffer);
283 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::cmd", command_buffer);
285 return checkResult(expected, command_buffer, wait_for_data);
290 CurrentOperation current_operation = NOP;
291 Client *command_ptr =
nullptr;
292 Client *data_ptr =
nullptr;
293 IPAddress remote_address;
295 char result_reply[100];
297 bool connect(IPAddress adr,
int port, Client *client_ptr,
298 bool doCheckResult =
false) {
301 #if defined(ESP32) || defined(ESP8266)
302 sprintf(buffer,
"connect %s:%d", adr.toString().c_str(), port);
303 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::connect", buffer);
306 if (client_ptr->connected()) client_ptr->stop();
307 for (
int j = 0; j < 10; j++) {
308 ok = client_ptr->connect(adr, port);
313 ok = client_ptr->connected();
314 if (ok && doCheckResult) {
315 const char *ok_result[] = {
"220",
"200",
nullptr};
316 ok = checkResult(ok_result,
"connect");
320 while (command_ptr->available() > 0) {
326 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::connected", buffer);
328 FTPLogger::writeLog(LOG_ERROR,
"FTPBasicAPI::connected", buffer);
FTPBasicAPI Implementation of Low Level FTP protocol. In order to simplify the logic we always use Pa...
Definition: FTPBasicAPI.h:17
FTPFile A single file which supports read and write operations. This class is implemented as an Ardui...
Definition: FTPFile.h:16