static void socket_command_callback_data_received(lwip_if_socket_t *socket, unsigned int length) { static const char command_string[] = "flash-send "; unsigned int chunk_length; int chunk_offset; if((command_left_to_read == 0) && string_nmatch_cstr(&command_socket_receive_buffer, command_string, sizeof(command_string) - 1) && (parse_uint(2, &command_socket_receive_buffer, &chunk_length, 10, ' ') == parse_ok) && ((chunk_offset = string_sep(&command_socket_receive_buffer, 0, 3, ' ')) >= 0)) command_left_to_read = chunk_offset + chunk_length; if(command_left_to_read > 0) { if(length > command_left_to_read) command_left_to_read = 0; else command_left_to_read -= length; } if((command_left_to_read == 0) && (string_trim_nl(&command_socket_receive_buffer) || lwip_if_received_udp(socket))) dispatch_post_command(command_task_received_command); else lwip_if_receive_buffer_unlock(&command_socket); }
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); }