修改软件版本号及启动状态信息

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <dirent.h>



typedef unsigned char U8;
typedef unsigned int U32;



#define DEBUG_THIS
#if defined(DEBUG_THIS)
#define DBGMODL "CHAGESTATE"
#define dbg_print(outflag,...) do{switch(outflag){case 1:printf("\n<INFO> " DBGMODL ": [%s],Line %d ",__FUNCTION__,__LINE__);printf(__VA_ARGS__);fflush(stdout);break;case 2:	printf("\n<ERROR> " DBGMODL ": [%s],Line %d ",__FUNCTION__,__LINE__);printf(__VA_ARGS__);fflush(stdout);break;default:break;}}while(0)
#else
#define dbg_print
#endif


#define E2P_JWT_LOADER_SIZE_FDCA 20

typedef struct
{
	U8 activation;
	U8 pid[2];
	U8 table_id;
	U8 freq[4];
	U8 symbol[4];
	U8 modulation;
	U8 block_index;
	U8 version[2];
	U8 crc[4];	
}JWT_UPDATE_FDCA_t;
typedef struct{
		U8 manufacturer_id; 
		U8 model_id; 
		U8 majorhardwrare_id; 
		U8 subhardwrare_id; 
		U8 ca_ident_number[4]; 
		U8 release_number[4];
		U8 broadcaster[4];
		U8 signature[152]; 
		U8 batch_id;
		U8 MAC_address[6];
		U8 build_year;
		U8 build_week;
		U8 STB_provider_id[2];
		U8 manager_code[4];
		U8 hardware_code[4];
		U8 software_version[4];
		U8 reserved[61];
		U8 crc[4];
}JWT_UPDATE_BCA_t;

typedef struct{
	U8 major_mrs_version;
	U8 sub_mrs_version;
	U8 reserved1[8];
	U8 release_year;
	U8 release_month;
	U8 release_date;
	U8 reserved2[11];
	U8 fdca_image[E2P_JWT_LOADER_SIZE_FDCA];
	U8 signature[152]; 
	U8 crc[4];
}JWT_UPDATE_FLASH_HEADER_t;



extern char *optarg;

//global variable
char exe_filename[20]="\0";
U8 chgstate = 0,ori_chgstate = 0;
U8 sw_ver = 0,ori_sw_ver = 0;
U8 auto_reboot = 0;
U32 dumplen = 2048;
U32 fgda_offset = 512;
U32 bca_offset = 0;
U8 quit = 0;
char dumpfile[256]="/mnt/info/stbinfotmp";

#ifdef BCM7581B0
U8 mtdnum = 7;
char *filename="/mnt/usb/kv_7581b0_update/usb_update.cfg";
char *platform="bcm7581b0";
#endif
#ifdef BCM7019C0
U8 mtdnum = 11;
char *filename="/mnt/usb/kv_update/usb_update.cfg";
char *platform="bcm7019c0";
#endif

