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

📄 tftp.c

📁 Boot code for ADM5120 with serial console for Edimax router.
💻 C
字号:
/*****************************************************************************;;    Project : Edimax;    Creator :;    File    : tftp.c;    Abstract:;;*****************************************************************************/#include <tftp.h>#include <ctype.h>#include <skbuff.h>#include <eth.h>#include <arp.h>#include <ip.h>#include <udp.h>#include <if_5120.h>#include <param.h>#include <bsp_cfg.h>#include <helpers.h>#include <test_def.h>static UINT32 remote_ip;			// TFTP server ipstatic unsigned short remote_port;	// TFTP server portstatic unsigned short remote_block;	// TFTP server data block numberstatic int tftpc_read_start;/*	The "gateway" and "mask" don't seem to be used anywhere */char errstr[] = "<error>";void print_tftpc_menu(char *dl_type){	char macstr[24];	char local_ipstr[16];	char tftp_ipstr[16];	char remfile[BSP_RFNAME_MAXLEN + 1];	buart_print("\r\n");	buart_print("\r\nTFTP Download to ");	buart_print(dl_type);	buart_print("\r\n====================================================");	buart_print("\r\n [m]: MAC address                : ");	buart_print(GetMAC(macstr) ? macstr : errstr);	buart_print("\r\n [i]: Local IP address           : ");	buart_print(GetLocalIP(local_ipstr) ? local_ipstr : errstr);	buart_print("\r\n [s]: TFTP server IP address     : ");	buart_print(GetTftpIP(tftp_ipstr) ? tftp_ipstr : errstr);	buart_print("\r\n [f]: Remote file to download    : ");	buart_print(GetRemFile(remfile) ? remfile : errstr);	buart_print("\r\n [a]: Accept values and continue");	buart_print("\r\n [c]: Cancel download");	buart_print("\r\n\r\nPlease enter your choice: ");}int tftp_client_menu(char *dltype){	char key;	while (1) {		print_tftpc_menu(dltype);		key = buart_getchar();		buart_put(key);		switch(key) {			case 'M':			case 'm':				AskMAC();				break;			case 'I':			case 'i':				AskLocalIP();								break;			case 'S':			case 's':				AskTftpIP();								break;			case 'F':			case 'f':				AskRemFile();								break;			case 'A':			case 'a':				/*	Continue with current network parameters */				return 1;			case 'C':			case 'c':				/*	Canceled.  Do nothing. */				return 0;			default:				break;		}	}	return 0;}int tftp_send_ack(int block){	struct tftphdr *tftp_ack;	struct sk_buff skb;	skb_headerinit(&skb);	udp_skb_reserve(&skb);	tftp_ack = (struct tftphdr *) skb_put(&skb, sizeof(struct tftphdr));	tftp_ack->th_opcode = htons(ACK);	tftp_ack->th_block = htons(block);	udp_send(&skb, remote_ip, TFTP, remote_port);	return 0;}int tftp_send_rrq(UINT32 servip, char *filename){	struct sk_buff skb;	char *temp;	unsigned int rrqlen;	short *opCode;	int fileNameLen, i;	skb_headerinit(&skb);	udp_skb_reserve(&skb);	temp = (char *) skb.data;	/*	Op code */	opCode = (short *) temp;	*opCode = htons(RRQ);	temp += 2;	/*	Remote file name */	fileNameLen = strlen(filename);	strncpy(temp, filename, fileNameLen);	temp += fileNameLen;	/*	String terminating byte */	*temp++ = 0;	/*	Op mode "octet" */	strncpy(temp, "octet", 5); 	temp += 5;	/*	String terminating byte */	*temp = 0;	/*	Opcode + filename + terminator + "octet" + terminator is the format of an RRQ */	rrqlen = 2 + fileNameLen + 1 + strlen("octet") + 1;	skb.len = rrqlen;	remote_ip = servip;	remote_port = TFTP;	remote_block = 1;	udp_send(&skb, remote_ip, TFTP, remote_port);	return 0;}int rcv_imgpkt(char *buf, int *buf_len){	struct sk_buff skb;	int status;	skb_headerinit(&skb);	if (tftp_rcv_packet(&skb) == 1) {		*buf_len = skb.len;		memcpy(buf, skb.data, *buf_len);		if (*buf_len < 512)			status = TFTP_END;		else			status = TFTP_CONTINUE;	} else {		*buf_len = 0;		status = TFTP_NO_DATA;	}	return status;}int tftp_rcv_packet(struct sk_buff *skb){	struct tftphdr *tftp_hdr;	int data_flag, len;	data_flag = 0;	if (udp_rcv_packet(skb) == 1) {		tftp_hdr = (struct tftphdr *) skb->data;		if (ntohs(tftp_hdr->th_opcode) == DATA) {			if (remote_ip != ip_get_source_ip(skb))				return data_flag;			remote_port = udp_get_source_port(skb);			if (remote_block == ntohs(tftp_hdr->th_block)) {				tftpc_read_start = 1;				skb_pull(skb, sizeof(struct tftphdr));				tftp_send_ack(remote_block);				remote_block++;				data_flag = 1;			} else if (remote_block > ntohs(tftp_hdr->th_block)) 				tftp_send_ack(ntohs(tftp_hdr->th_block));			else 				tftp_send_ack(remote_block);		}	}	return data_flag;}UINT32 tftpc(char *buf, int buf_size){	UINT32 ticks, servip, total_len;	char servfile[15];	int transmit_flag, pkt_len = 0, rrqcount = 0;	char *working = buf;	if (get_tftp_param(&servip, servfile) != 0) {		buart_print("\r\nBad TFTP Server IP or Filename.");		return;	}		transmit_flag = TFTP_START;	total_len = 0;	if5120turnon();	tftp_send_rrq(servip, servfile);	ticks = UpTime();	while (1) {		if(buart_get(0) == 0x1B) {			/*	User can press ESC at any time to stop the transfer. */			total_len = 0;			break;		}		if ((!tftpc_read_start) && ((UpTime()-ticks) > 100)) {			tftp_send_rrq(servip, servfile);			ticks = UpTime();			rrqcount++;			buart_print(".");			if (rrqcount == 5) {				break;	// FAIL			}		}		/*	This is the primary statement that gets TFTP's UDP data */		transmit_flag = rcv_imgpkt(working, &pkt_len);		if (tftpc_read_start) {			if (transmit_flag == TFTP_CONTINUE) {				/*	Got img packet successfully */				working += pkt_len;				total_len += pkt_len;				/*	Dump a '.' to the console every 64K */				if ((total_len % (32 * 1024 * 2) == 0))					buart_put('.');				ticks = UpTime();			} else if (transmit_flag == TFTP_NO_DATA) {				/*	Couldn't get an img packet */				if ((UpTime()-ticks) > (5 * 100)) {					/*	Timeout */					total_len = 0;					buart_print("\r\nTimeout after xfer started\r\n");	// already commented out					break;				}			} else if (transmit_flag == TFTP_END) {				/*	Transmission successful */				working += pkt_len;				total_len += pkt_len;								break;			}		}	}	tftpc_read_start = 0;	if5120shutdown();	return total_len;}void tftp_init(){    remote_port = TFTP;    remote_block = 1;    tftpc_read_start = 0;	unsigned char mac[8];	// Init socket buffer	skb_init();	// Init Ethernet protocol.	bsp_GetMAC(mac);	eth_init(mac);	// Init ARP protocol	arp_init();	// Init IP protocol	bsp_GetTftpIp(&remote_ip);	ip_init();	// Init UDP protocol	udp_init();	// Init Data Receive Queue	if (InitEthPktQueue() != 0) {		buart_print("\n\rInit ethernet receive queue error");		panic();	}	// Shutdown Switch until TFTP download starts	if5120shutdown();}

⌨️ 快捷键说明

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