⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tftp.c

📁 ucos~{VPJ5OV~}tftp~{T4Bk!#PhR*~}IPPACK~{V 3V~}
💻 C
字号:

/******************************************************************************
* Filename     : tftp.c                                                       *
* Program      : loader.                                                      *
* Copyright    : Copyright (C) 2001, Young-Su, Ahn.                           *
* Author       : Young-Su, Ahn <nurie@dreamwiz.com>                           *
* Description  : Use Tftp.                                                    *
*                Make tftp packet and transmit it.                            *
*                Handling received Tftp packet.                               *
* Created at   : Wed Mar 13 2001.                                             *
* Based on     : pptboot-0.5.3, CS8900A device driver.                        *
* Modified by  :                                                              *
* Modified at  :                                                              *
******************************************************************************/
/* This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include "main.h"

#define TFTP_PORT					69		// Well known TFTP port #
#define TFTP_TIMEOUT				5		// Seconds to tftpTimeout for a lost pkt
#define TIMEOUT_COUNT				10		// # of tftpTimeouts before giving up

// TFTP operations.
#define TFTP_RRQ					1
#define TFTP_WRQ					2
#define TFTP_DATA					3
#define TFTP_ACK					4
#define TFTP_ERROR					5


#define TFTP_NONE					0
#define TFTP_STATE_RRQ				1
#define TFTP_STATE_DATA				2
#define TFTP_STATE_TOO_LARGE		3
#define TFTP_STATE_BAD_MAGIC		4
#define TFTP_STATE_SUCCESS			5
#define TFTP_STATE_FAILURE			6


static short	tftpState = 0;
static short	tftpBlock = 0;
static short	tftpLastBlock = 0;
static U32		loadAddr = 0;
short			tftpPort = 69;
short			tftpHostPort=0;
short			tftpClientPort = 7777;
static char		requestFile[128];
static U32		tftpTimeout;

// Prototypes.
//bool			TftpStart(char *filename);
bool			TftpStart(int itype);
void			TftpTx(char *txBuf);

/**********************************************************************/
// 开且 : tftp [filename] [addr]狼 牢磊甫  tftp甫 角青窍扁 困茄 窃荐客 
//        楷搬.
// 概俺 : 
// 馆券 : 己傍窍搁 true, 角菩窍搁 false.
// 林狼 : 
bool DoTftp(int itype)
{
	// tftp肺 罐篮 file data甫 扁废且 林家甫 积己.
	if (itype==0)
	{
		loadAddr = (U32)KERNEL_DRAM_BASE;
	}
	else if(itype==1)
	{
		loadAddr = (U32)RAMDISK_DRAM_BASE;
	}
	else
	{
		loadAddr = (U32)LOADER_DRAM_DOWN_BASE;	
	}


	// IP啊 绝栏搁 bootp甫 角青窍咯 IP甫 且寸 罐澜.
	if (clientIP==0){
		Serial_Printf("\tNo IP. Bootp start...\n\r");
		if (DoBootp()==false)
		{
			Serial_Printf("\tBootp failed. try again.\n\r");
			return false;
		}
	}

	return TftpStart(itype);

}	// DoTftp.


// 开且 : tftp甫 角青且 券版 免仿.
// 概俺 : 
// 馆券 : 己傍窍搁 true, 角菩窍搁 false.
// 林狼 : 
//bool TftpStart(char *filename)



bool TftpStart(int itype)
{
	char		*txPktBuf, *rxPktBuf;
	char 		*kfd="zImage";
	char 		*rfd="ramdisk.gz";
	char 		*bfd="kloader.bin";


	txPktBuf = (char *)PktBuf;
	rxPktBuf = (char *)PktBuf;
	
	
	Serial_Printf("\ni-type = %d\n",itype);
	
	
	// tftp 角青 券版 免仿.
	Serial_Printf("TFTP Start...\n\r");
	
	Serial_Printf("\tHost   (server) IP       : ");
	PrintIPAddr(hostIP);
	Serial_Printf("\n\r");
	
	Serial_Printf("\tClient (target) IP       : ");
	PrintIPAddr(clientIP);
	Serial_Printf("\n\r");

	if(itype == 0) StrCpy(requestFile, kfd);
	else if(itype == 1) StrCpy(requestFile, rfd);
	else StrCpy(requestFile, bfd);

	Serial_Printf("\tLoading Filename         : %s",requestFile);
	Serial_Printf("\n\r");

	Serial_Printf("\tSave Address             : 0x%x",loadAddr);
	Serial_Printf("\n\r");
	
	Serial_Printf("\n\r\rLoading start...\n\r");

	// tftp 矫累 券版.
	protocol = PROT_TFTP;
	tftpState = TFTP_STATE_RRQ;
	tftpHostPort = 0;

	// tftp request packet 傈价.
	TftpTx(txPktBuf);

	// tftpTimeout篮 捞镑俊辑 沥窍哥, tftp data packet阑 罐阑 锭付促 盎脚等促.
	// 矫埃捞 檬苞窍搁 tftp绰 角菩肺 埃林窍绊 吝窜茄促.
	tftpTimeout = GetTime() + TFTP_TIMEOUT * HZ;
	
	// tftp啊 己傍窍芭唱 角菩且 锭鳖瘤 tftp data pakcet阑 荐脚.
	while (tftpState!=TFTP_STATE_SUCCESS && tftpState!=TFTP_STATE_FAILURE){
		RxPacket(rxPktBuf);
		// 矫埃 檬苞搁 角菩窍绊 吝窜.
		if (GetTime()>tftpTimeout){
			Serial_Printf("\n\r\tTftp is failed. Try again.\n\r\n\r");
			tftpState=TFTP_STATE_FAILURE;
		}
	}

	// 促澜 tftp 角青阑 困秦 券版阑 登倒覆.
	protocol = NOPROTOCOL;
	tftpState = TFTP_NONE;
	tftpBlock = 0;
	tftpHostPort = 0;
	return true;
}	// TftpStart.


// 开且 : tftp啊 鞘夸肺 窍绰 packet阑 父甸绢 傈价..
// 概俺 : 
// 馆券 : 己傍窍搁 true, 角菩窍搁 false.
// 林狼 : 
void TftpTx(char *txPktBuf)
{
	char		*pktPtr = (char *)(txPktBuf+ETHER_HDR_SIZE+IP_HDR_SIZE+UDP_HDR_SIZE);
	U16		hostPort = 0;
	int			len = 0;

//	Serial_Printf(" <TFTP Send -- %d> ",tftpState);
//	MemSet(txPktBuf, 0, MAX_PKT_SIZE);
	MemSet(txPktBuf-(ETHER_HDR_SIZE+IP_HDR_SIZE+UDP_HDR_SIZE), 0, MAX_PKT_SIZE);	
	// make tftp header.
	switch (tftpState){
		// tftp request packet阑 父惦.
		case TFTP_STATE_RRQ:
			*((U16 *)pktPtr)++ = SWAP16(TFTP_RRQ);
			StrCpy((char *)pktPtr, requestFile);
			pktPtr += StrLen(requestFile) + 1;
			StrCpy((char *)pktPtr, "octet");
			pktPtr += 5 + 1;
			len = pktPtr - txPktBuf;
			hostPort = tftpPort;
			break;

		// 荐脚茄 data packet俊 措茄 acknowledge packet阑 父惦.
		case TFTP_STATE_DATA:
			*((U16 *)pktPtr)++ = SWAP16(TFTP_ACK);
			*((U16 *)pktPtr)++ = SWAP16(tftpBlock);
			len = pktPtr - txPktBuf;
			hostPort = tftpHostPort;
			break;

		// error packet阑 父惦.
		case TFTP_STATE_TOO_LARGE:
			*((U16 *)pktPtr)++ = SWAP16(TFTP_ERROR);
			*((U16 *)pktPtr)++ = SWAP16(3);
			StrCpy((char *)pktPtr, "File too large");
			pktPtr += 14 + 1;
			len = pktPtr - txPktBuf;
			hostPort = tftpHostPort;

			break;

		// error packet阑 父惦.
		case TFTP_STATE_BAD_MAGIC:
			*((U16 *)pktPtr)++ = SWAP16(TFTP_ERROR);
			*((U16 *)pktPtr)++ = SWAP16(2);
			StrCpy((char *)pktPtr, "File has bad magic");
			pktPtr += 18 + 1;
			len = pktPtr - txPktBuf;
			hostPort = tftpHostPort;
			break;
		default :
			return;
	}
	// Ethernet, IP, UDP Header甫 父惦.
	SetUdpHeader((char *)(txPktBuf+ETHER_HDR_SIZE+IP_HDR_SIZE), hostPort, tftpClientPort, len);
	SetIPHeader((char *)(txPktBuf+ETHER_HDR_SIZE), clientIP, hostIP, UDP_HDR_SIZE+len);
	SetEtherHeader(txPktBuf, (char *)hostEther, PROT_IP);

	// tftp packet 傈价.
	TxPacket(txPktBuf, ETHER_HDR_SIZE+IP_HDR_SIZE+UDP_HDR_SIZE+len);
	return;
}	// TftpTx.


// 开且 : tftp packet阑 罐酒 贸府.
// 概俺 : 
// 馆券 : 己傍窍搁 true, 角菩窍搁 false.
// 林狼 : 
bool TftpRx(char *rxPktBuf, int len){
	char			*pktPtr = rxPktBuf;
	short			value;
	U32			rlen=0;			// tftp肺 傈价罐篮 data狼 辨捞(烙矫 buffer).
	
	// handling received data.
	value = SWAP16(*(short *)pktPtr);	// packet type.
//	Serial_Printf(" <TFTP Recv - %d> ",value);
	pktPtr+=2;
	len-=2;
	switch (value){
		case TFTP_RRQ :
		case TFTP_WRQ :
		case TFTP_ACK :
		default:
			break;
		// tftp data packet.
		case TFTP_DATA :
			// error. check data index.
			if (len < 2) 
			{
				Serial_Printf("\nLength err "); 
				return false;
			}	
			//Serial_Printf("\nBlockNo - 0x%x",*(U16 *)pktPtr);
			tftpBlock = SWAP16(*(U16 *)pktPtr);	// tftp data packet俊辑 block 锅龋.
			pktPtr += 2;
			len -= 2;
			// tftp receive 柳青 钎矫.
			if (((tftpBlock)%128)==0){	// each 64 kbyte.
			
				//ClearLine();
				rlen = (long)tftpBlock * 512;
				Serial_Printf("\n0x%08lx bytes received.", rlen);
			}

			// request俊 措茄 霉锅掳 data packet老锭 鞘夸茄 沥焊 汲沥.
			if (tftpState == TFTP_STATE_RRQ)
			{
				tftpState = TFTP_STATE_DATA;
				tftpLastBlock = 0;
				if (tftpBlock != 1){
					tftpState = TFTP_STATE_FAILURE;
					return false;
				}
			}
			// 捞傈狼 packet阑 促矫 罐疽阑 锭绰 公矫.
//			Serial_Printf(" <Recv Block - %d> ", tftpBlock);
			if (tftpBlock <= tftpLastBlock) break;

			tftpLastBlock = tftpBlock;
	
			// 荐脚茄 tftp packet狼 data 何盒阑 瘤沥茄 memory 康开俊 扁废. block篮 512 byte 窜困.
			MemCpy((char *)(loadAddr+(tftpBlock-1)*512), (char *)pktPtr, len);

			// TftpStart()俊辑 check窍绰 tftpTimeout 矫埃阑 盎脚.
			tftpTimeout = GetTime() + TFTP_TIMEOUT * HZ;
			
			// Acknowledge甫 焊晨. 捞巴阑 罐篮 饶 server绰 促澜 block狼 data甫 啊柳 packet阑 傈价.
			TftpTx(rxPktBuf);

			// 荐脚茄 tftp packet捞 data狼 付瘤阜 block老 锭.
			if (len < 512){
				// We received the whole thing.  Try to run it.
				//ClearLine();
				rlen = ((long)tftpBlock-1) * 512 + len;
				Serial_Printf("\n0x%08lx (%ld) bytes received.", rlen, rlen);
				Serial_Printf("\nftp done.\n\n");
				tftpState = TFTP_STATE_SUCCESS;				
			}
			break;
		// error 贸府.
		case TFTP_ERROR :
			// tftp RRQ or tftp ack pakcet has some error.
			Serial_Printf("\n\r\rTFTP error: '");
			Serial_Printf(pktPtr+2);
			Serial_Printf("' (");
			OutputDec(SWAP16(*(U16 *)pktPtr));
			Serial_Printf(")\n\r");
			tftpState = TFTP_STATE_FAILURE;
			break;
	}
	return true;
}	// TftpRx.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -