This is FTPClient Program.

Dependencies:   SDFileSystem WIZnetInterface_Ricky mbed-src

main.cpp

Committer:
Ricky_Kwon
Date:
2015-07-23
Revision:
2:3aa502df9b3b
Parent:
0:ae81a181c789

File content as of revision 2:3aa502df9b3b:

#include "mbed.h"
#include "SDFileSystem.h"
#include "EthernetInterface.h"

/* FTP */
#define USER                "user "
#define PASS                "pass "
#define PASV                "pasv "
#define PORT                "port "
#define LIST                "list "
#define STOR                "stor "
#define RETR                "retr "
#define END                 "\r\n"
#define FTP_SERVER_PORT     21
#define MAX_SS              256
bool gMenuStart = false;
bool gDataSockReady = false;
bool gDataPutGetStart = false;
bool FTPServerLogin = false;
int remote_port;
char ftpServer_data_ip_addr[4]={0,};
char ftpServer_data_ip_addr_str[20]={0,};
static char buf[256];
enum CommandFirst {
    f_nocmd,
    f_dir,
    f_put,
    f_get,
};
enum CommandSecond {
    s_nocmd,
    s_dir,
    s_put,
    s_get,
};
enum ftpc_datasock_state{
    DATASOCK_IDLE,
    DATASOCK_READY,
    DATASOCK_START
};
struct Command {
    enum CommandFirst First;
    enum CommandSecond Second;
};
struct ftpc {
    enum ftpc_datasock_state dsock_state;
};
struct ftpc FTPClient;
struct Command FTPCommand;

/* SD Card filesystem */
SDFileSystem sd(PB_3, PB_2, PB_1, PB_0, "sd"); // WIZwiki-W7500 
FILE *ftpfile;
char ftpfilename[32];
/* UART */
Serial pc(USBTX, USBRX);
char gMsgBuf[10];
int User_Keyboard_MSG_Cnt;

/* Fuction*/ 
char* User_Keyboard_MSG(void);
int pportc(char * arg);