unsigned long ulTable_MPEG32_ota[256] =
{
   0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L,
   0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L,
   0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L,
   0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL,
   0x4C11DB70L, 0x48D0C6C7L, 0x4593E01EL, 0x4152FDA9L,
   0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L,
   0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L,
   0x791D4014L, 0x7DDC5DA3L, 0x709F7B7AL, 0x745E66CDL,
   0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L,
   0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L,
   0xBE2B5B58L, 0xBAEA46EFL, 0xB7A96036L, 0xB3687D81L,
   0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL,
   0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L,
   0xC7361B4CL, 0xC3F706FBL, 0xCEB42022L, 0xCA753D95L,
   0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L,
   0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL,
   0x34867077L, 0x30476DC0L, 0x3D044B19L, 0x39C556AEL,
   0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L,
   0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L,
   0x018AEB13L, 0x054BF6A4L, 0x0808D07DL, 0x0CC9CDCAL,
   0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL,
   0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L,
   0x5E9F46BFL, 0x5A5E5B08L, 0x571D7DD1L, 0x53DC6066L,
   0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL,
   0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL,
   0xBFA1B04BL, 0xBB60ADFCL, 0xB6238B25L, 0xB2E29692L,
   0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L,
   0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL,
   0xE0B41DE7L, 0xE4750050L, 0xE9362689L, 0xEDF73B3EL,
   0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L,
   0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L,
   0xD5B88683L, 0xD1799B34L, 0xDC3ABDEDL, 0xD8FBA05AL,
   0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L,
   0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL,
   0x4F040D56L, 0x4BC510E1L, 0x46863638L, 0x42472B8FL,
   0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L,
   0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L,
   0x36194D42L, 0x32D850F5L, 0x3F9B762CL, 0x3B5A6B9BL,
   0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL,
   0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L,
   0xF12F560EL, 0xF5EE4BB9L, 0xF8AD6D60L, 0xFC6C70D7L,
   0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL,
   0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL,
   0xC423CD6AL, 0xC0E2D0DDL, 0xCDA1F604L, 0xC960EBB3L,
   0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L,
   0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL,
   0x9B3660C6L, 0x9FF77D71L, 0x92B45BA8L, 0x9675461FL,
   0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L,
   0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L,
   0x4E8EE645L, 0x4A4FFBF2L, 0x470CDD2BL, 0x43CDC09CL,
   0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L,
   0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L,
   0x119B4BE9L, 0x155A565EL, 0x18197087L, 0x1CD86D30L,
   0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL,
   0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L,
   0x2497D08DL, 0x2056CD3AL, 0x2D15EBE3L, 0x29D4F654L,
   0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L,
   0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL,
   0xE3A1CBC1L, 0xE760D676L, 0xEA23F0AFL, 0xEEE2ED18L,
   0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L,
   0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L,
   0x9ABC8BD5L, 0x9E7D9662L, 0x933EB0BBL, 0x97FFAD0CL,
   0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L,
   0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L
};

U32 calculateCRC(U8 *pData, U8 len)
{
	U32 section_len;
	U32 calucate_crc;
	U8 *tempData = pData;
	
	section_len = len;
	calucate_crc = 0xFFFFFFFF;

	/* calculate CRC */
	while (section_len--)
	{
	  	calucate_crc = ulTable_MPEG32_ota[((calucate_crc >> 24) ^ *tempData++) & 0xFFL] ^ (calucate_crc << 8);
	}

	return calucate_crc;
}

void print_help(char *name)
{
	printf("此程序用作更改机顶盒的信息-n改变进入选项,-s改变软件版本号\n");
	printf("用法:%s [选项] <[-n state] [-s sw_ver]>\n",name);
	printf("选项有:-m 指定的mtd号(默认是7)\n");
	printf("      :-f 指定要导出的文件名(默认为/mnt/info/stbinfotmp)\n");
	printf("      :-l 指定要导出的数据长度(默认为2048)\n");
	printf("      :-o 指定信息表的偏移(默认为512)\n");
	printf("      :-a 指定修改完成后是否自动重新启动机顶盒(默认是不自动重启)\n");
	printf("举例如:%s -n 0x1b -a\n\t\t将信息修改为0x1b后,自动重启\n",name);
	printf("      :%s -n 0x1b -m 9 -f /mnt/tmp -l 1024 -o 256\n",name);
	printf("This Program is for %s by KINGVON\n",platform);
	printf("Any Problem You can contact me:lqrensn@163.com\n");
}

