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); }
app_action_t application_function_flash_checksum(string_t *src, string_t *dst) { unsigned int address, current, length, done; SHA_CTX sha_context; unsigned char sha_result[SHA_DIGEST_LENGTH]; string_new(, sha_string, SHA_DIGEST_LENGTH * 2 + 2); if(parse_uint(1, src, &address, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-checksum: address required\n"); return(app_action_error); } if(parse_uint(2, src, &length, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-checksum: length required\n"); return(app_action_error); } if((address % SPI_FLASH_SEC_SIZE) != 0) { string_append(dst, "ERROR: flash_checksum: address should be divisible by flash sector size"); return(app_action_error); } if((length % SPI_FLASH_SEC_SIZE) != 0) { string_append(dst, "ERROR: flash_checksum: length should be divisible by flash sector size"); return(app_action_error); } SHA1Init(&sha_context); for(current = address, done = 0; done < length; current += SPI_FLASH_SEC_SIZE, done += SPI_FLASH_SEC_SIZE) { spi_flash_read(current, string_buffer_nonconst(dst), SPI_FLASH_SEC_SIZE); SHA1Update(&sha_context, string_buffer(dst), SPI_FLASH_SEC_SIZE); } SHA1Final(sha_result, &sha_context); string_bin_to_hex(&sha_string, sha_result, SHA_DIGEST_LENGTH); string_clear(dst); string_format(dst, "OK flash-checksum: checksummed bytes: %u, from address: %u, checksum: ", done, address); string_append_string(dst, &sha_string); string_append(dst, "\n"); return(app_action_normal); }
app_action_t application_function_flash_read(string_t *src, string_t *dst) { unsigned int address, sector; SHA_CTX sha_context; unsigned char sha_result[SHA_DIGEST_LENGTH]; string_new(, sha_string, SHA_DIGEST_LENGTH * 2 + 2); if(string_size(&flash_sector_buffer) < SPI_FLASH_SEC_SIZE) { string_format(dst, "ERROR flash-read: flash sector buffer too small: %d\n", string_size(&flash_sector_buffer)); return(app_action_error); } if(parse_uint(1, src, &address, 0, ' ') != parse_ok) { string_append(dst, "ERROR flash-read: address required\n"); return(app_action_error); } if((address % SPI_FLASH_SEC_SIZE) != 0) { string_append(dst, "ERROR flash-read: address should be divisible by flash sector size"); return(app_action_error); } if((flash_sector_buffer_use != fsb_free) && (flash_sector_buffer_use != fsb_config_cache)) { string_format(dst, "ERROR: flash-read: sector buffer in use: %u\n", flash_sector_buffer_use); return(app_action_error); } flash_sector_buffer_use = fsb_ota; sector = address / SPI_FLASH_SEC_SIZE; spi_flash_read(sector * SPI_FLASH_SEC_SIZE, string_buffer_nonconst(&flash_sector_buffer), SPI_FLASH_SEC_SIZE); string_setlength(&flash_sector_buffer, SPI_FLASH_SEC_SIZE); SHA1Init(&sha_context); SHA1Update(&sha_context, string_buffer(&flash_sector_buffer), SPI_FLASH_SEC_SIZE); SHA1Final(sha_result, &sha_context); string_bin_to_hex(&sha_string, sha_result, SHA_DIGEST_LENGTH); string_format(dst, "OK flash-read: read bytes: %d, from address: %u (%u), checksum: ", SPI_FLASH_SEC_SIZE, address, sector); string_append_string(dst, &sha_string); string_append(dst, "\n"); return(app_action_normal); }
int main(void) { char *hexstr = "0406ff2354124e6a9b2f6ed6ff00411287"; char binbuf[64]; int binlen; char newhex[64]; /* * string_hex_to_bin() and string_bin_to_hex() */ printf("*** Checking string_hex_to_bin() and string_bin_to_hex()\n"); printf("Original string : \"%s\"\n", hexstr); binlen = string_hex_to_bin(binbuf, hexstr); string_bin_to_hex(newhex, binbuf, binlen); printf("Resulting string : \"%s\"\n", newhex); if( strcmp(hexstr, newhex) ) printf("<<< ERROR!!! >>>\n"); return 0; }
static app_action_t flash_write_verify_(string_t *src, string_t *dst, bool verify) { unsigned int address, sector; int byte; int same = 0; int erase = 1; const char *ptr; const char *caller = verify ? "verify" : "write"; SHA_CTX sha_context; unsigned char sha_result[SHA_DIGEST_LENGTH]; string_new(, sha_string, SHA_DIGEST_LENGTH * 2 + 2); if(string_size(&flash_sector_buffer) < SPI_FLASH_SEC_SIZE) { string_format(dst, "ERROR flash-%s: flash sector buffer too small: %d\n", caller, string_size(&flash_sector_buffer)); return(app_action_error); } if(string_size(dst) < SPI_FLASH_SEC_SIZE) { string_format(dst, "ERROR flash-%s: dst buffer too small: %d\n", caller, string_size(dst)); return(app_action_error); } if(parse_uint(1, src, &address, 0, ' ') != parse_ok) { string_format(dst, "ERROR flash-%s: address required\n", caller); return(app_action_error); } if((address % SPI_FLASH_SEC_SIZE) != 0) { string_format(dst, "ERROR flash-%s: address should be divisible by flash sector size", caller); return(app_action_error); } if(flash_sector_buffer_use != fsb_ota) { string_format(dst, "ERROR: flash-%s: sector buffer in use: %u\n", caller, flash_sector_buffer_use); return(app_action_error); } sector = address / SPI_FLASH_SEC_SIZE; spi_flash_read(sector * SPI_FLASH_SEC_SIZE, string_buffer_nonconst(dst), SPI_FLASH_SEC_SIZE); erase = 0; same = 0; SHA1Init(&sha_context); if(verify) { if(!memcmp(string_buffer(&flash_sector_buffer), string_buffer(dst), SPI_FLASH_SEC_SIZE)) same = 1; SHA1Update(&sha_context, string_buffer(dst), SPI_FLASH_SEC_SIZE); } else { if(memcmp(string_buffer(&flash_sector_buffer), string_buffer(dst), SPI_FLASH_SEC_SIZE)) { for(byte = 0, ptr = string_buffer(dst); byte < SPI_FLASH_SEC_SIZE; byte++, ptr++) { if(*(const uint8_t *)ptr != 0xff) { erase = 1; break; } } if(erase) spi_flash_erase_sector(sector); spi_flash_write(sector * SPI_FLASH_SEC_SIZE, string_buffer(&flash_sector_buffer), SPI_FLASH_SEC_SIZE); } else same = 1; SHA1Update(&sha_context, string_buffer(&flash_sector_buffer), SPI_FLASH_SEC_SIZE); } SHA1Final(sha_result, &sha_context); string_bin_to_hex(&sha_string, sha_result, SHA_DIGEST_LENGTH); flash_sector_buffer_use = fsb_free; if(verify) string_format(dst, "OK flash-verify: verified bytes: %d, at address: %u (%u), same: %d, checksum: ", SPI_FLASH_SEC_SIZE, address, sector, same); else string_format(dst, "OK flash-write: written bytes: %d, to address: %u (%u), same: %d, erased: %d, checksum: ", SPI_FLASH_SEC_SIZE, address, sector, same, erase); string_append_string(dst, &sha_string); string_append(dst, "\n"); return(app_action_normal); }