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); }
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; }
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); }
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 *)¤t_blob_desc, sizeof(current_blob_desc_t)); return CS_OK; }