app_action_t application_function_flash_receive(string_t *src, string_t *dst) { unsigned int chunk_offset, chunk_length; if(string_size(&flash_sector_buffer) < SPI_FLASH_SEC_SIZE) { string_format(dst, "ERROR flash-receive: flash sector buffer too small: %d\n", string_size(&flash_sector_buffer)); return(app_action_error); } if(parse_uint(1, src, &chunk_offset, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-receive: chunk offset required\n"); return(app_action_error); } if(parse_uint(2, src, &chunk_length, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-receive: chunk chunk_length required\n"); return(app_action_error); } if((chunk_length == 0) || ((chunk_offset % chunk_length) != 0)) { string_append(dst, "ERROR: flash-receive: chunk offset should be divisible by chunk size"); return(app_action_error); } if((chunk_length == 0) || ((SPI_FLASH_SEC_SIZE % chunk_length) != 0)) { string_append(dst, "ERROR: flash-receive: chunk length should be divisible by flash sector size"); return(app_action_error); } if((chunk_offset + chunk_length) > SPI_FLASH_SEC_SIZE) { string_format(dst, "ERROR flash-receive: chunk_length(%u) + chunk_offset(%u) > sector size(%d)\n", chunk_length, chunk_offset, SPI_FLASH_SEC_SIZE); return(app_action_error); } if((flash_sector_buffer_use != fsb_free) && (flash_sector_buffer_use != fsb_config_cache) && (flash_sector_buffer_use != fsb_ota)) { string_format(dst, "ERROR: flash_send: sector buffer in use: %u\n", flash_sector_buffer_use); return(app_action_error); } flash_sector_buffer_use = fsb_ota; string_format(dst, "OK flash-receive: sending bytes: %u, from offset: %u, data: @", chunk_length, chunk_offset); string_splice(dst, -1, &flash_sector_buffer, chunk_offset, chunk_length); string_append(dst, "\n"); if((chunk_offset + chunk_length) >= SPI_FLASH_SEC_SIZE) flash_sector_buffer_use = fsb_free; return(app_action_normal); }
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); }
app_action_t application_function_flash_send(string_t *src, string_t *dst) { int chunk_offset; unsigned int offset, length, chunk_length; if(parse_uint(1, src, &offset, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-send: offset required\n"); return(app_action_error); } if(parse_uint(2, src, &length, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-send: length required\n"); return(app_action_error); } if((length != 0) && ((offset % length) != 0)) { string_append(dst, "ERROR: flash-send: chunk offset should be divisible by chunk size"); return(app_action_error); } if((length != 0) && ((SPI_FLASH_SEC_SIZE % length) != 0)) { string_append(dst, "ERROR: flash-send: chunk length should be divisible by flash sector size"); return(app_action_error); } if((offset + length) > SPI_FLASH_SEC_SIZE) { string_format(dst, "ERROR flash-send: length(%u) + offset(%u) > sector size(%d)\n", offset, length, SPI_FLASH_SEC_SIZE); return(app_action_error); } if((chunk_offset = string_sep(src, 0, 3, ' ')) < 0) { string_append(dst, "ERROR flash-send: missing data\n"); return(app_action_error); } if((chunk_length = string_length(src) - chunk_offset) != length) { string_format(dst, "ERROR flash-send: data length mismatch: %u != %u\n", length, chunk_length); return(app_action_error); } if(string_size(&flash_sector_buffer) < SPI_FLASH_SEC_SIZE) { string_format(dst, "ERROR flash-send: flash sector buffer too small: %d\n", string_size(&flash_sector_buffer)); return(app_action_error); } if((flash_sector_buffer_use != fsb_free) && (flash_sector_buffer_use != fsb_config_cache) && (flash_sector_buffer_use != fsb_ota)) { string_format(dst, "ERROR flash_send: sector buffer in use: %u\n", flash_sector_buffer_use); return(app_action_error); } flash_sector_buffer_use = fsb_ota; string_splice(&flash_sector_buffer, offset, src, chunk_offset, chunk_length); string_format(dst, "OK flash-send: received bytes: %u, at offset: %u\n", length, offset); return(app_action_normal); }