//parse input paramerter
void parse_input(int argc,char *argv[])
{
	int opt;
	U8 chgstate_flag = 0;
	U8 tmpbuf[2];

	if(argc <2)
	{
		print_help(exe_filename);
		exit(-1);
	}

	//To compatible the version before
	if(argc == 2)
	{
		if(!strncmp(argv[1],"-h",2))
		{
			print_help(exe_filename);
			exit(0);
		}
		if((!strncmp(argv[1],"0x",2)) || (!strncmp(argv[1],"0X",2)))
		{
			chgstate = strtoul(argv[1],NULL,16);
		}
		else
		{
			chgstate = atoi(argv[1]);
		}
		dbg_print(1,"The change value is %d\n",chgstate);
		return;
	}
	
	while((opt = getopt(argc,argv,"ahn:m:f:s:l:")) != -1)
	{
		switch(opt)
		{
			case 'n':
				if((!strncmp(optarg,"0x",2)) || (!strncmp(optarg,"0X",2)))
				{
					chgstate = strtoul(optarg,NULL,16);
				}
				else
				{
					chgstate = atoi(optarg);
				}
				dbg_print(1,"The change value is %d\n",chgstate);
				chgstate_flag = 1;
				break;
			case 'm':
				mtdnum = atoi(optarg);
				break;
			case 's':
				if((!strncmp(optarg,"0x",2)) || (!strncmp(optarg,"0X",2)))
				{
					sw_ver = strtoul(optarg,NULL,16);
				}
				else
				{
					sw_ver = atoi(optarg);
				}
				dbg_print(1,"The changed SW Version is %d\n",sw_ver);
				chgstate_flag = 1;
				break;
			case 'f':
				strcpy(dumpfile,optarg);
				break;
			case 'l':
				dumplen = atoi(optarg);
				break;
			case 'o':
				fgda_offset = atoi(optarg);
				break;
			case 'a':
				auto_reboot = 1;
				break;
			default:
				print_help(exe_filename);
				exit(-1);
				break;
		}
	}
	if(chgstate_flag != 1)
	{
		printf("Your Must Set the State Vaule or changed SW version!\n");		
		print_help(exe_filename);
		exit(-1);
	}
}

//get dir from file name
void getdir(char *src,char **buf)
{
	int l = strlen(src);
	dbg_print(1,"src:%s,len:%d\n",src,l);
	char *p = strrchr(src,'/');
	int len = strlen(p);
	dbg_print(1,"*p=%s,len:%d\n",p,len);
	strncpy(*buf,src,(l-len));
	(*buf)[l-len]='\0';
	dbg_print(1,"buf:%s\n",*buf);
}

//check the dir if exist,dump the file to dir
int check_dump_file(void)
{
	char *buf;
	int status;
	char cmd[64]="\0";

	if(!access(dumpfile,R_OK))
	{
		dbg_print(1,"The file allready existed !\n");
		return 0;
	}
	buf = malloc(50);
	memset(buf,'\0',sizeof(buf));
	//if file is not exist,then mkdir the path and dump the file
	getdir(dumpfile,&buf);
	dbg_print(1,"dir name is %s\n",buf);

	if(opendir(buf) == NULL)
	{
		status = mkdir(buf,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
		if(status == -1)
		{
			printf("mkdir %s error\n",buf);
			free(buf);
			return -1;
		}
	}
	free(buf);
	sprintf(cmd,"nanddump -q -o -l %d -f %s /dev/mtd%d",dumplen,dumpfile,mtdnum);
	system(cmd);
	return 0;
}

int jwtdrv_flash_read(const char *filename,U32 offset, U32 len, U8 *buff)						
{
	int flag = 0;
	FILE *fp = NULL;
	int nflag=-1;
	
	fp = fopen(filename,"r+");	
	if(NULL == fp)
	{		
		fclose(fp);		
		return -1;
	}
	fseek(fp,offset,SEEK_SET);
	nflag = fread(buff,1,len,fp);
	fclose(fp);	
	if(0 > nflag)
	{		
		return -1;
	}
	return nflag;
}

int jwtdrv_flash_write(const char *filename,U32 offset, U32 len, U8 *buff)								
{
	int fp;
	int nflag = -1;	
	fp = open(filename,O_RDWR);	
	if(-1 == fp)
	{		
		return -1;
	}
	lseek(fp,offset,SEEK_SET);
//	fseek(fp,offset,SEEK_SET);
	nflag = write(fp,buff,len);
//	nflag=fwrite(buff,1,len,fp);	
	if(0 > nflag)
	{
		close(fp);		
		return -1;
	}	
	fsync(fp);
	close(fp);
	return 0;
	
}
int parse_str(char *ssrc,char *src,char *dst)
{
	char *ptr;
	ptr = strstr(ssrc,src);
	ptr = strchr(ssrc,'=');
	ptr++;
	strcpy(dst,ptr);
	dbg_print(1,"buf:%s\n",dst);
	return 0;
}
int buf_to_int(char *buf)
{
	int conved = 0;
	if((!strncmp(buf,"0x",2)) || (!strncmp(buf,"0X",2)))
	{
		conved = strtoul(buf,NULL,16);
	}
	else
	{
		conved = atoi(buf);
	}
	return conved;	
}

int read_cfg_from_usb()
{
	FILE *fp = NULL;
	char chptr[256];
	char *ptr;
	char buf[256];
#if 0
	fp = fopen("usb_update.cfg","rb");
#else
	fp = fopen(filename,"rb");
#endif
	if(fp == NULL)
	{
		printf("Open File from USB error\n");
		return -1;
	}
	while(fgets(chptr,256,fp)!='\0')
	{
		if(strncasecmp(chptr,"[E_JWT_USB_UPDATE]",17) == 0)
		{
			printf("End of JWT Usb Update config!\n");
			break;
		}
		if(strncasecmp(chptr,"[S_JWT_USB_UPDATE]",17) == 0)
		{
			fgets(chptr,256,fp);
			parse_str(chptr,"state=",buf);
			chgstate = buf_to_int(buf);
			
			fgets(chptr,256,fp);
			parse_str(chptr,"sw_ver=",buf);
			sw_ver = buf_to_int(buf);
			
			fgets(chptr,256,fp);
			parse_str(chptr,"stbmtd=",buf);
			mtdnum = buf_to_int(buf);

			fgets(chptr,256,fp);
			parse_str(chptr,"dumpfile=",buf);
			strncpy(dumpfile,buf,strlen(dumpfile));

			fgets(chptr,256,fp);
			parse_str(chptr,"dumplen=",buf);
			dumplen = buf_to_int(buf);
			
			fgets(chptr,256,fp);
			parse_str(chptr,"off_bca=",buf);
			bca_offset = buf_to_int(buf);

			fgets(chptr,256,fp);
			parse_str(chptr,"off_fgda=",buf);
			fgda_offset = buf_to_int(buf);

			fgets(chptr,256,fp);
			parse_str(chptr,"auto_reboot=",buf);
			auto_reboot = buf_to_int(buf);

			fgets(chptr,256,fp);
			parse_str(chptr,"debug_print=",buf);
			quit = buf_to_int(buf);
		}
		
	}
	if(fp != NULL)
	{
		fclose(fp);
	}
	return 0;
}
void printf_usb_cfg()
{
	printf("chgstate:0x%x\n",chgstate);
	printf("sw_ver:0x%x\n",sw_ver);
	printf("mtdnum:%d\n",mtdnum);
	printf("dumpfile:%s\n",dumpfile);
	printf("dumplen:%d\n",dumplen);
	printf("bca_offset:%d\n",bca_offset);
	printf("fgda_offset:%d\n",fgda_offset);
	printf("auto_reboot:%d\n",auto_reboot);
}



int main(int argc,char *argv[])
{
	int ret = 0;
	char *buf;
	U32 FDCACRCValue;
	U32 BCACrc32Value;
	JWT_UPDATE_FDCA_t fdca_t;
	JWT_UPDATE_BCA_t bca_t;
	char cmd[128]="\0";
	//save the bin file name	
	strcpy(exe_filename,argv[0]);
	
	buf = malloc(1024);
	memset(buf,'\0',1024);
	
	//parse parameter
	if(argc<=1)
	{
		//read input from usbdisk
		ret = read_cfg_from_usb();
		if(-1 ==ret)
		{
			return -1;
		}
	}
	else
	{
		//input paramater
		parse_input(argc,argv);
	}

	//check the file 
	ret = check_dump_file();
	if(ret !=0)
	{
		dbg_print(2,"check and dump file error\n");
		return -1;
	}
	//get default stb infomation
	ret = jwtdrv_flash_read(dumpfile,0,1024,buf);
	if(ret < 0)
	{
		dbg_print(2,"flash read error\n");
		return -1;
	}
	else
	{
		memcpy(&fdca_t,&buf[512],sizeof(fdca_t));
		memcpy(&bca_t,buf,sizeof(bca_t));
		ori_chgstate = fdca_t.activation;
		ori_sw_ver = bca_t.software_version[1];
	}	
#if 0
	memset(&buf[offset],chgstate,1);
#else
	if((chgstate < 0x17) || (chgstate > 0x2a))
	{
		printf("Your input State error,use default\n");
		chgstate = ori_chgstate;
	}
	else
	{		
		fdca_t.activation = chgstate;
		FDCACRCValue = calculateCRC((U8 *)&fdca_t, sizeof(fdca_t) - 4);
		fdca_t.crc[0] = (FDCACRCValue >> 24) & 0xFF;
		fdca_t.crc[1] = (FDCACRCValue >> 16) & 0xFF;
		fdca_t.crc[2] = (FDCACRCValue >> 8) & 0xFF;
		fdca_t.crc[3] = FDCACRCValue & 0xFF;
		memcpy(&buf[512],&fdca_t,sizeof(fdca_t));
	}
#endif
	if((sw_ver <= 0) || (sw_ver > 255))
	{
		printf("Your input SW_VER:%d error(0,255],Use dafault\n");
		sw_ver = ori_sw_ver;
	}
	else
	{		
		bca_t.software_version[1] = (unsigned char)sw_ver;
		BCACrc32Value = calculateCRC((U8 *)&bca_t,sizeof(bca_t)-4);
		bca_t.crc[0] = (U8)((BCACrc32Value >> 24) & 0xff);
		bca_t.crc[1] = (U8)((BCACrc32Value >> 16) & 0xff);
		bca_t.crc[2] = (U8)((BCACrc32Value >> 8) & 0xff);
		bca_t.crc[3] = (U8)(BCACrc32Value & 0xff);
		memcpy(buf,&bca_t,sizeof(bca_t));
	}

	
	if(jwtdrv_flash_write(dumpfile,0,1024,buf) != 0)
	{
		dbg_print(2,"flash write error\n");
		return -1;
	}
	if(!quit)
	{
		printf_usb_cfg();
	}
	//erase flash first
	sprintf(cmd,"flash_erase -q /dev/mtd%d 0 0",mtdnum);
	system(cmd);
	//write to flash
	sprintf(cmd,"nandwrite -q /dev/mtd%d %s",mtdnum,dumpfile);
	system(cmd);
	if(auto_reboot)system("reboot");
	return 0;
	
}

Makefile
 

.PHONY: all clean help
CROSS?=mipsel-linux-
ifeq ($(CROSS),)
	arch:=x86
endif
ifeq ($(findstring mips,$(CROSS)),mips)
	arch=mipsel
else
	arch=other
endif

ifeq ($(findstring 7581,${platform}),7581)
	CFLAGS += -DBCM7581B0
endif
ifeq ($(findstring 7019,${platform}),7019)
	CFLAGS += -DBCM7019C0
endif
target:=chgstate_$(platform)_$(arch)
all:
	$(if ${platform},,$(error platform must be set!!!))
	@echo "flag ${CFLAGS} over"
	$(CROSS)gcc ${CFLAGS} -o ${target} chgstate.c
clean:
	rm -fr *.o chgstate_*
help:
	@echo	-e "*********************************************\n*"
	@echo -e "* This Program Used for  \n*  modify sw version and boot flag"
	@echo -e "*\n*"
	@echo -e "*Example:"
	@echo -e "*\tmake platform=7581"
	@echo -e "*\tmake platform=7019"
	@echo	-e "*\n*********************************************"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值