コード例 #1
0
ファイル: sys_api.c プロジェクト: yinhongxing/mico
void sys_adc_calibration(u8 write, u16 *offset, u16 *gain)
{
	flash_t		flash;
	u8*			pbuf;
	
	if(write){
		// backup
		pbuf = (unsigned char*)RtlMalloc(FLASH_SECTOR_SIZE);
		if(!pbuf) return;
		flash_stream_read(&flash, FLASH_SYSTEM_DATA_ADDR, FLASH_SECTOR_SIZE, pbuf);
		memcpy((char*)pbuf+FLASH_ADC_PARA_OFFSET, offset, 2);
		memcpy((char*)pbuf+FLASH_ADC_PARA_OFFSET+2, gain, 2);
		flash_erase_sector(&flash, FLASH_RESERVED_DATA_BASE);
		flash_stream_write(&flash, FLASH_RESERVED_DATA_BASE, FLASH_SECTOR_SIZE, pbuf);
		// Write
		flash_stream_read(&flash, FLASH_RESERVED_DATA_BASE, FLASH_SECTOR_SIZE, pbuf);
		flash_erase_sector(&flash, FLASH_SYSTEM_DATA_ADDR);
		flash_stream_write(&flash, FLASH_SYSTEM_DATA_ADDR, FLASH_SECTOR_SIZE, pbuf);
		RtlMfree(pbuf, FLASH_SECTOR_SIZE);
		printf("\n\rStore ADC calibration success.");
	}
	flash_stream_read(&flash, FLASH_ADC_PARA_BASE, 2, (u8*)offset);
	flash_stream_read(&flash, FLASH_ADC_PARA_BASE+2, 2, (u8*)gain);
	printf("\n\rADC offset = 0x%04X, gain = 0x%04X.\n\r", *offset, *gain);
}
コード例 #2
0
ファイル: sys_api.c プロジェクト: yinhongxing/mico
void sys_clear_ota_signature(void)
{
	flash_t		flash;
	u32			ota_offset=0xFFFFFFFF, part1_offset, part2_offset;
	u8			signature[OTA_Signature_len+1];
	
	flash_stream_read(&flash, 0x18, 4, (u8*)&part1_offset);
	part1_offset = (part1_offset&0xFFFF) * 1024;
	flash_stream_read(&flash, part1_offset+OTA_Signature_offset, OTA_Signature_len, signature);
	if(!memcmp((char const*)signature, OTA_Signature, OTA_Signature_len)){
		ota_offset = part1_offset;
	}
	
	flash_stream_read(&flash, FLASH_SYSTEM_DATA_ADDR, 4, (u8*)&part2_offset);
	flash_stream_read(&flash, part2_offset+OTA_Signature_offset, OTA_Signature_len, signature);
	if(!memcmp((char const*)signature, OTA_Signature, OTA_Signature_len)){
		ota_offset = part2_offset;
	}
	
	printf("\n\rOTA offset = 0x%08X", ota_offset);

	if(ota_offset < OTA_valid_offset){
		flash_stream_read(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature);
		signature[OTA_Signature_len] = '\0';
		printf("\n\rSignature = %s", signature);
		if(!memcmp((char const*)signature, OTA_Signature, OTA_Signature_len)){
			memcpy((char*)signature, OTA_Clear, OTA_Signature_len);
			flash_stream_write(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature);
			flash_stream_read(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature);
			signature[OTA_Signature_len] = '\0';
			printf("\n\rSignature = %s", signature);
			printf("\n\rClear OTA signature success.");
		}
	}
}
コード例 #3
0
ファイル: sys_api.c プロジェクト: yinhongxing/mico
void sys_recover_ota_signature(void)
{
	flash_t		flash;
	u32			ota_offset=0xFFFFFFFF, part1_offset, part2_offset;
	u8			signature[OTA_Signature_len+1];
	u8*			pbuf;
	
	flash_stream_read(&flash, 0x18, 4, (u8*)&part1_offset);
	part1_offset = (part1_offset&0xFFFF) * 1024;
	flash_stream_read(&flash, part1_offset+OTA_Signature_offset, OTA_Signature_len, signature);
	if(!memcmp((char const*)signature, OTA_Clear, OTA_Signature_len)){
		ota_offset = part1_offset;
	}
	
	flash_stream_read(&flash, FLASH_SYSTEM_DATA_ADDR, 4, (u8*)&part2_offset);
	flash_stream_read(&flash, part2_offset+OTA_Signature_offset, OTA_Signature_len, signature);
	if(!memcmp((char const*)signature, OTA_Clear, OTA_Signature_len)){
		ota_offset = part2_offset;
	}
	
	printf("\n\rOTA offset = 0x%08X", ota_offset);
	
	if(ota_offset < OTA_valid_offset){
		flash_stream_read(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature);
		signature[OTA_Signature_len] = '\0';
		printf("\n\rSignature = %s", signature);
		if(!memcmp((char const*)signature, OTA_Clear, OTA_Signature_len)){
			// backup
			pbuf = (unsigned char*)RtlMalloc(FLASH_SECTOR_SIZE);
			if(!pbuf) return;
			flash_stream_read(&flash, ota_offset, FLASH_SECTOR_SIZE, pbuf);
			memcpy((char*)pbuf+OTA_Signature_offset, OTA_Signature, OTA_Signature_len);
			flash_erase_sector(&flash, FLASH_RESERVED_DATA_BASE);
			flash_stream_write(&flash, FLASH_RESERVED_DATA_BASE, FLASH_SECTOR_SIZE, pbuf);
			// Write
			flash_stream_read(&flash, FLASH_RESERVED_DATA_BASE, FLASH_SECTOR_SIZE, pbuf);
			flash_erase_sector(&flash, ota_offset);
			flash_stream_write(&flash, ota_offset, FLASH_SECTOR_SIZE, pbuf);
			flash_stream_read(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature);
			signature[OTA_Signature_len] = '\0';
			printf("\n\rSignature = %s", signature);
			RtlMfree(pbuf, FLASH_SECTOR_SIZE);
			printf("\n\rRecover OTA signature success.");
		}
	}
}
コード例 #4
0
ファイル: HAPPlatform.c プロジェクト: Lee1124Amy/HomeKit
// Mandatory function to save controller pairing to persistent storage
// called when HAP controller pairing update
void HAPPlatformSavePairings(HAPPersistentPairing_t *pairing, int num)
{
	uint8_t *flash_buffer = (uint8_t *) malloc(FLASH_DATA_LEN);
	flash_stream_read(&flash, FLASH_DATA_ADDR, FLASH_DATA_LEN, flash_buffer);
	flash_erase_sector(&flash, FLASH_DATA_ADDR);
	memcpy(flash_buffer + HAP_FLASH_PAIRING_OFFSET, pairing, sizeof(HAPPersistentPairing_t) * num);
	flash_stream_write(&flash, FLASH_DATA_ADDR, FLASH_DATA_LEN, flash_buffer);
	free(flash_buffer);
}
コード例 #5
0
ファイル: HAPPlatform.c プロジェクト: Lee1124Amy/HomeKit
// Mandatory function to save accessory key pair to persistent storage
// called when HAP accessory key pair generation
void HAPPlatformSaveKeypair(HAPPersistentKeypair_t *keypair)
{
	uint8_t *flash_buffer = (uint8_t *) malloc(FLASH_DATA_LEN);
	flash_stream_read(&flash, FLASH_DATA_ADDR, FLASH_DATA_LEN, flash_buffer);
	flash_erase_sector(&flash, FLASH_DATA_ADDR);
	memcpy(flash_buffer + HAP_FLASH_KEYPAIR_OFFSET, keypair, sizeof(HAPPersistentKeypair_t));
	flash_stream_write(&flash, FLASH_DATA_ADDR, FLASH_DATA_LEN, flash_buffer);
	free(flash_buffer);
}
コード例 #6
0
ファイル: HAPPlatform.c プロジェクト: Lee1124Amy/HomeKit
void FlashSetupcodeWrite(char *code)
{
	if(strlen(code) == 10) {
		PersistentSetupcode_t setupcode;
		memset(&setupcode, 0, sizeof(PersistentSetupcode_t));
		setupcode.len = 10;
		strcpy(setupcode.code, code);

		uint8_t *flash_buffer = (uint8_t *) malloc(FLASH_DATA_LEN);
		flash_stream_read(&flash, FLASH_DATA_ADDR, FLASH_DATA_LEN, flash_buffer);
		flash_erase_sector(&flash, FLASH_DATA_ADDR);
		memcpy(flash_buffer + FLASH_SETUPCODE_OFFSET, &setupcode, sizeof(PersistentSetupcode_t));
		flash_stream_write(&flash, FLASH_DATA_ADDR, FLASH_DATA_LEN, flash_buffer);
		free(flash_buffer);
	}
}
コード例 #7
0
ファイル: OTA.cpp プロジェクト: Ameba8195/Arduino
int OTAClass::beginLocal(uint16_t port, bool reboot_when_success) {

    int ret = -1;

    // variables for image processing
    flash_t flash;
    uint32_t img2_addr, img2_len, img3_addr, img3_len;
    uint32_t img_upper_bound;
    uint32_t checksum = 0;
    uint32_t signature1, signature2;

    // variables for network processing
    int server_socket = -1;
    int client_socket = -1;
    struct sockaddr_in localHost;
    struct sockaddr_in client_addr;
    int socket_error, socket_timeout;
    socklen_t optlen;

    // variables for OTA
    unsigned char *buf = NULL;
    int read_bytes = 0, processed_len;
    uint32_t file_info[3];
    uint32_t ota_len;
    uint32_t ota_blk_size = 0;

    int i, n;

    do {
        sync_ota_addr();

        get_image_info(&img2_addr, &img2_len, &img3_addr, &img3_len);
        img_upper_bound = img2_addr + 0x10 + img2_len; // image2 base + header + len
        if (img3_len > 0) {
            img_upper_bound += 0x10 + img3_len; // image 3 header + len
        }

        if ((ota_addr & 0xfff != 0) || (ota_addr == ~0x0) || (ota_addr < img_upper_bound)) {
            OTA_PRINTF("Invalid OTA address: %08X\r\n", ota_addr);
            break;
        }

        buf = (unsigned char *) malloc (BUFSIZE);
        if (buf == NULL) {
            OTA_PRINTF("Fail to allocate memory\r\n");
            break;
        }

        server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (server_socket < 0) {
            OTA_PRINTF("Fail to create socket\r\n");
            break;
        }

        memset(&localHost, 0, sizeof(localHost));
        localHost.sin_family = AF_INET;
        localHost.sin_port = htons(port);
        localHost.sin_addr.s_addr = INADDR_ANY;

        if (lwip_bind(server_socket, (struct sockaddr *)&localHost, sizeof(localHost)) < 0) {
            OTA_PRINTF("Bind fail\r\n");
            break;
        }

        if (lwip_listen(server_socket , 1) < 0) {
            OTA_PRINTF("Listen fail\r\n");
            break;
        }

        OTA_PRINTF("Wait for client\r\n");
        n = (int) sizeof( client_addr );
        memset(&client_addr, 0, sizeof(client_addr));
        client_socket = lwip_accept(server_socket, (struct sockaddr *) &client_addr, (socklen_t *)&n);
        OTA_PRINTF("Client connected. IP:%s port:%d\r\n\r\n", inet_ntoa(client_addr.sin_addr.s_addr), ntohs(client_addr.sin_port));

        socket_timeout = DEFAULT_IMAGE_DOWNLOAD_TIMEOUT;
        lwip_setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, &socket_timeout, sizeof(socket_timeout));        

        OTA_PRINTF("Read OTA info...\r\n");
        read_bytes = read(client_socket, file_info, sizeof(file_info));
        if (read_bytes < 0) {
           OTA_PRINTF("Fail to read OTA info\r\n");
           break;
        }

        if (file_info[2] == 0) {
            OTA_PRINTF("OTA image len is 0\r\n");
            break;
        }

        ota_len = file_info[2];
        ota_blk_size = ((ota_len - 1) / 4096) + 1;
        for (i = 0; i < ota_blk_size; i++) {
            flash_erase_sector(&flash, ota_addr + i * 4096);
        }

        OTA_PRINTF("Start download\r\n");

        // Now download OTA image
        processed_len = 0;
        while( processed_len < ota_len ) {
            memset(buf, 0, BUFSIZE);
            read_bytes = read(client_socket, buf, BUFSIZE);

            if (read_bytes < 0) {
                optlen = sizeof(socket_error);
                getsockopt(client_socket, SOL_SOCKET, SO_ERROR, &socket_error, &optlen);
                if (socket_error == EAGAIN) {
                    // socket timeout
                }
                break;
            }

            if (flash_stream_write(&flash, ota_addr + processed_len, read_bytes, buf) < 0) {
                OTA_PRINTF("Write sector fail\r\n");
                break;
            }

            processed_len += read_bytes;
        }

        if (processed_len != ota_len) {
            OTA_PRINTF("Download fail\r\n");
            break;
        }

        // Read OTA image from flash and calculate checksum
        checksum = processed_len = 0;
        while ( processed_len < ota_len ) {
            n = (processed_len + BUFSIZE < ota_len) ? BUFSIZE : (ota_len - processed_len);
            flash_stream_read(&flash, ota_addr + processed_len, n, buf);
            for (i=0; i<n; i++) checksum += (buf[i] & 0xFF);
            processed_len += n;
        }

        if (checksum != file_info[0]) {
            OTA_PRINTF("Bad checksum:%d expected:%d\r\n", checksum, file_info[0]);
            break;
        }

        // Put signature for OTA image
        flash_write_word(&flash, ota_addr +  8, 0x35393138);
        flash_write_word(&flash, ota_addr + 12, 0x31313738);
        flash_read_word(&flash, ota_addr +  8, &signature1);
        flash_read_word(&flash, ota_addr + 12, &signature2);
        if (signature1 != 0x35393138 || signature2 != 0x31313738) {
            OTA_PRINTF("Put signature fail\r\n");
            break;
        }

        // Mark image 2 as old image
        flash_write_word(&flash, img2_addr + 8, 0x35393130);

        ret = 0;
        OTA_PRINTF("OTA success\r\n");

    } while (0);

    if (buf != NULL) {
        free(buf);
    }

    if (server_socket >= 0) {
        close(server_socket);
    }

    if (client_socket >= 0) {
        close(client_socket);
    }

    if (ret < 0) {
        OTA_PRINTF("OTA fail\r\n");
    } else {
        if (reboot_when_success) {
            sys_reset();
        }
    }

    return ret;
}
コード例 #8
0
ファイル: main.c プロジェクト: alex1818/rtk-8711af
void main(void)
{
    flash_t         flash;
    uint32_t        address = FLASH_APP_BASE;

#if 1
    uint32_t        val32_to_write = 0x13572468;
    uint32_t        val32_to_read;
    int loop = 0;
    int result = 0;
    for(loop = 0; loop < 10; loop++)
    {
        flash_read_word(&flash, address, &val32_to_read);
        DBG_8195A("Read Data 0x%x\n", val32_to_read);
        flash_erase_sector(&flash, address);
        flash_write_word(&flash, address, val32_to_write);
        flash_read_word(&flash, address, &val32_to_read);

        DBG_8195A("Read Data 0x%x\n", val32_to_read);

        // verify result
        result = (val32_to_write == val32_to_read) ? 1 : 0;
        //printf("\r\nResult is %s\r\n", (result) ? "success" : "fail");
        DBG_8195A("\r\nResult is %s\r\n", (result) ? "success" : "fail");
        result = 0;
    }
#else
    int VERIFY_SIZE = 256;
    int SECTOR_SIZE = 16;
    
    uint8_t writedata[VERIFY_SIZE];
    uint8_t readdata[VERIFY_SIZE];
    uint8_t verifydata = 0;
    int loop = 0;
    int index = 0;
    int sectorindex = 0;
    int result = 0;
    int resultsector = 0;
    int testloop = 0;
    for(testloop = 0; testloop < 1; testloop++){
        address = FLASH_APP_BASE;
        for(sectorindex = 0; sectorindex < 4080; sectorindex++){
            result = 0;
            //address += SECTOR_SIZE;
            flash_erase_sector(&flash, address);
            //DBG_8195A("Address = %x \n", address);
            for(loop = 0; loop < SECTOR_SIZE; loop++){
                for(index = 0; index < VERIFY_SIZE; index++)
                {
                    writedata[index] = verifydata + index;
                }
                flash_stream_write(&flash, address, VERIFY_SIZE, &writedata);
                flash_stream_read(&flash, address, VERIFY_SIZE, &readdata);

                for(index = 0; index < VERIFY_SIZE; index++)
                {
                    //DBG_8195A("Address = %x, Writedata = %x, Readdata = %x \n",address,writedata[index],readdata[index]);
                    if(readdata[index] != writedata[index]){
                        DBG_8195A("Error: Loop = %d, Address = %x, Writedata = %x, Readdata = %x \n",testloop,address,writedata[index],readdata[index]);
                    }
                    else{
                        result++;
                        //DBG_8195A(ANSI_COLOR_BLUE"Correct: Loop = %d, Address = %x, Writedata = %x, Readdata = %x \n"ANSI_COLOR_RESET,testloop,address,writedata[index],readdata[index]);
                    }
                }
                address += VERIFY_SIZE;
            }
            if(result == VERIFY_SIZE * SECTOR_SIZE){
                //DBG_8195A("Sector %d Success \n", sectorindex);
                resultsector++;
            }
        }
        if(resultsector == 4079){
            DBG_8195A("Test Loop %d Success \n", testloop);    
        }
        resultsector = 0;
        verifydata++;
    }
    //DBG_8195A("%d Sector Success \n", resultsector);
    DBG_8195A("Test Done");

#endif
    for(;;);
}
コード例 #9
0
int StoreApInfo()
{

    flash_t flash;

	rtw_wifi_config_t wifi_config;
	uint32_t address;
        uint32_t data,i = 0;


    address = DATA_SECTOR;

    wifi_config.boot_mode = 0x77665502;
    memcpy(wifi_config.ssid, wifi_setting.ssid, strlen((char*)wifi_setting.ssid));
    wifi_config.ssid_len = strlen((char*)wifi_setting.ssid);
    wifi_config.security_type = wifi_setting.security_type;
    if(wifi_setting.security_type !=0)
        wifi_config.security_type = 1;
    else
        wifi_config.security_type = 0;
    memcpy(wifi_config.password, wifi_setting.password, strlen((char*)wifi_setting.password));
    wifi_config.password_len= strlen((char*)wifi_setting.password);
    wifi_config.channel = wifi_setting.channel;
    printf("\n\rWritting boot mode 0x77665502 and Wi-Fi setting to flash ...");
    //printf("\n\r &wifi_config = 0x%x",&wifi_config);

   flash_read_word(&flash,address,&data);

   
    if(data == ~0x0)

      flash_stream_write(&flash, address,sizeof(rtw_wifi_config_t), (uint8_t *)&wifi_config);

    else{
    //flash_EraseSector(sector_nb);
      
      
        flash_erase_sector(&flash,BACKUP_SECTOR);
        for(i = 0; i < 0x1000; i+= 4){
            flash_read_word(&flash, DATA_SECTOR + i, &data);
            if(i < sizeof(rtw_wifi_config_t))
            {
                 memcpy(&data,(char *)(&wifi_config) + i,4);
                 //printf("\n\r Wifi_config + %d = 0x%x",i,(void *)(&wifi_config + i));
                 //printf("\n\r Data = %d",data);
            }
            flash_write_word(&flash, BACKUP_SECTOR + i,data);
        }
        flash_read_word(&flash,BACKUP_SECTOR + 68,&data);
        //printf("\n\r Base + BACKUP_SECTOR + 68 wifi channel = %d",data);
        //erase system data
        flash_erase_sector(&flash, DATA_SECTOR);
        //write data back to system data
        for(i = 0; i < 0x1000; i+= 4){
            flash_read_word(&flash, BACKUP_SECTOR + i, &data);
            flash_write_word(&flash, DATA_SECTOR + i,data);
        }
                  //erase backup sector
           flash_erase_sector(&flash, BACKUP_SECTOR);
        }
        
	//flash_Wrtie(address, (char *)&wifi_config, sizeof(rtw_wifi_config_t));
	//flash_stream_write(&flash, address,sizeof(rtw_wifi_config_t), (uint8_t *)&wifi_config);
	//flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),data);
        //flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),data);
	//printf("\n\r Base + 0x000FF000 +4  wifi config  = %s",data[4]);
        //printf("\n\r Base + 0x000FF000 +71 wifi channel = %d",data[71]);

	return 0;
}
コード例 #10
0
static void update_ota_local_task(void *param)
{
	int server_socket;
	struct sockaddr_in server_addr;
	unsigned char *buf;
        union { uint32_t u; unsigned char c[4]; } file_checksum;
	int read_bytes = 0, size = 0, i = 0;
	update_cfg_local_t *cfg = (update_cfg_local_t *)param;
	uint32_t address, checksum = 0;
	flash_t	flash;
	uint32_t NewImg2BlkSize = 0, NewImg2Len = 0, NewImg2Addr = 0, file_info[3];
	uint32_t Img2Len = 0;
	int ret = -1 ;
	//uint8_t signature[8] = {0x38,0x31,0x39,0x35,0x38,0x37,0x31,0x31};
	uint32_t IMAGE_x = 0, ImgxLen = 0, ImgxAddr = 0;
#if WRITE_OTA_ADDR
	uint32_t ota_addr = 0x80000;
#endif
#if CONFIG_CUSTOM_SIGNATURE
	char custom_sig[32] = "Customer Signature-modelxxx";
	uint32_t read_custom_sig[8];
#endif
	printf("\n\r[%s] Update task start", __FUNCTION__);
	buf = update_malloc(BUF_SIZE);
	if(!buf){
		printf("\n\r[%s] Alloc buffer failed", __FUNCTION__);
		goto update_ota_exit;
	}
	// Connect socket
	server_socket = socket(AF_INET, SOCK_STREAM, 0);
	if(server_socket < 0){
		printf("\n\r[%s] Create socket failed", __FUNCTION__);
		goto update_ota_exit;
	}
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = cfg->ip_addr;
	server_addr.sin_port = cfg->port;

	if(connect(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1){
		printf("\n\r[%s] socket connect failed", __FUNCTION__);
		goto update_ota_exit;
	}
	DBG_INFO_MSG_OFF(_DBG_SPI_FLASH_);

#if 1
	// The upgraded image2 pointer must 4K aligned and should not overlap with Default Image2
	flash_read_word(&flash, IMAGE_2, &Img2Len);
	IMAGE_x = IMAGE_2 + Img2Len + 0x10;
	flash_read_word(&flash, IMAGE_x, &ImgxLen);
	flash_read_word(&flash, IMAGE_x+4, &ImgxAddr);
	if(ImgxAddr==0x30000000){
		printf("\n\r[%s] IMAGE_3 0x%x Img3Len 0x%x", __FUNCTION__, IMAGE_x, ImgxLen);
	}else{
		printf("\n\r[%s] no IMAGE_3", __FUNCTION__);
		// no image3
		IMAGE_x = IMAGE_2;
		ImgxLen = Img2Len;
	}
#if WRITE_OTA_ADDR
	if((ota_addr > IMAGE_x) && ((ota_addr < (IMAGE_x+ImgxLen))) ||
            (ota_addr < IMAGE_x) ||
            ((ota_addr & 0xfff) != 0)||
	      (ota_addr == ~0x0)){
		printf("\n\r[%s] illegal ota addr 0x%x", __FUNCTION__, ota_addr);
		goto update_ota_exit;
	}else
	    write_ota_addr_to_system_data( &flash, ota_addr);
#endif
	//Get upgraded image 2 addr from offset
	flash_read_word(&flash, OFFSET_DATA, &NewImg2Addr);
	if((NewImg2Addr > IMAGE_x) && ((NewImg2Addr < (IMAGE_x+ImgxLen))) ||
            (NewImg2Addr < IMAGE_x) ||
            ((NewImg2Addr & 0xfff) != 0)||
	      (NewImg2Addr == ~0x0)){
		printf("\n\r[%s] Invalid OTA Address 0x%x", __FUNCTION__, NewImg2Addr);
		goto update_ota_exit;
	}
#else
	//For test, hard code addr
	NewImg2Addr = 0x80000;	
#endif
	
	//Clear file_info
	memset(file_info, 0, sizeof(file_info));
	
	if(file_info[0] == 0){
		printf("\n\r[%s] Read info first", __FUNCTION__);
		read_bytes = read(server_socket, file_info, sizeof(file_info));
		// !X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X
		// !W checksum !W padding 0 !W file size !W
		// !X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X
		printf("\n\r[%s] info %d bytes", __FUNCTION__, read_bytes);
		printf("\n\r[%s] tx chechsum 0x%x, file size 0x%x", __FUNCTION__, file_info[0],file_info[2]);
		if(file_info[2] == 0){
			printf("\n\r[%s] No checksum and file size", __FUNCTION__);
			goto update_ota_exit;
		}
	}
	
#if SWAP_UPDATE
	uint32_t SigImage0,SigImage1;
	uint32_t Part1Addr=0xFFFFFFFF, Part2Addr=0xFFFFFFFF, ATSCAddr=0xFFFFFFFF;
	uint32_t OldImg2Addr;
	flash_read_word(&flash, 0x18, &Part1Addr);
	Part1Addr = (Part1Addr&0xFFFF)*1024;	// first partition
	Part2Addr = NewImg2Addr;
	
	// read Part1/Part2 signature
	flash_read_word(&flash, Part1Addr+8, &SigImage0);
	flash_read_word(&flash, Part1Addr+12, &SigImage1);
	printf("\n\r[%s] Part1 Sig %x", __FUNCTION__, SigImage0);
	if(SigImage0==0x30303030 && SigImage1==0x30303030)
		ATSCAddr = Part1Addr;		// ATSC signature
	else if(SigImage0==0x35393138 && SigImage1==0x31313738)	
		OldImg2Addr = Part1Addr;	// newer version, change to older version
	else
		NewImg2Addr = Part1Addr;	// update to older version	
	
	flash_read_word(&flash, Part2Addr+8, &SigImage0);
	flash_read_word(&flash, Part2Addr+12, &SigImage1);
	printf("\n\r[%s] Part2 Sig %x", __FUNCTION__, SigImage0);
	if(SigImage0==0x30303030 && SigImage1==0x30303030)
		ATSCAddr = Part2Addr;		// ATSC signature
	else if(SigImage0==0x35393138 && SigImage1==0x31313738)
		OldImg2Addr = Part2Addr;
	else
		NewImg2Addr = Part2Addr;
	
	// update ATSC clear partitin first
	if(ATSCAddr != ~0x0){
		OldImg2Addr = NewImg2Addr;
		NewImg2Addr = ATSCAddr;
	}
	
	printf("\n\r[%s] New %x, Old %x", __FUNCTION__, NewImg2Addr, OldImg2Addr);
	
	if( NewImg2Addr==Part1Addr ){
		if( file_info[2] > (Part2Addr-Part1Addr) ){	// firmware size too large
			printf("\n\r[%s] Part1 size < OTA size", __FUNCTION__);
			goto update_ota_exit;
			// or update to partition2
			// NewImg2Addr = Part2Addr;	
		}
	}
		
#endif

	//Erase upgraded image 2 region
	if(NewImg2Len == 0){
		NewImg2Len = file_info[2];
		printf("\n\r[%s] NewImg2Len %d  ", __FUNCTION__, NewImg2Len);
		if((int)NewImg2Len > 0){
			NewImg2BlkSize = ((NewImg2Len - 1)/4096) + 1;
			printf("\n\r[%s] NewImg2BlkSize %d  0x%8x", __FUNCTION__, NewImg2BlkSize, NewImg2BlkSize);
			for( i = 0; i < NewImg2BlkSize; i++)
				flash_erase_sector(&flash, NewImg2Addr + i * 4096);
		}else{
			printf("\n\r[%s] Size INVALID", __FUNCTION__);
			goto update_ota_exit;
		}
	}	
	
	printf("\n\r[%s] NewImg2Addr 0x%x", __FUNCTION__, NewImg2Addr);
        
        // reset
        file_checksum.u = 0;
	// Write New Image 2 sector
	if(NewImg2Addr != ~0x0){
		address = NewImg2Addr;
		printf("\n\r");
		while(1){
			memset(buf, 0, BUF_SIZE);
			read_bytes = read(server_socket, buf, BUF_SIZE);
			if(read_bytes == 0) break; // Read end
			if(read_bytes < 0){
				printf("\n\r[%s] Read socket failed", __FUNCTION__);
				goto update_ota_exit;
			}
				checksum += file_checksum.c[0];              // not read end, this is not attached checksum
				checksum += file_checksum.c[1];
				checksum += file_checksum.c[2];
				checksum += file_checksum.c[3];
			//printf("\n\r[%s] read_bytes %d", __FUNCTION__, read_bytes);
			
			#if 1
			if(flash_stream_write(&flash, address + size, read_bytes, buf) < 0){
				printf("\n\r[%s] Write sector failed", __FUNCTION__);
				goto update_ota_exit;
			}
			size += read_bytes;
			for(i = 0; i < read_bytes-4; i ++)
				checksum += buf[i];
			file_checksum.c[0] = buf[read_bytes-4];      // checksum attached at file end
			file_checksum.c[1] = buf[read_bytes-3];
			file_checksum.c[2] = buf[read_bytes-2];
			file_checksum.c[3] = buf[read_bytes-1];
			#else
			size += read_bytes;
			for(i = 0; i < read_bytes-4; i ++){
				checksum += buf[i];				
			}	
			file_checksum.c[0] = buf[read_bytes-4];      // checksum attached at file end
			file_checksum.c[1] = buf[read_bytes-3];
			file_checksum.c[2] = buf[read_bytes-2];
			file_checksum.c[3] = buf[read_bytes-1];
			#endif			
		}
		printf("\n\r");
		printf("\n\rUpdate file size = %d  checksum 0x%x  attached checksum 0x%x", size, checksum, file_checksum.u);
#if CONFIG_WRITE_MAC_TO_FLASH
		//Write MAC address
		if(!(mac[0]==0xff&&mac[1]==0xff&&mac[2]==0xff&&mac[3]==0xff&&mac[4]==0xff&&mac[5]==0xff)){
			if(flash_write_word(&flash, FLASH_ADD_STORE_MAC, mac, ETH_ALEN) < 0){
				printf("\n\r[%s] Write MAC failed", __FUNCTION__);
				goto update_ota_exit;
			}	
		}
#endif
		//printf("\n\r checksum 0x%x  file_info 0x%x  ", checksum, *(file_info));
#if CONFIG_CUSTOM_SIGNATURE
		for(i = 0; i < 8; i ++){
		    flash_read_word(&flash, NewImg2Addr + 0x28 + i *4, read_custom_sig + i);
		}
		printf("\n\r[%s] read_custom_sig %s", __FUNCTION__ , (char*)read_custom_sig);
#endif
		// compare checksum with received checksum
		//if(!memcmp(&checksum,file_info,sizeof(checksum))
		if( (file_checksum.u == checksum)
#if CONFIG_CUSTOM_SIGNATURE
			&& !strcmp((char*)read_custom_sig,custom_sig)
#endif
			){
			
			//Set signature in New Image 2 addr + 8 and + 12
			uint32_t sig_readback0,sig_readback1;
			flash_write_word(&flash,NewImg2Addr + 8, 0x35393138);
			flash_write_word(&flash,NewImg2Addr + 12, 0x31313738);
			flash_read_word(&flash, NewImg2Addr + 8, &sig_readback0);
			flash_read_word(&flash, NewImg2Addr + 12, &sig_readback1);
			printf("\n\r[%s] signature %x,%x,  checksum 0x%x", __FUNCTION__ , sig_readback0, sig_readback1, checksum);
#if SWAP_UPDATE
			if(OldImg2Addr != ~0x0){
				flash_write_word(&flash,OldImg2Addr + 8, 0x35393130);
				flash_write_word(&flash,OldImg2Addr + 12, 0x31313738);
				flash_read_word(&flash, OldImg2Addr + 8, &sig_readback0);
				flash_read_word(&flash, OldImg2Addr + 12, &sig_readback1);
				printf("\n\r[%s] old signature %x,%x", __FUNCTION__ , sig_readback0, sig_readback1);
			}
#endif			
			printf("\n\r[%s] Update OTA success!", __FUNCTION__);
			
			ret = 0;
		}
	}
update_ota_exit:
	if(buf)
		update_free(buf);
	if(server_socket >= 0)
		close(server_socket);
	if(param)
		update_free(param);
	TaskOTA = NULL;
	printf("\n\r[%s] Update task exit", __FUNCTION__);	
	if(!ret){
		printf("\n\r[%s] Ready to reboot", __FUNCTION__);	
		ota_platform_reset();
	}
	vTaskDelete(NULL);	
	return;

}