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;
43 const char *ok_result[] = {
"200",
nullptr};
44 cmd(
"OPTS",
"UTF8", ok_result);
50 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"quit");
51 const char *ok_result[] = {
"221",
"226",
nullptr};
52 bool result = cmd(
"QUIT",
nullptr, ok_result,
false);
54 result = cmd(
"BYE",
nullptr, ok_result,
false);
57 result = cmd(
"DISCONNECT",
nullptr, ok_result,
false);
62 bool connected() {
return is_open; }
64 operator bool() {
return is_open; }
67 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"passv");
68 bool ok = cmd(
"PASV",
nullptr,
"227");
71 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::passv", result_reply);
73 int start1 = CStringFunctions::findNthInStr(result_reply,
',', 4) + 1;
74 int p1 = atoi(result_reply + start1);
76 sprintf(buffer,
"*** port1 -> %d ", p1);
77 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::passv", buffer);
79 int start2 = CStringFunctions::findNthInStr(result_reply,
',', 5) + 1;
80 int p2 = atoi(result_reply + start2);
82 sprintf(buffer,
"*** port2 -> %d ", p2);
83 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::passv", buffer);
85 int dataPort = (p1 * 256) + p2;
86 sprintf(buffer,
"*** data port: %d", dataPort);
87 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::passv", buffer);
89 ok = connect(remote_address, dataPort, data_ptr) == 1;
94 bool del(
const char *file) {
95 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"del");
96 return cmd(
"DELE", file,
"250");
99 bool mkdir(
const char *dir) {
100 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"mkdir");
101 return cmd(
"MKD", dir,
"257");
104 bool rmd(
const char *dir) {
105 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"rd");
106 return cmd(
"RMD", dir,
"250");
109 size_t size(
const char *file) {
110 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"size");
111 if (cmd(
"SIZE", file,
"213")) {
112 return atol(result_reply + 4);
117 ObjectType objectType(
const char *file) {
118 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"objectType");
119 const char *ok_result[] = {
"213",
"550",
nullptr};
120 ObjectType result = TypeDirectory;
121 if (cmd(
"SIZE", file, ok_result)) {
122 if (strncmp(result_reply,
"213", 3) == 0) {
131 if (current_operation == READ_OP || current_operation == WRITE_OP ||
132 current_operation == LS_OP) {
133 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"abort");
136 const char *ok[] = {
"426",
"226",
"225",
nullptr};
137 setCurrentOperation(NOP);
138 rc = cmd(
"ABOR",
nullptr, ok);
139 delay(FTP_ABORT_DELAY_MS);
140 while (command_ptr->available() > 0) {
148 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"binary");
149 const char *type_cmd = use_type ?
"TYPE I" :
"BIN";
150 return cmd(type_cmd,
nullptr,
"200");
154 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"ascii");
155 const char *type_cmd = use_type ?
"TYPE A" :
"ASC";
156 return cmd(type_cmd,
nullptr,
"200");
159 bool type(
const char *txt) {
160 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"type");
161 return cmd(
"TYPE", txt,
"200");
164 Stream *read(
const char *file_name) {
165 if (current_operation != READ_OP) {
166 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"read");
167 const char *ok[] = {
"150",
"125",
nullptr};
168 cmd(
"RETR", file_name, ok);
169 setCurrentOperation(READ_OP);
174 Stream *write(
const char *file_name, FileMode mode) {
175 if (current_operation != WRITE_OP) {
176 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"write");
177 const char *ok_write[] = {
"125",
"150",
nullptr};
178 cmd(mode == WRITE_APPEND_MODE ?
"APPE" :
"STOR", file_name, ok_write);
179 setCurrentOperation(WRITE_OP);
184 Stream *ls(
const char *file_name) {
185 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"ls");
186 const char *ok[] = {
"125",
"150",
nullptr};
187 cmd(
"NLST", file_name, ok);
188 setCurrentOperation(LS_OP);
193 FTPLogger::writeLog(LOG_INFO,
"FTPBasicAPI",
"closeData");
200 void setCurrentOperation(CurrentOperation op) {
202 sprintf(msg,
"setCurrentOperation: %d", (
int)op);
203 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI", msg);
204 current_operation = op;
207 CurrentOperation currentOperation() {
return current_operation; }
210 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI",
"flush");
214 bool checkResult(
const char *expected[],
const char *command,
215 bool wait_for_data =
true) {
218 result_reply[0] =
'\0';
219 Stream *stream_ptr = command_ptr;
221 char result_str[FTP_RESULT_BUFFER_SIZE];
222 if (wait_for_data || stream_ptr->available()) {
224 while (stream_ptr->available() == 0) {
229 CStringFunctions::readln(*stream_ptr, result_str, FTP_RESULT_BUFFER_SIZE);
231 if (strlen(result_str) > 3) {
232 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::checkResult", result_str);
233 strncpy(result_reply, result_str,
sizeof(result_reply) - 1);
235 if (expected[0] ==
nullptr) {
237 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::checkResult",
238 "success because of not expected result codes");
242 for (
int j = 0; expected[j] !=
nullptr; j++) {
243 sprintf(msg,
"- checking with %s", expected[j]);
244 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::checkResult", msg);
245 if (strncmp(result_str, expected[j], 3) == 0) {
246 sprintf(msg,
" -> success with %s", expected[j]);
247 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::checkResult", msg);
255 if (!wait_for_data) ok =
true;
263 FTPLogger::writeLog(LOG_ERROR,
"FTPBasicAPI::checkResult", command);
264 FTPLogger::writeLog(LOG_ERROR,
"FTPBasicAPI::checkResult", result_reply);
269 bool cmd(
const char *command,
const char *par,
const char *expected,
270 bool wait_for_data =
true) {
271 const char *expected_array[] = {expected,
nullptr};
272 return cmd(command, par, expected_array, wait_for_data);
275 bool cmd(
const char *command_str,
const char *par,
const char *expected[],
276 bool wait_for_data =
true) {
277 char command_buffer[FTP_COMMAND_BUFFER_SIZE];
278 Stream *stream_ptr = command_ptr;
279 if (par ==
nullptr) {
280 strncpy(command_buffer, command_str, FTP_COMMAND_BUFFER_SIZE);
281 stream_ptr->println(command_buffer);
283 snprintf(command_buffer, FTP_COMMAND_BUFFER_SIZE,
"%s %s", command_str,
285 stream_ptr->println(command_buffer);
287 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::cmd", command_buffer);
289 return checkResult(expected, command_buffer, wait_for_data);
292 void setUseTypeCommand(
bool useType) {
298 CurrentOperation current_operation = NOP;
299 Client *command_ptr =
nullptr;
300 Client *data_ptr =
nullptr;
301 IPAddress remote_address;
302 bool is_open =
false;
303 bool use_type =
false;
304 char result_reply[100];
306 bool connect(IPAddress adr,
int port, Client *client_ptr,
307 bool doCheckResult =
false) {
310#if defined(ESP32) || defined(ESP8266)
311 sprintf(buffer,
"connect %s:%d", adr.toString().c_str(), port);
312 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::connect", buffer);
315 if (client_ptr->connected()) client_ptr->stop();
316 for (
int j = 0; j < 10; j++) {
317 ok = client_ptr->connect(adr, port);
322 ok = client_ptr->connected();
323 if (ok && doCheckResult) {
324 const char *ok_result[] = {
"220",
"200",
nullptr};
325 ok = checkResult(ok_result,
"connect");
329 while (command_ptr->available() > 0) {
335 FTPLogger::writeLog(LOG_DEBUG,
"FTPBasicAPI::connected", buffer);
337 FTPLogger::writeLog(LOG_ERROR,
"FTPBasicAPI::connected", buffer);