📄 ftp.c
字号:
/*********************************************************************
*
* FTP ServerModule for Microchip TCP/IP Stack
*
*********************************************************************
* FileName: FTP.c
* Dependencies: StackTsk.h
* TCP.h
* Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F
* Complier: Microchip C18 v3.02 or higher
* Microchip C30 v2.01 or higher
* Company: Microchip Technology, Inc.
*
* Software License Agreement
*
* This software is owned by Microchip Technology Inc. ("Microchip")
* and is supplied to you for use exclusively as described in the
* associated software agreement. This software is protected by
* software and other intellectual property laws. Any use in
* violation of the software license may subject the user to criminal
* sanctions as well as civil liability. Copyright 2006 Microchip
* Technology Inc. All rights reserved.
*
* This software is provided "AS IS." MICROCHIP DISCLAIMS ALL
* WARRANTIES, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, NOT LIMITED
* TO MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
* INFRINGEMENT. Microchip shall in no event be liable for special,
* incidental, or consequential damages.
*
*
* Author Date Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Nilesh Rajbharti 4/23/01 Original (Rev 1.0)
* Nilesh Rajbharti 11/13/02 Fixed FTPServer()
* Howard Schlunder 07/10/06 Added hash printing to FTP client
* Howard Schlunder 07/20/06 Added FTP_RESP_DATA_NO_SOCKET error message
********************************************************************/
#define THIS_IS_FTP
#include <string.h>
#include <stdlib.h>
#include "..\Include\FTP.h"
#include "..\Include\TCP.h"
#include "..\Include\Tick.h"
#include "..\Include\MPFS.h"
#if defined(STACK_USE_FTP_SERVER)
#define FTP_COMMAND_PORT (21)
#define FTP_DATA_PORT (20)
#define FTP_TIMEOUT (TICK)((TICK)180 * TICK_SECOND)
#define MAX_FTP_ARGS (7)
#define MAX_FTP_CMD_STRING_LEN (31)
typedef enum _SM_FTP
{
SM_FTP_NOT_CONNECTED,
SM_FTP_CONNECTED,
SM_FTP_USER_NAME,
SM_FTP_USER_PASS,
SM_FTP_RESPOND
} SM_FTP;
typedef enum _SM_FTP_CMD
{
SM_FTP_CMD_IDLE,
SM_FTP_CMD_WAIT,
SM_FTP_CMD_RECEIVE,
SM_FTP_CMD_WAIT_FOR_DISCONNECT
} SM_FTP_CMD;
typedef enum _FTP_COMMAND
{
FTP_CMD_USER,
FTP_CMD_PASS,
FTP_CMD_QUIT,
FTP_CMD_STOR,
FTP_CMD_PORT,
FTP_CMD_ABORT,
FTP_CMD_UNKNOWN,
FTP_CMD_NONE,
} FTP_COMMAND;
// Each entry in following table must match with that of FTP_COMMAND enum.
ROM char *FTPCommandString[] =
{
"USER", // FTP_CMD_USER
"PASS", // FTP_CMD_PASS
"QUIT", // FTP_CMD_QUIT
"STOR", // FTP_CMD_STOR
"PORT", // FTP_CMD_PORT
"ABOR" // FTP_CMD_ABORT
};
#define FTP_COMMAND_TABLE_SIZE ( sizeof(FTPCommandString)/sizeof(FTPCommandString[0]) )
typedef enum _FTP_RESPONSE
{
FTP_RESP_BANNER,
FTP_RESP_USER_OK,
FTP_RESP_PASS_OK,
FTP_RESP_QUIT_OK,
FTP_RESP_STOR_OK,
FTP_RESP_UNKNOWN,
FTP_RESP_LOGIN,
FTP_RESP_DATA_OPEN,
FTP_RESP_DATA_READY,
FTP_RESP_DATA_CLOSE,
FTP_RESP_DATA_NO_SOCKET,
FTP_RESP_OK,
FTP_RESP_NONE // This must always be the last
// There is no corresponding string.
} FTP_RESPONSE;
// Each entry in following table must match with FTP_RESPONE enum
ROM char *FTPResponseString[] =
{
"220 Ready\r\n", // FTP_RESP_BANNER
"331 Password required\r\n", // FTP_RESP_USER_OK
"230 Logged in\r\n", // FTP_RESP_PASS_OK
"221 Bye\r\n", // FTP_RESP_QUIT_OK
"500 \r\n", // FTP_RESP_STOR_OK
"502 Not implemented\r\n", // FTP_RESP_UNKNOWN
"530 Login required\r\n", // FTP_RESP_LOGIN
"150 Transferring data...\r\n", // FTP_RESP_DATA_OPEN
"125 Done\r\n", // FTP_RESP_DATA_READY
"\r\n226 Transfer Complete\r\n", // FTP_RESP_DATA_CLOSE
"425 Can't create data socket. Increase MAX_SOCKETS.\r\n", //FTP_RESP_DATA_NO_SOCKET
"200 Ok\r\n" // FTP_RESP_OK
};
static union
{
struct
{
unsigned char bUserSupplied : 1;
unsigned char bLoggedIn: 1;
} Bits;
BYTE Val;
} FTPFlags;
static TCP_SOCKET FTPSocket; // Main ftp command socket.
static TCP_SOCKET FTPDataSocket; // ftp data socket.
static WORD_VAL FTPDataPort; // ftp data port number as supplied by client
static SM_FTP smFTP; // ftp server FSM state
static SM_FTP_CMD smFTPCommand; // ftp command FSM state
static FTP_COMMAND FTPCommand;
static FTP_RESPONSE FTPResponse;
static char FTPUser[FTP_USER_NAME_LEN];
static char FTPString[MAX_FTP_CMD_STRING_LEN+2];
static BYTE FTPStringLen;
static char *FTP_argv[MAX_FTP_ARGS]; // Parameters for a ftp command
static BYTE FTP_argc; // Total number of params for a ftp command
static TICK lastActivity; // Timeout keeper.
static MPFS FTPFileHandle;
// Private helper functions.
static void ParseFTPString(void);
static FTP_COMMAND ParseFTPCommand(char *cmd);
static void ParseFTPString(void);
static BOOL ExecuteFTPCommand(FTP_COMMAND cmd);
static BOOL PutFile(void);
static BOOL Quit(void);
// Uncomment following line if ftp transactions are to be displayed on
// RS-232 - for debug purpose only.
//#define FTP_SERVER_DEBUG_MODE
#define FTP_PUT_ENABLED
#if defined(FTP_SERVER_DEBUG_MODE)
static USARTPut(BYTE c)
{
while( !TXSTA_TRMT);
TXREG = c;
}
#else
#define USARTPut(a)
#endif
/*********************************************************************
* Function: void FTPInit(void)
*
* PreCondition: TCP module is already initialized.
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Initializes internal variables of FTP
*
* Note:
********************************************************************/
void FTPInit(void)
{
FTPSocket = TCPListen(FTP_COMMAND_PORT);
smFTP = SM_FTP_NOT_CONNECTED;
FTPStringLen = 0;
FTPFlags.Val = 0;
FTPDataPort.Val = FTP_DATA_PORT;
}
/*********************************************************************
* Function: void FTPServer(void)
*
* PreCondition: FTPInit() must already be called.
*
* Input: None
*
* Output: Opened FTP connections are served.
*
* Side Effects: None
*
* Overview:
*
* Note: This function acts as a task (similar to one in
* RTOS). This function performs its task in
* co-operative manner. Main application must call
* this function repeatdly to ensure all open
* or new connections are served on time.
********************************************************************/
BOOL FTPServer(void)
{
BYTE v;
TICK currentTick;
if ( !TCPIsConnected(FTPSocket) )
{
FTPStringLen = 0;
FTPCommand = FTP_CMD_NONE;
smFTP = SM_FTP_NOT_CONNECTED;
FTPFlags.Val = 0;
smFTPCommand = SM_FTP_CMD_IDLE;
return TRUE;
}
if ( TCPIsGetReady(FTPSocket) )
{
lastActivity = TickGet();
while( TCPGet(FTPSocket, &v ) )
{
USARTPut(v);
FTPString[FTPStringLen++] = v;
if ( FTPStringLen == MAX_FTP_CMD_STRING_LEN )
FTPStringLen = 0;
}
TCPDiscard(FTPSocket);
if ( v == '\n' )
{
FTPString[FTPStringLen] = '\0';
FTPStringLen = 0;
ParseFTPString();
FTPCommand = ParseFTPCommand(FTP_argv[0]);
}
}
else if ( smFTP != SM_FTP_NOT_CONNECTED )
{
currentTick = TickGet();
currentTick = TickGetDiff(currentTick, lastActivity);
if ( currentTick >= FTP_TIMEOUT )
{
lastActivity = TickGet();
FTPCommand = FTP_CMD_QUIT;
smFTP = SM_FTP_CONNECTED;
}
}
switch(smFTP)
{
case SM_FTP_NOT_CONNECTED:
FTPResponse = FTP_RESP_BANNER;
lastActivity = TickGet();
/* No break - Continue... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -