diff --git a/APP_Framework/Applications/app_test/Kconfig b/APP_Framework/Applications/app_test/Kconfig index 33b3bc740..74b6d0973 100644 --- a/APP_Framework/Applications/app_test/Kconfig +++ b/APP_Framework/Applications/app_test/Kconfig @@ -286,6 +286,10 @@ menu "test app" bool "Config test ftp client" default n + menuconfig USER_TEST_FTPCLIENT_RISCV + bool "Config test ftp client on riscv" + default n + menuconfig USER_TEST_LORA_P2P bool "Config test lora p2p" default n diff --git a/APP_Framework/Applications/app_test/Makefile b/APP_Framework/Applications/app_test/Makefile index 4710a2604..43cd4364f 100644 --- a/APP_Framework/Applications/app_test/Makefile +++ b/APP_Framework/Applications/app_test/Makefile @@ -124,7 +124,7 @@ ifeq ($(CONFIG_ADD_XIZI_FEATURES),y) ifeq ($(CONFIG_USER_TEST_MODBUS_TCP),y) SRC_DIR += test_modbus_tcp endif - + ifeq ($(CONFIG_USER_TEST_WEBSERVER),y) SRC_FILES += test_webserver/test_webserver.c endif @@ -139,6 +139,10 @@ ifeq ($(CONFIG_ADD_XIZI_FEATURES),y) test_ftpclient/ftp_client/my_socket.c endif + ifeq ($(CONFIG_USER_TEST_FTPCLIENT_RISCV),y) + SRC_FILES += test_ftpclient_riscv/test_ftpclient_riscv.c + endif + ifeq ($(CONFIG_USER_TEST_LORA_P2P),y) SRC_FILES += endif diff --git a/APP_Framework/Applications/app_test/test_ftpclient_riscv/README.md b/APP_Framework/Applications/app_test/test_ftpclient_riscv/README.md new file mode 100644 index 000000000..fa485085c --- /dev/null +++ b/APP_Framework/Applications/app_test/test_ftpclient_riscv/README.md @@ -0,0 +1,43 @@ +# 基于矽璓已实现的W5500网卡驱动,在Riscv上实现FTP协议的Client功能 # + +## 1. 简介 +利用w5500网络编程的api实现了ftp客户端的功能,具体功能包括向ftp服务器发送指定命令,根据用户名登陆ftp服务器,获取文件大小,下载指定文件并保存至sd卡内,并提供了测试函数模拟从ftp服务器上下载10个4KB文件的过程 + +## 2. 数据结构设计说明 +全局变量: +char sendBuffer[]:输出缓冲区 +char recvBuffer[]:输入缓冲区 + +包括以下函数功能,分别为: +`SendCommand`:发送指定的指令 +`EnterPasv`:进入被动模式 +`Login`:根据用户名登陆ftp服务器 +`GetFileSize`:获取指定文件的大小 +`Download`:下载指定文件 + + +## 3. 测试程序说明 +测试了创建套接字,与服务器建立连接并根据传入的用户名和密码发送登陆指令。登陆成功后下载服务器上指定的10个4KB大小的txt文件,然后调用开发板的相关api在系统根目录中创建对应的文件,写入从服务器接收到的数据。 + +## 4. 运行结果(##需结合运行测试截图按步骤说明##) +![image](img/01.png) +![image](img/02.png) +打开menuconfig之后,将test_ftp开启(y),将Using TFcard device 和 Using W5500 as network device 开启(y)保存后退出 + +![image](img/03.png) +编译XiZi-edu-riscv64.elf成功 + +![image](img/04.png) +启动kflash烧录bin文件,按reset键重置成功进入系统并显示SD卡已挂载 + +![image](img/05.png) +执行TestTfp命令,可以看到成功登陆ftp服务器,并开始下载10个大小为4KB的文件。 + +![image](img/06.png) +服务器日志信息 + +![image](img/07.png) +读取sd卡中的文件可以看到10个大小为4KB的文件被成功下载 +![image](img/08.png) +![image](img/09.png) +![image](img/10.png) \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/01.png b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/01.png new file mode 100644 index 000000000..ecf8ae8e6 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/01.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/02.png b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/02.png new file mode 100644 index 000000000..1c99e096a Binary files /dev/null and b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/02.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/03.png b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/03.png new file mode 100644 index 000000000..28c7339df Binary files /dev/null and b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/03.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/04.png b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/04.png new file mode 100644 index 000000000..f45b3588f Binary files /dev/null and b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/04.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/05.png b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/05.png new file mode 100644 index 000000000..9c3f3e064 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/05.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/06.png b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/06.png new file mode 100644 index 000000000..0b04f45c1 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/06.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/07.png b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/07.png new file mode 100644 index 000000000..26d9ef32c Binary files /dev/null and b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/07.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/08.png b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/08.png new file mode 100644 index 000000000..49bd8a3e3 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/08.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/09.png b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/09.png new file mode 100644 index 000000000..60f289d79 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/09.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/10.png b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/10.png new file mode 100644 index 000000000..e56ec0712 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_ftpclient_riscv/img/10.png differ diff --git a/APP_Framework/Applications/app_test/test_ftpclient_riscv/test_ftpclient_riscv.c b/APP_Framework/Applications/app_test/test_ftpclient_riscv/test_ftpclient_riscv.c new file mode 100644 index 000000000..876788358 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_ftpclient_riscv/test_ftpclient_riscv.c @@ -0,0 +1,241 @@ +/* +* Copyright (c) 2020 AIIT Ubiquitous Team +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL +v2. +* You may obtain a copy of Mulan PSL v2 at: +* +http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +#include +#include +#include +#include +#include "test_ftpclient_riscv.h" +#define SOCKET_DATA 2 +#define SOCKET_CMD 3 +char sendBuffer[1024]; +char recvBuffer[1024]; + +//quoted from https://kerndev.blog.csdn.net/article/details/89383888 +int SendCommand(char *cmd) +{ + int ret; + ret = wiz_sock_send(SOCKET_CMD,cmd,(int)strlen(cmd)); + if(ret < 0 ){ + return 0; + } + return 1; +} +int RecvRespond(char * respond,int len) +{ + int ret; + int off; + len -= -1; + for(off = 0;off < len;off += ret){ + ret = wiz_sock_recv(SOCKET_CMD,&respond[off],1); + if(ret < 0 ){ + printf("recv respond error\r\n"); + return 0; + } + if(respond[off] == '\n'){ + break; + } + } + respond[off + 1]=0; + return atoi(respond); +} +int EnterPasv(uint8_t *ipaddr,int *port) +{ + int ret; + char *find; + int ip1,ip2,ip3,ip4,tmp1,tmp2; + ret = SendCommand("PASV\r\n"); + if(ret != 1){ + return 0; + } + ret=RecvRespond(recvBuffer,1024); + if(ret != 227){ + return 0; + } + find=strrchr(recvBuffer,'('); + sscanf(find,"(%d,%d,%d,%d,%d,%d)",&ip1,&ip2,&ip3,&ip4,&tmp1,&tmp2); + ipaddr[0] = ip1; + ipaddr[1] = ip2; + ipaddr[2] = ip3; + ipaddr[3] = ip4; + *port = tmp1 * 256 + tmp2; + return 1; +} +int Login(uint8_t addr[4],int port,char *username,char *password) +{ + int ret; + printf("connect....\n"); + ret = wiz_sock_connect(SOCKET_CMD,addr,port); + if(ret != 1){ + printf("connect server failed\r\n"); + return 0; + } + printf("connect ok.\r\n"); + + ret = RecvRespond(recvBuffer,1024); + if(ret != 220){ + printf("bad server ret=%d\r\n",ret); + return 0; + } + printf("login....\r\n"); + sprintf(sendBuffer,"USER %s\r\n",username); + ret = SendCommand(sendBuffer); + + if(ret != 1){ + return 0; + } + ret = RecvRespond(recvBuffer,1024); + if(ret == 220)ret = RecvRespond(recvBuffer,1024); + if(ret != 331){ + return 0; + } + sprintf(sendBuffer,"PASS %s\r\n",password); + ret = SendCommand(sendBuffer); + if(ret != 1){ + return 0; + } + ret = RecvRespond(recvBuffer,1024); + if(ret != 230){ + return 0; + } + printf("login sucess \r\n"); + + + ret = SendCommand("TYPE I\r\n"); + if(ret != 1){ + return 0; + } + ret = RecvRespond(recvBuffer,1024); + if(ret != 200){ + return 0; + } + return 1; +} +int GetFileSize(char * name) +{ + int ret; + int size; + sprintf(sendBuffer,"SIZE %s\r\n",name); + ret = SendCommand(sendBuffer); + if(ret != 1){ + return 0; + } + ret = RecvRespond(recvBuffer,1024); + if(ret != 213){ + printf("get file size failed\r\n"); + return 0; + } + size = atoi(recvBuffer + 4); + return size; +} +int Download(char *name) +{ + wiz_socket(SOCKET_DATA, Sn_MR_TCP,12345,0); + int len = GetFileSize(name); + char *buf = malloc(len+1); + printf("downloading file %s\r\n",name); + int it; + int ret; + uint8_t addr[4]; + int port; + ret = EnterPasv(addr,&port); + + if(ret != 1){ + wiz_sock_disconnect(SOCKET_DATA); + return 0; + } + ret = wiz_sock_connect(SOCKET_DATA,addr,port); + if(ret != 1){ + wiz_sock_disconnect(SOCKET_DATA); + printf("fail to connect data port\r\n"); + return 0; + } + sprintf(sendBuffer,"RETR %s\r\n",name); + ret = SendCommand(sendBuffer); + if(ret != 1){ + wiz_sock_disconnect(SOCKET_DATA); + return 0; + } + ret = RecvRespond(recvBuffer,1024); + if(ret!=150){ + wiz_sock_disconnect(SOCKET_DATA); + return 0; + } + for(it = 0;it < len;it += ret){ + ret = wiz_sock_recv(SOCKET_DATA,((char *)buf + it),len); + if(ret<0){ + printf("download was interupted\r\n"); + break; + } + } + buf[len] = 0; + printf("download %d/%d bytes complete. \r\n",it,len); + ret = RecvRespond(recvBuffer,1024); + if(ret != 226){ + wiz_sock_disconnect(SOCKET_DATA); + return 0; + } + wiz_sock_disconnect(SOCKET_DATA); + + printf("creating file %s ....\r\n",name); + int fd=open(name,O_RDWR | O_CREAT); + if(fd > 0){ + ret = write(fd,buf,strlen(buf)); + if(ret < 0 ){ + printf("write failed\r\n"); + } + else printf("success!\r\n"); + } + else { + printf("create file %s failed\r\n",name); + } + if(buf != NULL){ + free(buf); + } + return 1; +} +void Init() +{ + + wiz_socket(SOCKET_CMD, Sn_MR_TCP,54321,0); + printf("socket created\n"); +} +void Quit() +{ + wiz_sock_disconnect(SOCKET_CMD); +} +int TestFtp() +{ + + Init(); + + uint8_t ip[4] = {192,168,130,70}; + Login(ip,21,"frank","114514"); + + Download("File0.txt"); + Download("File1.txt"); + Download("File2.txt"); + Download("File3.txt"); + Download("File4.txt"); + Download("File5.txt"); + Download("File6.txt"); + Download("File7.txt"); + Download("File8.txt"); + Download("File9.txt"); + + Quit(); + + return 0; +} +PRIV_SHELL_CMD_FUNCTION(TestFtp, Implement ftp, PRIV_SHELL_CMD_MAIN_ATTR); diff --git a/APP_Framework/Applications/app_test/test_ftpclient_riscv/test_ftpclient_riscv.h b/APP_Framework/Applications/app_test/test_ftpclient_riscv/test_ftpclient_riscv.h new file mode 100644 index 000000000..a92585c45 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_ftpclient_riscv/test_ftpclient_riscv.h @@ -0,0 +1,14 @@ +#include +#include +#include +#include + +int SendCommand(char *cmd); +int RecvRespond(char * respond,int len); +int EnterPasv(uint8_t *ipaddr,int *port); +int Login(uint8_t addr[4],int port,char *username,char *password); +int GetFileSize(char * name); +int Download(char *name); +void Init(); +void Quit(); +int TestFtp(); \ No newline at end of file