FTP 开发指导_Rev1.1

English

修订记录

版本

日期

作者

审核

修订内容

Rev1.0

2023-10-08

chw

创建文档

Rev1.1

2024-03-25

sxx

更改文档名称

Rev1.2

2025-02-13

sxx

新增更换传输类型接口

1 简介

本文档介绍 LTE-EC71X FTP 接口 API 情况, API 接口位于 components/kernel/lierda_api/liot_ftp/liot_ftp.h 文件声明。

本套API接口属于同步接口。

2 API 函数概览

函数

说明

liot_ftp_client_new()

创建FTP客户端

liot_ftp_client_release()

释放FTP客户端

liot_ftp_client_setopt()

设置客户端选项

liot_ftp_client_open()

连接FTP服务器

liot_ftp_client_close()

断开FTP服务器

liot_ftp_client_get_ex()

下载文件

liot_ftp_client_put_ex()

上传文件

liot_ftp_client_delete()

删除文件

liot_ftp_client_pwd()

获取当前目录路径

liot_ftp_client_cwd()

变更当前目录路径

liot_ftp_client_mkdir()

新建目录

liot_ftp_client_rmdir()

删除目录

liot_ftp_client_list()

获取目录信息

liot_ftp_client_size()

获取文件大小

liot_ftp_client_rename()

重命名文件

liot_ftp_client_FileTpye()

设置传输文件类型

3 类型说明

3.1 LIOT_FTP_CLIENT_ERR_E

FTP API 执行结果返回码。

  • 声明

typedef enum
{
    LIOT_FTP_CLIENT_ERR_SUCCESS = 0,           //函数执行成功
    LIOT_FTP_CLIENT_ERR_INVALID_CLIENT = 1,    //不可用的FTP客户端句柄
    LIOT_FTP_CLIENT_ERR_INVALID_HOST,          //不可用的主机地址
    LIOT_FTP_CLIENT_ERR_DNS_FAIL,              //DNS解析失败
    LIOT_FTP_CLIENT_ERR_SOCK_CREATE_FAIL,      //创建SOCKET失败
    LIOT_FTP_CLIENT_ERR_SOCK_BIND_FAIL = 5,    //绑定SOCKET失败
    LIOT_FTP_CLIENT_ERR_SOCK_CONN_FAIL,        //SOCKET连接失败
    LIOT_FTP_CLIENT_ERR_SOCK_SEND_FAIL,        //SOCKET发送失败
    LIOT_FTP_CLIENT_ERR_SOCK_RECV_FAIL,        //SOCKET接收失败
    LIOT_FTP_CLIENT_ERR_SOCK_CLOSE_FAIL,       //SOCKET断开连接失败
    LIOT_FTP_CLIENT_ERR_SOCK_DISCONNECTED = 10,//连接断开
    LIOT_FTP_CLIENT_ERR_SSL_CONN_FAIL,         //SSL连接失败
    LIOT_FTP_CLIENT_ERR_RESP_TIMEOUT,          //请求超时
    LIOT_FTP_CLIENT_ERR_CREATE_FILE_FAIL,      //创建文件失败
    LIOT_FTP_CLIENT_ERR_NO_FILE,               //文件不存在
    LIOT_FTP_CLIENT_ERR_NO_DIR = 15,           //目录不存在
    LIOT_FTP_CLIENT_ERR_UNKNOWN                //未知错误
} LIOT_FTP_CLIENT_ERR_E;

3.2 LIOT_FTP_CLIENT_OPT_E

FTP 客户端属性设置标签。

  • 声明

typedef enum {
    LIOT_FTP_CLIENT_SSL_ENABLE,   //SSL使能,0:FTP,1:FTPS隐式加密,2:FTPS显示加密。当前不支持FTPS
    LIOT_FTP_CLIENT_OPT_START_POS,//文件起始位置设置,默认为0
    LIOT_FTP_CLIENT_FILE_TYPE,    //文件类型,0:二进制,1:ASCII
    LIOT_FTP_CLIENT_TRANS_MODE,   //传输模式,0:主动模式,1:被动模式
    LIOT_FTP_CLIENT_RSP_TIMEOUT,  //超时时间,默认90s
}LIOT_FTP_CLIENT_OPT_E;
  • 标签说明

LIOT_FTP_CLIENT_SSL_ENABLE:

