irom app_action_t application_function_ota_finish(const string_t *src, string_t *dst)
{
	static uint8_t md5_result[16];
	string_new(static, local_md5_string, 34);
	string_new(static, remote_md5_string, 34);
	app_action_t action;

	if((ota_state != state_write) && (ota_state != state_verify))
	{
		string_cat(dst, "OTA: not active\n");
		ota_state = state_inactive;
		return(app_action_error);
	}

	string_clear(&remote_md5_string);

	if((parse_string(1, src, &remote_md5_string)) != parse_ok)
	{
		string_copy(dst, "OTA: missing md5sum string\n");
		ota_state = state_inactive;
		return(app_action_error);
	}

	if((string_length(&buffer_4k) > 0) &&
			((action = flash_write_verify(src, dst)) != app_action_normal))
	{
		ota_state = state_inactive;
		return(action);
	}

	if(remote_file_length != received)
	{
		string_format(dst, "OTA: file size differs: %u != %u\n", remote_file_length, received);
		ota_state = state_inactive;
		return(app_action_error);
	}

	string_clear(&local_md5_string);

	MD5Final(md5_result, &md5);
	string_bin_to_hex(&local_md5_string, md5_result, 16);
	string_clear(dst);

	if(!string_match_string(&local_md5_string, &remote_md5_string))
	{
		string_format(dst, "OTA: invalid md5sum: \"%s\" != \"%s\"\n",
				string_to_const_ptr(&local_md5_string), string_to_ptr(&remote_md5_string));
		ota_state = state_inactive;
		return(app_action_error);
	}

	string_format(dst, "%s %s %s %d %d\n", ota_state == state_verify ? "VERIFY_OK" : "WRITE_OK",
			string_to_const_ptr(&local_md5_string),
			string_to_const_ptr(&remote_md5_string),
			written, skipped);

	ota_state = state_successful;

	return(app_action_normal);
}
Exemple #2
0
static int startup_config_write_to_flash(void *addr , int len)
{
#ifdef HAVE_SCFG_PROTECTION
    unsigned int part_index = IROS_FLASH_PARTITION_INDEX_ANY;
#endif
    char *startup_cfg_addr = NULL;
    int written_len = 0;

    if(!scfg_autosave_flag)
        return 0;

#ifdef HAVE_SCFG_PROTECTION
    part_index = flash_part_id_to_part_index(SCFG_PARTION);
    if(active_part_index == part_index)
        active_part_index = flash_part_id_to_part_index(SCFG_PARTION1);
    else
        active_part_index = part_index;
#endif
    if(active_part_index == IROS_FLASH_PARTITION_INDEX_ANY)
    {
        if(scfg_warning_flag == 0)
            cs_printf("write startup-cfg error!\n");
        return -1;
    }
    startup_cfg_addr = flash_dev.info.super_block.part_tab[active_part_index].part_loc;
    if (flash_part_write_init(active_part_index, startup_cfg_addr)) { /* prepare to write flash */
        startup_cfg_encrypt((char *)addr+sizeof(tlv_header_t), len-sizeof(tlv_header_t));
        written_len = flash_write(startup_cfg_addr, (char *)addr, len);
        flash_part_write_done(active_part_index);
        flash_write_verify(startup_cfg_addr, (char *)addr, len);
        if(written_len != len)
        {
            startup_cfg_decrypt((char *)addr+sizeof(tlv_header_t), len-sizeof(tlv_header_t));
            if(scfg_warning_flag == 0)
                cs_printf("write startup-config error\n");
            return -1;
        }
        startup_cfg_decrypt((char *)addr+sizeof(tlv_header_t), len-sizeof(tlv_header_t));
        if(scfg_warning_flag == 0)
            cs_printf("write startup-cfg successfully\n");
        return 0;
    }
    else
    {
        if(scfg_warning_flag == 0)
            cs_printf("write startup-cfg error\n");
    }

    return -1;
}
Exemple #3
0
cs_uint32 iros_image_sync_flash()
{
    cs_uint8 active_blob_idx, standby_blob_idx;
    cs_int8 *standby_flash_des, *active_flash_des;
    blob_info_desc_t *standby_blob_info, *active_blob_info;
    cs_uint8 part_index;
    cs_uint32 wrt_len, wrt_blk;
    cs_uint32 image_len, left_len;
    cs_int8 *flash_ptr, *img_buf, *img_ptr;
    cs_uint32 ver_offset;
    cs_int8 ver_buf[NTT_VERSION_LEN + 1];

    sync_status = IMAGE_SYNC_NOT_COMP;

    active_blob_idx = current_blob_desc.blob_idx;
    active_blob_info = blob_info_tab[active_blob_idx];
    active_flash_des = (cs_int8 *)active_blob_info + sizeof(blob_info_desc_t);

    standby_blob_idx = 0x1 &(active_blob_idx + 1);
    standby_blob_info = blob_info_tab[standby_blob_idx];
    standby_flash_des = (cs_int8 *)standby_blob_info + sizeof(blob_info_desc_t);

    // check if images are the same
    if(active_blob_info->len == standby_blob_info->len
        && standby_blob_info->is_not_confirmed == 0
        && standby_blob_info->is_not_executed == 0)
    {
        ver_offset = CS_OFFSET(ntt_image_header_t, onu_sw_version);

        if(!flash_memcmp(standby_flash_des + ver_offset, active_flash_des + ver_offset, NTT_VERSION_LEN))
        {
            memcpy(ver_buf, standby_flash_des + ver_offset, NTT_VERSION_LEN);
            ver_buf[NTT_VERSION_LEN] = 0;
            diag_printf("NTT sw version: %s\n", ver_buf);
            sync_status = IMAGE_SYNC_DONE;
            return CS_OK;
        }
    }

    // get standby blob partition ready, and sync
    part_index = blob_part_tab[standby_blob_idx];
    if(0 == flash_part_write_init(part_index, (cs_int8 *)standby_blob_info))
    {
        diag_printf("flash part not ready\n");
        sync_status = IMAGE_SYNC_DONE;
        return CS_ERROR;
    }

    image_len = active_blob_info->len;
    if(image_len > MAX_IMAGE_SIZE)
    {
        flash_part_write_done(part_index);
        diag_printf("image size exceeding max\n");
        sync_status = IMAGE_SYNC_DONE;
        return CS_ERROR;
    }

    img_buf = iros_malloc(IROS_MID_SYS, WRT_BLOCK_LEN);
    if(img_buf == NULL)
    {
        flash_part_write_done(part_index);
        diag_printf("no memory for image sync\n");
        sync_status = IMAGE_SYNC_DONE;
        return CS_ERROR;
    }

    //iros_flash_read(active_flash_des, img_buf, image_len);
    diag_printf("\n Begin to sync image on flash...\n");

    wrt_len = 0;
    wrt_blk = 0;
    img_ptr = img_buf;
    left_len = image_len;
    flash_ptr = standby_flash_des;

    while (left_len)
    {
        wrt_len = (left_len > WRT_BLOCK_LEN) ? WRT_BLOCK_LEN : left_len;
        iros_flash_read(active_flash_des + image_len - left_len, img_buf, wrt_len);

        // diag_printf("flash write: %p, left 0x%x, wrt 0x%x\n", flash_ptr, left_len, wrt_len);

        if(wrt_len != flash_write(flash_ptr, img_ptr, wrt_len))
        {
            diag_printf("flash wrt not equal\n");
            break;
        }

        if(!flash_write_verify(flash_ptr, img_ptr, wrt_len))
        {
            diag_printf("verify failed at %p\n", flash_ptr);
            break;
        }

        flash_ptr += wrt_len;
        //img_ptr   += wrt_len;
        left_len  -= wrt_len;

        wrt_blk++;
        if(!(wrt_blk % 32))
        {
            diag_printf("\n");
        }
        diag_printf(".");
        cs_thread_delay(5);
    }

    iros_free(img_buf);

    blob_info_desc_t info;
    info.head_signature = BLOB_INFO_HEAD_SIGNATURE;
    // standby stamp less than active, active always from 1, standby always -1
    info.upgrade_stamp = blob_info_tab[active_blob_idx]->upgrade_stamp - 1;
    info.len = image_len;
    info.blob_start_ptr = (struct image_blob_header_t *) standby_flash_des;
    // cofirm the image copy
    info.is_not_confirmed   = 0;
    info.is_not_executed    = 0;
    info.tail_signature     = BLOB_INFO_TAIL_SIGNATURE;

    /* write control block of this blob, each by field */
    flash_write((char *)&standby_blob_info->head_signature, (char *)&info.head_signature, sizeof(info.head_signature));
    flash_write((char *)&standby_blob_info->upgrade_stamp, (char *)&info.upgrade_stamp, sizeof(info.upgrade_stamp));
    flash_write((char *)&standby_blob_info->blob_start_ptr, (char *)&info.blob_start_ptr, sizeof(info.blob_start_ptr));
    flash_write((char *)&standby_blob_info->tail_signature, (char *)&info.tail_signature, sizeof(info.tail_signature));
    flash_write((char *)&standby_blob_info->len, (char *)&info.len, sizeof(info.len));
    flash_write((char *)&standby_blob_info->is_not_confirmed, (char *)&info.is_not_confirmed, sizeof(info.is_not_confirmed));
    flash_write((char *)&standby_blob_info->is_not_executed, (char *)&info.is_not_executed, sizeof(info.is_not_executed));

    flash_part_write_done(part_index);
    sync_status = IMAGE_SYNC_DONE;
    diag_printf("sync blob %d done\n", standby_blob_idx);

    return CS_OK;
}
irom app_action_t application_function_ota_send(const string_t *src, string_t *dst)
{
	int chunk_offset, chunk_length, remote_chunk_length;
	uint32_t crc, remote_crc;
	app_action_t action;

	if((ota_state != state_write) && (ota_state != state_verify))
	{
		string_cat(dst, "OTA: not active\n");
		ota_state = state_inactive;
		return(app_action_error);
	}

	if(parse_int(1, src, &remote_chunk_length, 0) != parse_ok)
	{
		string_cat(dst, "OTA: missing chunk length\n");
		ota_state = state_inactive;
		return(app_action_error);
	}

	if(parse_int(2, src, &remote_crc, 0) != parse_ok)
	{
		string_cat(dst, "OTA: missing crc\n");
		ota_state = state_inactive;
		return(app_action_error);
	}

	if((chunk_offset = string_sep(src, 0, 3, ' ')) < 0)
	{
		string_cat(dst, "OTA: missing data chunk\n");
		ota_state = state_inactive;
		return(app_action_error);
	}

	if((chunk_length = string_length(src) - chunk_offset) != remote_chunk_length)
	{
		string_format(dst, "OTA: chunk length mismatch: %d != %d\n", remote_chunk_length, chunk_length);
		ota_state = state_inactive;
		return(app_action_error);
	}

	if((crc = string_crc32(src, chunk_offset, chunk_length)) != remote_crc)
	{
		string_format(dst, "OTA: CRC mismatch %08x != %08x\n", remote_crc, crc);
		ota_state = state_inactive;
		return(app_action_error);
	}

	string_splice(&buffer_4k, src, chunk_offset, chunk_length);

	if(string_length(&buffer_4k) > 0x1000)
	{
		string_format(dst, "OTA: unaligned %u\n", string_length(&buffer_4k));
		ota_state = state_inactive;
		return(app_action_error);
	}

	if((string_length(&buffer_4k) == 0x1000) &&
			((action = flash_write_verify(src, dst)) != app_action_normal))
	{
		ota_state = state_inactive;
		return(action);
	}

	string_format(dst, "ACK %d\n", received);

	return(app_action_normal);
}
Exemple #5
0
cs_uint32 iros_image_write_flash(cs_int8* _image, cs_uint32 _len)
{
    cs_uint8 cur_blob_idx;
    cs_int8* flash_des;
    cs_uint8 blob_idx;
    cs_uint8 part_index;
    blob_info_desc_t *blob_info;
    cs_uint32 wrt_len, wrt_blk;
    cs_uint32 left_len;
    cs_int8 *flash_ptr, *img_ptr;
    cs_uint32 wdt_time;
    cs_callback_context_t     context;

    cur_blob_idx = current_blob_desc.blob_idx;

    blob_idx = 0x1 &(cur_blob_idx + 1);
    blob_info = blob_info_tab[blob_idx];
    flash_des = (cs_int8 *)((cs_int8 *)blob_info + sizeof(blob_info_desc_t));
    part_index = blob_part_tab[blob_idx];

    if(0 == flash_part_write_init(part_index, (char*)blob_info))
    {
        diag_printf("flash part not ready\n");
        return CS_ERROR;
    }

    wrt_len = 0;
    wrt_blk = 0;
    img_ptr = _image;
    left_len = _len;
    flash_ptr = flash_des;

    while (left_len)
    {
        wrt_len = (left_len > WRT_BLOCK_LEN) ? WRT_BLOCK_LEN : left_len;

        // diag_printf("flash write: %p, left 0x%x, wrt 0x%x\n", flash_ptr, left_len, wrt_len);

        if(wrt_len != flash_write(flash_ptr, img_ptr, wrt_len))
        {
            flash_part_write_done(part_index);
            diag_printf("flash wrt not equal\n");
            return CS_ERROR;
        }

        if(!flash_write_verify(flash_ptr, img_ptr, wrt_len))
        {
            flash_part_write_done(part_index);
            diag_printf("verify failed at %p\n", flash_ptr);
            return CS_ERROR;
        }

        flash_ptr += wrt_len;
        img_ptr   += wrt_len;
        left_len  -= wrt_len;

        wrt_blk++;
        if(!(wrt_blk % 32))
        {
            diag_printf("\n");
        }
        diag_printf(".");
        cs_thread_delay(5);
    }

    diag_printf("image wrt done\n");

    blob_info_desc_t info;
    info.head_signature = BLOB_INFO_HEAD_SIGNATURE;
    info.upgrade_stamp = blob_info_tab[cur_blob_idx]->upgrade_stamp + 1;
    info.len = _len;
    info.blob_start_ptr = (struct image_blob_header_t *) flash_des;
    #ifdef HAVE_KT_OAM /* confirm directly */
    info.is_not_confirmed = 0;
    info.is_not_executed  = 0;
    #else
    info.is_not_confirmed = 0xffff;
    info.is_not_executed  = 0xffff;
    #endif
    info.xip_len    = 0xffff;
    info.xip_crc32  = 0xffff;
    info.tail_signature = BLOB_INFO_TAIL_SIGNATURE;

    /* write control block of this blob, each by field */
    flash_write((char *)&blob_info->head_signature, (char *)&info.head_signature, sizeof(info.head_signature));
    flash_write((char *)&blob_info->upgrade_stamp, (char *)&info.upgrade_stamp, sizeof(info.upgrade_stamp));
    flash_write((char *)&blob_info->blob_start_ptr, (char *)&info.blob_start_ptr, sizeof(info.blob_start_ptr));
    flash_write((char *)&blob_info->tail_signature, (char *)&info.tail_signature, sizeof(info.tail_signature));
    flash_write((char *)&blob_info->len, (char *)&info.len, sizeof(info.len));
    flash_write((char *)&blob_info->is_not_confirmed, (char *)&info.is_not_confirmed, sizeof(info.is_not_confirmed));
    flash_write((char *)&blob_info->is_not_executed, (char *)&info.is_not_executed, sizeof(info.is_not_executed));

    diag_printf("update blob %d done\n", blob_idx);
    flash_part_write_done(part_index);

    /* get current WDT, transfer to loader */
    cs_plat_wdt_interval_get(context,0,0,&wdt_time);
    current_blob_desc.update_timeout = wdt_time;
    memcpy((char *)CURRENT_BLOB_DESC_BASEADDR, (char *)&current_blob_desc, sizeof(current_blob_desc_t));

    return CS_OK;
}