int main() {

    char Msg_c;
    int size;
    int remain_datasize;
    int remain_filesize;
    int send_byte;
    
    
    pc.baud(115200);
    
    pc.printf("Hello FTPClient World!\r\n"); 
      
    //Module IP, Please set according to your network environment.
    uint8_t mac_addr[6] = {0x00, 0x08, 0xdc, 0x12, 0x34, 0x45};
    const char ip_addr[] = "192.168.0.123"; 
    const char mask_addr[] = "255.255.255.0"; 
    const char gateway_addr[] = "192.168.0.1"; 
    
    //FTPServer IP, Please set according to your network environment.
    const char ftpServer_control_ip_addr[] = "192.168.0.230";
    
    
    EthernetInterface eth;
    eth.init(mac_addr, ip_addr, mask_addr, gateway_addr); //Use Static
    eth.connect();
    
    TCPSocketConnection FTP_CONTROL_SOCK;
    TCPSocketConnection FTP_DATA_SOCK;
    
    mkdir("/sd/FTPClient", 0777);
    //while 1
    while(true)
    {
        //while 2
        while(!FTP_CONTROL_SOCK.is_connected()){
            pc.printf("Connecting...FTPServer\r\nIP:%s, PORT:%d\r\n", ftpServer_control_ip_addr, FTP_SERVER_PORT);
            FTP_CONTROL_SOCK.connect(ftpServer_control_ip_addr, FTP_SERVER_PORT);
            FTP_CONTROL_SOCK.set_blocking(false, 15000); // Timeout after (1.5)s
        }//end of while 2
        
        //while 3
        while(true)
        {
            /* User Interface */
            //gMenuStart if
            if(gMenuStart){
                gMenuStart = false;
                pc.printf("\r\n----------------------------------------\r\n");
                pc.printf("Press menu key\r\n");
                pc.printf("----------------------------------------\r\n");
                pc.printf("1> View FTPServer Directory\r\n");
                pc.printf("2> View My Directory\r\n");
                pc.printf("3> Put File to Server\r\n");
                pc.printf("4> Get File from Server\r\n");
                pc.printf("----------------------------------------\r\n");
                //while 4
                Msg_c = pc.getc();
                // Msg_c if
                if(Msg_c=='1'){
                    FTP_CONTROL_SOCK.send(PASV, sizeof(PASV)-1);
                    FTP_CONTROL_SOCK.send(END, sizeof(END)-1);
                    FTPCommand.First = f_dir;
                    break;                         
                }
                else if(Msg_c=='2'){
                    pc.printf("Open directory on /sd/FTPClient\r\n");    
                    DIR *d = opendir("/sd/FTPClient");              
                    struct dirent *p;
                    while((p = readdir(d)) != NULL) {         
                      pc.printf("%s\r\n", p->d_name);            
                    }
                    closedir(d);
                    gMenuStart = true;
                    break;
                }
                else if(Msg_c=='3'){
                    FTP_CONTROL_SOCK.send(PASV, sizeof(PASV)-1);
                    FTP_CONTROL_SOCK.send(END, sizeof(END)-1);
                    FTPCommand.First = f_put;
                    break;
                }
                else if(Msg_c=='4'){
                    FTP_CONTROL_SOCK.send(PASV, sizeof(PASV)-1);
                    FTP_CONTROL_SOCK.send(END, sizeof(END)-1);
                    FTPCommand.First = f_get;
                    break;                          
                }
                else{
                    pc.printf("Retry...\r\n");
                    gMenuStart = true;
                    break;  
                }//end of Msg_c if                                       
            }//end of gMenuStart if
            
            //gDataSockReady if
            if(gDataSockReady){
                gDataSockReady = false;
                //FTPCommand.First switch case
                switch(FTPCommand.First){
                    case f_dir:
                        FTP_CONTROL_SOCK.send(LIST, sizeof(LIST)-1);
                        FTP_CONTROL_SOCK.send(END, sizeof(END)-1);
                        break;
                    case f_put:
                        pc.printf(">put file name?");
                        User_Keyboard_MSG();
                        FTP_CONTROL_SOCK.send(STOR, sizeof(STOR)-1);
                        FTP_CONTROL_SOCK.send(gMsgBuf, User_Keyboard_MSG_Cnt-1);
                        FTP_CONTROL_SOCK.send(END, sizeof(END)-1);
                        break;
                    case f_get:
                        pc.printf(">get file name?");
                        User_Keyboard_MSG();
                        FTP_CONTROL_SOCK.send(RETR, sizeof(RETR)-1);
                        FTP_CONTROL_SOCK.send(gMsgBuf, User_Keyboard_MSG_Cnt-1);
                        FTP_CONTROL_SOCK.send(END, sizeof(END)-1);
                        break;
                    default:
                        pc.printf("Command.First = default\r\n");
                        break;
                }//end of FTPCommand.First switch case
            }//end of gDataSockReady if          
            /* received from FTPServer ControlSock*/
            int n = FTP_CONTROL_SOCK.receive(buf, sizeof(buf));
            if (n <= 0) break;
            buf[n] = '\0';
            pc.printf("Received message from server: '%s' \n", buf);
            
            //buf if
            if (!strncmp(buf, "220", 3)){
                pc.printf("\r\nInput your User ID > ");
                User_Keyboard_MSG();
                FTP_CONTROL_SOCK.send(USER, sizeof(USER)-1);
                FTP_CONTROL_SOCK.send(gMsgBuf, User_Keyboard_MSG_Cnt-1);
                FTP_CONTROL_SOCK.send(END, sizeof(END)-1);
            }
            else if(!strncmp(buf, "331", 3)){
                pc.printf("\r\nInput your Password > ");
                User_Keyboard_MSG();
                FTP_CONTROL_SOCK.send(PASS, sizeof(PASS)-1);
                FTP_CONTROL_SOCK.send(gMsgBuf, User_Keyboard_MSG_Cnt-1);
                FTP_CONTROL_SOCK.send(END, sizeof(END)-1);        
            }
            else if(!strncmp(buf, "230", 3)){
                gMenuStart = true;      
            }
            else if(!strncmp(buf, "227", 3)){
                if (pportc(buf) == -1){
                    pc.printf("Bad port syntax\r\n");
                }
                else{
                    pc.printf("Go Open Data Sock...\r\n ");
                    FTPClient.dsock_state = DATASOCK_READY;
                }    
            }
            else if(!strncmp(buf, "150", 3)){
                switch(FTPCommand.First){
                case f_dir:
                    FTPCommand.First = f_nocmd;
                    FTPCommand.Second = s_dir;
                    gDataPutGetStart = true;
                    break;
                case f_get:
                    FTPCommand.First = f_nocmd;
                    FTPCommand.Second = s_get;
                    gDataPutGetStart = true;
                    break;
                case f_put:
                    FTPCommand.First = f_nocmd;
                    FTPCommand.Second = s_put;
                    gDataPutGetStart = true;
                    break;
                default :
                    printf("Command.First = default\r\n");
                    break;
                }  
            }
            else if(!strncmp(buf, "226", 3)){
                gMenuStart = true; 
            }
            else if(!strncmp(buf, "530", 3)){
                FTPServerLogin = true;
            }
            else if(!strncmp(buf, "500", 3)){
                gDataPutGetStart = false;
                FTPCommand.Second = s_nocmd; 
                gMenuStart = true;
                FTP_DATA_SOCK.close(); 
            }//end of buf if
            
            if(FTPServerLogin){
                FTPServerLogin = false;
                pc.printf("\r\nID or Password is wrong...Retry\r\n");
                pc.printf("\r\nInput your User ID > ");
                User_Keyboard_MSG();
                FTP_CONTROL_SOCK.send(USER, sizeof(USER)-1);
                FTP_CONTROL_SOCK.send(gMsgBuf, User_Keyboard_MSG_Cnt-1);
                FTP_CONTROL_SOCK.send(END, sizeof(END)-1);
            }
            
            //DATASOCK_READY if
            if(FTPClient.dsock_state == DATASOCK_READY){
                while(!FTP_DATA_SOCK.is_connected()){
                    pc.printf("Connecting...FTPServer Data sock\r\nIP:%s, PORT:%d\r\n", ftpServer_data_ip_addr_str, remote_port);
                    FTP_DATA_SOCK.connect(ftpServer_control_ip_addr, remote_port);
                    FTP_DATA_SOCK.set_blocking(false, 15000); // Timeout after (1.5)s
                }
                FTPClient.dsock_state = DATASOCK_IDLE;
                gDataSockReady = true;
            }//end of DATASOCK_READY if
            
            //gDataPutGetStart if
            if(gDataPutGetStart){
                //FTPCommand.Second switch case
                switch(FTPCommand.Second){
                case s_dir:
                    pc.printf("dir waiting...\r\n");
                    pc.printf("FTPServer Directory\r\n");
                    while(true){
                        memset(buf, 0, sizeof(buf));
                        size = FTP_DATA_SOCK.receive(buf, sizeof(buf));
                        buf[size] = '\0';
                        if(size>0){
                            pc.printf("%s", buf);
                        }
                        else{
                            break;
                        }
                    }
                    pc.printf("FTPServer Directory\r\n%s\r\n", buf);
                    gDataPutGetStart = false; 
                    FTPCommand.Second = s_nocmd;     
                    FTP_DATA_SOCK.close();
                    break;    
                case s_get:
                    pc.printf("get waiting...\r\n");
                    sprintf(ftpfilename, "/sd/FTPClient/%s", gMsgBuf);
                    ftpfile = fopen(ftpfilename, "w");                  
                    while(true){
                        memset(buf, 0, sizeof(buf));
                        remain_datasize = FTP_DATA_SOCK.receive(buf, sizeof(buf));
                        if(remain_datasize>0){
                            for (int i = 0; i < (int)remain_datasize; i++) {
                                fprintf(ftpfile, "%c", buf[i]);
                            }
                            pc.printf("#"); 
                        }
                        else{
                            break;
                        }
                    }
                    fclose(ftpfile);
                    gDataPutGetStart = false; 
                    FTPCommand.Second = s_nocmd;     
                    FTP_DATA_SOCK.close(); 
                    break; 
                case s_put:
                    pc.printf("put waiting...\r\n");
                    sprintf(ftpfilename, "/sd/FTPClient/%s", gMsgBuf);
                    ftpfile = fopen(ftpfilename, "r");  
                    fseek(ftpfile, 0, SEEK_END);            // seek to end of file
                    remain_filesize = ftell(ftpfile);       // get current file pointer
                    fseek(ftpfile, 0, SEEK_SET);            // seek back to beginning of file                
                    do{
                        memset(buf, 0, sizeof(buf));
                        if(remain_filesize > MAX_SS)
                            send_byte = MAX_SS;
                        else
                            send_byte = remain_filesize;
                        fread (buf, 1, send_byte, ftpfile);
                        FTP_DATA_SOCK.send(buf, send_byte);
                        remain_filesize -= send_byte;
                        pc.printf("#");
                    }while(remain_filesize!=0);
                    fclose(ftpfile);
                    gDataPutGetStart = false; 
                    FTPCommand.Second = s_nocmd;     
                    FTP_DATA_SOCK.close(); 
                    break;   
                        
                }//end of FTPCommand.Second switch case
            }//end of gDataPutGetStart if
        }//end of while 3
    }//end of while 1
}
char* User_Keyboard_MSG(void)
{
    User_Keyboard_MSG_Cnt = 0;
    memset(gMsgBuf, 0, sizeof(gMsgBuf));
    do{
        gMsgBuf[User_Keyboard_MSG_Cnt] = pc.getc();
        if(gMsgBuf[User_Keyboard_MSG_Cnt]==0x08){
            User_Keyboard_MSG_Cnt--;
        }
        else{
            User_Keyboard_MSG_Cnt++; 
        }
    }while(gMsgBuf[User_Keyboard_MSG_Cnt-1]!=0x0d);
    return gMsgBuf;
}
int pportc(char * arg)
{
    int i;
    char* tok=0;
    strtok(arg,"(");
    for (i = 0; i < 4; i++)
    {
        if(i==0) tok = strtok(NULL,",\r\n");
        else     tok = strtok(NULL,",");
        ftpServer_data_ip_addr[i] = (uint8_t)atoi(tok);
        if (!tok){
            pc.printf("bad pport : %s\r\n", arg);
            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){
            pc.printf("bad pport : %s\r\n", arg);
            return -1;
        }
    }
    pc.printf("ip : %d.%d.%d.%d, port : %d\r\n", ftpServer_data_ip_addr[0], ftpServer_data_ip_addr[1], ftpServer_data_ip_addr[2], ftpServer_data_ip_addr[3], remote_port);
    sprintf(ftpServer_data_ip_addr_str, "%d.%d.%d.%d", ftpServer_data_ip_addr[0], ftpServer_data_ip_addr[1], ftpServer_data_ip_addr[2], ftpServer_data_ip_addr[3]);
    return 0;
}