[] SSL使能,0:FTP,1:FTPS隐式加密,2:FTPS显示加密。当前不支持FTPS。

LIOT_FTP_CLIENT_OPT_START_POS:

[] 文件起始位置设置,默认为0。

LIOT_FTP_CLIENT_FILE_TYPE:

[] 文件类型,0:二进制,1:ASCII。

LIOT_FTP_CLIENT_TRANS_MODE:

[]传输模式,0:主动模式,1:被动模式。

LIOT_FTP_CLIENT_RSP_TIMEOUT:

[] 超时时间,默认90s。

3.3 LIOT_FTP_CLIENT_WRITE_CB_EX

下载完成回调函数。

  1. 声明

typedef void (*LIOT_FTP_CLIENT_WRITE_CB_EX)(void *ptr, uint32_t size);
  1. 参数

ptr:

[In]下载数据指针。

size:

[In]下载数据长度,单位:字节。

  1. 返回值

无。

4 API 函数详解

4.1 liot_ftp_client_new

创建FTP客户端。

  1. 声明

void *liot_ftp_client_new(void);
  1. 参数

无。

  1. 返回值

void  *:FTP客户端句柄。

4.2 liot_ftp_client_release

释放FTP客户端。

  1. 声明

void liot_ftp_client_release(void *client);
  1. 参数

client:

[In] FTP客户端句柄。

  1. 返回值

无。

4.3 liot_ftp_client_setopt

设置FTP客户端属性。

  1. 声明

int liot_ftp_client_setopt(void *client, LIOT_FTP_CLIENT_OPT_E tag, void *param);
  1. 参数

client:

[In]FTP客户端句柄。

tag:

[In]属性标签,请参考3.2 LIOT_FTP_CLIENT_OPT_E。

param:

[In]属性值。

  1. 返回值

int:执行结果码,请参考3.1。

4.4 liot_ftp_client_open

连接FTP服务器。

  1. 声明

int liot_ftp_client_open(void *client, char *hostname, char *port, char *username, char *password);
  1. 参数

client:

[In]FTP客户端句柄。

hostname:

[In]服务器地址,最大长度255字节。

port:

[In]服务器端口,0~65535。

username:

[In]用户名,最大长度255字节。

password:

[In]密码,最大长度255字节。

  1. 返回值

int:执行结果码,请参考 3.1。

4.5 liot_ftp_client_close

断开FTP服务器。

  1. 声明

int liot_ftp_client_close(void *client);
  1. 参数

client:

[In]FTP客户端句柄。

  1. 返回值

int:执行结果码,请参考 3.1。

4.6 liot_ftp_client_get_ex

下载文件。

  1. 声明

int liot_ftp_client_get_ex(void *client, char *remotefile, char *localfile, LIOT_FTP_CLIENT_WRITE_CB_EX write_cb);
  1. 参数

client:

[In]FTP客户端句柄。

remotefile:

[In]服务器文件路径,最大长度255字节。

localfile:

[In]本地文件名,回调函数write_cb为空时有效,下载文件到本地文件中,最大长度84字节。

write_cb:

[In]下载完成回调函数,不为空时,下载的数据在该函数中获取,请参考3.3 LIOT_FTP_CLIENT_WRITE_CB_EX。

  1. 返回值

int:执行结果码,请参考 3.1。

4.7 liot_ftp_client_put_ex

上传文件。

  1. 声明

int liot_ftp_client_put_ex(void *client, char *localfile, char *remotefile, void *userData, uint32_t uploadlen);
  1. 参数

client:

[In]FTP客户端句柄。

localfile:

[In]本地文件名,待上传数据userData为空时有效,上传本地文件到服务器,最大长度84字节。

remotefile:

[In]服务器文件路径,最大长度255字节。

userData:

[In]待上传数据,不为空时,将该地址中的数据上传到服务器。

uploadlen:

[In]userData指向的数据长度。

  1. 返回值

int:执行结果码,请参考3.1。

4.8 liot_ftp_client_delete

删除服务器文件。

  1. 声明

int liot_ftp_client_delete(void *client, char *remotefile);
  1. 参数

client:

[In]FTP客户端句柄。

remotefile:

[In]服务器文件路径,最大长度255字节。

  1. 返回值

int:执行结果码,请参考 3.1。

4.9 liot_ftp_client_pwd

获取服务器目录路径。

  1. 声明

int liot_ftp_client_pwd(void *client, char *path);
  1. 参数

