diff --git a/sonixflasher.c b/sonixflasher.c index 4819d51..c5a7cda 100644 --- a/sonixflasher.c +++ b/sonixflasher.c @@ -37,6 +37,7 @@ #define USER_ROM_PAGES_SN32F290 256 #define QMK_OFFSET_DEFAULT 0x200 +#define MIN_FIRMWARE 0x100 #define CMD_BASE 0x55AA #define CMD_GET_FW_VERSION 0x1 @@ -51,7 +52,7 @@ #define CMD_VERIFY(x) ((CMD_BASE << 8) | (x)) #define CMD_ACK 0xFAFAFAFA -#define VALID_FW 0xAAAA5555 +#define LAST_CHUNK_OFFSET (REPORT_SIZE - sizeof(uint32_t)) #define SN240 1 #define SN260 2 @@ -657,12 +658,21 @@ bool flash(hid_device *dev, long offset, const char *file_name, long fw_size, bo size_t bytes_read = 0; uint16_t checksum = 0; + uint32_t last_chunk = 0; clear_buffer(buf, REPORT_SIZE); while ((bytes_read = fread(buf, 1, REPORT_SIZE, firmware)) > 0) { if (bytes_read < REPORT_SIZE) { fprintf(stderr, "WARNING: Read %zu bytes, expected %d bytes.\n", bytes_read, REPORT_SIZE); } checksum += checksum16(buf, bytes_read); + + // Capture the last 4 bytes of this buffer for last_chunk + if (bytes_read >= sizeof(uint32_t)) { + memcpy(&last_chunk, buf + (bytes_read - sizeof(uint32_t)), sizeof(uint32_t)); + } else { + memcpy(&last_chunk, buf, bytes_read); + } + if (!hid_set_feature(dev, buf, bytes_read)) return false; clear_buffer(buf, REPORT_SIZE); @@ -675,19 +685,23 @@ bool flash(hid_device *dev, long offset, const char *file_name, long fw_size, bo printf("\n"); printf("Verifying flash completion...\n"); if (!hid_get_feature(dev, buf, REPORT_SIZE, CMD_ENABLE_PROGRAM)) return false; - if (read_response_32(buf, (sizeof(buf) - sizeof(VALID_FW)), VALID_FW, &resp)) { + if (read_response_32(buf, LAST_CHUNK_OFFSET, last_chunk, &resp)) { printf("Flash completion verified. \n"); uint16_t resp_16 = (uint16_t)resp; if (read_response_16(buf, 8, checksum, &resp_16)) { printf("Flash Verification Checksum: OK!\n"); return true; } else { + if (offset != 0) { + printf("Warning: offset 0x%04lx requested. Flash Verification Checksum disabled.\n", offset); + return true; + } fprintf(stderr, "ERROR:Flash Verification Checksum: FAILED! response is 0x%04x, expected 0x%04x.\n", resp_16, checksum); return false; } return false; } else { - fprintf(stderr, "ERROR: Failed to verify flash completion: response is 0x%08x, expected 0x%08x.\n", resp, VALID_FW); + fprintf(stderr, "ERROR: Failed to verify flash completion: response is 0x%08x, expected 0x%08x.\n", resp, last_chunk); return false; } return false; @@ -717,7 +731,7 @@ bool sanity_check_firmware(long fw_size, long offset) { fprintf(stderr, "ERROR: Firmware is too large too flash: 0x%08lx max allowed is 0x%08lx.\n", fw_size, MAX_FIRMWARE - offset); return false; } - if (fw_size < 0x100) { + if (fw_size < MIN_FIRMWARE) { fprintf(stderr, "ERROR: Firmware is too small."); return false; } @@ -757,6 +771,22 @@ long get_file_size(FILE *fp) { return file_size; } +bool truncate_and_reopen(const char *file_name, FILE **fp, long new_size) { + fclose(*fp); // Close the file before truncating + if (truncate(file_name, new_size) != 0) { + fprintf(stderr, "ERROR: Could not truncate file to size %ld.\n", new_size); + return false; + } + + *fp = fopen(file_name, "rb"); // Reopen the file in read mode + if (*fp == NULL) { + fprintf(stderr, "ERROR: Could not reopen file after truncation.\n"); + return false; + } + + return true; +} + long prepare_file_to_flash(const char *file_name, bool flash_jumploader) { FILE *fp = fopen(file_name, "rb"); if (fp == NULL) { @@ -783,22 +813,14 @@ long prepare_file_to_flash(const char *file_name, bool flash_jumploader) { printf("Warning: jumploader binary doesn't have a size of: 0x%04x bytes.\n", QMK_OFFSET_DEFAULT); printf("Truncating jumploader binary to: 0x%04x.\n", QMK_OFFSET_DEFAULT); - fclose(fp); - if (truncate(file_name, QMK_OFFSET_DEFAULT) != 0) { - fprintf(stderr, "ERROR: Could not truncate file.\n"); - return -1; - } - - // Reopen the file - fp = fopen(file_name, "rb"); - if (fp == NULL) { - fprintf(stderr, "ERROR: Could not open file after truncation.\n"); + if (!truncate_and_reopen(file_name, &fp, QMK_OFFSET_DEFAULT)) { return -1; } // Recalculate file size file_size = get_file_size(fp); if (file_size == -1L) { + fprintf(stderr, "ERROR: Truncated file size calculation failed.\n"); fclose(fp); return -1; } @@ -813,7 +835,18 @@ long prepare_file_to_flash(const char *file_name, bool flash_jumploader) { padded_file_size++; } printf("File size after padding: %ld bytes\n", padded_file_size); - file_size = padded_file_size; + + if (!truncate_and_reopen(file_name, &fp, padded_file_size)) { + return -1; + } + + // Recalculate file size + file_size = get_file_size(fp); + if (file_size == -1L) { + fprintf(stderr, "ERROR: Truncated file size calculation failed.\n"); + fclose(fp); + return -1; + } } fclose(fp);