diff --git a/mbtk/libmbtk_ftp/mbtk_ftp.c b/mbtk/libmbtk_ftp/mbtk_ftp.c
new file mode 100755
index 0000000..2821087
--- /dev/null
+++ b/mbtk/libmbtk_ftp/mbtk_ftp.c
@@ -0,0 +1,3058 @@
+/*************************************************************
+ Description:
+ $file_description$
+ Author:
+ LiuBin
+ Date:
+ 2020/10/28 11:49:08
+ *************************************************************/
+#include "mbtk_ftp.h"
+#include "mbtk_list.h"
+#include "mbtk_sock.h"
+#include "mbtk_str.h"
+#include "mbtk_sock2.h"
+#include<linux/msg.h>
+
+/*************************************************************
+ Constants and Macros
+ *************************************************************/
+#define FTP_HANDLE_MAX 5
+#define FTP_ANONYMOUS_USER "Anonymous"
+#define FTP_ANONYMOUS_PASS "@"
+
+//#define FTP_RESUME_DEBUG
+
+#ifdef MBTK_PLATFORM_QCOMM
+#define FTP_TIMEOUT 60000    // 60s
+#else
+#define FTP_TIMEOUT 3000    // 3s
+#endif
+
+/*************************************************************
+ typedef struct:local at
+ *************************************************************/
+typedef struct
+{
+    char host[64];
+    uint16 port;
+    mbtk_ftp_auth_type_enum auth_type;
+    bool ftp_type;
+    bool use_cert;
+    char name[FTP_SERVER_USER_NAME_MAX+1];
+    char pass[FTP_SERVER_USER_PASS_MAX+1];
+    mbtk_ftp_handle at_ftp_handle;
+    char remote_path[MBTK_FTP_FILE_NAME_MAX+1];
+    char local_path[MBTK_FTP_FILE_NAME_MAX+1];
+    int rest_size;
+    int read_size;
+    int put_len;
+} mbtk_at_init_parameter;
+
+mbtk_at_init_parameter mbtk_at_ftp_par={0};
+
+/*************************************************************
+ Variables:local
+ *************************************************************/
+static list_node_t *ftp_client_list = NULL;
+
+/*************************************************************
+ Variables:public
+ *************************************************************/
+
+/*************************************************************
+ Local Function Declaration
+ *************************************************************/
+
+/*************************************************************
+ Local Function Definitions
+ *************************************************************/
+static bool ftp_ch_is_space(char ch)
+{
+    if (ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t')
+        return true;
+
+    return false;
+}
+
+static const char* ftp_str_next(const char* str, char *result, uint32 len)
+{
+    memset(result, 0x0, len);
+    const char* ptr = str;
+    const char* ptr_result;
+    while (*ptr && ftp_ch_is_space(*ptr))
+    {
+        ptr++;
+    }
+    if (*ptr == '\0')
+    {
+        return NULL;
+    }
+    // Point to first no space char.
+    ptr_result = ptr;
+    while (*ptr && !ftp_ch_is_space(*ptr))
+    {
+        ptr++;
+    }
+
+    // Point to first space char or '\0'.
+    memcpy(result, ptr_result, ptr - ptr_result);
+
+    if (*ptr == '\0')
+    {
+        return NULL;
+    }
+
+    return ptr;
+}
+
+static int ftp_cmd_handle(mbtk_ftp_info_s *info, const void *cmd, void *rsp,
+                          uint32 *rsp_len)
+{
+    int err;
+    int rsp_code;
+    int len = strlen((char*) cmd);
+    // Write cmd
+    if(info->auth_type != 0)
+    {
+        mbtk_sock_write(info->ftp_ssl_handle,info->session,cmd,len,60000,&err);
+        if(err!=0)
+        {
+            printf("\nmbtk_sock_write error:%d\n",err);
+            return err;
+        }
+    }
+    else
+    {
+        if (sock_write(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], cmd, len, 60000, &err)
+            != len)
+        {
+            LOGE("Socket write fail[err = %d].", err);
+            return -1;
+        }
+    }
+
+    // Read cmd response
+    if (rsp != NULL && *rsp_len > 0)
+    {
+    read_angin_1:
+        memset(rsp, 0x0, *rsp_len);
+        if(info->auth_type != 0)
+        {
+            unsigned char mbtk_ftp_ssl_read_buf[16384 + 1];
+            len = mbtk_sock_read(info->ftp_ssl_handle,info->session,mbtk_ftp_ssl_read_buf,sizeof(mbtk_ftp_ssl_read_buf),FTP_TIMEOUT,&err);
+            if(err != 0)
+            {
+                printf("\n mbtk_sock_read error:%d \n",err);
+            }
+            rsp_code = atoi(mbtk_ftp_ssl_read_buf);
+            printf("%s -> Code:%d; RSP:%s\n", (char*)cmd, rsp_code, (char* )mbtk_ftp_ssl_read_buf);
+            if (rsp_code == 0)
+            {
+                goto read_angin_1;
+            }
+            memcpy((char* )rsp, mbtk_ftp_ssl_read_buf, strlen(mbtk_ftp_ssl_read_buf));
+            //printf("\nrsp = %s\n",(char* )rsp);
+            return rsp_code;
+        }
+        else
+        {
+            len = sock_readline(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], rsp, *rsp_len, FTP_TIMEOUT,&err);
+        }
+        if (len <= 0)
+        {
+            LOGE("Socket read fail[len = %d].", len);
+            return -1;
+        }
+        rsp_code = atoi(rsp);
+        LOGI("%s -> Code:%d; RSP:%s", (char*)cmd, rsp_code, (char* )rsp);
+        //log_hex("FTP_RSP",(char* )rsp,len);
+
+        if (rsp_code == 0)
+        {
+            goto read_angin_1;
+        }
+
+        *rsp_len = len;
+    }
+    else
+    {
+        char buff[1024];
+
+    read_angin_2:
+        memset(buff, 0x0, 1024);
+        if(info->auth_type != 0)
+        {
+            unsigned char mbtk_ftp_ssl_read_buf[16384 + 1];
+            len = mbtk_sock_read(info->ftp_ssl_handle,info->session,mbtk_ftp_ssl_read_buf,sizeof(mbtk_ftp_ssl_read_buf),FTP_TIMEOUT,&err);
+            if(err != 0)
+            {
+                printf("\nmbtk_sock_read error:%d\n",err);
+            }
+            rsp_code = atoi(mbtk_ftp_ssl_read_buf);
+            printf("%s -> Code:%d; RSP:%s\n", (char*)cmd, rsp_code, (char* )mbtk_ftp_ssl_read_buf);
+            char *mbtk_ftp_ssl_read_buf_p = NULL;
+            mbtk_ftp_ssl_read_buf_p = strstr(mbtk_ftp_ssl_read_buf,"\n");
+            if(mbtk_ftp_ssl_read_buf_p!=NULL);
+            {
+                if(strlen(mbtk_ftp_ssl_read_buf_p)>1)
+                {
+                    mbtk_ftp_ssl_read_buf_p++;
+                    rsp_code = atoi(mbtk_ftp_ssl_read_buf_p);
+                }
+            }
+            if (rsp_code == 0)
+            {
+                goto read_angin_2;
+            }
+            return rsp_code;
+        }
+        else
+        {
+            len = sock_readline(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], buff, 1024, FTP_TIMEOUT,
+                            &err);
+        }
+        if (len <= 0)
+        {
+            LOGE("Socket read fail[len = %d].", len);
+            return -1;
+        }
+
+        rsp_code = atoi(buff);
+        LOGI("%s -> Code:%d; RSP:%s", (char*)cmd, rsp_code, buff);
+        //log_hex("FTP_RSP",buff,len);
+
+        if (rsp_code == 0)
+        {
+            goto read_angin_2;
+        }
+    }
+
+    return rsp_code;
+}
+
+// Create data socket service and waitting client connect.
+static mbtk_ftp_error_enum ftp_data_sock_service_create(mbtk_ftp_sock_s *sock)
+{
+    return FTP_ERR_SUCCESS;
+}
+
+static bool ftp_internal_ipv4_check(void *ipv4)
+{
+    char *ip = (char*) ipv4;
+    int ip1 = atoi(ip);
+    ip = strstr(ip, ".");
+    if (!ip)
+        return FALSE;
+    int ip2 = atoi(ip + 1);
+
+    if (ip1 == 10)   // 10.x.x.x
+    {
+        return TRUE;
+    }
+    else if (ip1 == 172 && (ip2 >= 16 && ip2 <= 31))     // 172.16.0.0 ~ 172.31.255.255
+    {
+        return TRUE;
+    }
+    else if (ip1 == 192 && ip2 == 168)     // 192.168.x.x
+    {
+        return TRUE;
+    }
+    else
+    {
+        return FALSE;
+    }
+}
+
+static mbtk_ftp_error_enum ftp_sock_set_by_port(mbtk_ftp_info_s *info,
+        mbtk_ftp_sock_s *sock)
+{
+    // port = port1 * 256 + port2
+    // "PORT ip1,ip2,ip3,ip4,port1,port2\r\n"
+    int code;
+    char cmd_buff[100];
+    memset(cmd_buff, 0x0, 100);
+    if (info->sock_info[FTP_SOCK_CTRL].addr_family == MBTK_ADDR_IPV6 || sock->port <= 1024
+        || strlen((char*) sock->host) == 0)
+    {
+        LOGE("FTP params set error.");
+        return FTP_ERR_PARAM_SET;
+    }
+
+    if (ftp_data_sock_service_create(sock) != FTP_ERR_SUCCESS)
+    {
+        LOGE("FTP data services create fail.");
+        return FTP_ERR_UNKNOWN;
+    }
+
+    uint8 *ptr = sock->host;
+    while (*ptr)
+    {
+        if (*ptr == '.')
+            *ptr = ',';
+        ptr++;
+    }
+    // Waitting client connect.
+    snprintf(cmd_buff, 100, "PORT %s,%d,%d\r\n", sock->host, sock->port / 256,
+             sock->port % 256);
+    code = ftp_cmd_handle(info, cmd_buff, NULL, NULL);
+    if (code / 100 != 2)   // Not 2xx
+    {
+        LOGE("PORT rsp error[code = %d].", code);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return FTP_ERR_SUCCESS;
+}
+
+static mbtk_ftp_error_enum ftp_sock_set_by_eprt(mbtk_ftp_info_s *info,
+        mbtk_ftp_sock_s *sock)
+{
+    int code;
+    char cmd_buff[100];
+    memset(cmd_buff, 0x0, 100);
+    if (sock->port <= 1024 || strlen((char*) sock->host) == 0)
+    {
+        LOGE("FTP params set error.");
+        return FTP_ERR_PARAM_SET;
+    }
+    if (ftp_data_sock_service_create(sock) != FTP_ERR_SUCCESS)
+    {
+        LOGE("FTP data services create fail.");
+        return FTP_ERR_UNKNOWN;
+    }
+
+    // "EPRT |2|1080::8:800:200C:417A|5282|"
+    if (info->sock_info[FTP_SOCK_CTRL].addr_family == MBTK_ADDR_IPV6)
+    {
+        uint8 *ptr = NULL;
+        if (sock->host[strlen((char*) sock->host) - 1] == ']')
+            sock->host[strlen((char*) sock->host) - 1] = '\0';
+
+        if (sock->host[0] == '[')
+            ptr = sock->host + 1;
+        else
+            ptr = sock->host;
+        snprintf(cmd_buff, 100, "EPRT |2|%s|%d|\r\n", ptr, sock->port);
+    }
+    else       // IPV4 "EPRT |1|132.235.1.2|6275|"
+    {
+        snprintf(cmd_buff, 100, "EPRT |1|%s|%d|\r\n", sock->host, sock->port);
+    }
+
+    code = ftp_cmd_handle(info, cmd_buff, NULL, NULL);
+    if (code / 100 != 2)   // Not 2xx
+    {
+        LOGE("PORT rsp error[code = %d].", code);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return FTP_ERR_SUCCESS;
+}
+
+static mbtk_ftp_error_enum ftp_sock_get_by_pasv(mbtk_ftp_info_s *info,
+        mbtk_ftp_sock_s *sock)
+{
+    int code;
+    uint8 rsp[1024];
+    uint32 rsp_len = 1024;
+    memset(sock, 0x0, sizeof(mbtk_ftp_sock_s));
+    code = ftp_cmd_handle(info, "PASV\r\n", rsp, &rsp_len);
+    /* Found reply-strings include:
+     * "227 Entering Passive Mode (127,0,0,1,4,51)"
+     * "227 Data transfer will passively listen to 127,0,0,1,4,51"
+     * "227 Entering passive mode. 127,0,0,1,4,51"
+     */
+    if (code != 227)
+    {
+        LOGE("PASV rsp error[code = %d].", code);
+        if(code == 421)
+        {
+            printf("\n code:%d\n",code);
+            return FTP_ERR_UNKNOWN+1;
+        }
+        return FTP_ERR_UNKNOWN;
+    }
+
+    // Get IPv4 and port
+    uint8 *ptr = rsp + 4;
+    while (*ptr)
+    {
+        if (isdigit(*ptr))
+            break;
+        ptr++;
+    }
+    // ptr point to first digit.
+    memcpy(sock->host, ptr, strlen((char*) ptr));
+    ptr = sock->host;
+    int count = 0;
+    while (*ptr)
+    {
+        if (*ptr == ',')
+        {
+            *ptr = '.';
+            count++;
+        }
+        if (count == 4)
+        {
+            *ptr = '\0';
+            break;
+        }
+        ptr++;
+    }
+    ptr++;
+
+    // ptr point to first port digit.
+    int port1 = atoi((char*) ptr);
+    while (*ptr)
+    {
+        if (*ptr == ',')
+            break;
+        ptr++;
+    }
+    ptr++;
+
+    // ptr point to second port digit.
+    int port2 = atoi((char*) ptr);
+    sock->port = port1 * 256 + port2;
+
+    LOGI("PASV: %s:%d", sock->host, sock->port);
+
+    if(ftp_internal_ipv4_check(sock->host))
+    {
+        memset(sock->host,0x0,MBTK_FTP_IP_MAX + 1);
+        memcpy(sock->host,info->sock_info[FTP_SOCK_CTRL].host,strlen(info->sock_info[FTP_SOCK_CTRL].host));
+        LOGI("This is internal ipv4,so use IP - %s:%d",sock->host, sock->port);
+    }
+
+    return FTP_ERR_SUCCESS;
+}
+
+static mbtk_ftp_error_enum ftp_sock_get_by_epsv(mbtk_ftp_info_s *info,
+        mbtk_ftp_sock_s *sock)
+{
+    int code;
+    char rsp[1024];
+    uint32 rsp_len = 1024;
+    memset(sock, 0x0, sizeof(mbtk_ftp_sock_s));
+    // |||6446|
+    code = ftp_cmd_handle(info, "EPSV\r\n", rsp, &rsp_len);
+    if (code != 229)
+    {
+        LOGE("EPSV rsp error[code = %d].", code);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    /* positive EPSV response */
+    char *ptr = strchr(rsp, '(');
+    if (ptr)
+    {
+        unsigned int num;
+        char separator[4];
+        ptr++;
+        if (5
+            == sscanf(ptr, "%c%c%c%u%c", &separator[0], &separator[1],
+                      &separator[2], &num, &separator[3]))
+        {
+            const char sep1 = separator[0];
+            int i;
+
+            /* The four separators should be identical, or else this is an oddly
+             formatted reply and we bail out immediately. */
+            for (i = 1; i < 4; i++)
+            {
+                if (separator[i] != sep1)
+                {
+                    ptr = NULL; /* set to NULL to signal error */
+                    break;
+                }
+            }
+            if (num > 0xffff)
+            {
+                LOGE("Illegal port number in EPSV reply");
+                return FTP_ERR_UNKNOWN;
+            }
+            if (ptr)
+            {
+                sock->port = (uint32) (num & 0xffff);
+                memcpy(sock->host, info->sock_info[FTP_SOCK_CTRL].host,
+                       strlen(info->sock_info[FTP_SOCK_CTRL].host));
+            }
+        }
+        else
+        {
+            ptr = NULL;
+        }
+    }
+    if (!ptr)
+    {
+        LOGE("Weirdly formatted EPSV reply");
+        return FTP_ERR_UNKNOWN;
+    }
+
+    LOGI("PASV: %s:%d", sock->host, sock->port);
+
+    return FTP_ERR_SUCCESS;
+}
+
+/*
+ * 04-26-20  02:13PM               379193 audio_0426.zip
+ * 09-10-20  02:31PM              4660645 Log.zip
+ * 10-28-20  01:53PM       <DIR>          PicLibs
+ */
+
+ /*
+ *-rw-r--r-- 1 ftp ftp     2097152000 Feb 18 17:28 ASR1803_Linux.tar.gz_aa
+ *-rw-r--r-- 1 ftp ftp     2097152000 Feb 18 17:21 ASR1803_Linux.tar.gz_ab
+ *-rw-r--r-- 1 ftp ftp     1198057917 Feb 18 17:29 ASR1803_Linux.tar.gz_ac
+ *-rw-r--r-- 1 ftp ftp         445043 Apr 06  2021 data
+ *drwxr-xr-x 1 ftp ftp              0 Apr 10  2021 L306
+ */
+static mbtk_ftp_error_enum ftp_cmd_list_parse(mbtk_ftp_info_s *info,
+        mbtk_ftp_file_info_s *file_list)
+{
+    char line[1024];
+    char line_buf[1024];
+    int len, err;
+    mbtk_ftp_file_info_s file_ptr;
+    memset(file_list, 0x0, sizeof(mbtk_ftp_file_info_s)-sizeof(void *));
+
+    // Save file number.
+    file_list->size = 0;
+    len = 1;
+    int read_line_count=0;
+    while (len > 0)
+    {
+        if(info->auth_type!=0)
+        {
+            len = mbtk_sock_readline(info->ftp_ssl_handle,info->session_data,line_buf,1024,FTP_TIMEOUT,&err,&read_line_count,line);
+        }
+        else
+        {
+            len = sock_readline(&info->net_info, &info->sock_info[FTP_SOCK_DATA], line, 1024,FTP_TIMEOUT, &err);
+        }
+        LOGD("Line:%s", line);
+        if(len <= 0)
+            {
+                if (err == MBTK_SOCK_SUCCESS)
+                    return FTP_ERR_SUCCESS;
+                break;
+            }
+        else
+            len = strlen(line) - 1;
+        if (line[0] >= '0' && line[0] <= '9')
+        {
+            /*
+             * 04-26-20  02:13PM               379193 audio_0426.zip
+             * 09-10-20  02:31PM              4660645 Log.zip
+             * 10-28-20  01:53PM       <DIR>          PicLibs
+             */
+            line[len] = '\0';
+            /*
+            file_ptr = (mbtk_ftp_file_info_s*) malloc(
+                           sizeof(mbtk_ftp_file_info_s));
+            if (!file_ptr)
+            {
+                LOGE("malloc() fail.");
+                return FTP_ERR_UNKNOWN;
+            }
+            */
+            memset(&file_ptr, 0x0, sizeof(mbtk_ftp_file_info_s));
+
+            char str[MBTK_FTP_FILE_NAME_MAX];
+            const char *temp = line;
+            // Data
+            temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX);
+            if (strlen(str) > 0)
+            {
+                LOGV("Data:%s", str);
+            }
+
+            // Time
+            temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX);
+            if (strlen(str) > 0)
+            {
+                LOGV("Time:%s", str);
+            }
+
+            // <DIR> or file size
+            temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX);
+            if (strlen(str) > 0)
+            {
+                LOGV("<DIR>/size:%s", str);
+                if (!strcmp("<DIR>", str))
+                {
+                    file_ptr.is_file = false;
+                    file_ptr.size = 0;
+                }
+                else
+                {
+                    file_ptr.is_file = true;
+                    file_ptr.size = atoi(str);
+                }
+            }
+
+            const char *name = temp;
+            while (*name && ftp_ch_is_space(*name))
+            {
+                name++;
+            }
+
+            // Name
+            if (strlen(name) > 0)
+            {
+                LOGV("Name:%s",name);
+                memset(file_ptr.name,0,strlen(file_ptr.name)+1);
+                memcpy(file_ptr.name, name, strlen(name));
+                char *temp = (char*) file_ptr.name
+                             + strlen((char*) file_ptr.name) - 1;
+                while (ftp_ch_is_space(*temp))
+                {
+                    *temp = '\0';
+                    temp--;
+                }
+            }
+            else
+            {
+                LOGE("Can not get name[%s].", line);
+                return FTP_ERR_UNKNOWN;
+            }
+
+            (file_list->ftp_ls_cb_typedef)(&file_ptr);
+            //file_ptr->next = file_list->next;
+            //file_list->next = file_ptr;
+            //file_list->size++;
+            //free(file_ptr);
+        } else if(!ftp_ch_is_space(line[0])) {
+             /*
+             *-rw-r--r-- 1 ftp ftp     2097152000 Feb 18 17:28 ASR1803_Linux.tar.gz_aa
+             *-rw-r--r-- 1 ftp ftp     2097152000 Feb 18 17:21 ASR1803_Linux.tar.gz_ab
+             *-rw-r--r-- 1 ftp ftp     1198057917 Feb 18 17:29 ASR1803_Linux.tar.gz_ac
+             *-rw-r--r-- 1 ftp ftp         445043 Apr 06  2021 data
+             *drwxr-xr-x 1 ftp ftp              0 Apr 10  2021 L306
+             */
+            line[len] = '\0';
+             /*
+            file_ptr = (mbtk_ftp_file_info_s*) malloc(
+                           sizeof(mbtk_ftp_file_info_s));
+            if (!file_ptr)
+            {
+                LOGE("malloc() fail.");
+                return FTP_ERR_UNKNOWN;
+            }
+            */
+            memset(&file_ptr, 0x0, sizeof(mbtk_ftp_file_info_s));
+
+            char str[MBTK_FTP_FILE_NAME_MAX];
+            const char *temp = line;
+            // rwx
+            temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX);
+            if (strlen(str) > 0)
+            {
+                LOGV("rwx:%s", str);
+                file_ptr.is_file = (str[0] == '-' ? true : false);
+            }
+
+            // 1 ftp ftp
+            temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX);
+            temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX);
+            temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX);
+
+            // size
+            temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX);
+            if (strlen(str) > 0)
+            {
+                LOGV("Size:%s", str);
+                file_ptr.size = atoi(str);
+            }
+
+            // Feb 18 17:28
+            // or
+            // Apr 10  2021
+            temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX);
+            temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX);
+            temp = ftp_str_next(temp, str, MBTK_FTP_FILE_NAME_MAX);
+
+            const char *name = temp;
+            while (*name && ftp_ch_is_space(*name))
+            {
+                name++;
+            }
+
+            // Name
+            if (strlen(name) > 0)
+            {
+                LOGV("Name:%s",name);
+                memset(file_ptr.name,0,strlen(file_ptr.name)+1);
+                memcpy(file_ptr.name, name, strlen(name));
+                char *temp = (char*) file_ptr.name
+                             + strlen((char*) file_ptr.name) - 1;
+                while (ftp_ch_is_space(*temp))
+                {
+                    *temp = '\0';
+                    temp--;
+                }
+            }
+            else
+            {
+                LOGE("Can not get name[%s].", line);
+                return FTP_ERR_UNKNOWN;
+            }
+
+            (file_list->ftp_ls_cb_typedef)(&file_ptr);
+            //file_ptr->next = file_list->next;
+            //file_list->next = file_ptr;
+            //file_list->size++;
+            //free(file_ptr);
+        }else {
+            LOGE("Data error.");
+            return FTP_ERR_UNKNOWN;
+        }
+    }
+    return FTP_ERR_SUCCESS;
+}
+
+static mbtk_ftp_error_enum ftp_download_process(mbtk_ftp_info_s *info)
+{
+#define READ_BUF_SIZE 2048
+    char buff[READ_BUF_SIZE];
+    int len, err, len_read;
+    int read_count = info->file_trans.size_send;
+
+#ifdef FTP_RESUME_DEBUG
+    int count = 0;
+#endif
+
+    if (info->file_trans.size_count - read_count > READ_BUF_SIZE)
+        len_read = READ_BUF_SIZE;
+    else
+        len_read = info->file_trans.size_count - read_count;
+
+    if(info->auth_type != 0)
+        len = mbtk_sock_read(info->ftp_ssl_handle,info->session_data,buff,len_read,FTP_TIMEOUT,&err);
+    else
+        len = sock_read(&info->net_info, &info->sock_info[FTP_SOCK_DATA], buff, len_read,FTP_TIMEOUT, &err);
+    /*
+    while (len_read > 0 && (len = sock_read(&info->net_info, &info->sock_info[FTP_SOCK_DATA], buff, len_read,
+                                    FTP_TIMEOUT, &err)) > 0)
+    */
+    while (len_read > 0 && len > 0)
+    {
+        read_count += len;
+
+#ifdef FTP_RESUME_DEBUG
+        count++;
+        if (count <= 1000)
+        {
+#endif
+            if (info->file_trans.data_cb)
+            {
+                info->file_trans.data_cb(buff, len);
+            }
+            else     // Write to efs.
+            {
+                if (len != file_write(info->file_trans.fd, buff, len))
+                {
+                    LOGE("EFS write fail.");
+                    return FTP_ERR_EFS_FILE;
+                }
+            }
+            memset(buff,0,sizeof(buff));
+            info->file_trans.size_send = read_count;
+#ifdef FTP_RESUME_DEBUG
+        }
+#endif
+
+        if (info->file_trans.size_count - read_count > READ_BUF_SIZE)
+            len_read = READ_BUF_SIZE;
+        else
+            len_read = info->file_trans.size_count - read_count;
+
+        if(info->auth_type != 0)
+            len = mbtk_sock_read(info->ftp_ssl_handle,info->session_data,buff,len_read,FTP_TIMEOUT,&err);
+        else
+            len = sock_read(&info->net_info, &info->sock_info[FTP_SOCK_DATA], buff, len_read,FTP_TIMEOUT, &err);
+    }
+
+    return FTP_ERR_SUCCESS;
+}
+
+static mbtk_ftp_error_enum ftp_update_process(mbtk_ftp_info_s *info)
+{
+#define READ_BUF_SIZE 2048
+    char buff[READ_BUF_SIZE];
+    int len, err, len_write;
+	int file_total_size = 0;
+    int write_count = 0;
+
+	if(info->file_trans.fd > 0)
+	{
+		file_total_size = file_length(info->file_trans.fd);
+        info->file_trans.size_count = file_total_size;
+		while((len_write = file_read(info->file_trans.fd, buff, READ_BUF_SIZE)) > 0 )
+		{
+			LOGE("file_read.len:%d, buf；%s", len_write, buff);
+            if(info->auth_type != 0)
+                len = mbtk_sock_write(info->ftp_ssl_handle,info->session_data,buff,len_write,FTP_TIMEOUT,&err);
+            else
+			    len = sock_write(&info->net_info, &info->sock_info[FTP_SOCK_DATA], buff, len_write,
+                                    FTP_TIMEOUT, &err);
+			if(len < 0)
+			{
+				LOGE("EFS write fail.len:%d, err；%d", len, err);
+                return FTP_ERR_EFS_FILE;
+			}
+
+			write_count += len;
+		}
+
+        info->file_trans.size_send = write_count;
+		if( write_count != file_total_size)
+		{
+			LOGE("socket write fail.,file_total_size:%d, write_count:%d", file_total_size,write_count);
+            return FTP_ERR_NET_WRITE;
+		}
+		else{
+			LOGE("socket write success.,file_total_size:%d, write_count:%d", file_total_size, write_count);
+		}
+
+	}
+	else
+	{
+		LOGE("EFS write fail.");
+        return FTP_ERR_EFS_FILE;
+	}
+
+	return FTP_ERR_SUCCESS;
+}
+
+
+/*
+ * audio_0426.zip
+ * Log.zip
+ * PicLibs
+ */
+static mbtk_ftp_error_enum ftp_cmd_nlst_parse(mbtk_ftp_info_s *info,
+        mbtk_ftp_file_info_s *file_list)
+{
+    char line[1024];
+    int len, err;
+    mbtk_ftp_file_info_s *file_ptr = NULL;
+    while ((len = sock_readline(&info->net_info, &info->sock_info[FTP_SOCK_DATA], line, 1024,
+                                FTP_TIMEOUT, &err)) > 0)
+    {
+        if (!ftp_ch_is_space(line[0]))
+        {
+            file_ptr = (mbtk_ftp_file_info_s*) malloc(
+                           sizeof(mbtk_ftp_file_info_s));
+            if (!file_ptr)
+            {
+                LOGE("malloc() fail.");
+                return FTP_ERR_UNKNOWN;
+            }
+            memset(file_ptr, 0x0, sizeof(mbtk_ftp_file_info_s));
+            memcpy(file_ptr->name, line, strlen(line));
+            char *temp = (char*) file_ptr->name + strlen((char*) file_ptr->name)
+                         - 1;
+            while (ftp_ch_is_space(*temp))
+            {
+                *temp = '\0';
+                temp--;
+            }
+
+            file_ptr->next = file_list->next;
+            file_list->next = file_ptr;
+        }
+    }
+    return FTP_ERR_SUCCESS;
+}
+
+static mbtk_ftp_error_enum ftp_data_sock_read(mbtk_ftp_info_s *info,
+        mbtk_ftp_cmd_enum cmd, void *req, void *rsp)
+{
+    int err, len, code;
+    mbtk_ftp_error_enum result = FTP_ERR_SUCCESS;
+    char buff[1024];
+    if (info->is_data_sock_busy)
+    {
+        LOGW("Data socket is busy!");
+        return FTP_ERR_DATA_SOCK_BUSY;
+    }
+
+    info->is_data_sock_busy = true;
+    // Connect to service by data socket.
+    if (info->data_mode == FTP_MODE_PASSIVE)
+    {
+        mbtk_ftp_sock_s sock;
+        if(info->auth_type != FTP_AUTH_TYPE_NON) {
+            // PROT P
+            char cmd_ssl[50];
+            memset(cmd_ssl,0,50);
+            snprintf(cmd_ssl, 50, "PROT P\r\n");
+            code = ftp_cmd_handle(info, cmd_ssl, NULL,NULL);
+            if (code/100 != 2)
+            {
+                LOGE("PROT P error[code = %d].", code);
+                goto end;
+            }
+        }
+
+        if (info->sock_info[FTP_SOCK_CTRL].addr_family == MBTK_ADDR_IPV6)
+        {
+            if ((result = ftp_sock_get_by_epsv(info, &sock))
+                != FTP_ERR_SUCCESS)
+            {
+                goto end;
+            }
+        }
+        else
+        {
+            if ((result = ftp_sock_get_by_pasv(info, &sock))
+                != FTP_ERR_SUCCESS)
+            {
+                printf("\nftp_sock_get_by_pasv end.result=%d\n",result);
+            }
+            else
+            {
+                printf("\nftp_sock_get_by_pasv ok!\n");
+            }
+        }
+
+        if(info->auth_type != FTP_AUTH_TYPE_NON)
+        {
+            info->ftp_ssl_handle_data = mbtk_sock_init(&info->ftp_ssl_info_data);
+            if(info->ftp_ssl_handle_data == -1)
+            {
+                printf("mbtk_sock_init error\n");
+            }
+            info->ftp_sock_ssl_info_data = (mbtk_sock_info*) malloc(sizeof(mbtk_sock_info));
+            memset(info->ftp_sock_ssl_info_data, 0x0, sizeof(mbtk_sock_info));
+            info->ftp_sock_ssl_info_data->is_support_ssl = info->auth_type;
+            info->ftp_sock_ssl_info_data->ftp_ssl_support=1;
+            info->ftp_sock_ssl_info_data->port = sock.port;
+            info->ftp_sock_ssl_info_data->type = MBTK_SOCK_TCP;
+            info->ftp_sock_ssl_info_data->ingnore_cert = ~(info->sock_info[FTP_SOCK_CTRL].use_cert);
+            memcpy(info->ftp_sock_ssl_info_data->address, sock.host, strlen(sock.host));
+            if(info->ftp_sock_ssl_info_data->is_support_ssl != 0)
+            {
+                info->ftp_sock_ssl_info_data->is_support_ssl = 0;
+            }
+            info->session_data = mbtk_sock_open(info->ftp_ssl_handle,info->ftp_sock_ssl_info_data,60000,&err);
+            if(err!=0)
+            {
+                printf("mbtk_sock_open error : %d\n",err);
+            }
+            else
+            {
+                info->ftp_sock_ssl_info_data->is_support_ssl = info->auth_type;
+                //printf("\ninfo->session_data = %d \n",info->session_data);
+            }
+        }
+        else
+        {
+            memcpy(info->sock_info[FTP_SOCK_DATA].host, sock.host, strlen((char*)sock.host));
+            info->sock_info[FTP_SOCK_DATA].port = sock.port;
+            info->sock_info[FTP_SOCK_DATA].is_ssl = (info->auth_type != FTP_AUTH_TYPE_NON);
+            info->sock_info[FTP_SOCK_DATA].addr_family = info->sock_info[FTP_SOCK_CTRL].addr_family;
+            info->sock_info[FTP_SOCK_DATA].use_cert = info->sock_info[FTP_SOCK_CTRL].use_cert;
+            info->net_info.keep_alive = FALSE;
+            info->net_info.recv_buff_size = 32 * 1024; // 32K
+            info->sock_info[FTP_SOCK_DATA].fd = sock_open(&info->net_info, &info->sock_info[FTP_SOCK_DATA],
+                                                    FTP_TIMEOUT, &err);
+        }
+
+    }
+    else    // Active mode
+    {
+        if (req == NULL)
+        {
+            result = FTP_ERR_PARAM_SET;
+            goto end;
+        }
+        mbtk_ftp_sock_s *sock = (mbtk_ftp_sock_s*) req;
+
+        if (info->sock_info[FTP_SOCK_CTRL].addr_family == MBTK_ADDR_IPV6)
+        {
+            if ((result = ftp_sock_set_by_eprt(info, sock))
+                != FTP_ERR_SUCCESS)
+            {
+                goto end;
+            }
+        }
+        else
+        {
+            if ((result = ftp_sock_set_by_port(info, sock))
+                != FTP_ERR_SUCCESS)
+            {
+                goto end;
+            }
+        }
+
+        // Wait for client[service] connect.
+
+    }
+    if(info->auth_type != FTP_AUTH_TYPE_NON)
+    {
+        if(info->session_data < 0)
+        {
+               //printf("Socket open/connect ssl fail[err = %d].", err);
+               result = FTP_ERR_NET_CONN;
+               goto read_end;
+        }
+    }
+    else
+    {
+        if (info->sock_info[FTP_SOCK_DATA].fd < 0)
+        {
+            LOGE("Socket open/connect fail[err = %d].", err);
+            result = FTP_ERR_NET_CONN;
+            goto read_end;
+        }
+
+        if(info->auth_type == FTP_AUTH_TYPE_IMPLICIT) {
+            info->sock_info[FTP_SOCK_DATA].is_ssl = true;
+        }
+    }
+
+    if (cmd == FTP_CMD_GET)   // Is download
+    {
+        char cmd[100];
+        if (info->file_trans.size_send > 0)   // Resume transmission
+        {
+            // REST size
+            memset(cmd, 0x0, 100);
+            snprintf(cmd, 100, "REST %ld\r\n", info->file_trans.size_send);
+            code = ftp_cmd_handle(info, cmd, NULL, NULL);
+            if (code != 350)
+            {
+                LOGE("REST rsp error[code = %d].", code);
+                result = FTP_ERR_UNKNOWN;
+                goto end;
+            }
+        }
+
+        memset(cmd, 0x0, 100);
+        snprintf(cmd, 100, "RETR %s\r\n", info->file_trans.remote_name);
+        code = ftp_cmd_handle(info, cmd, NULL, NULL);
+        if (code != 125 && code != 150)
+        {
+            LOGE("RETR %s rsp error[code = %d].", info->file_trans.remote_name,
+                 code);
+            result = FTP_ERR_UNKNOWN;
+            goto end;
+        }
+
+        int mbtk_errno;
+        if(info->auth_type != 0)
+        {
+            mbtk_errno = mbtk_ssl_init_func(info->ftp_ssl_handle,info->ftp_sock_ssl_info_data->ingnore_cert,info->session_data);
+            if(mbtk_errno != 0)
+            {
+                printf("\nmbtk_ssl_init_func error = %d",mbtk_errno);
+                goto end;
+            }
+
+        }
+        result = ftp_download_process(info);
+        if(info->auth_type != 0)
+        {
+            char mbtk_ftp_ssl_read_buf[256];
+            memset(mbtk_ftp_ssl_read_buf,0,sizeof(mbtk_ftp_ssl_read_buf));
+            mbtk_sock_read(info->ftp_ssl_handle,info->session,
+                                       mbtk_ftp_ssl_read_buf,
+                                       sizeof(mbtk_ftp_ssl_read_buf),
+                                       6000,
+                                       &mbtk_errno);
+            printf("\nmbtk_sock_read:\n%s\n",mbtk_ftp_ssl_read_buf);
+        }
+        if(info->auth_type != 0)
+            goto read_end;
+    }
+	else if (cmd == FTP_CMD_PUT)   // Is download
+    {
+        if(info->auth_type != 0)
+        {
+                int mbtk_errno;
+                char cmd[100];
+                memset(cmd, 0x0, 100);
+                snprintf(cmd, 100, "STOR %s\r\n", info->file_trans.remote_name);
+        		LOGE("STOR %s .name:%s ", cmd, info->file_trans.remote_name);
+                code = ftp_cmd_handle(info, cmd, NULL, NULL);
+                if (code != 125 && code != 150)
+                {
+                    LOGE("RETR %s rsp error[code = %d].", info->file_trans.remote_name,
+                         code);
+                    //printf("RETR %s rsp error[code = %d].\n", info->file_trans.remote_name,code);
+                    result = FTP_ERR_UNKNOWN;
+                    goto end;
+                }
+
+                mbtk_errno = mbtk_ssl_init_func(info->ftp_ssl_handle,info->ftp_sock_ssl_info_data->ingnore_cert,info->session_data);
+                if(mbtk_errno != 0)
+                {
+                    printf("\nmbtk_ssl_init_func error = %d",mbtk_errno);
+                    goto end;
+                }
+                if(info->file_trans.size_count == 0)
+            	{
+            	    result = ftp_update_process(info);
+            	    goto read_end;
+            	}
+            	else
+            	{
+                    //printf("FTP_SOCK_DATA,fd:%d\n",info->file_trans.size_count);
+            	    return FTP_ERR_SUCCESS;
+            	}
+            goto end;
+        }
+        else
+        {
+            char cmd[100];
+            memset(cmd, 0x0, 100);
+            snprintf(cmd, 100, "STOR %s\r\n", info->file_trans.remote_name);
+    		LOGE("STOR %s .name:%s ", cmd, info->file_trans.remote_name);
+            code = ftp_cmd_handle(info, cmd, NULL, NULL);
+            if (code != 125 && code != 150)
+            {
+                LOGE("RETR %s rsp error[code = %d].", info->file_trans.remote_name,
+                     code);
+                result = FTP_ERR_UNKNOWN;
+                goto end;
+            }
+
+        	if(info->file_trans.size_count == 0)
+        	{
+        	    result = ftp_update_process(info);
+        	    goto read_end;
+        	}
+        	else
+        	{
+                    LOGE("FTP_SOCK_DATA,fd:%d", info->sock_info[FTP_SOCK_DATA].fd);
+        	    return FTP_ERR_SUCCESS;
+        	}
+        }
+    }
+    else if (cmd == FTP_CMD_LIST)
+    {
+        if(info->auth_type != 0)
+        {
+        	int mbtk_errno;
+        	code = ftp_cmd_handle(info, "LIST\r\n", NULL, NULL);
+        	if (code != 125 && code != 150)
+            {
+            	LOGE("LIST rsp error[code = %d].", code);
+                result = FTP_ERR_UNKNOWN;
+                goto read_end;
+            }
+
+            mbtk_errno = mbtk_ssl_init_func(info->ftp_ssl_handle,info->ftp_sock_ssl_info_data->ingnore_cert,info->session_data);
+            if(mbtk_errno != 0)
+            {
+            	printf("\nmbtk_ssl_init_func error = %d",mbtk_errno);
+                goto read_end;
+            }
+
+            result = ftp_cmd_list_parse(info, (mbtk_ftp_file_info_s*) rsp);
+            char mbtk_ftp_ssl_read_buf[1024];
+            memset(mbtk_ftp_ssl_read_buf,0,sizeof(mbtk_ftp_ssl_read_buf));
+            mbtk_sock_read(info->ftp_ssl_handle,info->session,
+                                mbtk_ftp_ssl_read_buf,
+                                sizeof(mbtk_ftp_ssl_read_buf),
+                                6000,
+                                &mbtk_errno);
+            printf("\nmbtk_sock_read:\n%s\n",mbtk_ftp_ssl_read_buf);
+            int rsp_code = atoi(mbtk_ftp_ssl_read_buf);
+            if(rsp_code / 200)
+            	result = FTP_ERR_SUCCESS;
+            goto read_end;
+        }
+        else
+        {
+            code = ftp_cmd_handle(info, "LIST\r\n", NULL, NULL);
+            if (code != 125 && code != 150)
+            {
+                LOGE("LIST rsp error[code = %d].", code);
+                result = FTP_ERR_UNKNOWN;
+                goto end;
+            }
+
+            result = ftp_cmd_list_parse(info, (mbtk_ftp_file_info_s*) rsp);
+        }
+    }
+    else if (cmd == FTP_CMD_NLST)
+    {
+        code = ftp_cmd_handle(info, "NLST\r\n", NULL, NULL);
+        if (code != 125 && code != 150)
+        {
+            LOGE("LIST rsp error[code = %d].", code);
+            result = FTP_ERR_UNKNOWN;
+            goto end;
+        }
+
+        result = ftp_cmd_nlst_parse(info, (mbtk_ftp_file_info_s*) rsp);
+    }
+    else
+    {
+        LOGE("No support this cmd[%d].", cmd);
+        result = FTP_ERR_UNKNOWN;
+        goto read_end;
+    }
+
+    // Read [226 Transfer complete.]
+read_code:
+    memset(buff, 0x0, 1024);
+    len = sock_readline(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], buff, 1024, FTP_TIMEOUT,
+                    &err);
+    if (len <= 0)
+    {
+        LOGE("Socket read fail[len = %d].", len);
+        result = FTP_ERR_NET_READ;
+        goto sock_error;
+    }
+    LOGI("RSP[len-%d]:%s",len,buff);
+    //log_hex("FTP_RSP",buff,len);
+    code = atoi(buff);
+    if (code == 0)
+    {
+        goto read_code;
+    }
+#if 1
+    // 426 Connection closed; aborted transfer of "/files/test"
+    else if (code == 426)
+    {
+        LOGE("Connection closed,restart download...");
+        result = FTP_ERR_UNKNOWN;
+        goto sock_error;
+    }
+#endif
+    else if (code != 226)
+    {
+        LOGE("Code not be 226[%s].", buff);
+        result = FTP_ERR_UNKNOWN;
+        goto read_end;
+    }
+
+    goto read_end;
+sock_error:
+    {
+        if (info->sock_info[FTP_SOCK_CTRL].fd > 0)
+        {
+            if (sock_close(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], FTP_TIMEOUT, &err))
+            {
+                LOGE("Close ctrl socket fail[%d].", err);
+            }
+        }
+        info->state = FTP_STATE_NON;
+        info->sock_info[FTP_SOCK_CTRL].fd = -1;
+    }
+read_end:
+    // Close data socket.
+    if (info->sock_info[FTP_SOCK_DATA].fd > 0)
+    {
+        if (sock_close(&info->net_info, &info->sock_info[FTP_SOCK_DATA], FTP_TIMEOUT, &err))
+        {
+            LOGE("Close data socket fail[%d].", err);
+            result = FTP_ERR_NET_CLOSE;
+        }
+        else
+        {
+            info->sock_info[FTP_SOCK_DATA].fd = -1;
+        }
+    }
+    if(info->auth_type != 0)
+    {
+        if(mbtk_sock_close(info->ftp_ssl_handle,info->session_data,6000,&err))
+        {
+            LOGE("Close ssl data socket fail[%d].", err);
+            result = FTP_ERR_NET_CLOSE;
+        }
+        else
+        {
+        //    info->sock_info[FTP_SOCK_DATA].fd = -1;
+        }
+    }
+    if (info->data_mode == FTP_MODE_PASSIVE)
+    {
+
+    }
+    else
+    {
+
+    }
+
+end:
+    // Default is passive.
+    info->data_mode = FTP_MODE_PASSIVE;
+    info->is_data_sock_busy = false;
+
+    return result;
+}
+
+static mbtk_ftp_error_enum ftp_cmd_process_pwd(mbtk_ftp_info_s *info,
+        char *path)
+{
+    int code;
+    char rsp[100];
+    uint32 rsp_len = 100;
+    code = ftp_cmd_handle(info, "PWD\r\n", rsp, &rsp_len);
+    if (code != 257)
+    {
+        LOGE("PWD rsp error[code = %d].", code);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    // "path" is current ....
+    char *ptr = strchr(rsp, '"');
+    if (!ptr)
+    {
+        LOGE("PWD rsp error[%d].", code);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    ptr++;
+    char *ptr_temp = ptr;
+    while (*ptr_temp)
+    {
+        if (*ptr_temp == '"')
+        {
+            *ptr_temp = '\0';
+            break;
+        }
+        ptr_temp++;
+    }
+    memcpy(path, ptr, strlen(ptr));
+    path[strlen(ptr)] = '\0';
+
+    return FTP_ERR_SUCCESS;
+}
+
+static mbtk_ftp_error_enum ftp_cmd_process_cwd(mbtk_ftp_info_s *info,
+        const char *path)
+{
+    int code;
+    char cmd[100] = { 0 };
+    snprintf(cmd, 100, "CWD %s\r\n", path);
+    code = ftp_cmd_handle(info, cmd, NULL, NULL);
+    if (code != 250)
+    {
+        LOGE("CWD rsp error[code = %d].", code);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return FTP_ERR_SUCCESS;
+}
+
+static mbtk_ftp_error_enum ftp_cmd_process_mkd(mbtk_ftp_info_s *info,
+        const char *path)
+{
+    int code;
+    char cmd[100] = { 0 };
+    snprintf(cmd, 100, "MKD %s\r\n", path);
+    code = ftp_cmd_handle(info, cmd, NULL, NULL);
+    if (code == 257)
+    {
+        return FTP_ERR_SUCCESS;
+    }
+    else if (code == 550)
+    {
+        LOGE("Dir has exist[%s].", path);
+        return FTP_ERR_FILE_EXIST;
+    }
+    else
+    {
+        LOGE("MKD rsp error[code = %d].", code);
+        return FTP_ERR_UNKNOWN;
+    }
+}
+
+static mbtk_ftp_error_enum ftp_cmd_process_rmd(mbtk_ftp_info_s *info,
+        const char *path)
+{
+    int code;
+    char cmd[100] = { 0 };
+    snprintf(cmd, 100, "RMD %s\r\n", path);
+    code = ftp_cmd_handle(info, cmd, NULL, NULL);
+    if (code == 250)
+    {
+        return FTP_ERR_SUCCESS;
+    }
+    else if (code == 550)
+    {
+        LOGE("Dir not exist or not empty[%s].", path);
+        return FTP_ERR_FILE_NO_FOUND;
+    }
+    else
+    {
+        LOGE("RMD rsp error[code = %d].", code);
+        return FTP_ERR_UNKNOWN;
+    }
+}
+
+static mbtk_ftp_error_enum ftp_cmd_process_stat(mbtk_ftp_info_s *info,
+        void *status)
+{
+    int code;
+    char rsp[1024];
+    uint32 rsp_len = 1024;
+    code = ftp_cmd_handle(info, "STAT\r\n", rsp, &rsp_len);
+    if (code != 211)
+    {
+        LOGE("STAT rsp error[code = %d].", code);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    memcpy(status, rsp, rsp_len);
+
+    return FTP_ERR_SUCCESS;
+}
+
+static mbtk_ftp_error_enum ftp_cmd_process_type(mbtk_ftp_info_s *info,
+        mbtk_ftp_data_type_enum type)
+{
+    int code;
+    if (type == FTP_DATA_TYPE_I)
+        code = ftp_cmd_handle(info, "TYPE I\r\n", NULL, NULL);
+    else if (type == FTP_DATA_TYPE_E)
+        code = ftp_cmd_handle(info, "TYPE E\r\n", NULL, NULL);
+    else
+        code = ftp_cmd_handle(info, "TYPE A\r\n", NULL, NULL);
+
+    if (code != 200)
+    {
+        LOGE("TYPE rsp error[code = %d].", code);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return FTP_ERR_SUCCESS;
+}
+
+static mbtk_ftp_error_enum ftp_cmd_process_size(mbtk_ftp_info_s *info,
+        const char *path, uint32 *size)
+{
+    int code;
+    char cmd[100] = { 0 };
+    char rsp[100];
+    uint32 rsp_len = 100;
+    snprintf(cmd, 100, "SIZE %s\r\n", path);
+    code = ftp_cmd_handle(info, cmd, rsp, &rsp_len);
+
+    if (code == 213)
+    {
+        // "213 4660645"
+        *size = atoi(rsp + 4);
+    }
+    else if (code == 550)
+    {
+        LOGW("No found file[%s].", path);
+        return FTP_ERR_FILE_NO_FOUND;
+    }
+    else
+    {
+        LOGE("SIZE rsp error[code = %d].", code);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return FTP_ERR_SUCCESS;
+}
+
+static mbtk_ftp_error_enum ftp_cmd_process_mdtm(mbtk_ftp_info_s *info,
+        const char *path, char *time)
+{
+    int code;
+    char cmd[100] = { 0 };
+    char rsp[100];
+    uint32 rsp_len = 100;
+    snprintf(cmd, 100, "MDTM %s\r\n", path);
+    code = ftp_cmd_handle(info, cmd, rsp, &rsp_len);
+
+    if (code == 213)
+    {
+        // "213 20181017014716"
+        memcpy(time, rsp + 4, 14);
+    }
+    else if (code == 550)
+    {
+        LOGW("No found file[%s].", path);
+        return FTP_ERR_FILE_NO_FOUND;
+    }
+    else
+    {
+        LOGE("MDTM rsp error[code = %d].", code);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return FTP_ERR_SUCCESS;
+}
+
+static mbtk_ftp_error_enum ftp_cmd_process_dele(mbtk_ftp_info_s *info,
+        const char *path)
+{
+    int code;
+    char cmd[100] = { 0 };
+    snprintf(cmd, 100, "DELE %s\r\n", path);
+    code = ftp_cmd_handle(info, cmd, NULL, NULL);
+    if (code == 250)
+    {
+        return FTP_ERR_SUCCESS;
+    }
+    else if (code == 550)
+    {
+        LOGW("No found file[%s].", path);
+        return FTP_ERR_FILE_NO_FOUND;
+    }
+    else
+    {
+        LOGE("DELE rsp error[code = %d].", code);
+        return FTP_ERR_UNKNOWN;
+    }
+}
+
+static mbtk_ftp_error_enum ftp_cmd_process_quit(mbtk_ftp_info_s *info)
+{
+    int code;
+    code = ftp_cmd_handle(info, "QUIT\r\n", NULL, NULL);
+    if (code != 221)
+    {
+        LOGE("CWD rsp error[code = %d].", code);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return FTP_ERR_SUCCESS;
+}
+
+static mbtk_ftp_error_enum ftp_cmd_process(mbtk_ftp_info_s *info,
+        mbtk_ftp_cmd_enum cmd, void *req, void *rsp)
+{
+    mbtk_ftp_error_enum result = FTP_ERR_SUCCESS;
+    if (info->state == FTP_STATE_READY)   // FTP login
+    {
+        info->state = FTP_STATE_CMD_PROCESS;
+        switch (cmd)
+        {
+            case FTP_CMD_LIST:
+            {
+                result = ftp_data_sock_read(info, FTP_CMD_LIST, req, rsp);
+                break;
+            }
+            case FTP_CMD_NLST:
+            {
+                result = ftp_data_sock_read(info, FTP_CMD_NLST, req, rsp);
+                break;
+            }
+            case FTP_CMD_PWD:
+            {
+                result = ftp_cmd_process_pwd(info, rsp);
+                break;
+            }
+            case FTP_CMD_CWD:
+            {
+                result = ftp_cmd_process_cwd(info, (char*) req);
+                break;
+            }
+            case FTP_CMD_MKD:
+            {
+                result = ftp_cmd_process_mkd(info, (char*) req);
+                break;
+            }
+            case FTP_CMD_RMD:
+            {
+                result = ftp_cmd_process_rmd(info, (char*) req);
+                break;
+            }
+            case FTP_CMD_STAT:
+            {
+                result = ftp_cmd_process_stat(info, rsp);
+                break;
+            }
+            case FTP_CMD_TYPE:
+            {
+                mbtk_ftp_data_type_enum *type = (mbtk_ftp_data_type_enum*) req;
+                result = ftp_cmd_process_type(info, *type);
+                break;
+            }
+            case FTP_CMD_SIZE:
+            {
+                result = ftp_cmd_process_size(info, (char*) req, (uint32*) rsp);
+                break;
+            }
+            case FTP_CMD_MDTM:
+            {
+                result = ftp_cmd_process_mdtm(info, (char*) req, (char*) rsp);
+                break;
+            }
+            case FTP_CMD_DELE:
+            {
+                result = ftp_cmd_process_dele(info, (char*) req);
+                break;
+            }
+            case FTP_CMD_QUIT:
+            {
+                result = ftp_cmd_process_quit(info);
+                break;
+            }
+            default:
+            {
+                LOGE("Unknown cmd:%d", cmd);
+                result = FTP_ERR_UNKNOWN;
+                break;
+            }
+        }
+        info->state = FTP_STATE_READY;
+    }
+    else
+    {
+        LOGW("FTP state error[%d].", info->state);
+        result = FTP_ERR_UNKNOWN;
+    }
+
+    return result;
+}
+
+static mbtk_ftp_error_enum ftp_login(mbtk_ftp_info_s *info,mbtk_ftp_user_info_s *user)
+{
+    // Open net in the first.
+    if(info->net_info.net_id <= 0) {
+        if(sock_net_open(&info->net_info,info->sock_info[FTP_SOCK_CTRL].addr_family))
+        {
+            LOGE("sock_net_open() fail.");
+            return FTP_ERR_NET_CONN;
+        }
+    }
+
+    int err;
+    mbtk_ftp_error_enum ftp_err = FTP_ERR_SUCCESS;
+    info->state = FTP_STATE_CONNECTING;
+    info->net_info.keep_alive = TRUE;
+    info->net_info.recv_buff_size = 0; // Default
+    info->sock_info[FTP_SOCK_CTRL].fd = sock_open(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], FTP_TIMEOUT, &err);
+    if (info->sock_info[FTP_SOCK_CTRL].fd < 0)   // Fail
+    {
+        LOGE("Socket open/connect fail[err = %d].", err);
+        ftp_err = FTP_ERR_NET_CONN;
+        goto login_fail;
+    }
+
+    if(info->auth_type == FTP_AUTH_TYPE_IMPLICIT)
+        info->sock_info[FTP_SOCK_CTRL].is_ssl = true;
+
+    // Ctrl socket connect success.
+    info->state = FTP_STATE_CONNECTED;
+    LOGI("FTP ctrl socket connected.");
+
+    char buff[1024];
+    int len;
+    char *ptr = NULL;
+
+    // 220-FileZilla Server version 0.9.43 beta
+    // 220-written by Tim Kosse (tim.kosse@filezilla-project.org)
+    // 220 Please visit http://sourceforge.net/projects/filezilla/
+    while(TRUE) {
+        memset(buff, 0x0, 1024);
+        len = sock_readline(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], buff, 1024, FTP_TIMEOUT,
+                            &err);
+        if (len <= 0)
+        {
+            LOGE("Socket read fail[err = %d].", err);
+            ftp_err = FTP_ERR_NET_READ;
+            goto login_fail;
+        } else {// xxx yyyyyy
+            if((ptr = strstr(buff,"220 ")) || (ptr = strstr(buff,"230 "))) {
+                LOGI("RSP:%s",ptr);
+                break;
+            }
+        }
+    }
+
+    int code = atoi(ptr);
+    if (code == 230)   // Has logged in.
+    {
+        info->state = FTP_STATE_READY;
+        LOGI("FTP Has logged in.");
+        return FTP_ERR_SUCCESS;
+    }
+    else if (code == 220)       // Should logn in.
+    {
+        int len;
+        char cmd_buff[50];
+
+#if 0
+        // Read other data.
+        char buff[1024];
+        memset(buff,0x0,1024);
+        while((len = sock_read(&info->net_info,info->ctrl_sock.fd, buff, 1024, info->ssl_enable, 1000,
+                                &err)) > 0)
+        {
+            LOGI("RSP[%d]:%s",len,buff);
+            memset(buff,0x0,1024);
+        }
+#endif
+
+        if(info->auth_type == FTP_AUTH_TYPE_EXPLICIT_SSL
+            || info->auth_type == FTP_AUTH_TYPE_EXPLICIT_TLS) {
+            if(info->auth_type == FTP_AUTH_TYPE_EXPLICIT_SSL) {
+                len = snprintf(cmd_buff, 50, "AUTH SSL\r\n");
+            } else {
+                len = snprintf(cmd_buff, 50, "AUTH TLS\r\n");
+            }
+            cmd_buff[len] = '\0';
+            code = ftp_cmd_handle(info, cmd_buff, NULL, NULL);
+            if (code != 234 && code != 334)
+            {
+                LOGE("AUTH SSL/TLS fail[code = %d].", code);
+                ftp_err = FTP_ERR_LOGIN_DENIED;
+                goto login_fail;
+            }
+
+#if 0
+            if(sock_ssl_enable(&info->net_info,info->ctrl_sock.fd
+                ,info->ctrl_sock.host,info->ctrl_sock.port,info->use_cert,FTP_TIMEOUT)){
+                LOGE("sock_ssl_enable() fail.");
+                ftp_err = FTP_ERR_LOGIN_DENIED;
+                goto login_fail;
+            }
+#endif
+            info->sock_info[FTP_SOCK_CTRL].is_ssl = true;
+        }
+
+        if(info->auth_type != FTP_AUTH_TYPE_NON) {
+            len = snprintf(cmd_buff, 50, "PBSZ 0\r\n");
+            cmd_buff[len] = '\0';
+            code = ftp_cmd_handle(info, cmd_buff, NULL, NULL);
+            if (code != 200 && code != 220)
+            {
+                LOGE("PBSZ 0 fail[code = %d].", code);
+                ftp_err = FTP_ERR_LOGIN_DENIED;
+                goto login_fail;
+            }
+        }
+
+        len = snprintf(cmd_buff, 50, "USER %s\r\n", user->name);
+        cmd_buff[len] = '\0';
+        code = ftp_cmd_handle(info, cmd_buff, NULL, NULL);
+        if (code == 331) // USER is 331
+        {
+            len = snprintf(cmd_buff, 50, "PASS %s\r\n", user->pass);
+            cmd_buff[len] = '\0';
+            code = ftp_cmd_handle(info, cmd_buff, NULL, NULL);
+        }
+
+        if (code / 100 == 2)   // USER/PASS is 2xx
+        {
+            info->state = FTP_STATE_READY;
+            LOGI("FTP logn in success.");
+            return FTP_ERR_SUCCESS;
+        }
+        else if (code == 332)   // // USER/PASS is 332
+        {
+            LOGW("Should set ACCT.");
+            ftp_err = FTP_ERR_UNKNOWN;
+            goto login_fail;
+        }
+        else
+        {
+            LOGE("FTP login denied[code = %d].", code);
+            ftp_err = FTP_ERR_LOGIN_DENIED;
+            goto login_fail;
+        }
+    }
+    else
+    {
+        LOGE("FTP code error[%d].", code);
+        ftp_err = FTP_ERR_UNKNOWN;
+        goto login_fail;
+    }
+
+login_fail:
+    info->state = FTP_STATE_NON;
+    return ftp_err;
+}
+
+static mbtk_ftp_info_s* ftp_info_find(mbtk_ftp_handle handle)
+{
+    if (!ftp_client_list)
+    {
+        LOGE("FTP Client List not init.");
+        return NULL;
+    }
+
+    mbtk_ftp_info_s *result = NULL;
+    list_first(ftp_client_list);
+    while ((result = (mbtk_ftp_info_s*) list_next(ftp_client_list)))
+    {
+        if (result->handle == handle)
+            break;
+    }
+
+    return result;
+}
+
+mbtk_ftp_handle mbtk_ftp_upload_end(mbtk_ftp_handle handle)
+{
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        printf("No such FTP handle:%d\n", handle);
+    }
+
+    char buff[1024]={0};
+    int err=0;
+    int len=0;
+    int result;
+
+    if (info->sock_info[FTP_SOCK_DATA].fd > 0)
+    {
+        if (sock_close(&info->net_info, &info->sock_info[FTP_SOCK_DATA], FTP_TIMEOUT, &err))
+        {
+            LOGE("Close data socket fail[%d].", err);
+            result = FTP_ERR_NET_CLOSE;
+        }
+        else
+        {
+        //    info->sock_info[FTP_SOCK_DATA].fd = -1;
+        }
+    }
+    if(info->auth_type != 0)
+    {
+        if(mbtk_sock_close(info->ftp_ssl_handle,info->session_data,6000,&err))
+        {
+            LOGE("Close ssl data socket fail[%d].", err);
+            result = FTP_ERR_NET_CLOSE;
+        }
+        else
+        {
+        //    info->sock_info[FTP_SOCK_DATA].fd = -1;
+        }
+    }
+    info->data_mode = FTP_MODE_PASSIVE;
+    info->is_data_sock_busy = false;
+    info->file_trans.size_count = 0;
+    info->file_trans.size_send = 0;
+
+    char line_buf[1024];
+    if(info->auth_type != 0)
+        len = mbtk_sock_read(info->ftp_ssl_handle,info->session,buff,sizeof(buff),FTP_TIMEOUT,&err);
+    else
+        len = sock_readline(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], buff, 1024, FTP_TIMEOUT, &err);
+    if(len > 0)
+    {
+        printf("\n%s\n",buff);
+        if(err != 0)
+            printf("socket read error: %d\n",err);
+    }
+    else
+    {
+        printf("socket_read error:%d\n",err);
+        result = -1;
+    }
+
+    return result;
+}
+
+static mbtk_ftp_handle ftp_next_handle()
+{
+    if (!ftp_client_list)
+    {
+        LOGE("FTP Client List not init.");
+        return -1;
+    }
+
+    mbtk_ftp_info_s *info = NULL;
+    mbtk_ftp_handle handle = 1;
+    bool used;
+    while (handle <= FTP_HANDLE_MAX)
+    {
+        used = false;
+        // This handle used?
+        list_first(ftp_client_list);
+        while ((info = (mbtk_ftp_info_s*) list_next(ftp_client_list)))
+        {
+            if (handle == info->handle)
+            {
+                used = true;
+                break;
+            }
+        }
+
+        if (!used)
+        {
+            break;
+        }
+
+        handle++;
+    }
+
+    LOGI("Get free handle:%d", handle);
+
+    return handle;
+}
+
+static void ftp_free_func(void *data)
+{
+    if (data)
+    {
+        mbtk_ftp_info_s *info = (mbtk_ftp_info_s*) data;
+        LOGI("Free FTP client[handle = %d].", info->handle);
+        free(info);
+    }
+}
+
+/*************************************************************
+ Public Function Definitions
+ *************************************************************/
+mbtk_ftp_handle mbtk_ftp_init(const void* host, uint16 port, mbtk_ftp_auth_type_enum auth_type,
+                              bool is_ipv6, bool use_cert)
+{
+    if (!ftp_client_list)
+        ftp_client_list = list_create(ftp_free_func);
+
+    if (!ftp_client_list)
+    {
+        LOGE("FTP Client List not init.");
+        return -1;
+    }
+
+    if (list_size(ftp_client_list) > FTP_HANDLE_MAX)
+    {
+        LOGE("FTP client is full.");
+        return -1;
+    }
+
+    if (host == NULL || strlen(host) == 0)
+    {
+        LOGE("Host error.");
+        return -1;
+    }
+
+    if (port == 0)
+    {
+        port = FTP_SERVICE_PORT_DEF;
+    }
+
+    mbtk_ftp_info_s *info = (mbtk_ftp_info_s*) malloc(sizeof(mbtk_ftp_info_s));
+    if (!info)
+    {
+        LOGE("malloc() fail.");
+        return -1;
+    }
+    memset(info, 0x0, sizeof(mbtk_ftp_info_s));
+    list_add(ftp_client_list, info);
+    memcpy(info->sock_info[FTP_SOCK_CTRL].host, host, strlen(host));
+    info->sock_info[FTP_SOCK_CTRL].port = port;
+    // info->auth_type == FTP_AUTH_TYPE_IMPLICIT, info->is_ipv6 ? MBTK_ADDR_IPV6 : MBTK_ADDR_IPV4,info->use_cert,
+    info->sock_info[FTP_SOCK_CTRL].is_ssl = (auth_type == FTP_AUTH_TYPE_IMPLICIT);
+    info->sock_info[FTP_SOCK_CTRL].addr_family = is_ipv6 ? MBTK_ADDR_IPV6: MBTK_ADDR_IPV4;
+    info->sock_info[FTP_SOCK_CTRL].use_cert = use_cert;
+
+    info->handle = ftp_next_handle();
+    info->state = FTP_STATE_NON;
+    info->data_mode = FTP_MODE_PASSIVE;
+    info->sock_info[FTP_SOCK_CTRL].fd = -1;
+    info->sock_info[FTP_SOCK_DATA].fd = -1;
+    //info->is_ipv6 = is_ipv6;
+    info->auth_type = auth_type;
+    //info->use_cert = use_cert;
+
+    LOGI("FTP info#host:%s,port:%d,ipv6:%d,ssl:%d,cert:%d",info->sock_info[FTP_SOCK_CTRL].host,
+            info->sock_info[FTP_SOCK_CTRL].port,
+            is_ipv6,info->auth_type,use_cert);
+
+    if(auth_type != FTP_AUTH_TYPE_NON)
+    {
+        info->ftp_ssl_handle = mbtk_sock_init(&info->ftp_ssl_info);
+        if(info->ftp_ssl_handle == -1)
+        {
+            printf("mbtk_sock_init error\n");
+        }
+
+        info->ftp_sock_ssl_info = (mbtk_sock_info*) malloc(sizeof(mbtk_sock_info));
+        memset(info->ftp_sock_ssl_info, 0x0, sizeof(mbtk_sock_info));
+        info->ftp_sock_ssl_info->is_support_ssl = (auth_type != FTP_AUTH_TYPE_NON);
+        info->ftp_sock_ssl_info->ftp_ssl_support = 1;
+        info->ftp_sock_ssl_info->port = port;
+        info->ftp_sock_ssl_info->type = MBTK_SOCK_TCP;
+        info->ftp_sock_ssl_info->ingnore_cert = !use_cert;
+        memcpy(info->ftp_sock_ssl_info->address, host, strlen(host));
+    }
+    return info->handle;
+}
+
+mbtk_ftp_error_enum mbtk_ftp_reconfig(mbtk_ftp_handle handle,const void* host, uint16 port, mbtk_ftp_auth_type_enum auth_type,
+                                      bool is_ipv6, bool use_cert)
+{
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+    if(auth_type != FTP_AUTH_TYPE_NON)
+    {
+        info->ftp_sock_ssl_info = (mbtk_sock_info*) malloc(sizeof(mbtk_sock_info));
+        memset(info->ftp_sock_ssl_info, 0x0, sizeof(mbtk_sock_info));
+        if(host && strlen(host) > 0)
+        {
+            memcpy(info->ftp_sock_ssl_info->address, host, strlen(host));
+            info->ftp_sock_ssl_info->address[strlen(host)] = '\0';
+        }
+        info->ftp_sock_ssl_info->is_support_ssl = (auth_type != FTP_AUTH_TYPE_NON);
+        info->ftp_sock_ssl_info->ftp_ssl_support = 1;
+        info->ftp_sock_ssl_info->port = port;
+        info->ftp_sock_ssl_info->ingnore_cert = !use_cert;
+        info->ftp_sock_ssl_info->type = MBTK_SOCK_TCP;
+    }
+    if(info->state == FTP_STATE_NON)
+    {
+        if(host && strlen(host) > 0)
+        {
+            memcpy(info->sock_info[FTP_SOCK_CTRL].host, host, strlen(host));
+            info->sock_info[FTP_SOCK_CTRL].host[strlen(host)] = '\0';
+        }
+        info->sock_info[FTP_SOCK_CTRL].port = port;
+        info->sock_info[FTP_SOCK_CTRL].addr_family = is_ipv6 ? MBTK_ADDR_IPV6 : MBTK_ADDR_IPV4;
+        info->auth_type = auth_type;
+        info->sock_info[FTP_SOCK_CTRL].use_cert = use_cert;
+
+        return FTP_ERR_SUCCESS;
+    }
+    else
+    {
+        LOGE("Not reset FTP config.The state is %d", info->state);
+        return FTP_ERR_UNKNOWN;
+    }
+}
+
+mbtk_ftp_error_enum mbtk_ftp_user_set(mbtk_ftp_handle handle,void* user,void* pass)
+{
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    if(info->state == FTP_STATE_NON && !str_empty(user) && !str_empty(pass))
+    {
+        memset(&info->user,0x0,sizeof(mbtk_ftp_user_info_s));
+        memcpy(info->user.name, user, strlen(user));
+        memcpy(info->user.pass, pass, strlen(pass));
+        return FTP_ERR_SUCCESS;
+    }
+    else
+    {
+        LOGE("Not reset FTP config.The state is %d", info->state);
+        return FTP_ERR_UNKNOWN;
+    }
+}
+
+mbtk_ftp_error_enum mbtk_ftp_deinit(mbtk_ftp_handle handle)
+{
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    if (list_remove(ftp_client_list, info))
+    {
+        int err;
+        if(info->auth_type == FTP_AUTH_TYPE_NON) {
+            sock_close(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], FTP_TIMEOUT, &err);
+            sock_close(&info->net_info, &info->sock_info[FTP_SOCK_DATA], FTP_TIMEOUT, &err);
+        } else {
+            mbtk_sock_deinit(info->ftp_ssl_handle);
+        }
+        ftp_free_func(info);
+    }
+
+    return FTP_ERR_SUCCESS;
+}
+
+/*
+ * Quit FTP service.
+ */
+mbtk_ftp_error_enum mbtk_ftp_quit(mbtk_ftp_handle handle)
+{
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    int err = 0;
+    if(info->sock_info[FTP_SOCK_CTRL].fd > 0) {
+        mbtk_ftp_error_enum ftp_err = ftp_cmd_process(info, FTP_CMD_QUIT, NULL,
+                                      NULL);
+        if (ftp_err != FTP_ERR_SUCCESS)
+        {
+            LOGE("FTP QUIT fail[%d].", ftp_err);
+            //return ftp_err;
+        }
+
+        // FTP quit success.
+        info->state = FTP_STATE_CONNECTED;
+    }
+
+    if(info->auth_type == FTP_AUTH_TYPE_NON) {
+        if (sock_close(&info->net_info, &info->sock_info[FTP_SOCK_CTRL], FTP_TIMEOUT, &err))
+        {
+            LOGE("Close ctrl socket fail[%d].", err);
+            return FTP_ERR_NET_CLOSE;
+        }
+
+        if (sock_close(&info->net_info, &info->sock_info[FTP_SOCK_DATA], FTP_TIMEOUT, &err))
+        {
+            LOGE("Close data socket fail[%d].", err);
+            return FTP_ERR_NET_CLOSE;
+        }
+    } else {
+        if(mbtk_sock_close(info->ftp_ssl_handle,info->session,6000,&err))
+        {
+            LOGE("Close ssl ctrl socket fail[%d].", err);
+            //return FTP_ERR_NET_CLOSE;
+        }
+
+        if(mbtk_sock_close(info->ftp_ssl_handle,info->session_data,6000,&err))
+        {
+            LOGE("Close ssl data socket fail[%d].", err);
+            //return FTP_ERR_NET_CLOSE;
+        }
+    }
+
+
+    info->state = FTP_STATE_NON;
+    info->data_mode = FTP_MODE_PASSIVE;
+    memset(&info->file_trans, 0x0, sizeof(mbtk_ftp_file_trans_info_s));
+    info->sock_info[FTP_SOCK_CTRL].fd = -1;
+    info->sock_info[FTP_SOCK_DATA].fd = -1;
+
+    return FTP_ERR_SUCCESS;
+}
+
+mbtk_ftp_error_enum mbtk_ftp_net_close(mbtk_ftp_handle handle)
+{
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    if(info->net_info.net_id > 0) {
+        int err;
+        if(sock_net_close(&info->net_info, FTP_TIMEOUT,&err))
+        {
+            LOGE("sock_net_close() fail[%ld].",err);
+            return FTP_ERR_NET_CLOSE;
+        }
+
+        info->net_info.net_id = -1;
+    }
+
+    return FTP_ERR_SUCCESS;
+}
+
+
+mbtk_ftp_info_s* mbtk_ftp_info_get(mbtk_ftp_handle handle)
+{
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return NULL;
+    }
+
+    return info;
+}
+
+/*
+ * Login specified FTP service.
+ */
+mbtk_ftp_error_enum mbtk_ftp_login(mbtk_ftp_handle handle, void *name,
+                                   void *pass)
+{
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    if (info->state == FTP_STATE_NON)
+    {
+        mbtk_ftp_user_info_s user;
+        memset(&user,0x0,sizeof(mbtk_ftp_user_info_s));
+        if (!str_empty(name) && !str_empty(pass))
+        {
+            memcpy(user.name, name, strlen(name));
+            memcpy(user.pass, pass, strlen(pass));
+            memcpy(info->user.name, name, strlen(name));
+            memcpy(info->user.pass, pass, strlen(pass));
+        }
+        else
+        {
+            memcpy(user.name, FTP_ANONYMOUS_USER, strlen(FTP_ANONYMOUS_USER));
+            memcpy(user.pass, FTP_ANONYMOUS_PASS, strlen(FTP_ANONYMOUS_PASS));
+            memcpy(info->user.name, FTP_ANONYMOUS_USER, strlen(FTP_ANONYMOUS_USER));
+            memcpy(info->user.pass, FTP_ANONYMOUS_PASS, strlen(FTP_ANONYMOUS_PASS));
+        }
+
+        LOGI("FTP login#user:%s,pass:%s",user.name,user.pass);
+
+        if(info->auth_type != 0)
+        {
+            int mbtk_errno=-1;
+            info->session = mbtk_sock_open(info->ftp_ssl_handle,info->ftp_sock_ssl_info,60000,&mbtk_errno);
+            if(mbtk_errno!=0)
+            {
+                printf("mbtk_sock_open error : %d\n",mbtk_errno);
+            }
+            else
+            {
+                unsigned char mbtk_ftp_ssl_read_buf[16384 + 1];
+                char cmd[50];
+                memset(cmd,0,50);
+                int len_ssl;
+
+
+                memset(cmd,0,50);
+                snprintf(cmd, 50, "PBSZ 0\r\n");
+                mbtk_sock_write(info->ftp_ssl_handle,info->session,
+                                    cmd,
+                                    sizeof(cmd),
+                                    60000,
+                                    &mbtk_errno);
+                memset(mbtk_ftp_ssl_read_buf,0,sizeof(mbtk_ftp_ssl_read_buf));
+                mbtk_sock_read(info->ftp_ssl_handle,info->session,
+                            mbtk_ftp_ssl_read_buf,
+                            sizeof(mbtk_ftp_ssl_read_buf),
+                            60000,
+                            &mbtk_errno);
+                printf("\nmbtk_sock_read PBSZ 0:\n%s\n",mbtk_ftp_ssl_read_buf);
+                memset(cmd,0,50);
+                snprintf(cmd, 50, "PROT P\r\n");
+                mbtk_sock_write(info->ftp_ssl_handle,info->session,
+                                    cmd,
+                                    sizeof(cmd),
+                                    60000,
+                                    &mbtk_errno);
+                memset(mbtk_ftp_ssl_read_buf,0,sizeof(mbtk_ftp_ssl_read_buf));
+                mbtk_sock_read(info->ftp_ssl_handle,info->session,
+                            mbtk_ftp_ssl_read_buf,
+                            sizeof(mbtk_ftp_ssl_read_buf),
+                            60000,
+                            &mbtk_errno);
+                printf("\nmbtk_sock_read PROT P:\n%s\n",mbtk_ftp_ssl_read_buf);
+                memset(cmd,0,50);
+                snprintf(cmd, 50, "USER %s\r\n",info->user.name);
+                mbtk_sock_write(info->ftp_ssl_handle,info->session,
+                                    cmd,
+                                    sizeof(cmd),
+                                    60000,
+                                    &mbtk_errno);
+                memset(mbtk_ftp_ssl_read_buf,0,sizeof(mbtk_ftp_ssl_read_buf));
+                mbtk_sock_read(info->ftp_ssl_handle,info->session,
+                            mbtk_ftp_ssl_read_buf,
+                            sizeof(mbtk_ftp_ssl_read_buf),
+                            60000,
+                            &mbtk_errno);
+                printf("\nmbtk_sock_read USER:\n%s\n",mbtk_ftp_ssl_read_buf);
+                memset(cmd,0,50);
+                snprintf(cmd, 50, "PASS %s\r\n",info->user.pass);
+                mbtk_sock_write(info->ftp_ssl_handle,info->session,
+                                    cmd,
+                                    sizeof(cmd),
+                                    60000,
+                                    &mbtk_errno);
+                memset(mbtk_ftp_ssl_read_buf,0,sizeof(mbtk_ftp_ssl_read_buf));
+                mbtk_sock_read(info->ftp_ssl_handle,info->session,
+                            mbtk_ftp_ssl_read_buf,
+                            sizeof(mbtk_ftp_ssl_read_buf),
+                            60000,
+                            &mbtk_errno);
+                printf("\nmbtk_sock_read PASS:\n%s\n",mbtk_ftp_ssl_read_buf);
+                char *ptr = NULL;
+                if((ptr = strstr(mbtk_ftp_ssl_read_buf,"220 ")) || (ptr = strstr(mbtk_ftp_ssl_read_buf,"230 "))) {
+                    LOGI("RSP:%s",ptr);
+                    printf("RSP:%s\n",ptr);
+                }
+                else
+                {
+                    printf("\nptr error.\n");
+                    return FTP_ERR_UNKNOWN;
+                }
+                int code = atoi(ptr);
+                if (code / 100 == 2)   // USER/PASS is 2xx
+                {
+                    info->state = FTP_STATE_READY;
+                    LOGI("FTP logn in success.");
+                    printf("FTP logn in success.\n");
+                }
+                else if (code == 332)   // // USER/PASS is 332
+                {
+                    LOGW("Should set ACCT.");
+                    printf("Should set ACCT.\n");
+                    return FTP_ERR_UNKNOWN;
+                }
+                else
+                {
+                    LOGE("FTP login denied[code = %d].", code);
+                    printf("FTP login denied[code = %d].\n", code);
+                    return FTP_ERR_UNKNOWN;
+                }
+
+                memset(cmd,0,50);
+                snprintf(cmd, 50, "PWD\r\n");
+                mbtk_sock_write(info->ftp_ssl_handle,info->session,
+                                    cmd,
+                                    sizeof(cmd),
+                                    60000,
+                                    &mbtk_errno);
+                memset(mbtk_ftp_ssl_read_buf,0,sizeof(mbtk_ftp_ssl_read_buf));
+                mbtk_sock_read(info->ftp_ssl_handle,info->session,
+                            mbtk_ftp_ssl_read_buf,
+                            sizeof(mbtk_ftp_ssl_read_buf),
+                            60000,
+                            &mbtk_errno);
+                printf("\nmbtk_sock_read PWD:\n%s\n",mbtk_ftp_ssl_read_buf);
+            }
+            return mbtk_errno;
+        }
+
+        return ftp_login(info,&user);
+    }
+    else
+    {
+        LOGD("Has login.");
+        return FTP_ERR_SUCCESS;
+    }
+}
+
+/*
+ * Get current directory's path.
+ */
+mbtk_ftp_error_enum mbtk_ftp_pwd(mbtk_ftp_handle handle, void *path)
+{
+    if (!path)
+    {
+        LOGE("No set path");
+        return FTP_ERR_PARAM_SET;
+    }
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return ftp_cmd_process(info, FTP_CMD_PWD, NULL, path);
+}
+
+/*
+ * Go to specified directory.
+ */
+mbtk_ftp_error_enum mbtk_ftp_cd(mbtk_ftp_handle handle, void *path)
+{
+    if (!path)
+    {
+        LOGE("No set path");
+        return FTP_ERR_PARAM_SET;
+    }
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return ftp_cmd_process(info, FTP_CMD_CWD, path, NULL);
+}
+
+/*
+ * Get the native ip and free port.
+ */
+mbtk_ftp_error_enum mbtk_ftp_get_ip_and_port(char *ipBuf_out,
+                                    int *port,int iptype)
+{
+    char psz_port_cmd[128];
+    int i=0;
+
+    *port = rand() % (60000 - 50000 + 1) + 50000;
+    sprintf(psz_port_cmd, "netstat -an | grep :%d > /dev/null", *port);
+
+        char ipBuf[32] = "";
+        FILE *fstream=NULL;
+
+        char buff[1024];
+        char iptype_str[8];
+        memset(buff,0,sizeof(buff));
+        /*eth0可以换成eth1、docker0、em1、lo等*/
+        if(iptype == MBTK_ADDR_IPV6)
+        {
+
+            if(NULL==(fstream=popen("ifconfig ccinet0 | grep \"inet6 addr: 2\" | awk '{print $3}'","r")))
+            {
+                snprintf(ipBuf, 39, "%s","0:0:0:0:0:0:0:0");
+            }
+            if(NULL!=fgets(buff, sizeof(buff), fstream))
+            {
+                snprintf(ipBuf, 39, "%s",buff);
+            }
+            else
+            {
+                snprintf(ipBuf, 39, "%s","0:0:0:0:0:0:0:0");
+                pclose(fstream);
+            }
+        }
+        else
+        {
+            if(NULL==(fstream=popen("ifconfig ccinet0 | grep \"inet addr:\" | awk \'{print $2}\' | cut -c 6-","r")))
+            {
+                snprintf(ipBuf, 18, "%s","0.0.0.0");
+            }
+            if(NULL!=fgets(buff, sizeof(buff), fstream))
+            {
+                snprintf(ipBuf, 18, "%s",buff);
+            }
+            else
+            {
+                snprintf(ipBuf, 18, "%s","0.0.0.0");
+                pclose(fstream);
+            }
+        }
+            pclose(fstream);
+
+        printf("ip:%s\n", ipBuf);
+        memcpy(ipBuf_out, ipBuf, 32);
+        return 0;
+}
+/*
+ * Get current directory's subdirectory.
+ */
+mbtk_ftp_error_enum mbtk_ftp_dir_ls(mbtk_ftp_handle handle,
+                                    mbtk_ftp_file_info_s *list_head)
+{
+    if (!list_head)
+    {
+        LOGE("No set file list.");
+        return FTP_ERR_PARAM_SET;
+    }
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return ftp_cmd_process(info, FTP_CMD_LIST, NULL, list_head);
+}
+
+/*
+ * Get specified file's size.
+ */
+uint32 mbtk_ftp_file_size(mbtk_ftp_handle handle, void *path)
+{
+    if (!path)
+    {
+        LOGE("No set path");
+        return 0;
+    }
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return 0;
+    }
+    uint32 size = 0;
+    if (ftp_cmd_process(info, FTP_CMD_SIZE, path, &size) != FTP_ERR_SUCCESS)
+        return 0;
+
+    return size;
+}
+
+/*
+ * Get specified file's modify time.
+ */
+mbtk_ftp_error_enum mbtk_ftp_file_time(mbtk_ftp_handle handle, void *path,
+                                       void *time)
+{
+    if (!path)
+    {
+        LOGE("No set path");
+        return FTP_ERR_PARAM_SET;
+    }
+
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return ftp_cmd_process(info, FTP_CMD_MDTM, path, time);
+}
+
+/*
+ * Delete specified file.
+ */
+mbtk_ftp_error_enum mbtk_ftp_file_del(mbtk_ftp_handle handle, void *path)
+{
+    if (!path)
+    {
+        LOGE("No set path");
+        return FTP_ERR_PARAM_SET;
+    }
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return ftp_cmd_process(info, FTP_CMD_DELE, path, NULL);
+}
+
+/*
+ * Create specified directory.
+ */
+mbtk_ftp_error_enum mbtk_ftp_dir_mkdir(mbtk_ftp_handle handle, void *path)
+{
+    if (!path)
+    {
+        LOGE("No set path");
+        return FTP_ERR_PARAM_SET;
+    }
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return ftp_cmd_process(info, FTP_CMD_MKD, path, NULL);
+}
+
+/*
+ * Delete specified directory.
+ */
+mbtk_ftp_error_enum mbtk_ftp_dir_rmdir(mbtk_ftp_handle handle, void *path)
+{
+    if (!path)
+    {
+        LOGE("No set path");
+        return FTP_ERR_PARAM_SET;
+    }
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return ftp_cmd_process(info, FTP_CMD_RMD, path, NULL);
+}
+
+/*
+ * Set data type.
+ */
+mbtk_ftp_error_enum mbtk_ftp_data_type_set(mbtk_ftp_handle handle,
+        mbtk_ftp_data_type_enum data_type)
+{
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    return ftp_cmd_process(info, FTP_CMD_TYPE, &data_type, NULL);
+}
+
+/*
+ * Set FTP mode.
+ */
+mbtk_ftp_error_enum mbtk_ftp_mode_set(mbtk_ftp_handle handle,
+                                      mbtk_ftp_mode_enum mode)
+{
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    info->data_mode = mode;
+
+    return FTP_ERR_SUCCESS;
+}
+
+uint32 mbtk_ftp_download_start(mbtk_ftp_handle handle, void *remote_path,
+                               void *local_path, mbtk_data_cb_func data_cb)
+{
+    if (!remote_path || (local_path && data_cb) || (!local_path && !data_cb))
+    {
+        LOGE("Param set error.");
+        return 0;
+    }
+
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return 0;
+    }
+
+    if (info->state >= FTP_STATE_READY && !info->is_trans)
+    {
+        int retry_time = 0;
+        memset(&info->file_trans, 0x0, sizeof(mbtk_ftp_file_trans_info_s));
+
+        // Set data type to "I"
+        if (FTP_ERR_SUCCESS
+            != mbtk_ftp_data_type_set(handle, FTP_DATA_TYPE_I))
+        {
+            LOGE("Set data type to I fail.");
+            return 0;
+        }
+
+        // Get file size.
+        info->file_trans.size_count = mbtk_ftp_file_size(handle, remote_path);
+        if (info->file_trans.size_count > 0)
+        {
+            LOGI("File size:%d", info->file_trans.size_count);
+        }
+        else
+        {
+            LOGE("File not exist.");
+            return 0;
+        }
+
+        //Get file modify time.
+        if (FTP_ERR_SUCCESS
+            != mbtk_ftp_file_time(handle, remote_path,
+                                  (char*) info->file_trans.modify_time))
+        {
+            LOGE("Get file modify time fail.");
+            return 0;
+        }
+
+        memcpy(info->file_trans.remote_name, remote_path,
+               strlen((char*) remote_path));
+        if (local_path)
+        {
+            memcpy(info->file_trans.local_name, local_path,
+                   strlen((char*) local_path));
+            info->file_trans.data_cb = NULL;
+        }
+        else
+        {
+            info->file_trans.data_cb = data_cb;
+        }
+        info->file_trans.size_send = 0;
+        info->file_trans.is_download = true;
+        info->file_trans.fd = -1;
+        info->is_trans = true;
+
+        if (!info->file_trans.data_cb)   // Save to efs
+        {
+            info->file_trans.fd = file_open((const char*)info->file_trans.local_name,
+                                            O_WRONLY | O_CREAT | O_TRUNC);
+            if (info->file_trans.fd <= 0)
+            {
+                LOGE("Can not open EFS file[%s].", info->file_trans.local_name);
+                return 0;
+            }
+        }
+
+        do {
+            // Start download file.
+            if (FTP_ERR_SUCCESS
+                != ftp_data_sock_read(info, FTP_CMD_GET, NULL, NULL))
+            {
+                LOGW("ftp_data_sock_read() fail.");
+            }
+
+            if(info->sock_info[FTP_SOCK_CTRL].fd <= 0) {
+                // Download fail.
+                LOGW("Ctrl socket error,should login angin.");
+                break;
+            } else if (info->file_trans.size_send == info->file_trans.size_count) {
+                // Download success
+                break;
+            }
+
+            // Should redownload without quit.
+            char time[20] = { 0 };
+            if (FTP_ERR_SUCCESS
+                != mbtk_ftp_file_time(handle, info->file_trans.remote_name,
+                                      time))
+            {
+                LOGE("Get file modify time fail.");
+                break;
+            }
+
+            if (strcmp(time, (char*) info->file_trans.modify_time))
+            {
+                LOGW("Service file changed.");
+                break;
+            }
+
+            retry_time++;
+        } while(retry_time < 5);
+
+
+        if (!info->file_trans.data_cb && info->file_trans.fd > 0)   // Save to efs
+        {
+            if (file_close(info->file_trans.fd))
+            {
+                LOGE("EFS close fail.");
+                return 0;
+            }
+        }
+
+        // Download success.
+        if (info->file_trans.size_send == info->file_trans.size_count)
+        {
+            LOGI("Download %s success[%d].", (char* )remote_path,
+                 info->file_trans.size_count);
+
+            // Reset download configs.
+            info->is_trans = false;
+            // memset(&info->file_trans, 0x0, sizeof(mbtk_ftp_file_trans_info_s));
+        }
+        else
+        {
+            LOGW("Download %s fail[%d / %d].", (char* )remote_path,
+                 info->file_trans.size_send, info->file_trans.size_count);
+        }
+
+        return info->file_trans.size_send;
+    }
+    else
+    {
+        LOGE("FTP state error[%d].", info->state);
+        return 0;
+    }
+}
+
+uint32 mbtk_ftp_download_continue(mbtk_ftp_handle handle)
+{
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return 0;
+    }
+
+    if(info->state == FTP_STATE_NON) {
+        if(FTP_ERR_SUCCESS != ftp_login(info,&info->user)) {
+            LOGE("FTP login fail.");
+            return 0;
+        }
+    }
+
+    if (info->state >= FTP_STATE_READY && info->is_trans
+        && info->file_trans.is_download
+        && info->file_trans.size_send < info->file_trans.size_count)
+    {
+        // Set data type to "I"
+        if (FTP_ERR_SUCCESS
+            != mbtk_ftp_data_type_set(handle, FTP_DATA_TYPE_I))
+        {
+            LOGE("Set data type to I fail.");
+            return 0;
+        }
+
+        // Get file size.
+        uint32 size = mbtk_ftp_file_size(handle, info->file_trans.remote_name);
+        if (size > 0)
+        {
+            LOGI("File size:%d", size);
+        }
+        else
+        {
+            LOGE("File not exist.");
+            return 0;
+        }
+        if (size != info->file_trans.size_count)
+        {
+            LOGW("Service file changed.");
+            return 0;
+        }
+
+        //Get file modify time.
+        char time[20] = { 0 };
+        if (FTP_ERR_SUCCESS
+            != mbtk_ftp_file_time(handle, info->file_trans.remote_name,
+                                  time))
+        {
+            LOGE("Get file modify time fail.");
+            return 0;
+        }
+        if (strcmp(time, (char*) info->file_trans.modify_time))
+        {
+            LOGW("Service file changed.");
+            return 0;
+        }
+
+        if (!info->file_trans.data_cb)   // Save to efs
+        {
+            info->file_trans.fd = file_open((const char*)info->file_trans.local_name,
+                                            O_WRONLY | O_CREAT | O_APPEND);
+            if (info->file_trans.fd <= 0)
+            {
+                LOGE("Can not open EFS file[%s].", info->file_trans.local_name);
+                return FTP_ERR_EFS_FILE;
+            }
+        }
+
+        uint32 size_last = info->file_trans.size_send;
+        // Start download file.
+        if (FTP_ERR_SUCCESS
+            != ftp_data_sock_read(info, FTP_CMD_GET, NULL, NULL))
+        {
+            LOGW("Data download fail.");
+        }
+
+        if (!info->file_trans.data_cb && info->file_trans.fd > 0)
+        {
+            if (file_close(info->file_trans.fd))
+            {
+                LOGE("EFS close fail.");
+                return 0;
+            }
+        }
+
+        // Download success.
+        if (info->file_trans.size_send == info->file_trans.size_count)
+        {
+            LOGI("Download %s success[%d].", info->file_trans.remote_name,
+                 info->file_trans.size_count);
+
+            // Reset download configs.
+            info->is_trans = false;
+            //memset(&info->file_trans, 0x0, sizeof(mbtk_ftp_file_trans_info_s));
+        }
+        else
+        {
+            LOGW("Download %s fail[%d / %d].", info->file_trans.remote_name,
+                 info->file_trans.size_send, info->file_trans.size_count);
+        }
+
+        return info->file_trans.size_send - size_last;
+    }
+    else
+    {
+        LOGE("FTP state error[%d].", info->state);
+        return 0;
+    }
+}
+
+/*
+* Upload EFS:  local_path is efs path;size_byte is 0.
+* Upload data: local_path is NULL;size_byte is data size.
+*/
+int mbtk_ftp_upload_start(mbtk_ftp_handle handle, const void *remote_path,
+                          const void *local_path, uint32 size_byte)
+{
+    if (!remote_path || (size_byte == 0 && !local_path)
+        || (size_byte > 0 && local_path))
+    {
+        LOGE("Param set error.");
+        return -1;
+    }
+
+	int result = 0;
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return -1;
+    }
+
+    LOGE("info->state:%d, info->is_trans:%d", info->state,info->is_trans);
+
+    if (info->state >= FTP_STATE_READY && !info->is_trans)
+    {
+		        // Set data type to "I"
+        if (FTP_ERR_SUCCESS
+            != mbtk_ftp_data_type_set(handle, FTP_DATA_TYPE_I))
+        {
+            LOGE("Set data type to I fail.");
+            return -1;
+        }
+
+        memset(&info->file_trans, 0x0, sizeof(mbtk_ftp_file_trans_info_s));
+        info->file_trans.is_download = false;
+
+        memcpy(info->file_trans.remote_name, remote_path,
+               strlen((char*) remote_path));
+
+        if (local_path)
+        {
+            memcpy(info->file_trans.local_name, local_path,
+                   strlen((char*) local_path));
+            info->file_trans.fd = file_open((const char*)info->file_trans.local_name,
+                                            O_RDONLY);
+            if (info->file_trans.fd <= 0)
+            {
+                LOGE("Can not open EFS file[%s].", info->file_trans.local_name);
+                return -1;
+            }
+
+        }
+        info->file_trans.size_count = size_byte;
+        info->file_trans.size_send = 0;
+        // Start upload data.
+
+
+	    // Start update file.
+        if (FTP_ERR_SUCCESS != ftp_data_sock_read(info, FTP_CMD_PUT, NULL, NULL))
+        {
+            LOGW("ftp_data_sock_read() fail.");
+			if(info->file_trans.size_count == info->file_trans.size_send && info->file_trans.size_send != 0)
+			{
+				result = FTP_ERR_SUCCESS;
+			}
+			else
+			{
+			    mbtk_at_ftp_par.rest_size = info->file_trans.size_send;
+				result = FTP_ERR_UNKNOWN;
+			}
+        }
+
+		if (info->file_trans.fd > 0 )   // Save to efs
+		{
+            info->file_trans.size_count = 0;
+			info->file_trans.size_send = 0;
+			if (file_close(info->file_trans.fd))
+			{
+				LOGE("EFS close fail.");
+				return -1;
+			}
+		}
+
+    }
+    else
+    {
+        LOGE("FTP state error[%d].", info->state);
+        return -1;
+    }
+
+    return result;
+}
+
+/*
+* This only for upload data(No for upload efs).
+*/
+int mbtk_ftp_upload_send(mbtk_ftp_handle handle, const void *data,uint16 data_len)
+{
+    if (!data || data_len == 0)
+    {
+        LOGE("Param set error.");
+        return -1;
+    }
+
+    int err;
+	int result = 0;
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return -1;
+    }
+
+    if(info->file_trans.fd > 0)   // Is upload from efs.
+    {
+        LOGE("Not upload from EFS.");
+        return -1;
+    }
+
+//LOGE("1socket:%d, data:%s, data_len:%d", info->sock_info[FTP_SOCK_DATA].fd, data, data_len );
+    if((info->file_trans.size_send + data_len) > info->file_trans.size_count)
+	{
+		printf("send over set length\n");
+        result = FTP_ERR_UNKNOWN;
+        goto overlong;
+    }
+    int len;
+    if(info->auth_type != 0)
+        len = mbtk_sock_write(info->ftp_ssl_handle,info->session_data,data,data_len,FTP_TIMEOUT,&err);
+    else
+	    len = sock_write(&info->net_info, &info->sock_info[FTP_SOCK_DATA], data, data_len,
+                            FTP_TIMEOUT, &err);
+	if(len < 0)
+	{
+		LOGE("EFS write fail.len:%d, err；%d", len, err);
+        return FTP_ERR_EFS_FILE;
+	}
+
+	info->file_trans.size_send += len;
+    mbtk_at_ftp_par.rest_size = info->file_trans.size_send;
+
+    LOGE("size_count:%d, size_send:%d.", info->file_trans.size_count,info->file_trans.size_send);
+
+    if((info->file_trans.size_count <= info->file_trans.size_send) )
+	{
+	    printf("\nClose data socket begin!\n ");
+			    // Close data socket.
+overlong:    if (info->sock_info[FTP_SOCK_DATA].fd > 0)
+	    {
+	        if (sock_close(&info->net_info, &info->sock_info[FTP_SOCK_DATA], FTP_TIMEOUT, &err))
+	        {
+	            LOGE("Close data socket fail[%d].", err);
+                printf("\nClose data socket fail[%d].\n", err);
+	            result = FTP_ERR_NET_CLOSE;
+	        }
+	        else
+	        {
+	            printf("\nClose data socket ok[%d].\n", err);
+	        //    info->sock_info[FTP_SOCK_DATA].fd = -1;
+	        }
+	    }
+        if(info->auth_type != 0)
+        {
+            if(mbtk_sock_close(info->ftp_ssl_handle,info->session_data,6000,&err))
+            {
+	            LOGE("Close ssl data socket fail[%d].", err);
+                printf("\nClose ssl data socket fail[%d].\n", err);
+	            result = FTP_ERR_NET_CLOSE;
+	        }
+	        else
+	        {
+	            printf("\nClose ssl data socket ok[%d].\n", err);
+	        //    info->sock_info[FTP_SOCK_DATA].fd = -1;
+	        }
+        }
+        info->data_mode = FTP_MODE_PASSIVE;
+        info->is_data_sock_busy = false;
+        info->file_trans.size_count = 0;
+        info->file_trans.size_send = 0;
+	}
+	else
+	{
+		LOGE("size_count:%d, size_send:%d.", info->file_trans.size_count,info->file_trans.size_send);
+	}
+
+
+    // Start update data.
+
+    return result;
+}
+
+mbtk_ftp_error_enum mbtk_ftp_trans_reset(mbtk_ftp_handle handle)
+{
+    mbtk_ftp_info_s *info = ftp_info_find(handle);
+    if (!info)
+    {
+        LOGE("No such FTP handle:%d", handle);
+        return FTP_ERR_UNKNOWN;
+    }
+
+    info->is_trans = false;
+    memset(&info->file_trans, 0x0, sizeof(mbtk_ftp_file_trans_info_s));
+
+    return FTP_ERR_SUCCESS;
+}
+
+
