📄 tftps.c
字号:
/* THIS SAMPLE CODE IS PROVIDED AS IS AND IS SUBJECT TO ALTERATIONS. FUJITSU */
/* MICROELECTRONICS ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR */
/* ELIGIBILITY FOR ANY PURPOSES. */
/* (C) Fujitsu Microelectronics Europe GmbH */
/*---------------------------------------------------------------------------
/*
*Copyright (c) 2000-2002 Viola Systems Ltd.
*All rights reserved.
*
*Redistribution and use in source and binary forms, with or without
*modification, are permitted provided that the following conditions
*are met:
*
*1. Redistributions of source code must retain the above copyright
*notice, this list of conditions and the following disclaimer.
*
*2. Redistributions in binary form must reproduce the above copyright
*notice, this list of conditions and the following disclaimer in the
*documentation and/or other materials provided with the distribution.
*
*3. The end-user documentation included with the redistribution, if
*any, must include the following acknowledgment:
* "This product includes software developed by Viola
* Systems (http://www.violasystems.com/)."
*
*Alternately, this acknowledgment may appear in the software itself,
*if and wherever such third-party acknowledgments normally appear.
*
*4. The names "OpenTCP" and "Viola Systems" must not be used to
*endorse or promote products derived from this software without prior
*written permission. For written permission, please contact
*opentcp@opentcp.org.
*
*5. Products derived from this software may not be called "OpenTCP",
*nor may "OpenTCP" appear in their name, without prior written
*permission of the Viola Systems Ltd.
*
*THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
*WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
*MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
*IN NO EVENT SHALL VIOLA SYSTEMS LTD. OR ITS CONTRIBUTORS BE LIABLE
*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
*CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
*SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
*WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
*OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
*EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*====================================================================
*
*OpenTCP is the unified open source TCP/IP stack available on a series
*of 8/16-bit microcontrollers, please see <http://www.opentcp.org>.
*
*For more information on how to network-enable your devices, or how to
*obtain commercial technical support for OpenTCP, please see
*<http://www.violasystems.com/>.
*/
/** \file tftps.c
* \brief OpenTCP TFTP server implementation
* \author
* \li Jari Lahti (jari.lahti@violasystems.com)
* \version 1.0
* \date 7.10.2002
* \bug
* \warning
* \todo
* \li Offer callback functions for TFTP server
*
* OpenTCP implementation of TFTP server application. For interface
* functions declarations see /inet/tftp/tftps.h.
*/
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../inet/debug.h"
#include "../inet/datatypes.h"
#include "../inet/globalvariables.h"
#include "../inet/system.h"
#include "../inet/timers.h"
#include "../inet/tcp_ip.h"
#include "../inet/tftp/tftps.h"
#include "../inet/http/http_fs.h"
#include "../../flash.h"
#include "../../help.h"
UINT8 tftpsapp_init = 0; /**< Defines whether tftps_init has already been invoked or not */
/* TFTPS states */
#define TFTPS_STATE_ENABLED 1
#define TFTPS_STATE_CONNECTED 2
/* Maximum File size */
#define MAXFILE 8100
/* TFTP Error codes */
#define TFTPS_NOTDEFINED 0 /* Not Defined Error */
#define TFTPS_FILENOTFOUND 1 /* File not found */
#define TFTPS_ACCESSVIOLATION 2 /* Access Violation Error */
#define TFTPS_DISKFULL 3 /* Disk is full */
#define TFTPS_ILLEGALOPERATION 4 /* Not supported Opcode */
#define TFTPS_UNKNOWNID 5 /* Unknown ID */
#define TFTPS_FILEALREADYAVAIL 6 /* File already exists */
/* TFTP Opcodes */
#define TFTPS_OPCODE_RRQ 1 /* Packet is Read Request */
#define TFTPS_OPCODE_WRQ 2 /* Packet is Write Request */
#define TFTPS_OPCODE_DATA 3 /* Data Packet */
#define TFTPS_OPCODE_ACK 4 /* ACK Packet */
#define TFTPS_OPCODE_ERROR 5 /* Error Packet */
/**
* \brief TFTP server state information
*
* tftps variable holds various information that the tftp server
* needs for proper operation. These include server state, socket handle,
* timer handle, remote IP address and port number of the host we're
* communicating with, retransmit counter and TFTP block number.
*/
struct _tftpsdef tftps;
struct _tftps_filehandle tftps_file;
UINT8 tfcount = 1;
UINT16 tftparray = 0;
UINT8 rrqtest = 0;
/** \brief Initializes TFTP server
* \author
* \li Jari Lahti (jari.lahti@violasystems.com)
* \date 19.07.2002
* \return
* \li -1 - Error
* \li >=0 - OK, server intialized
*
* This function should be called before the TFTP Server application
* is used to set the operating parameters of it
*/
INT8 tftps_init (void){
/* Already initialized? */
if(tftpsapp_init)
return(1);
/* Get socket handle */
tftps.sochandle = udp_getsocket(0, tftps_eventlistener, UDP_OPT_SEND_CS | UDP_OPT_CHECK_CS);
if(tftps.sochandle < 0)
return(-1);
/* Put it to listening mode */
if( udp_open(tftps.sochandle, TFTPS_SERVERPORT) < 0 )
return(-1);
/* Get timer handle */
tftps.tmrhandle = get_timer();
tftps.state = TFTPS_STATE_ENABLED;
tftps.remip = 0;
tftps.remport = 0;
tftps.retries = 0;
tftps.blocknumber = 0;
tftps.bytecount = 0;
tftpsapp_init = 1;
/* File transfer structures */
tftps_file.flen = 0;
tftps_file.fpoint = 0;
tftps_file.actualblock = 1;
tftps_file.finish = 0;
tftps_file.tftpfile = NULL;
tftps_file.haverrq = 0;
tftps_file.flashseek = 0;
tftps_file.receivedfsize = 0;
tftps_file.filesize = 0;
return(1);
}
/********************************************************************************
Function: tftps_run
Parameters: void
Return val: void
Date: 7.10.2002
Desc: The main thread of TFTP server that should be called periodically
*********************************************************************************/
void tftps_run (void)
{
if(tftpsapp_init == 0)
return;
/* Check for timeouts */
if(tftps.state == TFTPS_STATE_CONNECTED)
{
if(check_timer(tftps.tmrhandle) == 0)
{
tftps_deletesocket();
}
}
}
INT32 tftps_eventlistener (INT8 cbhandle, UINT8 event, UINT32 remip, UINT16 remport, UINT16 bufindex, UINT16 dlen)
{
UINT16 opcode;
UINT16 i;
UINT8 ch;
UINT16 u16temp;
UINT8 fname[TFTPS_FILENAME_MAXLEN];
UINT16 tftpdata = 0;
UINT16 packetcount = 0;
UINT16 flashpointer = 0;
int result = 0;
event = 0; // Just to prevent warnings
if(tftpsapp_init == 0)
return(-1);
if(cbhandle != tftps.sochandle)
return(-1);
/* If we are on other state than enabled, check that we are talking with the same guy */
if( tftps.state != TFTPS_STATE_ENABLED)
{
if(remip != tftps.remip)
return(-1);
if(remport != tftps.remport)
return(-1);
}
if(dlen < 2)
return(-1);
/* Bind socket */
tftps.remip = remip;
tftps.remport = remport;
/* Get information */
NETWORK_RECEIVE_INITIALIZE(bufindex);
opcode = RECEIVE_NETWORK_B();
opcode <<= 8;
opcode |= RECEIVE_NETWORK_B();
dlen -= 2;
/* Process it */
printf("Received OPCODE: %i\n", opcode);
switch(opcode)
{
case TFTPS_OPCODE_RRQ: /* Read request? */
{
for(i=0; i<dlen; i++) {
if(i >= TFTPS_FILENAME_MAXLEN)
{
tftps_senderror(TFTPS_NOTDEFINED);
tftps_deletesocket();
return(1);
}
ch = RECEIVE_NETWORK_B();
fname[i] = ch;
if(ch == '\0')
{
i++;
break;
}
}
dlen -= i;
result = ffs_OpenFile(fname, strlen((const char *)fname));
if(result < 0)
{
tftps_senderror(TFTPS_FILENOTFOUND);
tftps_deletesocket();
return(1);
}
printf("tftp: Find file result?: %i\n", result);
if(dlen < 6)
{
tftps_senderror(TFTPS_NOTDEFINED);
tftps_deletesocket();
return(1);
}
if( (RECEIVE_NETWORK_B() != 'o') || (RECEIVE_NETWORK_B() != 'c') || (RECEIVE_NETWORK_B() != 't') ||
(RECEIVE_NETWORK_B() != 'e') || (RECEIVE_NETWORK_B() != 't') || (RECEIVE_NETWORK_B() != '\0') )
{
tftps_senderror(TFTPS_NOTDEFINED);
tftps_deletesocket();
return(1);
}
/* OK, lets send a data packet */
if(!tftps_file.haverrq)
{
tftps_file.flen = result;
tftps_sendblock();
rrqtest++;
printf("RRQ Nr. %i File: %s\n", rrqtest, fname);
tftps_file.haverrq = 1;
}
return(1);
}
case TFTPS_OPCODE_ACK:
{
UINT16 receivedack = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -