1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <unistd.h> 5#include <signal.h> 6#include "shutils.h" 7#include "shared.h" 8 9static int crc_table_empty = 1; 10static unsigned long crc_table[256]; 11 12#define SWAP_LONG(x) \ 13 ((u_int32_t)( \ 14 (((u_int32_t)(x) & (u_int32_t)0x000000ffUL) << 24) | \ 15 (((u_int32_t)(x) & (u_int32_t)0x0000ff00UL) << 8) | \ 16 (((u_int32_t)(x) & (u_int32_t)0x00ff0000UL) >> 8) | \ 17 (((u_int32_t)(x) & (u_int32_t)0xff000000UL) >> 24) )) 18 19#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); 20#define DO2(buf) DO1(buf); DO1(buf); 21#define DO4(buf) DO2(buf); DO2(buf); 22#define DO8(buf) DO4(buf); DO4(buf); 23 24#define TC_HDR_LEN 0x100 25 26static void make_crc_table() 27{ 28 unsigned long c; 29 int n, k; 30 unsigned long poly; /* polynomial exclusive-or pattern */ 31 /* terms of polynomial defining this crc (except x^32): */ 32 static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; 33 34 /* make exclusive-or pattern from polynomial (0xedb88320L) */ 35 poly = 0L; 36 for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) 37 poly |= 1L << (31 - p[n]); 38 39 for (n = 0; n < 256; n++) 40 { 41 c = (unsigned long)n; 42 for (k = 0; k < 8; k++) 43 c = c & 1 ? poly ^ (c >> 1) : c >> 1; 44 crc_table[n] = c; 45 } 46 crc_table_empty = 0; 47} 48 49unsigned long crc32_no_comp(unsigned long crc,const unsigned char* buf, int len) 50{ 51 if (crc_table_empty) 52 make_crc_table(); 53 54 while (len >= 8) 55 { 56 DO8(buf); 57 len -= 8; 58 } 59 if (len) do { 60 DO1(buf); 61 } while (--len); 62 63 return crc; 64} 65 66int separate_tc_fw_from_trx(char* trxpath) 67{ 68 FILE* FpTrx; 69 char TrxHdrBuf[512]; 70 char buf[4096]; 71 unsigned int *pTrxSize; 72 unsigned int TrxSize = 0; 73 unsigned int filelen; 74 unsigned int TcFwSize; 75 int RetVal = 0; 76 77 FILE* fpSrc = NULL; 78 FILE* fpDst = NULL; 79 80 FpTrx = fopen(trxpath, "rb"); 81 if (FpTrx == NULL) goto err; 82 fread(TrxHdrBuf,1,sizeof(TrxHdrBuf),FpTrx); 83 fseek( FpTrx, 0, SEEK_END); 84 filelen = ftell( FpTrx ); 85 fclose(FpTrx); 86 87 pTrxSize = (unsigned int*)(TrxHdrBuf+4); //bcm 88 TrxSize = *pTrxSize; 89 cprintf("trx size %u, file size %u\n", TrxSize, filelen); 90 if (filelen > TrxSize) 91 { 92 TcFwSize = filelen - TrxSize; 93 cprintf("tcfw size %u\n",TcFwSize); 94 95 if (TcFwSize > TC_HDR_LEN) 96 { 97 fpSrc = fopen(trxpath, "rb"); 98 if (fpSrc==NULL) goto err; 99 fpDst = fopen("/tmp/tcfw.bin", "wb"); 100 if (fpDst==NULL) goto err; 101 102 fseek(fpSrc, TrxSize, SEEK_SET); 103 104 fread(buf, 1, TC_HDR_LEN, fpSrc); 105 fwrite(buf, 1, TC_HDR_LEN, fpDst); 106 TcFwSize -= TC_HDR_LEN; 107 108 cprintf("tcfw magic : %c%c%c%c\n",buf[0],buf[1],buf[2],buf[3]); 109 if (strncmp(&buf[0], "2RDH", 4)) 110 goto err; 111 112 while (TcFwSize > 0) 113 { 114 if (TcFwSize > sizeof(buf)) 115 { 116 fread(buf, 1, sizeof(buf), fpSrc); 117 fwrite(buf, 1, sizeof(buf), fpDst); 118 TcFwSize -= sizeof(buf); 119 } 120 else 121 { 122 fread(buf, 1, TcFwSize, fpSrc); 123 fwrite(buf, 1, TcFwSize, fpDst); 124 TcFwSize = 0; 125 } 126 } 127 } 128 else { 129 cprintf("not tc fw\n"); 130 goto err; 131 } 132 } 133 else if (TrxSize == filelen) 134 { 135 // only trx, no tc fw 136 printf("no tc fw\n"); 137 goto err; 138 } 139 140 RetVal = 1; 141 142err: 143 if(TrxSize) 144 truncate(trxpath, TrxSize); 145 146 if (fpSrc) 147 fclose(fpSrc); 148 149 if (fpDst) 150 fclose(fpDst); 151 152 return RetVal; 153} 154 155int check_tc_firmware_crc() 156{ 157 FILE* fpSrc = NULL; 158 FILE* fpDst = NULL; 159 unsigned long* crc_value_ptr = NULL; 160 unsigned long ulfw_crc = 0, calc_crc = 0; 161 unsigned long trxlen, *trxlenptr; 162 int skip_flag = 0; 163 int RetVal = 0; 164 char buf[4096] = {0}; 165 166 fpSrc = fopen("/tmp/tcfw.bin", "rb"); 167 if (fpSrc==NULL) 168 { 169 skip_flag = 1; 170 goto exit; 171 } 172 fpDst = fopen("/tmp/tclinux.bin", "wb"); 173 if (fpDst==NULL) 174 { 175 skip_flag = 1; 176 goto exit; 177 } 178 179 fread(buf, 1, 0x100, fpSrc); 180 181 trxlenptr=(unsigned long*)(buf+8); 182 trxlen=*trxlenptr; 183 trxlen=SWAP_LONG(trxlen); 184 cprintf("tcfw len: %lu\n", trxlen); 185 186 fwrite(buf, 1, 0x100, fpDst); 187 trxlen -= 0x100; 188 189 crc_value_ptr=(unsigned long*)(buf+12); 190 ulfw_crc=*crc_value_ptr; 191 ulfw_crc=SWAP_LONG(ulfw_crc); 192 cprintf("ulfw crc: %lx\n", ulfw_crc); 193 194 calc_crc = 0xffffffff; 195 196 while(trxlen>0) 197 { 198 if (trxlen > sizeof(buf)) 199 { 200 fread(buf, 1, sizeof(buf), fpSrc); 201 fwrite(buf, 1, sizeof(buf), fpDst); 202 calc_crc = crc32_no_comp(calc_crc, (unsigned char*)buf, sizeof(buf)); 203 trxlen-=sizeof(buf); 204 } 205 else 206 { 207 fread(buf, 1, trxlen, fpSrc); 208 fwrite(buf, 1, trxlen, fpDst); 209 calc_crc = crc32_no_comp(calc_crc, (unsigned char*)buf, trxlen); 210 trxlen=0; 211 } 212 } 213 214 cprintf("calc crc: %lx\n", calc_crc); 215 216 if (ulfw_crc != calc_crc) 217 skip_flag = 1; 218#ifdef RTCONFIG_BRCM_NAND_JFFS2 219 else { 220 cprintf("backup tclinux\n"); 221 eval("cp", "-f", "/tmp/tclinux.bin", "/jffs/tclinux.bin"); 222 } 223#endif 224 225 unlink("/tmp/tcfw.bin"); 226 227 228 cprintf("check tcfw done\n"); 229 230exit: 231 232 if(skip_flag) 233 RetVal = -1; 234 235 if (fpSrc) 236 fclose(fpSrc); 237 238 if (fpDst) 239 fclose(fpDst); 240 241 return RetVal; 242} 243 244void do_upgrade_adsldrv(void) 245{ 246 char UpdateFwBuf[256]; 247 char ipaddr[80]; 248 FILE* fp; 249 int ret; 250 int skip_flag = 0, force_flag = 0; 251 unsigned long old_crc = 0, new_crc = 0; 252 253 cprintf("%s\n", __FUNCTION__); 254 255 if(!check_if_file_exist("/tmp/tclinux.bin")) 256 return; 257 258 fp = fopen("/tmp/adsl/tc_ip_addr.txt","r"); 259 if (fp) { 260 fgets(ipaddr,sizeof(ipaddr),fp); 261 fclose(fp); 262 } 263 else { 264 snprintf(ipaddr, sizeof(ipaddr), "169.254.0.1"); 265 force_flag = 1; 266 } 267 268 strcpy(UpdateFwBuf,"cd /tmp; tftp -p -l tclinux.bin "); 269 strcat(UpdateFwBuf,ipaddr); 270 271 fp = fopen("/tmp/adsl/tc_hdr.bin", "rb"); 272 if (fp) 273 { 274 fseek(fp, 12L, SEEK_SET); 275 fread(&old_crc, 1, sizeof(unsigned long), fp); 276 old_crc = SWAP_LONG(old_crc); 277 cprintf("old crc: %lx\n", old_crc); 278 fclose(fp); 279 } 280 fp = fopen("/tmp/tclinux.bin", "rb"); 281 if (fp) 282 { 283 fseek(fp, 12L, SEEK_SET); 284 fread(&new_crc, 1, sizeof(unsigned long), fp); 285 new_crc = SWAP_LONG(new_crc); 286 cprintf("new crc: %lx\n", new_crc); 287 fclose(fp); 288 } 289 290 if (old_crc && new_crc && new_crc == old_crc) 291 skip_flag = 1; 292 293 if (!skip_flag) 294 { 295 if(force_flag) { 296 killall("tp_init", SIGKILL); 297 } 298 else { 299 eval("adslate", "waitadsl"); 300 eval("adslate", "quitdrv"); 301 } 302 eval("iptables", "-I", "INPUT", "-p", "udp", "-j", "ACCEPT"); 303 eval("ifconfig", "vlan2", "169.254.10.10"); //tmp 304 eval("route", "add", "-host", ipaddr, "vlan2"); 305 306 cprintf("Start to upgrade tc fw\n"); 307 printf(UpdateFwBuf); 308 ret = system(UpdateFwBuf); 309 if(ret) 310 cprintf("tftp failed\n"); 311 else 312 cprintf("tftp done\n"); 313 314 eval("iptables", "-D", "INPUT", "-p", "udp", "-j", "ACCEPT"); 315 } 316 else 317 cprintf("Skip upgrade tc firmware\n"); 318} 319