?? 復件 update.c
字號:
#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 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 (FtpRecvReply(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' && ftp_reply[1] =='3')
{
#ifdef __UPDATE_DEBUG__
printf("%.3s: user %s logging, needn't pass\n", ftp_reply, user);
#endif
return UPDATE_OK;
}
else
{
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')
{
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 + -