diff --git a/APP_Framework/Applications/app_test/Kconfig b/APP_Framework/Applications/app_test/Kconfig index 5afee6e45..a9b308b12 100644 --- a/APP_Framework/Applications/app_test/Kconfig +++ b/APP_Framework/Applications/app_test/Kconfig @@ -4,7 +4,7 @@ menu "test app" default n if USER_TEST - config USER_TEST_ADC + menuconfig USER_TEST_ADC bool "Config test adc" default n if USER_TEST_ADC diff --git a/APP_Framework/Applications/app_test/Makefile b/APP_Framework/Applications/app_test/Makefile index 47ead8787..968d84c24 100644 --- a/APP_Framework/Applications/app_test/Makefile +++ b/APP_Framework/Applications/app_test/Makefile @@ -138,7 +138,7 @@ ifeq ($(CONFIG_ADD_XIZI_FEATURES),y) endif ifeq ($(CONFIG_USER_TEST_FTPCLIENT),y) - SRC_FILES += + SRC_FILES += test_ftpclient_final/test_ftpclient.c endif ifeq ($(CONFIG_USER_TEST_LORA_P2P),y) diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/test_ftpclient.c b/APP_Framework/Applications/app_test/test_ftpclient_final/test_ftpclient.c new file mode 100644 index 000000000..b81177641 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_ftpclient_final/test_ftpclient.c @@ -0,0 +1,242 @@ +/* +* 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 "lwip/sockets.h" +#include "test_ftpclient.h" + +char sendBuffer[1024]; +char recvBuffer[1024]; +int cmd_fd; +//quoted from https://kerndev.blog.csdn.net/article/details/89383888 +int SendCommand(char *cmd) +{ + int ret; + int fd = socket(AF_INET, SOCK_STREAM, 0); + ret = send(fd, cmd, (int)strlen(cmd)); + closesocket(fd); + if (ret < 0) { + return 0; + } + return 1; +} +int RecvRespond(char * respond,int len) +{ + int ret; + int off; + len -= -1; + int fd = socket(AF_INET, SOCK_STREAM, 0); + for (off = 0;off < len;off += ret) { + ret = recv(fd,&respond[off],1); + if(ret < 0 ){ + printf("recv respond error\r\n"); + closesocket(fd); + return 0; + } + if(respond[off] == '\n'){ + break; + } + } + respond[off + 1] = 0; + closesocket(fd); + 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"); + struct sockaddr_in tcp_sock; + tcp_sock.sin_family = AF_INET; + tcp_sock.sin_port = htons(port); + tcp_sock.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(addr[0],addr[1],addr[2],addr[3])); + memset(&(tcp_sock.sin_zero), 0, sizeof(tcp_sock.sin_zero)); + ret = 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) +{ + int fd = socket(AF_INET, SOCK_STREAM, 0); + 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){ + closesocket(fd); + return 0; + } + ret = wiz_sock_connect(SOCKET_DATA,addr,port); + if(ret != 1){ + closesocket(fd); + printf("fail to connect data port\r\n"); + return 0; + } + sprintf(sendBuffer,"RETR %s\r\n",name); + ret = SendCommand(sendBuffer); + if(ret != 1){ + closesocket(fd); + return 0; + } + ret = RecvRespond(recvBuffer,1024); + if(ret!=150){ + closesocket(fd); + 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){ + closesocket(fd); + return 0; + } + closesocket(fd); + + 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; +} + +int TestFtp() +{ + + cmd_fd = socket(AF_INET, SOCK_STREAM, 0); + + 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"); + + closesocket(cmd_fd); + return 0; +} +PRIV_SHELL_CMD_FUNCTION(TestFtp, Implement ftp, PRIV_SHELL_CMD_MAIN_ATTR); diff --git a/APP_Framework/Applications/app_test/test_ftpclient_final/test_ftpclient.h b/APP_Framework/Applications/app_test/test_ftpclient_final/test_ftpclient.h new file mode 100644 index 000000000..49e7d9650 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_ftpclient_final/test_ftpclient.h @@ -0,0 +1,13 @@ +#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