client:

[In]FTP客户端句柄。

path:

[Out]返回的服务器当前路径,最大长度255字节。

  1. 返回值

int:执行结果码,请参考 3.1。

4.10 liot_ftp_client_cwd

变更服务器目录路径。

  1. 声明

int liot_ftp_client_cwd(void *client, char *path);
  1. 参数

client:

[In]FTP客户端句柄。

path:

[In]要变更到的目录路径,最大长度255字节。

  1. 返回值

int:执行结果码,请参考 3.1。

4.11 liot_ftp_client_mkdir

创建新的服务器目录。

  1. 声明

int liot_ftp_client_mkdir(void *client, char *path);
  1. 参数

client:

[In]FTP客户端句柄。

path:

[In]新的目录路径,最大长度255字节。

  1. 返回值

int:执行结果码,请参考 3.1。

4.12 liot_ftp_client_rmdir

删除服务器目录。

  1. 声明

int liot_ftp_client_rmdir(void *client, char *path);
  1. 参数

client:

[In]FTP客户端句柄。

path:

[In]要删除的目录路径,最大长度255字节。

  1. 返回值

int:执行结果码,请参考 3.1。

4.13 liot_ftp_client_list

获取服务器目录信息列表。

  1. 声明

int liot_ftp_client_list(void *client, char *path, char *list);
  1. 参数

client:

[In]FTP客户端句柄。

path:

[In]目录路径,最大长度255字节。

list:

[Out]目录列表信息。

  1. 返回值

int:执行结果码,请参考 3.1。

4.14 liot_ftp_client_size

获取服务器文件大小。

  1. 声明

int liot_ftp_client_size(void *client, char *filename, uint32_t *size);
  1. 参数

client:

[In]FTP客户端句柄。

filename:

[In]服务器文件路径,最大长度255字节。

size:

[Out]文件大小,单位为字节。

  1. 返回值

int:执行结果码,请参考3.1。

4.15 liot_ftp_client_rename

重命名服务器文件。

  1. 声明

int liot_ftp_client_rename(void *client, char *old_name, char *new_name);
  1. 参数

client:

[In]FTP客户端句柄。

old_name:

[In]旧文件名,最大长度255字节。

new_name:

[In]新文件名,最大长度255字节。

  1. 返回值

int:执行结果码,请参考 3.1。

4.16 liot_ftp_client_FileTpye

更改传输文件类型。

  1. 声明

int liot_ftp_client_FileTpye(void *client, uint32_t Type);
  1. 参数

client:

[In]FTP客户端句柄。

Type:

[In]传输文件类型,FTP_ASCII 或者 FTP_BINARY。

  1. 返回值

int:执行结果码,请参考 3.1。

5 代码示例

示例代码参考  examples/demo/src/demo_ftp.c 文件。


void receiveCB(void *dataPtr, uint32_t len)
{
    liot_trace("--receive len = %d--\r\n%s", len, (char *)dataPtr);
}

