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

📄 update.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "vxWorks.h"
#include "string.h" 
#include "stdio.h"
#include "sockLib.h" 
#include "inetLib.h"
#include "config.h"
#include "pgi_ifLib.h" 
#include "bepcommon.h"
#include "update.h"

#include "h/drv/mem/T830xFlash.h"  /**add by chen for update boot **/

#ifdef __cplusplus
extern "C" {
#endif

/*******************************************************
* 定义在DHCP.C
*******************************************************/
extern int readable_timeo(int, int);
/*******************************************************
* 写Flash的函数 定义在drv/mem/FLASHUPD.C
*******************************************************/
extern UCHAR   gFlashType ;
extern STATUS Program_Boot_Flash_Mem ( unsigned short *pVersion, unsigned long Length );
extern STATUS Program_Version_Flash_Mem ( unsigned short *pVersion, unsigned short *pAddr, unsigned long Length );

/*******************************************************
* Part FTP_UPDATE
*******************************************************/
static int FtpUpdate();
static int FtpCommand(int sockfd, char * cmd, const char * param);
static int FtpRecvReply(int);
static int FtpRecvReply2(int);
static int FtpInitDataConn(unsigned int server_ip, unsigned short * ptr_port);
static int FtpLoginServer(int ctrl_fd, const char * user, const char * pass);
static int FtpOpenCtrlConn(unsigned int server_ip);
static int FtpPrepareTransfer(int ctrl_fd, unsigned short port);
static int FtpGetUpdate(int ctrl_fd, int data_fd, const char * filename);
static int FtpQuitServer(int ctrl_fd);

static unsigned char ftp_request[FTP_REQ_LENGTH];
static unsigned char ftp_reply[3];
static unsigned char ftp_fileblock[FTP_BLOCK_SIZE];

static char * ftp_user_cmd = "USER";
static char * ftp_pass_cmd = "PASS";
static char * ftp_type_cmd = "TYPE";
static char * ftp_port_cmd = "PORT";
static char * ftp_retr_cmd = "RETR";
static char * ftp_quit_cmd = "QUIT";

/*******************************************************
* Part TFTP_UPDATE
*******************************************************/
static int TftpUpdate();
static int TftpSendRRQ(int sockfd, char * filename);
static int TftpSendAck(int sockfd, unsigned short index);
static int TftpGetResponse(int sockfd, int * p_len);
static int TftpGetUpdate(int sockfd);

static char * tftp_filemode = "octet";
static struct sockaddr_in tftp_server_addr;
static unsigned short tftp_tid;
static unsigned short tftp_index;
static s_lastdata tftp_lastdata;
static s_tftp_data tftp_fileblock;

/*******************************************************
* Part UPDATE_COMMON
*******************************************************/
static s_updateblock * ConstructBlockNode(void);
void ClearUpdateBlock(s_updateblock * ptr_updatefile);
int UpdateFlashRom(s_updateblock * ptr_updatefile, int count, int fileT);

#ifdef __UPDATE_DEBUG__
static void CheckUpdateBlock(s_updateblock * ptr);
#endif

static int yes = 1;
static int addr_len = sizeof(struct sockaddr_in);

/*******************************************************
* 升级函数
*******************************************************/
int Update()
{
	if (phoneconfig.conf_ftp.mode == MODE_FTP)
	{
		return FtpUpdate();
	}
	else
	{
		return TftpUpdate();
	}
}

/*******************************************************
* Part FTP_UPDATE
*******************************************************/
static int FtpUpdate()
{
	int ctrl_fd, data_fd;
	unsigned short data_port;
	int result;

	#ifdef __UPDATE_DEBUG__
	printf("Begin FTP Update...\n");
	#endif
	
	if ((ctrl_fd = FtpOpenCtrlConn(phoneconfig.conf_ftp.server)) < 0)
	{
		fprintf(stderr, "can not connect to server\n");
		return UPDATE_CONN_ERROR;
	}
	if ((result = FtpLoginServer(ctrl_fd, 
		(strlen(phoneconfig.conf_ftp.usrid)==0?"anonymous":phoneconfig.conf_ftp.usrid), 
		phoneconfig.conf_ftp.pin)) 
		< 0)
	{
		close(ctrl_fd);
		fprintf(stderr, "login error\n");
		return result;
	}	
	if ((data_fd = FtpInitDataConn(phoneconfig.conf_ftp.server, &data_port)) < 0)
	{
		close(ctrl_fd);
		fprintf(stderr, "error open data connection\n");
		return data_fd;
	}
	if ((result = FtpPrepareTransfer(ctrl_fd, data_port)) < 0)
	{
		close(data_fd);
		close(ctrl_fd);
		fprintf(stderr, "error prepare for transfer\n");
		return result;
	}
	if ((result = FtpGetUpdate(ctrl_fd, data_fd, phoneconfig.conf_ftp.filename)) < 0)
	{
		close(data_fd);
		close(ctrl_fd);
		fprintf(stderr, "error get ftp update file\n");
		return result;
	}
	/*close(data_fd);
	FtpQuitServer(ctrl_fd);
	close(ctrl_fd);*/
	
	#ifdef __UPDATE_DEBUG__
	printf("FTP Update OK.\n");
	#endif
	
	return UPDATE_OK;
}

/**
* 打开控制连接
*/
static int FtpOpenCtrlConn(unsigned int server_ip)
{
	struct sockaddr_in server_addr;
	int ctrl_fd;
	struct timeval timeVal = {20, 0};
	
	#if 1
	printf("Begin FtpOpenCtrlConn\n");
	#endif
	if ((ctrl_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		perror("create control socket");
		return UPDATE_CONN_ERROR;
	}
	if (setsockopt(ctrl_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &yes, sizeof(yes)) < 0)
	{
		close(ctrl_fd);
		perror("setsockopt ctrl socket");
		return UPDATE_CONN_ERROR;
	}
	memset(&server_addr, '\0', addr_len);
	server_addr.sin_family = AF_INET;
	server_addr.sin_len = addr_len;
	server_addr.sin_port = htons(FTP_CTRL_PORT);
	server_addr.sin_addr.s_addr = htonl(server_ip);

	printf("try connect\n");
	if (connectWithTimeout(ctrl_fd, (struct sockaddr *) &server_addr, addr_len, &timeVal) < 0)
	{
		close(ctrl_fd);
		perror("connect to ctrl");
		return UPDATE_CONN_ERROR;
	}
	/**
	* Reply should be "220"
	*/
	if (FtpRecvReply2(ctrl_fd) < 0 || ftp_reply[0] != '2')
	{
		close(ctrl_fd);
		fprintf(stderr, "error while open control connection\n");
		return UPDATE_CONN_ERROR;
	}
	else
	{
		#ifdef __UPDATE_DEBUG__
		printf("connected to server %u.%u.%u.%u\n", 
				(unsigned char) (server_ip >> 24),
				(unsigned char) (server_ip >> 16),
				(unsigned char) (server_ip >> 8),
				(unsigned char) (server_ip >> 0)
				);
		#endif
	}
	return ctrl_fd;
}

/**
* 登录FTP服务器
*/
static int FtpLoginServer(int ctrl_fd, const char * user, const char * pass)
{
	#if 1
	printf("FtpLoginServer\n");
	#endif
	/**
	* Command USER
	*/
	if (FtpCommand(ctrl_fd, ftp_user_cmd, user) < 0)
	{
		fprintf(stderr, "USER command error\n");
		return UPDATE_CONN_ERROR;
	}
	/**
	* USER reply should be "331"
	*/
	if (FtpRecvReply(ctrl_fd) < 0 || ftp_reply[0] != '3')
	{
		if (ftp_reply[0] == '2')
		{
			#ifdef __UPDATE_DEBUG__
			printf("%.3s: user %s logging, needn't pass\n", ftp_reply, user);
			#endif
			return UPDATE_OK;
		}
		fprintf(stderr, "error recv USER\n");
		return UPDATE_CONN_ERROR;
	}
	else
	{
		#ifdef __UPDATE_DEBUG__
		printf("%.3s: user %s logging\n", ftp_reply, user);
		#endif
	}
	/**
	* Command PASS
	*/
	if (FtpCommand(ctrl_fd, ftp_pass_cmd, pass) < 0)
	{
		fprintf(stderr, "PASS command error\n");
		return UPDATE_CONN_ERROR;
	}
	/**
	* PASS reply should be "230"
	*/
	for (;;)
	{
		if (FtpRecvReply(ctrl_fd) < 0)
		{
			fprintf(stderr, "error recv PASS\n");
			return UPDATE_CONN_ERROR;
		}
		else if (ftp_reply[0] == '2')
		{
			#ifdef __UPDATE_DEBUG__
			printf("%.3s: user %s logged in\n", ftp_reply, user);
			#endif
			return UPDATE_OK;
		}
		else if (ftp_reply[0] == '3')
		{
			printf("%.3s: user %s\n", ftp_reply, user);
			continue;
		}
		else
		{
			fprintf(stderr, "PASS or USER error\n");
			return UPDATE_PASSWD_ERROR;
		}
	}
}

/**
* 打开数据连接
*/
static int FtpInitDataConn(unsigned int server_ip, unsigned short * ptr_port)
{
	struct sockaddr_in client_addr;
	int data_fd;
	int len = addr_len;
	
	int listen_fd;
	
	#if 1
	printf("FtpInitDataConn\n");
	#endif
	if ((data_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		perror("create data socket");
		return UPDATE_CONN_ERROR;
	}	
	if (setsockopt(data_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &yes, sizeof(yes)) < 0)
	{
		close(data_fd);
		perror("setsockopt data socket");
		return UPDATE_CONN_ERROR;
	}
	
	memset(&client_addr, '\0', addr_len);
	client_addr.sin_family = AF_INET;
	client_addr.sin_len = addr_len;
	client_addr.sin_port = 0;
	client_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	
	if (bind(data_fd, (struct sockaddr *) &client_addr, addr_len) < 0)
	{
	    perror("bind data socket");
		close(data_fd);
		return UPDATE_CONN_ERROR;
	}
	if ((listen_fd=listen(data_fd, 1)) < 0)
	{
		perror("listen on data socket");
		close(data_fd);
		return UPDATE_CONN_ERROR;
	}
	
	if (getsockname(data_fd, (struct sockaddr *) &client_addr, &len) < 0)
	{
		perror("getsockname");
		close(data_fd);
		return UPDATE_CONN_ERROR;
	}
	*ptr_port = ntohs(client_addr.sin_port);
	#ifdef __UPDATE_DEBUG__
	printf("client port %u\n", *ptr_port);
	#endif
	return data_fd;
}

static int FtpPrepareTransfer(int ctrl_fd, unsigned short port)
{
	unsigned char port_data[FTP_REQ_LENGTH];
	unsigned int i_ip;
	/**
	* Command TYPE
	*/
	if (FtpCommand(ctrl_fd, ftp_type_cmd, "I") < 0)
	{
		fprintf(stderr, "TYPE I command error\n");
		return UPDATE_CONN_ERROR;
	}
	/**
	* PASS reply should be "200"
	*/
	if (FtpRecvReply(ctrl_fd) < 0 || ftp_reply[0] != '2')
	{
		fprintf(stderr, "error recv TYPE I\n");
		return UPDATE_CONN_ERROR;
	}
	else
	{
		#ifdef __UPDATE_DEBUG__
		printf("%.3s: TYPE set to binary\n", ftp_reply);
		#endif
	}
	/**
	* Command PORT
	*/
	memset(port_data, 0, FTP_REQ_LENGTH);
	if (ifAddrGet(LOCAL_IF0, port_data) != IF_OK)
	{
		fprintf(stderr, "error get ip\n");
		return UPDATE_CONN_ERROR;
	}
	i_ip = ntohl(inet_addr(port_data));
	memset(port_data, 0, FTP_REQ_LENGTH);
	/**
	* 获得自己的IP
	*/
	sprintf(port_data, "%u,%u,%u,%u,%u,%u", 
		(unsigned char) (i_ip >> 24), 
		(unsigned char) (i_ip >> 16),
		(unsigned char) (i_ip >> 8),
		(unsigned char) (i_ip),
		(unsigned char) (port >> 8),
		(unsigned char) port
		);
	if (FtpCommand(ctrl_fd, ftp_port_cmd, port_data) < 0)
	{
		fprintf(stderr, "PORT command error\n");
		return UPDATE_CONN_ERROR;
	}
	/**
	* PORT reply should be "200"
	*/
	if (FtpRecvReply(ctrl_fd) < 0 || ftp_reply[0] != '2')
	{
		fprintf(stderr, "error recv PORT\n");
		return UPDATE_CONN_ERROR;
	}
	else
	{
		#ifdef __UPDATE_DEBUG__
		printf("%.3s: PORT set to %u.%u.%u.%u.%u.%u\n", ftp_reply,
		(unsigned char) (i_ip >> 24), 
		(unsigned char) (i_ip >> 16),
		(unsigned char) (i_ip >> 8),
		(unsigned char) (i_ip),
		(unsigned char) (port >> 8),
		(unsigned char) port
		);
		#endif
	}
	return UPDATE_OK;
}
extern int iftelnet;
static int FtpGetUpdate(int ctrl_fd, int data_fd, const char * filename)
{
	int transfer_fd;
	int ret;
	fd_set fdset;
	int maxfd;
	int len = sizeof(struct sockaddr);
	struct sockaddr_in addr;
	s_updateblock update_block; 
	s_updateblock * ptr_block;
	int count, result;
	int fileType;
	struct timeval tv;
	unsigned int spareCount;/**add by chen**/
	/**
	* Command RETR
	*/
	if (FtpCommand(ctrl_fd, ftp_retr_cmd, filename) < 0)
	{
		fprintf(stderr, "RETR command error\n");
		return UPDATE_CONN_ERROR;
	}
	/**
	* RETR reply should be "150"
	*/
	if (FtpRecvReply(ctrl_fd) < 0)
	{
		fprintf(stderr, "error recv RETR\n");
		return UPDATE_CONN_ERROR;
	}
	else if (ftp_reply[0] != '1')
	{
	
		if((ftp_reply[0]=='4') && (ftp_reply[1] == '2') && (ftp_reply[2] == '5'))
		{
			fprintf(stderr, "server busy now\n");
			return UPDATE_BUSY;
		}
		else
		{
			fprintf(stderr, "RETR file error\n");
			return UPDATE_FILE_NOTEXIST;
		}
	}
	else
	{
		#ifdef __UPDATE_DEBUG__
		printf("%.3s: RETR success\n", ftp_reply);
		#endif
	}
	/**
	* accept server connect
	*/
	FD_ZERO(&fdset);
	tv.tv_sec = 10*60;
	tv.tv_usec = 0;
	FD_SET(data_fd,&fdset);
	ret=select(data_fd+1,&fdset,NULL,NULL,&tv);
	
	if(ret<=0)
	{
		perror("select error");
		return UPDATE_CONN_ERROR;
	}
	
	if ((transfer_fd = accept(data_fd, (struct sockaddr *) &addr, &len)) < 0)
	{
		perror("accept server");
		return UPDATE_CONN_ERROR;
	}
	#ifdef __UPDATE_DEBUG__
	printf("server port %u\n", ntohs(addr.sin_port));
	#endif
	
	count = 0;
	update_block.next = NULL;
	ptr_block = & update_block;
	fileType = 0;
	spareCount = 0;
	/**
	* get data
	*/
	while ((len = recv(transfer_fd, ftp_fileblock, FTP_BLOCK_SIZE, 0)) > 0) 
	{
		/*printf("###spareCount = %u###\n",spareCount);
		printf("###len = %d###\n",len);
		printf("###count = %d###\n",count);*/
		/*判断文件头是否有效*/
		if ( count == 0 )
		{
			if (len > 4)
			{
				if ( memcmp(ftp_fileblock, phoneconfig.bootFileHead, 4) == 0 )
					fileType = 1;
				if ( memcmp(ftp_fileblock, phoneconfig.appFileHead, 4) == 0 )
					fileType = 2;
			}
			if (fileType != 1 && fileType != 2)
			{
				printf("file type error!\n\n");
				return UPDATE_INVALID_FILE;
			}
		}
		if(iftelnet)
			taskDelay(1);
		if ((count + len) > COMPRESSED_IMAGE_SIZE /*||
			(ptr_block -> next = ConstructBlockNode()) == NULL*/)
		{
			fprintf(stderr, "file too long, can't malloc\n");
			/* 释放内存 */
			ClearUpdateBlock(update_block.next);
			return UPDATE_NO_SPACE;;
		}
		if(spareCount == 0)
		{
			if((ptr_block -> next = ConstructBlockNode()) == NULL)
			{
				fprintf(stderr, "file too long, can't malloc\n");
				/* 释放内存 */
				ClearUpdateBlock(update_block.next);
				return UPDATE_NO_SPACE;;
		      }
			ptr_block = ptr_block -> next;
			memcpy(ptr_block -> fileblock, ftp_fileblock, len);
			ptr_block -> length = len;
			count += len;
			spareCount = 1024 - len;
			
		}
		else 
		{
			if(len > spareCount)
			{
				memcpy((ptr_block -> fileblock)+ptr_block ->length, ftp_fileblock, spareCount);
				ptr_block -> length = 1024;
				count += spareCount;
				len -= spareCount;
				if((ptr_block -> next = ConstructBlockNode()) == NULL)
				{
					fprintf(stderr, "file too long, can't malloc\n");
					/* 释放内存 */
					ClearUpdateBlock(update_block.next);
					return UPDATE_NO_SPACE;
		     		 }
				ptr_block = ptr_block -> next;
				memcpy(ptr_block -> fileblock, ftp_fileblock + spareCount, len);
				ptr_block -> length = len;
				count += len;
				spareCount = 1024 -len;
			}
			else
			{
				memcpy((ptr_block -> fileblock)+ptr_block ->length, ftp_fileblock, len);
				ptr_block -> length += len;
				count += len;
				spareCount -= len;
			}
		}
	}
	
	if (count == 0)
	{
		printf("file size is 0!!!\n\n");
		return UPDATE_INVALID_FILE;
	}
	/**

⌨️ 快捷键说明

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