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);
}
Beispiel #3
0
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);
}