void liot_ftp_demo_thread(void *argv)
{
    int ret            = -1;

    liot_rtos_task_sleep_s(2);
    liot_trace("==========tcp demo start==========");

    int times          = 0;
    uint8_t nSim = 0; //0:sim1 or 1:sim2
    while (LIOT_DATACALL_SUCCESS != (ret = liot_network_register_wait(nSim, 120)) && times < 10)
    {
        times++;
        liot_rtos_task_sleep_s(1);
    }

    if (LIOT_DATACALL_SUCCESS != ret)
    {
        liot_trace("====network register failure!!!!!====");
        goto exit;
    }
    liot_trace("====network registered!!!!====");

    void *ftpClient = NULL;
    ftpClient = liot_ftp_client_new();
    if(ftpClient != NULL)
    {
        liot_trace("FTP CLIENT CREATE SUCCESS!!!");

        ret = liot_ftp_client_open(ftpClient, "121.89.205.240", "21", "ftpuser", "123456");
        if(ret == LIOT_FTP_CLIENT_ERR_SUCCESS)
        {
            liot_trace("FTP CLIENT OPEN SUCCESS!!!");

            //get server dir
            #if 1
            char path\[64\] = {0};
            liot_ftp_client_pwd(ftpClient, path);
            if(ret == LIOT_FTP_CLIENT_ERR_SUCCESS)
            {
                liot_trace("GET DIR SUCCESS: %s", path);
            }
            #endif

            //create server dir
            #if 1
            ret = liot_ftp_client_mkdir(ftpClient, (char *)"DIR_TEST");
            if(ret == LIOT_FTP_CLIENT_ERR_SUCCESS)
            {
                liot_trace("CREATE DIR SUCCESS!!!");
            }
            #endif

            //change server dir
            #if 1
            ret = liot_ftp_client_cwd(ftpClient, "DIR_TEST");
            if(ret == LIOT_FTP_CLIENT_ERR_SUCCESS)
            {
                liot_trace("CHANGE DIR SUCCESS!!!");
            }
            #endif

            //put local file to server
            #if 1
            lfs_file_t *lofi = malloc(sizeof(lfs_file_t));
            LFS_fileOpen(lofi, (char *)"localfile", (LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC));
            char databuf\[\] = "HELLO WORLD!!!";
            LFS_fileWrite(lofi, databuf, strlen(databuf));
            LFS_fileClose(lofi);
            free(lofi);
            liot_trace("Write Data Success: %s",databuf);
            ret = liot_ftp_client_put_ex(ftpClient, "localfile", "oldName.txt", NULL, 0);
            if(ret == LIOT_FTP_CLIENT_ERR_SUCCESS)
            {
                liot_trace("PUT SUCCESS!!!");
            }
            #endif

            //rename file
            #if 1
            ret = liot_ftp_client_rename(ftpClient, (char *)"oldName.txt", (char *)"newName.txt");
            if(ret == LIOT_FTP_CLIENT_ERR_SUCCESS)
            {
                liot_trace("RENAME FILE SUCCESS!!!");
            }
            #endif

            //get file size
            #if 1
            uint32_t filelen = 0;
            ret = liot_ftp_client_size(ftpClient, (char *)"newName.txt", &filelen);
            if(ret == LIOT_FTP_CLIENT_ERR_SUCCESS)
            {
                liot_trace("GET FILE SIZE SUCCESS: %d", filelen);
            }
            #endif

            //get file
            #if 1
            ret = liot_ftp_client_get_ex(ftpClient, "newName.txt", NULL, receiveCB);
            if(ret == LIOT_FTP_CLIENT_ERR_SUCCESS)
            {
                liot_trace("GET SUCCESS!!!");
            }
            #endif

            //change server dir
            #if 1
            ret = liot_ftp_client_cwd(ftpClient, "/");
            if(ret == LIOT_FTP_CLIENT_ERR_SUCCESS)
            {
                liot_trace("CHANGE DIR SUCCESS!!!");
            }
            #endif

            //get server dir or file information
            #if 1
            char ftplist\[256\] = {0};
            ret = liot_ftp_client_list(ftpClient, (char *)"DIR_TEST", ftplist);
            if(ret == LIOT_FTP_CLIENT_ERR_SUCCESS)
            {
                liot_trace("GET DIR LIST SUCCESS:%d\r\n%s", strlen(ftplist), ftplist);
            }
            #endif

            //delete file
            #if 1
            ret = liot_ftp_client_delete(ftpClient, (char *)"DIR_TEST/newName.txt");
            if(ret == LIOT_FTP_CLIENT_ERR_SUCCESS)
            {
                liot_trace("DELETE SUCCESS!!!");
            }
            #endif

            //remote server dir
            #if 1
            ret = liot_ftp_client_rmdir(ftpClient, (char *)"DIR_TEST");
            if(ret == LIOT_FTP_CLIENT_ERR_SUCCESS)
            {
                liot_trace("DELETE DIR SUCCESS!!!");
            }
            #endif

            ret = liot_ftp_client_close(ftpClient);
            if(ret == LIOT_FTP_CLIENT_ERR_SUCCESS)
            {
                liot_trace("FTP CLIENT CLOSE SUCCESS!!!");
            }
        }

        liot_ftp_client_release(ftpClient);
        ftpClient = NULL;
        liot_trace("FTP CLIENT RELEASE SUCCESS!!!");

        while(1) liot_rtos_task_sleep_s(1);
    }

exit:
    if (LIOT_OSI_SUCCESS != liot_rtos_task_delete(NULL))
    {
        liot_trace("task deleted failed");
    }
    liot_trace("task deleted successed");

    return;
}

运行结果:

打开USB口抓取测试日志

_images/ftp-guide/image_1.png
_images/ftp-guide/image_2.png