From b9a49e08d4923f84321dc65c55f79866a79f658c Mon Sep 17 00:00:00 2001 From: Luke Oxley Date: Wed, 24 Apr 2024 22:49:00 -0400 Subject: [PATCH] FTP Server for DAQ PCB (#119) * FTP Server Working with WinSCP * FTP Server Speedup --- common/phal_F4_F7/can/can.c | 3 + common/phal_F4_F7/can/can.h | 1 + source/daq/daq_hub/daq_hub.c | 94 ++- source/daq/daq_hub/daq_hub.h | 4 + source/daq/ftp/README.md | 64 ++ source/daq/ftp/ftpd.c | 1441 ++++++++++++++++++++++++++++++++++ source/daq/ftp/ftpd.h | 169 ++++ source/daq/main.c | 6 +- source/daq/sdio/sdio.h | 2 +- 9 files changed, 1752 insertions(+), 32 deletions(-) create mode 100644 source/daq/ftp/README.md create mode 100644 source/daq/ftp/ftpd.c create mode 100644 source/daq/ftp/ftpd.h diff --git a/common/phal_F4_F7/can/can.c b/common/phal_F4_F7/can/can.c index be96fc21..ed971c3e 100644 --- a/common/phal_F4_F7/can/can.c +++ b/common/phal_F4_F7/can/can.c @@ -61,6 +61,9 @@ bool PHAL_initCAN(CAN_TypeDef* bus, bool test_mode, uint32_t bit_rate) case 24000000: bus->BTR = PHAL_CAN_24MHz_500k; break; + case 42000000: + bus->BTR = PHAL_CAN_42MHz_500k; + break; default: return false; } diff --git a/common/phal_F4_F7/can/can.h b/common/phal_F4_F7/can/can.h index 840ef916..74702821 100644 --- a/common/phal_F4_F7/can/can.h +++ b/common/phal_F4_F7/can/can.h @@ -30,6 +30,7 @@ // Bit timing recovered from http://www.bittiming.can-wiki.info/ #define PHAL_CAN_16MHz_500k (0x033a0001) // sample point = 75%, SJW = 4 #define PHAL_CAN_24MHz_500k (0x033a0002) // sample point = 75%, SJW = 4 +#define PHAL_CAN_42MHz_500k (0x034e0003) // sample point = 75%, SJW = 4 #define PHAL_CAN_16MHz_250k (0x003a0003) // sample point = 75% #define PHAL_CAN_24MHz_250k (0x003a0005) // sample point = 75% diff --git a/source/daq/daq_hub/daq_hub.c b/source/daq/daq_hub/daq_hub.c index 3f0f8d0d..3d0fdabe 100644 --- a/source/daq/daq_hub/daq_hub.c +++ b/source/daq/daq_hub/daq_hub.c @@ -23,6 +23,7 @@ /* Module Includes */ #include "buffer.h" #include "daq_hub.h" +#include "ftpd.h" #include "main.h" #include "sdio.h" @@ -48,10 +49,13 @@ eth_config_t eth_config = { .udp_bc_sock = 0, .tcp_port = 5005, .tcp_sock = 1, + // NOTE: ftp uses 2, 3, 4 }; daq_hub_t dh; +uint8_t gFTPBUF[_FTP_BUF_SIZE]; + // Local protoptypes static void sd_handle_error(sd_error_t err, FRESULT res); static void sd_update_connection_state(void); @@ -92,6 +96,10 @@ void daq_init(void) dh.log_enable_tcp = false; dh.my_watch = 0x420; + // FTP + ftpd_init(eth_config.net_info.ip); + dh.ftp_busy = false; + // General dh.loop_time_avg_ms = 0; dh.loop_time_max_ms = 0; @@ -227,6 +235,35 @@ static void conv_tcp_frame_to_can_msg(tcp_can_frame_t *t, CanMsgTypeDef_t *c) for (uint8_t i = 0; i < 8; ++i) c->Data[i] = t->data[i]; } +bool daq_request_sd_mount(void) +{ + FRESULT res; + if (dh.sd_state == SD_MOUNTED || dh.sd_state == SD_FILE_CREATED) + { + return true; + } + + if (!SD_Detect()) + { + sd_handle_error(SD_ERROR_DETEC, 0); + } + else + { + res = f_mount(&dh.fat_fs, "", 1); + if (res == FR_OK) + { + dh.sd_state = SD_MOUNTED; + return true; + } + else + { + sd_handle_error(SD_ERROR_MOUNT, res); + dh.sd_state = SD_FAIL; // force fail from idle + } + } + return false; +} + static void sd_update_connection_state(void) { FRESULT res; @@ -247,7 +284,7 @@ static void sd_update_connection_state(void) if (dh.sd_state != SD_IDLE) { if (!SD_Detect()) sd_handle_error(SD_ERROR_DETEC, 0); - else if (!get_log_enable()) dh.sd_state = SD_SHUTDOWN; + else if (!get_log_enable() && !dh.ftp_busy) dh.sd_state = SD_SHUTDOWN; } else if (!get_log_enable()) { @@ -264,35 +301,25 @@ static void sd_update_connection_state(void) PHAL_writeGPIO(SD_ACTIVITY_LED_PORT, SD_ACTIVITY_LED_PIN, 0); // Activity LED disable if (get_log_enable() && dh.sd_error_ct == 0) // TODO: revert, ensuring no auto-reset for now { - bActivateTail(&b_rx_can, RX_TAIL_SD); - if (!SD_Detect()) sd_handle_error(SD_ERROR_DETEC, 0); - else - { - res = f_mount(&dh.fat_fs, "", 1); - if (res == FR_OK) - { - dh.sd_state = SD_MOUNTED; - } - else - { - sd_handle_error(SD_ERROR_MOUNT, res); - dh.sd_state = SD_FAIL; // force fail from idle - } - } + daq_request_sd_mount(); } break; case SD_MOUNTED: - if (sd_new_log_file()) + PHAL_writeGPIO(SD_DETECT_LED_PORT, SD_DETECT_LED_PIN, 1); + if (get_log_enable()) { - dh.sd_state = SD_FILE_CREATED; - dh.sd_last_err = SD_ERROR_NONE; // back to okay - PHAL_writeGPIO(SD_DETECT_LED_PORT, SD_DETECT_LED_PIN, 1); - } - else - { - sd_handle_error(SD_ERROR_FOPEN, 0); + bActivateTail(&b_rx_can, RX_TAIL_SD); + if (sd_new_log_file()) + { + dh.sd_state = SD_FILE_CREATED; + dh.sd_last_err = SD_ERROR_NONE; // back to okay + } + else + { + sd_handle_error(SD_ERROR_FOPEN, 0); + } } - break; + break; case SD_FILE_CREATED: if ((tick_ms - dh.log_start_ms) > SD_NEW_FILE_PERIOD_MS) { @@ -300,6 +327,11 @@ static void sd_update_connection_state(void) if ((res = f_close(&dh.log_fp)) != FR_OK) sd_handle_error(SD_ERROR_FCLOSE, res); else if (!sd_new_log_file()) sd_handle_error(SD_ERROR_FOPEN, 0); } + if (!get_log_enable()) + { + if ((res = f_close(&dh.log_fp)) != FR_OK) sd_handle_error(SD_ERROR_FCLOSE, res); + dh.sd_state = SD_MOUNTED; + } break; case SD_FAIL: // Intentional fall-through @@ -419,9 +451,14 @@ static void eth_update_connection_state(void) static uint32_t last_init_time; static uint32_t init_try_counter; - if (dh.eth_error_ct - last_error_count > 0) dh.eth_state = ETH_FAIL; + if (dh.eth_error_ct - last_error_count > 0) + { + dh.eth_state = ETH_FAIL; + } last_error_count = dh.eth_error_ct; + // TODO: on forceful dismount, reset the ports (maybe even ftp_init()) + switch(dh.eth_state) { case ETH_IDLE: @@ -468,6 +505,7 @@ static void eth_update_connection_state(void) } last_link_check_time = tick_ms; } + ftpd_run(gFTPBUF); break; case ETH_FAIL: // Intentional fall-through @@ -487,7 +525,7 @@ static void eth_update_connection_state(void) // Update connection LED if (dh.eth_state == ETH_LINK_UP) { - if (dh.eth_tcp_state == ETH_TCP_ESTABLISHED) + if (dh.eth_tcp_state == ETH_TCP_ESTABLISHED || dh.ftp_busy) { if (tick_ms - last_blink_time > 250) { @@ -531,7 +569,7 @@ static int8_t eth_init(void) } uint8_t rxBufSizes[] = {2, 2, 2, 2, 2, 2, 2, 2}; // kB - uint8_t txBufSizes[] = {2, 2, 2, 2, 2, 2, 2, 2}; // kB + uint8_t txBufSizes[] = {2, 2, 2, 8, 2, 0, 0, 0}; // kB if(wizchip_init(txBufSizes, rxBufSizes)) { diff --git a/source/daq/daq_hub/daq_hub.h b/source/daq/daq_hub/daq_hub.h index e6416b73..4ffb85cd 100644 --- a/source/daq/daq_hub/daq_hub.h +++ b/source/daq/daq_hub/daq_hub.h @@ -16,6 +16,7 @@ #include #include "ff.h" +#include "common/phal_F4_F7/rtc/rtc.h" /* Begin CAN Definitions from */ @@ -177,10 +178,13 @@ typedef struct // General uint32_t loop_time_max_ms; uint32_t loop_time_avg_ms; + // FTP + bool ftp_busy; } daq_hub_t; extern daq_hub_t dh; void daq_init(void); void daq_loop(void); +bool daq_request_sd_mount(void); #endif diff --git a/source/daq/ftp/README.md b/source/daq/ftp/README.md new file mode 100644 index 00000000..c4905e6d --- /dev/null +++ b/source/daq/ftp/README.md @@ -0,0 +1,64 @@ +# FTP Server + +## init wizchip +### variable and function + + uint8_t gFTPBUF[_MAX_SS]; + uint8_t wiznet_memsize[2][8] = {{8,8,8,8,8,8,8,8}, {8,8,8,8,8,8,8,8}}; + #define ETH_MAX_BUF_SIZE 2048 + uint8_t ethBuf0[ETH_MAX_BUF_SIZE]; + wiz_NetInfo gWIZNETINFO = { + .mac = {0x00, 0x08, 0xdc, 0x11, 0x22, 0x33}, + .ip = {192, 168, 15, 111}, + .sn = {255, 255, 255, 0}, + .gw = {192, 168, 15, 1}, + .dns = {8, 8, 8, 8}, + .dhcp = NETINFO_STATIC + + + +### run init funciton in main funcion + + Reset_WIZCHIP(); + reg_wizchip_bus_cbfunc(Chip_read, Chip_write); + reg_wizchip_cs_cbfunc(ChipCsEnable, ChipCsDisable); + + if (ctlwizchip(CW_INIT_WIZCHIP, (void*)wiznet_memsize) == -1) + { + printf("WIZchip memory initialization failed\r\n"); + } + + ctlnetwork(CN_SET_NETINFO, (void *)&gWIZNETINFO); + print_network_information(); + + +## Run function + + if((ret = ftpd_run(gFTPBUF)) < 0) + { + porintf(" FTP server Error %d \r\n", ret); + } + +## FTP ID & PASSWORD + +### USED ID +#### ID Enable in ftpd_init function + + ftp.ID_Enable = STATUS_USED; + +#### ID Setting + + #define ftp_ID "wiznet" + +### USED PASSWORD +#### PW Enable in ftpd_init function + + ftp.PW_Enable = STATUS_USED; + +#### PW Setting + + #define ftp_PW "wiznet54321" + +### Connedtion remain count + + #define remain_time 400000 diff --git a/source/daq/ftp/ftpd.c b/source/daq/ftp/ftpd.c new file mode 100644 index 00000000..9f1a670e --- /dev/null +++ b/source/daq/ftp/ftpd.c @@ -0,0 +1,1441 @@ +/* +* Wiznet. +* (c) Copyright 2002, Wiznet. +* +* Filename : ftpd.c +* Version : 1.0 +* Programmer(s) : +* Created : 2003/01/28 +* Description : FTP daemon. (AVR-GCC Compiler) +*/ + + +#include +#include +#include +#include +#include +#include +#include "socket.h" +#include "ftpd.h" +#include "main.h" // tick_ms +#include "daq_hub.h" // sd connection state + +/* If you need this header, use it. */ +//#include "stdio_private.h" + +/* Command table */ +static char *commands[] = { + "user", + "acct", + "pass", + "type", + "list", + "cwd", + "dele", + "name", + "quit", + "retr", + "stor", + "port", + "nlst", + "pwd", + "xpwd", + "mkd", + "xmkd", + "xrmd", + "rmd ", + "stru", + "mode", + "syst", + "xmd5", + "xcwd", + "feat", + "pasv", + "size", + "mlsd", + "appe", + NULL +}; + +#if 0 +/* Response messages */ +char banner[] = "220 %s FTP version %s ready.\r\n"; +char badcmd[] = "500 Unknown command '%s'\r\n"; +char binwarn[] = "100 Warning: type is ASCII and %s appears to be binary\r\n"; +char unsupp[] = "500 Unsupported command or option\r\n"; +char givepass[] = "331 Enter PASS command\r\n"; +char logged[] = "230 Logged in\r\n"; +char typeok[] = "200 Type %s OK\r\n"; +char only8[] = "501 Only logical bytesize 8 supported\r\n"; +char deleok[] = "250 File deleted\r\n"; +char mkdok[] = "200 MKD ok\r\n"; +char delefail[] = "550 Delete failed: %s\r\n"; +char pwdmsg[] = "257 \"%s\" is current directory\r\n"; +char badtype[] = "501 Unknown type \"%s\"\r\n"; +char badport[] = "501 Bad port syntax\r\n"; +char unimp[] = "502 Command does not implemented yet.\r\n"; +char bye[] = "221 Goodbye!\r\n"; +char nodir[] = "553 Can't read directory \"%s\": %s\r\n"; +char cantopen[] = "550 Can't read file \"%s\": %s\r\n"; +char sending[] = "150 Opening data connection for %s (%d.%d.%d.%d,%d)\r\n"; +char cantmake[] = "553 Can't create \"%s\": %s\r\n"; +char writerr[] = "552 Write error: %s\r\n"; +char portok[] = "200 PORT command successful.\r\n"; +char rxok[] = "226 Transfer complete.\r\n"; +char txok[] = "226 Transfer complete.\r\n"; +char noperm[] = "550 Permission denied\r\n"; +char noconn[] = "425 Data connection reset\r\n"; +char lowmem[] = "421 System overloaded, try again later\r\n"; +char notlog[] = "530 Please log in with USER and PASS\r\n"; +char userfirst[] = "503 Login with USER first.\r\n"; +char okay[] = "200 Ok\r\n"; +char syst[] = "215 %s Type: L%d Version: %s\r\n"; +char sizefail[] = "550 File not found\r\n"; +#endif +#define remain_time 400000 +#define connect_timeout_en 1 +#define ftp_ID "PER" +#define ftp_PW "" + +un_l2cval remote_ip; +uint16_t remote_port; +un_l2cval local_ip; +uint16_t local_port; +uint8_t connect_state_control = 0; +uint8_t connect_state_control1 = 0; +uint8_t connect_state_data = 0; +uint8_t connect_count = 0; +uint32_t con_remain_cnt1 = 0; +uint32_t con_remain_cnt2 = 0; +uint8_t cur_sn = CTRL_SOCK; +struct ftpd ftp; + +int current_year = 2014; +int current_month = 12; +int current_day = 31; +int current_hour = 10; +int current_min = 10; +int current_sec = 30; + +uint32_t tics[10] = {0}; + +static int check_directory(char* path); +static FRESULT scan_files(char* path, char* buf); +static int get_filesize(char* path, char *filename); + +int fsprintf(uint8_t s, const char *format, ...) +{ + int i; +/* + char buf[LINELEN]; + FILE f; + va_list ap; + + f.flags = __SWR | __SSTR; + f.buf = buf; + f.size = INT_MAX; + va_start(ap, format); + i = vfprintf(&f, format, ap); + va_end(ap); + buf[f.len] = 0; + + send(s, (uint8_t *)buf, strlen(buf)); +*/ + return i; +} + +void ftpd_init(uint8_t * src_ip) +{ + ftp.state = FTPS_NOT_LOGIN; + ftp.current_cmd = NO_CMD; + ftp.dsock_mode = ACTIVE_MODE; + + ftp.ID_Enable = STATUS_USED; + ftp.PW_Enable = STATUS_USED; + + if(ftp.ID_Enable == STATUS_USED) + { + strcpy(ftp.username, ftp_ID); + printf(" FTP ID[%d]:%s \r\n", strlen(ftp.username), ftp.username); + } + if(ftp.PW_Enable == STATUS_USED) + { + strcpy(ftp.userpassword, ftp_PW); + printf(" FTP PW[%d]:%s \r\n", strlen(ftp.userpassword), ftp.userpassword); + } + + + + local_ip.cVal[0] = src_ip[0]; + local_ip.cVal[1] = src_ip[1]; + local_ip.cVal[2] = src_ip[2]; + local_ip.cVal[3] = src_ip[3]; + local_port = 35000; + + strcpy(ftp.workingdir, "/"); + + socket(CTRL_SOCK, Sn_MR_TCP, IPPORT_FTP, 0x0); + socket(CTRL_SOCK1, Sn_MR_TCP, IPPORT_FTP, 0x0); +} + +uint8_t ftpd_run(uint8_t * dbuf) +{ + uint16_t size = 0, i; + long ret = 0; + UINT blocklen, send_byte, recv_byte; + uint32_t remain_filesize; + int32_t remain_datasize; + //static uint32_t con_remain_cnt1 = 0; + //static uint32_t con_remain_cnt2 = 0; +#if defined(F_FILESYSTEM) + // FILINFO fno; +#endif + + static uint32_t last_run_time; + if (!connect_state_control && (tick_ms - last_run_time) < 100) + { + // slow down polling if no connection active + return ret; + } + + last_run_time = tick_ms; + + //memset(dbuf, 0, sizeof(_FTP_BUF_SIZE)); + ////////////////////////FTP Control 1 + // #if 1 + switch(getSn_SR(CTRL_SOCK)) + { + case SOCK_ESTABLISHED : + if(!connect_state_control) + { +#if defined(_FTP_DEBUG_) + printf("%d:FTP Connected\r\n", CTRL_SOCK); +#endif + if (!daq_request_sd_mount()) + { + // Stop if SD card not mounted + close(CTRL_SOCK); + return ret; + } + dh.ftp_busy = true; + //fsprintf(CTRL_SOCK, banner, HOSTNAME, VERSION); + strcpy(ftp.workingdir, "/"); + sprintf((char *)dbuf, "220 %s FTP version %s ready.\r\n", HOSTNAME, VERSION); + ret = send(CTRL_SOCK, (uint8_t *)dbuf, strlen((const char *)dbuf)); + +#if defined(_FTP_DEBUG_) + printf("%d:send() [%s]\r\n",CTRL_SOCK,dbuf); +#endif + if(ret < 0) + { +#if defined(_FTP_DEBUG_) + printf("%d:send() error:%ld\r\n",CTRL_SOCK,ret); +#endif + close(CTRL_SOCK); + return ret; + } + connect_state_control = 1; + } + #if connect_timeout_en + else + { + if(con_remain_cnt1 > remain_time) + { + if((ret=disconnect(CTRL_SOCK)) != SOCK_OK) return ret; + #if defined(_FTP_DEBUG_) + printf("%d:Timeout Closed\r\n",CTRL_SOCK); + #endif + } + #if defined(_FTP_DEBUG_) + else if(((con_remain_cnt1 % 10000) == 0) && (con_remain_cnt1 != 0)) + { + printf("%d:Timeout Count:%ld\r\n", CTRL_SOCK, con_remain_cnt1); + } + #endif + con_remain_cnt1++; + } + #endif + +#if defined(_FTP_DEBUG_) + //printf("ftp socket %d\r\n", CTRL_SOCK); +#endif + + if((size = getSn_RX_RSR(CTRL_SOCK)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur. + { +#if defined(_FTP_DEBUG_) + printf("%d:size: %d\r\n", CTRL_SOCK, size); +#endif + + memset(dbuf, 0, _FTP_BUF_SIZE); + + if(size > _FTP_BUF_SIZE) size = _FTP_BUF_SIZE - 1; + + ret = recv(CTRL_SOCK,dbuf,size); + dbuf[ret] = '\0'; + if(ret != size) + { + if(ret==SOCK_BUSY) return 0; + if(ret < 0) + { +#if defined(_FTP_DEBUG_) + printf("%d:recv() error:%ld\r\n",CTRL_SOCK,ret); +#endif + close(CTRL_SOCK); + return ret; + } + } +#if defined(_FTP_DEBUG_) + printf("%d:Rcvd Command: %s", CTRL_SOCK, dbuf); +#endif + proc_ftpd(CTRL_SOCK, (char *)dbuf); + con_remain_cnt1 = 0; + } + break; + + case SOCK_CLOSE_WAIT : +#if defined(_FTP_DEBUG_) + printf("%d:CloseWait\r\n",CTRL_SOCK); +#endif + if((ret=disconnect(CTRL_SOCK)) != SOCK_OK) return ret; +#if defined(_FTP_DEBUG_) + printf("%d:Closed\r\n",CTRL_SOCK); +#endif + break; + + case SOCK_CLOSED : +#if defined(_FTP_DEBUG_) + printf("%d:FTPStart\r\n",CTRL_SOCK); +#endif + if((ret=socket(CTRL_SOCK, Sn_MR_TCP, IPPORT_FTP, 0x0)) != CTRL_SOCK) + { +#if defined(_FTP_DEBUG_) + printf("%d:socket() error:%ld\r\n", CTRL_SOCK, ret); +#endif + close(CTRL_SOCK); + return ret; + } + break; + + case SOCK_INIT : +#if defined(_FTP_DEBUG_) + printf("%d:Opened\r\n",CTRL_SOCK); +#endif + dh.ftp_busy = false; + //strcpy(ftp.workingdir, "/"); + if( (ret = listen(CTRL_SOCK)) != SOCK_OK) + { +#if defined(_FTP_DEBUG_) + printf("%d:Listen error\r\n",CTRL_SOCK); +#endif + return ret; + } + connect_state_control = 0; + con_remain_cnt1 = 0; + +#if defined(_FTP_DEBUG_) + printf("%d:Listen ok\r\n",CTRL_SOCK); +#endif + break; + + default : + break; + } + ////////////////////////FTP Control 2 +/* + switch(getSn_SR(CTRL_SOCK1)) + { + case SOCK_ESTABLISHED : + if(!connect_state_control1) + { +#if defined(_FTP_DEBUG_) + printf("%d:FTP Connected\r\n", CTRL_SOCK1); +#endif + strcpy(ftp.workingdir, "/"); + sprintf((char *)dbuf, "220 %s FTP version %s ready.\r\n", HOSTNAME, VERSION); + ret = send(CTRL_SOCK1, (uint8_t *)dbuf, strlen((const char *)dbuf)); + +#if defined(_FTP_DEBUG_) + printf("%d:send() [%s]\r\n",CTRL_SOCK1,dbuf); +#endif + if(ret < 0) + { +#if defined(_FTP_DEBUG_) + printf("%d:send() error:%ld\r\n",CTRL_SOCK1,ret); +#endif + close(CTRL_SOCK1); + return ret; + } + connect_state_control1 = 1; + } + #if connect_timeout_en + else + { + if(con_remain_cnt2 > remain_time) + { + if((ret=disconnect(CTRL_SOCK1)) != SOCK_OK) return ret; + #if defined(_FTP_DEBUG_) + printf("%d:Timeout Closed\r\n",CTRL_SOCK1); + #endif + } + #if defined(_FTP_DEBUG_) + else if(((con_remain_cnt2 % 10000) == 0) && (con_remain_cnt2 != 0)) + { + printf("%d:Timeout Count:%ld\r\n", CTRL_SOCK1, con_remain_cnt2); + } + #endif + con_remain_cnt2++; + } + #endif + +#if defined(_FTP_DEBUG_) + //printf("ftp socket %d\r\n", CTRL_SOCK); +#endif + + if((size = getSn_RX_RSR(CTRL_SOCK1)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur. + { +#if defined(_FTP_DEBUG_) + printf("%d: size: %d\r\n", CTRL_SOCK1, size); +#endif + + memset(dbuf, 0, _FTP_BUF_SIZE); + + if(size > _FTP_BUF_SIZE) size = _FTP_BUF_SIZE - 1; + + ret = recv(CTRL_SOCK1,dbuf,size); + dbuf[ret] = '\0'; + if(ret != size) + { + if(ret==SOCK_BUSY) return 0; + if(ret < 0) + { +#if defined(_FTP_DEBUG_) + printf("%d:recv() error:%ld\r\n",CTRL_SOCK1,ret); +#endif + close(CTRL_SOCK1); + return ret; + } + } +#if defined(_FTP_DEBUG_) + printf("%d: Rcvd Command: %s", CTRL_SOCK1, dbuf); +#endif + proc_ftpd(CTRL_SOCK1, (char *)dbuf); + con_remain_cnt2 = 0; + } + break; + + case SOCK_CLOSE_WAIT : +#if defined(_FTP_DEBUG_) + printf("%d:CloseWait\r\n",CTRL_SOCK1); +#endif + if((ret=disconnect(CTRL_SOCK1)) != SOCK_OK) return ret; + connect_count--; +#if defined(_FTP_DEBUG_) + printf("%d:Closed\r\n",CTRL_SOCK1); +#endif + break; + + case SOCK_CLOSED : +#if defined(_FTP_DEBUG_) + printf("%d:FTPStart\r\n",CTRL_SOCK1); +#endif + if((ret=socket(CTRL_SOCK1, Sn_MR_TCP, IPPORT_FTP, 0x0)) != CTRL_SOCK1) + { +#if defined(_FTP_DEBUG_) + printf("%d:socket() error:%ld\r\n", CTRL_SOCK1, ret); +#endif + close(CTRL_SOCK1); + return ret; + } + break; + + case SOCK_INIT : +#if defined(_FTP_DEBUG_) + printf("%d:Opened\r\n",CTRL_SOCK1); +#endif + //strcpy(ftp.workingdir, "/"); + if( (ret = listen(CTRL_SOCK1)) != SOCK_OK) + { +#if defined(_FTP_DEBUG_) + printf("%d:Listen error\r\n",CTRL_SOCK1); +#endif + return ret; + } + connect_state_control1 = 0; + con_remain_cnt2 = 0; +#if defined(_FTP_DEBUG_) + printf("%d:Listen ok\r\n",CTRL_SOCK1); +#endif + break; + + default : + break; + } + + #endif +*/ +/////////////////////////////////// ftp data part +#if 1 + switch(getSn_SR(DATA_SOCK)) + { + case SOCK_ESTABLISHED : + if(!connect_state_data) + { +#if defined(_FTP_DEBUG_) + printf("%d:FTP Data socket Connected\r\n", DATA_SOCK); +#endif + connect_state_data = 1; + } + + switch(ftp.current_cmd) + { + case LIST_CMD: + case MLSD_CMD: +#if defined(_FTP_DEBUG_) + printf("previous size: %d\r\n", size); +#endif +#if defined(F_FILESYSTEM) + scan_files(ftp.workingdir, dbuf); +#endif +#if defined(_FTP_DEBUG_) + printf("returned size: %d\r\n", size); + printf("%s\r\n", dbuf); +#endif +#if !defined(F_FILESYSTEM) + if (strncmp(ftp.workingdir, "/$Recycle.Bin", sizeof("/$Recycle.Bin")) != 0) + size = sprintf(dbuf, "drwxr-xr-x 1 ftp ftp 0 Dec 31 2014 $Recycle.Bin\r\n-rwxr-xr-x 1 ftp ftp 512 Dec 31 2014 test.txt\r\n"); +#endif + // Moved the following to scan_files + // size = strlen(dbuf); + // send(DATA_SOCK, dbuf, size); + ftp.current_cmd = NO_CMD; + disconnect(DATA_SOCK); + size = sprintf(dbuf, "226 Successfully transferred \"%s\"\r\n", ftp.workingdir); + send(cur_sn, dbuf, size); + break; + + case RETR_CMD: +#if defined(_FTP_DEBUG_) + printf("filename to retrieve : %s %d\r\n", ftp.filename, strlen(ftp.filename)); +#endif +#if defined(F_FILESYSTEM) + ftp.fr = f_open(&(ftp.fil), (const char *)ftp.filename, FA_READ); + //print_filedsc(&(ftp.fil)); + if(ftp.fr == FR_OK){ + remain_filesize = f_size(&ftp.fil); + // remain_filesize = ftp.fil.fsize; +#if defined(_FTP_DEBUG_) + printf("f_open return FR_OK\r\n"); +#endif + do{ +#if defined(_FTP_DEBUG_) + //printf("remained file size: %d\r\n", ftp.fil.fsize); +#endif + // memset(dbuf, 0, _FTP_BUF_SIZE); + + if(remain_filesize > _FTP_BUF_SIZE) + send_byte = _FTP_BUF_SIZE; + else + send_byte = remain_filesize; + + tics[0] = tick_ms; + ftp.fr = f_read(&(ftp.fil), dbuf, send_byte , &blocklen); + tics[1] = tick_ms; + if(ftp.fr != FR_OK) + break; +#if defined(_FTP_DEBUG_) + printf("#"); + //printf("----->fsize:%d recv:%d len:%d \r\n", remain_filesize, send_byte, blocklen); + //printf("----->fn:%s data:%s \r\n", ftp.filename, dbuf); +#endif + tics[2] = tick_ms; + send(DATA_SOCK, dbuf, blocklen); + tics[3] = tick_ms; + remain_filesize -= blocklen; + }while(remain_filesize != 0); +#if defined(_FTP_DEBUG_) + printf("\r\nFile read finished\r\n"); +#endif + ftp.fr = f_close(&(ftp.fil)); + }else{ +#if defined(_FTP_DEBUG_) + printf("File Open Error: %d\r\n", ftp.fr); +#endif + } +#else + remain_filesize = strlen(ftp.filename); + #if defined(_FTP_DEBUG_) + printf("<<<<<1recv data[%d]\r\n", remain_datasize); + #endif + do{ + memset(dbuf, 0, _FTP_BUF_SIZE); + + blocklen = sprintf(dbuf, "%s", ftp.filename); + + printf("####1[%d] dbuf:%s\r\n",remain_filesize ,dbuf); + + send(DATA_SOCK, dbuf, blocklen); + remain_filesize -= blocklen; + }while(remain_filesize != 0); + +#endif + ftp.current_cmd = NO_CMD; + disconnect(DATA_SOCK); + size = sprintf(dbuf, "226 Successfully transferred \"%s\"\r\n", ftp.filename); + send(cur_sn, dbuf, size); + break; + + case STOR_CMD: +#if defined(_FTP_DEBUG_) + printf("filename to store : %s %d\r\n", ftp.filename, strlen(ftp.filename)); +#endif +#if defined(F_FILESYSTEM) + ftp.fr = f_open(&(ftp.fil), (const char *)ftp.filename, FA_CREATE_ALWAYS | FA_WRITE); + //print_filedsc(&(ftp.fil)); + if(ftp.fr == FR_OK){ +#if defined(_FTP_DEBUG_) + printf("f_open return FR_OK\r\n"); +#endif + while(1){ + if((remain_datasize = getSn_RX_RSR(DATA_SOCK)) > 0){ + while(1){ + memset(dbuf, 0, _FTP_BUF_SIZE); + + if(remain_datasize > _FTP_BUF_SIZE) + recv_byte = _FTP_BUF_SIZE; + else + recv_byte = remain_datasize; + + ret = recv(DATA_SOCK, dbuf, recv_byte); +#if defined(_FTP_DEBUG_) + //printf("----->fn:%s data:%s \r\n", ftp.filename, dbuf); +#endif + + ftp.fr = f_write(&(ftp.fil), dbuf, (UINT)ret, &blocklen); +#if defined(_FTP_DEBUG_) + //printf("----->dsize:%d recv:%d len:%d \r\n", remain_datasize, ret, blocklen); +#endif + remain_datasize -= blocklen; + + if(ftp.fr != FR_OK){ +#if defined(_FTP_DEBUG_) + printf("f_write failed\r\n"); +#endif + break; + } + + if(remain_datasize <= 0) + break; + } + + if(ftp.fr != FR_OK){ +#if defined(_FTP_DEBUG_) + printf("f_write failed\r\n"); +#endif + break; + } + +#if defined(_FTP_DEBUG_) + printf("#"); +#endif + }else{ + if(getSn_SR(DATA_SOCK) != SOCK_ESTABLISHED) + break; + } + } +#if defined(_FTP_DEBUG_) + printf("\r\nFile write finished\r\n"); +#endif + ftp.fr = f_close(&(ftp.fil)); + }else{ +#if defined(_FTP_DEBUG_) + printf("File Open Error: %d\r\n", ftp.fr); +#endif + } + + //fno.fdate = (WORD)(((current_year - 1980) << 9) | (current_month << 5) | current_day); + //fno.ftime = (WORD)((current_hour << 11) | (current_min << 5) | (current_sec >> 1)); + //f_utime((const char *)ftp.filename, &fno); +#else + while(1){ + if((remain_datasize = getSn_RX_RSR(DATA_SOCK)) > 0){ + #if defined(_FTP_DEBUG_) + printf("<<<<<2recv data[%ld]\r\n", remain_datasize); + #endif + while(1){ + memset(dbuf, 0, _FTP_BUF_SIZE); + + if(remain_datasize > _FTP_BUF_SIZE) + recv_byte = _FTP_BUF_SIZE; + else + recv_byte = remain_datasize; + + ret = recv(DATA_SOCK, dbuf, recv_byte); + if(ret < 0) + { + #if defined(_FTP_DEBUG_) + printf("finish ret[%d\r\n", ret); + #endif + break; + } + + #if defined(_FTP_DEBUG_) + printf("#####2[%ld] dbuf:%s\r\n", remain_datasize, dbuf); + #endif + + remain_datasize -= ret; + #if defined(_FTP_DEBUG_) + printf("###ret:%ld,remain:%d\r\n",ret, remain_datasize); + #endif + + if(remain_datasize <= 0) + break; + } + }else{ + if(getSn_SR(DATA_SOCK) != SOCK_ESTABLISHED) + break; + } + } +#endif + ftp.current_cmd = NO_CMD; + disconnect(DATA_SOCK); + size = sprintf(dbuf, "226 Successfully transferred \"%s\"\r\n", ftp.filename); + send(cur_sn, dbuf, size); + break; + + case NO_CMD: + default: + break; + } + break; + + case SOCK_CLOSE_WAIT : +#if defined(_FTP_DEBUG_) + printf("%d:CloseWait\r\n",DATA_SOCK); +#endif + if((ret=disconnect(DATA_SOCK)) != SOCK_OK) return ret; +#if defined(_FTP_DEBUG_) + printf("%d:Closed\r\n",DATA_SOCK); +#endif + break; + + case SOCK_CLOSED : + if(ftp.dsock_state == DATASOCK_READY) + { + if(ftp.dsock_mode == PASSIVE_MODE){ +#if defined(_FTP_DEBUG_) + printf("%d:FTPDataStart, port : %d\r\n",DATA_SOCK, local_port); +#endif + if((ret=socket(DATA_SOCK, Sn_MR_TCP, local_port, 0x0)) != DATA_SOCK) + { +#if defined(_FTP_DEBUG_) + printf("%d:socket() error:%ld\r\n", DATA_SOCK, ret); +#endif + close(DATA_SOCK); + return ret; + } + + local_port++; + if(local_port > 50000) + local_port = 35000; + }else{ +#if defined(_FTP_DEBUG_) + printf("%d:FTPDataStart, port : %d\r\n",DATA_SOCK, IPPORT_FTPD); +#endif + if((ret=socket(DATA_SOCK, Sn_MR_TCP, IPPORT_FTPD, 0x0)) != DATA_SOCK) + { +#if defined(_FTP_DEBUG_) + printf("%d:socket() error:%ld\r\n", DATA_SOCK, ret); +#endif + close(DATA_SOCK); + return ret; + } + } + + ftp.dsock_state = DATASOCK_START; + } + break; + + case SOCK_INIT : +#if defined(_FTP_DEBUG_) + printf("%d:Opened\r\n",DATA_SOCK); +#endif + if(ftp.dsock_mode == PASSIVE_MODE){ + if( (ret = listen(DATA_SOCK)) != SOCK_OK) + { +#if defined(_FTP_DEBUG_) + printf("%d:Listen error\r\n",DATA_SOCK); +#endif + return ret; + } + +#if defined(_FTP_DEBUG_) + printf("%d:Listen ok\r\n",DATA_SOCK); +#endif + }else{ + if((ret = connect(DATA_SOCK, remote_ip.cVal, remote_port)) != SOCK_OK){ +#if defined(_FTP_DEBUG_) + printf("%d:Connect error\r\n", DATA_SOCK); +#endif + return ret; + } + } + connect_state_data = 0; + break; + + default : + break; + } +#endif + + return 0; +} + +char proc_ftpd(uint8_t sn, char * buf) +{ + char **cmdp, *cp, *arg, *tmpstr; + char sendbuf[200]; + int slen; + long ret; + + + /* Translate first word to lower case */ + for (cp = buf; *cp != ' ' && *cp != '\0'; cp++) + *cp = tolower(*cp); + + /* Find command in table; if not present, return syntax error */ + for (cmdp = commands; *cmdp != NULL; cmdp++) + if (strncmp(*cmdp, buf, strlen(*cmdp)) == 0) + break; + + if (*cmdp == NULL) + { + //fsprintf(CTRL_SOCK, badcmd, buf); + slen = sprintf(sendbuf, "500 Unknown command '%s'\r\n", buf); + send(sn, (uint8_t *)sendbuf, slen); + return 0; + } + /* Allow only USER, PASS and QUIT before logging in */ + if (ftp.state == FTPS_NOT_LOGIN) + { + switch(cmdp - commands) + { + case USER_CMD: + case PASS_CMD: + case QUIT_CMD: + break; + default: + //fsprintf(CTRL_SOCK, notlog); + slen = sprintf(sendbuf, "530 Please log in with USER and PASS\r\n"); + send(sn, (uint8_t *)sendbuf, slen); + return 0; + } + } + + arg = &buf[strlen(*cmdp)]; + while(*arg == ' ') arg++; + + /* Execute specific command */ + switch (cmdp - commands) + { + case USER_CMD : +#if defined(_FTP_DEBUG_) + printf("USER_CMD : %s", arg); +#endif + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; + if(ftp.ID_Enable == STATUS_USED) + { + if(strcmp(ftp.username, arg) != 0) + { + slen = sprintf(sendbuf, "430 Invalid username\r\n"); + ret = send(sn, (uint8_t *)sendbuf, slen); + if(ret < 0) + { + #if defined(_FTP_DEBUG_) + printf("%d:send() error:%ld\r\n",sn,ret); + #endif + close(sn); + return ret; + } + break; + } + } + else + { + strcpy(ftp.username, arg); + } + //fsprintf(CTRL_SOCK, givepass); + slen = sprintf(sendbuf, "331 Enter PASS command\r\n"); + ret = send(sn, (uint8_t *)sendbuf, slen); + if(ret < 0) + { +#if defined(_FTP_DEBUG_) + printf("%d:send() error:%ld\r\n",sn,ret); +#endif + close(sn); + return ret; + } + break; + + case PASS_CMD : +#if defined(_FTP_DEBUG_) + printf("PASS_CMD : %s", arg); +#endif + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; + if(ftp.PW_Enable == STATUS_USED) + { + if(strcmp(ftp.userpassword, arg) != 0) + { + slen = sprintf(sendbuf, "430 Invalid password\r\n"); + ret = send(sn, (uint8_t *)sendbuf, slen); + if(ret < 0) + { + #if defined(_FTP_DEBUG_) + printf("%d:send() error:%ld\r\n",sn,ret); + #endif + close(sn); + return ret; + } + break; + } + } + ftplogin(sn, arg); + break; + + case TYPE_CMD : + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; + switch(arg[0]) + { + case 'A': + case 'a': /* Ascii */ + ftp.type = ASCII_TYPE; + //fsprintf(CTRL_SOCK, typeok, arg); + slen = sprintf(sendbuf, "200 Type set to %s\r\n", arg); + send(sn, (uint8_t *)sendbuf, slen); + break; + + case 'B': + case 'b': /* Binary */ + case 'I': + case 'i': /* Image */ + ftp.type = IMAGE_TYPE; + //fsprintf(CTRL_SOCK, typeok, arg); + slen = sprintf(sendbuf, "200 Type set to %s\r\n", arg); + send(sn, (uint8_t *)sendbuf, slen); + break; + + default: /* Invalid */ + //fsprintf(CTRL_SOCK, badtype, arg); + slen = sprintf(sendbuf, "501 Unknown type \"%s\"\r\n", arg); + send(sn, (uint8_t *)sendbuf, slen); + break; + } + break; + + case FEAT_CMD : + slen = sprintf(sendbuf, "211-Features:\r\n MDTM\r\n REST STREAM\r\n SIZE\r\n MLST size*;type*;create*;modify*;\r\n MLSD\r\n UTF8\r\n CLNT\r\n MFMT\r\n211 END\r\n"); + send(sn, (uint8_t *)sendbuf, slen); + break; + + case QUIT_CMD : +#if defined(_FTP_DEBUG_) + printf("QUIT_CMD\r\n"); +#endif + //fsprintf(CTRL_SOCK, bye); + slen = sprintf(sendbuf, "221 Goodbye!\r\n"); + send(sn, (uint8_t *)sendbuf, slen); + disconnect(sn); + break; + + case RETR_CMD : + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; +#if defined(_FTP_DEBUG_) + printf("RETR_CMD\r\n"); +#endif + if(strlen(ftp.workingdir) == 1) + sprintf(ftp.filename, "/%s", arg); + else + sprintf(ftp.filename, "%s/%s", ftp.workingdir, arg); + slen = sprintf(sendbuf, "150 Opening data channel for file downloand from server of \"%s\"\r\n", ftp.filename); + send(sn, (uint8_t *)sendbuf, slen); + ftp.current_cmd = RETR_CMD; + break; + + case APPE_CMD : + case STOR_CMD: + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; +#if defined(_FTP_DEBUG_) + printf("STOR_CMD\r\n"); +#endif + if(strlen(ftp.workingdir) == 1) + sprintf(ftp.filename, "/%s", arg); + else + sprintf(ftp.filename, "%s/%s", ftp.workingdir, arg); + slen = sprintf(sendbuf, "150 Opening data channel for file upload to server of \"%s\"\r\n", ftp.filename); + send(sn, (uint8_t *)sendbuf, slen); + ftp.current_cmd = STOR_CMD; + if(ftp.dsock_mode == ACTIVE_MODE) + { + if((ret = connect(DATA_SOCK, remote_ip.cVal, remote_port)) != SOCK_OK){ + #if defined(_FTP_DEBUG_) + printf("%d:Connect error\r\n", DATA_SOCK); + #endif + return ret; + } + } + connect_state_data = 0; + break; + + case PORT_CMD: +#if defined(_FTP_DEBUG_) + printf("PORT_CMD\r\n"); +#endif + if (pport(arg) == -1){ + //fsprintf(CTRL_SOCK, badport); + slen = sprintf(sendbuf, "501 Bad port syntax\r\n"); + send(sn, (uint8_t *)sendbuf, slen); + } else{ + //fsprintf(CTRL_SOCK, portok); + ftp.dsock_mode = ACTIVE_MODE; + ftp.dsock_state = DATASOCK_READY; + slen = sprintf(sendbuf, "200 PORT command successful.\r\n"); + send(sn, (uint8_t *)sendbuf, slen); + } + break; + + case MLSD_CMD: +#if defined(_FTP_DEBUG_) + printf("MLSD_CMD\r\n"); +#endif + slen = sprintf(sendbuf, "150 Opening data channel for directory listing of \"%s\"\r\n", ftp.workingdir); + send(sn, (uint8_t *)sendbuf, slen); + ftp.current_cmd = MLSD_CMD; + break; + + case LIST_CMD: +#if defined(_FTP_DEBUG_) + printf("LIST_CMD\r\n"); +#endif + slen = sprintf(sendbuf, "150 Opening data channel for directory listing of \"%s\"\r\n", ftp.workingdir); + send(sn, (uint8_t *)sendbuf, slen); + ftp.current_cmd = LIST_CMD; + break; + + case NLST_CMD: +#if defined(_FTP_DEBUG_) + printf("NLST_CMD\r\n"); +#endif + break; + + case SYST_CMD: + slen = sprintf(sendbuf, "215 UNIX emulated by WIZnet\r\n"); + send(sn, (uint8_t *)sendbuf, slen); + break; + + case PWD_CMD: + case XPWD_CMD: + slen = sprintf(sendbuf, "257 \"%s\" is current directory.\r\n", ftp.workingdir); + send(sn, (uint8_t *)sendbuf, slen); + break; + + case PASV_CMD: + slen = sprintf(sendbuf, "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n", local_ip.cVal[0], local_ip.cVal[1], local_ip.cVal[2], local_ip.cVal[3], local_port >> 8, local_port & 0x00ff); + send(sn, (uint8_t *)sendbuf, slen); + + if(getSn_SR(DATA_SOCK) == SOCK_ESTABLISHED) + { +#if defined(_FTP_DEBUG_) + printf("data disconnect: %d\r\n", DATA_SOCK); +#endif + disconnect(DATA_SOCK); + } + ftp.dsock_mode = PASSIVE_MODE; + ftp.dsock_state = DATASOCK_READY; + cur_sn = sn; +#if defined(_FTP_DEBUG_) + printf("PASV port: %d\r\n", local_port); +#endif + break; + + case SIZE_CMD: + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; + if(slen > 3) + { + tmpstr = strrchr(arg, '/'); + if (tmpstr != NULL) + { + *tmpstr = 0; + } +#if defined(F_FILESYSTEM) + if (tmpstr != NULL) + slen = get_filesize(arg, tmpstr + 1); + else + slen = get_filesize(&arg[slen-1], arg); +#else + slen = _FTP_BUF_SIZE; +#endif + if(slen > 0) + slen = sprintf(sendbuf, "213 %d\r\n", slen); + else + slen = sprintf(sendbuf, "550 File not Found\r\n"); + } + else + { + slen = sprintf(sendbuf, "550 File not Found\r\n"); + } + send(sn, (uint8_t *)sendbuf, slen); + break; + + case CWD_CMD: + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; + if(slen > 2) + { + if (arg[0] == '.' && arg[1] == '.') arg = "/"; + } + // // arg[slen - 3] = 0x00; + // tmpstr = strrchr(arg, '/'); + // if (tmpstr != NULL) + // { + // *tmpstr = 0; + // } + +#if defined(F_FILESYSTEM) + slen = check_directory(arg); + // if (tmpstr != NULL) + // slen = get_filesize(arg, tmpstr + 1); + // else + // slen = get_filesize(&arg[slen-1], arg); +#else + slen = 0; +#endif + // if (tmpstr != NULL) *tmpstr = '/'; + if(slen == 0){ + slen = sprintf(sendbuf, "213 %d\r\n", slen); + strcpy(ftp.workingdir, arg); + slen = sprintf(sendbuf, "250 CWD successful. \"%s\" is current directory.\r\n", ftp.workingdir); + } + else + { + slen = sprintf(sendbuf, "550 CWD failed. \"%s\"\r\n", arg); + } + // } + // else + // { + // strcpy(ftp.workingdir, arg); + // slen = sprintf(sendbuf, "250 CWD successful. \"%s\" is current directory.\r\n", ftp.workingdir); + // } + send(sn, (uint8_t *)sendbuf, slen); + break; + + case MKD_CMD: + case XMKD_CMD: + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; +#if defined(F_FILESYSTEM) + if (f_mkdir(arg) != 0) + { + slen = sprintf(sendbuf, "550 Can't create directory. \"%s\"\r\n", arg); + } + else + { + slen = sprintf(sendbuf, "257 MKD command successful. \"%s\"\r\n", arg); + //strcpy(ftp.workingdir, arg); + } +#else + slen = sprintf(sendbuf, "550 Can't create directory. Permission denied\r\n"); +#endif + send(sn, (uint8_t *)sendbuf, slen); + break; + + case DELE_CMD: + slen = strlen(arg); + arg[slen - 1] = 0x00; + arg[slen - 2] = 0x00; +#if defined(F_FILESYSTEM) + if (f_unlink(arg) != 0) + { + slen = sprintf(sendbuf, "550 Could not delete. \"%s\"\r\n", arg); + } + else + { + slen = sprintf(sendbuf, "250 Deleted. \"%s\"\r\n", arg); + } +#else + slen = sprintf(sendbuf, "550 Could not delete. Permission denied\r\n"); +#endif + send(sn, (uint8_t *)sendbuf, slen); + break; + + case XCWD_CMD: + case ACCT_CMD: + case XRMD_CMD: + case RMD_CMD: + case STRU_CMD: + case MODE_CMD: + case XMD5_CMD: + //fsprintf(CTRL_SOCK, unimp); + slen = sprintf(sendbuf, "502 Command does not implemented yet.\r\n"); + send(sn, (uint8_t *)sendbuf, slen); + break; + + default: /* Invalid */ + //fsprintf(CTRL_SOCK, badcmd, arg); + slen = sprintf(sendbuf, "500 Unknown command \'%s\'\r\n", arg); + send(sn, (uint8_t *)sendbuf, slen); + break; + } + + return 1; +} + + +char ftplogin(uint8_t sn, char * pass) +{ + char sendbuf[100]; + int slen = 0; + + //memset(sendbuf, 0, DATA_BUF_SIZE); + +#if defined(_FTP_DEBUG_) + printf("%s logged in\r\n", ftp.username); +#endif + //fsprintf(CTRL_SOCK, logged); + slen = sprintf(sendbuf, "230 Logged on\r\n"); + send(sn, (uint8_t *)sendbuf, slen); + ftp.state = FTPS_LOGIN; + + return 1; +} + +int pport(char * arg) +{ + int i; + char* tok=0; + + for (i = 0; i < 4; i++) + { + if(i==0) tok = strtok(arg,",\r\n"); + else tok = strtok(NULL,","); + remote_ip.cVal[i] = (uint8_t)atoi(tok); + if (!tok) + { +#if defined(_FTP_DEBUG_) + printf("bad pport : %s\r\n", arg); +#endif + return -1; + } + } + remote_port = 0; + for (i = 0; i < 2; i++) + { + tok = strtok(NULL,",\r\n"); + remote_port <<= 8; + remote_port += atoi(tok); + if (!tok) + { +#if defined(_FTP_DEBUG_) + printf("bad pport : %s\r\n", arg); +#endif + return -1; + } + } +#if defined(_FTP_DEBUG_) + printf("ip : %d.%d.%d.%d, port : %d\r\n", remote_ip.cVal[0], remote_ip.cVal[1], remote_ip.cVal[2], remote_ip.cVal[3], remote_port); +#endif + + return 0; +} + +#if defined(F_FILESYSTEM) +void print_filedsc(FIL *fil) +{ +#if defined(_FTP_DEBUG_) + printf("File System pointer : %08X\r\n", fil->fs); + printf("File System mount ID : %d\r\n", fil->id); + printf("File status flag : %08X\r\n", fil->flag); + printf("File System pads : %08X\r\n", fil->err); + printf("File read write pointer : %08X\r\n", fil->fptr); + printf("File size : %08X\r\n", fil->fsize); + printf("File start cluster : %08X\r\n", fil->sclust); + printf("current cluster : %08X\r\n", fil->clust); + printf("current data sector : %08X\r\n", fil->dsect); + printf("dir entry sector : %08X\r\n", fil->dir_sect); + printf("dir entry pointer : %08X\r\n", fil->dir_ptr); +#endif +} +#endif + +static int check_directory(char* path) +{ + DIR dir; + FRESULT res; + if (!path) return -1; + if (*path == 0x00) + res = f_opendir(&dir, "/"); + else + res = f_opendir(&dir, path); + if (res != FR_OK) return -1; + f_closedir(&dir); + return 0; +} + + +#include +static FRESULT scan_files(char* path, char *buf) +{ + FRESULT res; + FILINFO fno; + DIR dir; + int i, len, buf_ptr, size = 0; + char *fn; /* This function is assuming no_Unicode cfg.*/ + char date_str[15]; + int date_str_ptr = 0; +#ifdef FF_USE_LFN + // static char lfn[FF_MAX_LFN + 1]; + // fno.lfname = lfn; + // fno.lfsize = sizeof(lfn); +#endif + + res = f_opendir(&dir, path); + //printf("f_opendir res: %d\r\n", res); + if(res == FR_OK){ + i = strlen(path); + //printf("strlen of path: %s %d \r\n", path, i); + for(;;){ + res = f_readdir(&dir, &fno); + if(res != FR_OK || fno.fname[0] == 0) break; + if(fno.fname[0] == '.') continue; +// #ifdef FF_USE_LFN +// fn = *fno.lfname ? fno.lfname : fno.fname; +// #else + fn = fno.fname; +// #endif + switch((fno.fdate >> 5) & 0x0f) + { + case 1: + len = sprintf(date_str, "JAN "); + break; + case 2: + len = sprintf(date_str, "FEB "); + break; + case 3: + len = sprintf(date_str, "MAR "); + break; + case 4: + len = sprintf(date_str, "APR "); + break; + case 5: + len = sprintf(date_str, "MAY "); + break; + case 6: + len = sprintf(date_str, "JUN "); + break; + case 7: + len = sprintf(date_str, "JUL "); + break; + case 8: + len = sprintf(date_str, "AUG "); + break; + case 9: + len = sprintf(date_str, "SEP "); + break; + case 10: + len = sprintf(date_str, "OCT "); + break; + case 11: + len = sprintf(date_str, "NOV "); + break; + case 12: + len = sprintf(date_str, "DEC "); + break; + } + date_str_ptr += len; + len = sprintf(date_str + date_str_ptr, "%d ", (fno.fdate & 0x1f)); + date_str_ptr += len; + len = sprintf(date_str + date_str_ptr, "%d", (((fno.fdate >> 9) & 0x7f) + 1980)); + date_str_ptr = 0; + //printf("date str : %s \r\n", date_str); + + if(fno.fattrib & AM_DIR) + { + sprintf(buf + buf_ptr, "d"); + }else + { + sprintf(buf + buf_ptr, "-"); + } + buf_ptr++; + // drwxr-xr-x 1 ftp ftp 0 Apr 07 2014 $RECYCLE.BIN\r\n + //len = sprintf(buf + buf_ptr, "rwxr-xr-x 1 ftp ftp %d %s %s\r\n", fno.fsize, date_str, fn); + len = sprintf(buf + buf_ptr, "rwxr-xr-x 1 ftp ftp %d %s %s\r\n", fno.fsize, date_str, fn); + // buf_ptr += len; + //printf("fn: %s \r\n", fn); + + size = strlen(buf); + send(DATA_SOCK, buf, size); + buf_ptr = 0; + } + //*buf_len = strlen(buf); + //printf("%s", buf); + //printf("\r\nbuf_len : %d, sizeof(buf): %d\r\n", buf_len, sizeof(buf)); + //f_closedir(&dir); + } + return res; +} + +static int get_filesize(char* path, char *filename) +{ + FRESULT res; + FILINFO fno; + DIR dir; + int i, len, buf_ptr = 0; + char *fn; /* This function is assuming no_Unicode cfg.*/ +#ifdef FF_USE_LFN + // static char lfn[_MAX_LFN + 1]; + // fno.lfname = lfn; + // fno.lfsize = sizeof(lfn); +#endif + + if(*path == 0x00) + res = f_opendir(&dir, "/"); + else + res = f_opendir(&dir, path); + //printf("f_opendir res: %d\r\n", res); + if(res == FR_OK){ + for(;;){ + res = f_readdir(&dir, &fno); + if(res != FR_OK || fno.fname[0] == 0) break; + if(fno.fname[0] == '.') continue; +// #ifdef FF_USE_LFN +// fn = *fno.lfname ? fno.lfname : fno.fname; +// #else + fn = fno.fname; +// #endif + if(!strcmp(fn, filename)) + { + if(fno.fattrib & AM_DIR){ + //printf("\r\n%s/%s is a directory\r\n", path, filename); + return 0; + } + return fno.fsize; + } + } + //printf("\r\n%s/%s was not found\r\n", path, filename); + //f_closedir(&dir); + } + return -1; +} diff --git a/source/daq/ftp/ftpd.h b/source/daq/ftp/ftpd.h new file mode 100644 index 00000000..371bbf20 --- /dev/null +++ b/source/daq/ftp/ftpd.h @@ -0,0 +1,169 @@ +#ifndef _FTPD_H_ +#define _FTPD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +* Wiznet. +* (c) Copyright 2002, Wiznet. +* +* Filename : ftpd.h +* Version : 1.0 +* Programmer(s) : +* Created : 2003/01/28 +* Description : Header file of FTP daemon. (AVR-GCC Compiler) +*/ + +#include + +#define F_FILESYSTEM // If your target support a file system, you have to activate this feature and implement. + +#if defined(F_FILESYSTEM) +#include "ff.h" +#endif + +#define F_APP_FTP + +#define _FTP_BUF_SIZE 512//8192 +// #define _FTP_DEBUG_ + + +#define LINELEN 100 +//#define DATA_BUF_SIZE 100 +#if !defined(F_FILESYSTEM) +#define _MAX_SS 512 +#endif + +#define CTRL_SOCK 2 +#define DATA_SOCK 3 +#define CTRL_SOCK1 4 + + +#define IPPORT_FTPD 20 /* FTP Data port */ +#define IPPORT_FTP 21 /* FTP Control port */ + +#define HOSTNAME "PER_DAQ" +#define VERSION "1.0" + +#define FILENAME "a.txt" + +/* FTP commands */ +enum ftp_cmd { + USER_CMD, + ACCT_CMD, + PASS_CMD, + TYPE_CMD, + LIST_CMD, + CWD_CMD, + DELE_CMD, + NAME_CMD, + QUIT_CMD, + RETR_CMD, + STOR_CMD, + PORT_CMD, + NLST_CMD, + PWD_CMD, + XPWD_CMD, + MKD_CMD, + XMKD_CMD, + XRMD_CMD, + RMD_CMD, + STRU_CMD, + MODE_CMD, + SYST_CMD, + XMD5_CMD, + XCWD_CMD, + FEAT_CMD, + PASV_CMD, + SIZE_CMD, + MLSD_CMD, + APPE_CMD, + NO_CMD, +}; + +enum ftp_type { + ASCII_TYPE, + IMAGE_TYPE, + LOGICAL_TYPE +}; + +enum ftp_state { + FTPS_NOT_LOGIN, + FTPS_LOGIN +}; + +enum datasock_state{ + DATASOCK_IDLE, + DATASOCK_READY, + DATASOCK_START +}; + +enum datasock_mode{ + PASSIVE_MODE, + ACTIVE_MODE +}; + +enum ftp_use_status{ + STATUS_USED, + STATUS_NOT_USED +}; + +struct ftpd { + uint8_t control; /* Control stream */ + uint8_t data; /* Data stream */ + + enum ftp_type type; /* Transfer type */ + enum ftp_state state; + + enum ftp_cmd current_cmd; + + enum datasock_state dsock_state; + enum datasock_mode dsock_mode; + + enum ftp_use_status ID_Enable; + enum ftp_use_status PW_Enable; + + char username[LINELEN]; /* Arg to USER command */ + char userpassword[LINELEN]; + char workingdir[LINELEN]; + char filename[LINELEN]; + +#if defined(F_FILESYSTEM) + FIL fil; // FatFs File objects + FRESULT fr; // FatFs function common result code +#endif + +}; + +#ifndef un_I2cval +typedef union _un_l2cval { + uint32_t lVal; + uint8_t cVal[4]; +}un_l2cval; +#endif + +void ftpd_init(uint8_t * src_ip); +uint8_t ftpd_run(uint8_t * dbuf); +char proc_ftpd(uint8_t sn, char * buf); + +char ftplogin(uint8_t sn,char * pass); + +int pport(char * arg); + +int sendit(char * command); +int recvit(char * command); + +long sendfile(uint8_t s, char * command); +long recvfile(uint8_t s); + +#if defined(F_FILESYSTEM) +void print_filedsc(FIL *fil); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // _FTPD_H_ diff --git a/source/daq/main.c b/source/daq/main.c index f68db34b..1dff79a7 100644 --- a/source/daq/main.c +++ b/source/daq/main.c @@ -60,7 +60,7 @@ GPIOInitConfig_t gpio_config[] = { dma_init_t spi_rx_dma_config = SPI2_RXDMA_CONT_CONFIG(NULL, 2); dma_init_t spi_tx_dma_config = SPI2_TXDMA_CONT_CONFIG(NULL, 1); SPI_InitConfig_t eth_spi_config = { - .data_rate = 24000000 / 24, + .data_rate = 42000000 / 2, .data_len = 8, .nss_sw = false, .nss_gpio_port = ETH_CS_PORT, @@ -88,11 +88,11 @@ extern uint32_t APB2ClockRateHz; extern uint32_t AHBClockRateHz; extern uint32_t PLLClockRateHz; -#define TargetCoreClockrateHz 96000000 // 144000000 +#define TargetCoreClockrateHz 168000000 ClockRateConfig_t clock_config = { .system_source =SYSTEM_CLOCK_SRC_PLL, .pll_src =PLL_SRC_HSI16, - .vco_output_rate_target_hz = 192000000,//288000000, + .vco_output_rate_target_hz = 336000000,//288000000, .system_clock_target_hz =TargetCoreClockrateHz, .ahb_clock_target_hz =(TargetCoreClockrateHz / 1), .apb1_clock_target_hz =(TargetCoreClockrateHz / 4), diff --git a/source/daq/sdio/sdio.h b/source/daq/sdio/sdio.h index eeec1273..fad8ef3c 100644 --- a/source/daq/sdio/sdio.h +++ b/source/daq/sdio/sdio.h @@ -387,7 +387,7 @@ bool PHAL_SDIO_init(void); * @brief SDIO Data Transfer Frequency (25MHz max) */ // #define SDIO_TRANSFER_CLK_DIV ((uint8_t)78) -#define SDIO_TRANSFER_CLK_DIV ((uint8_t)46) +#define SDIO_TRANSFER_CLK_DIV ((uint8_t)0)//(46) // #define SDIO_TRANSFER_CLK_DIV ((uint8_t)78) // TODO: see about increasing (1MHz now)