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); }
static void string_value_print (const GValue *value, GString *str) { string_append_string (str, g_value_get_string (value)); }
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); }