Initial commit: OTA chunk transfer protocol implementation
- Protocol definition with 6-byte header (chunk_idx: 2B, payload: N B, crc32: 4B) - Node.js server with chunk-based HTTP delivery - C client library with resumable download support - CRC32 implementation (IEEE 802.3) - Test suites for both server and CRC32 - 1024B default chunk size (0.59% overhead)
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @file test_crc32.c
|
||||
* @brief CRC32 Test Suite
|
||||
*/
|
||||
|
||||
#include "protocol.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static int passed = 0;
|
||||
static int failed = 0;
|
||||
|
||||
#define TEST_ASSERT(cond, msg) do { \
|
||||
if (cond) { \
|
||||
printf("[PASS] %s\n", msg); \
|
||||
passed++; \
|
||||
} else { \
|
||||
printf("[FAIL] %s\n", msg); \
|
||||
failed++; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Test vector from IEEE 802.3 */
|
||||
static void test_crc32_basic(void) {
|
||||
printf("\n--- CRC32 Basic Tests ---\n");
|
||||
|
||||
/* Test 1: Empty data */
|
||||
uint32_t crc = chunk_crc32(NULL, 0);
|
||||
TEST_ASSERT(crc == 0x00000000UL, "Empty data CRC = 0x00000000");
|
||||
|
||||
/* Test 2: Single byte */
|
||||
uint8_t data1[] = {0x41}; /* 'A' */
|
||||
crc = chunk_crc32(data1, 1);
|
||||
TEST_ASSERT(crc == 0xD3D99E8BUL, "Single byte 'A' CRC = 0xD3D99E8B");
|
||||
|
||||
/* Test 3: "foobar" */
|
||||
uint8_t data2[] = "foobar";
|
||||
crc = chunk_crc32(data2, 6);
|
||||
TEST_ASSERT(crc == 0x9EF61F95UL, "'foobar' CRC = 0x9EF61F95");
|
||||
|
||||
/* Test 4: Incremental update */
|
||||
uint32_t crc1 = chunk_crc32((uint8_t*)"foo", 3);
|
||||
uint32_t crc2 = chunk_crc32_update(crc1, (uint8_t*)"bar", 3);
|
||||
uint32_t crc3 = chunk_crc32(data2, 6);
|
||||
TEST_ASSERT(crc2 == crc3, "Incremental update matches single call");
|
||||
}
|
||||
|
||||
/* Test chunk size calculations */
|
||||
static void test_chunk_calculations(void) {
|
||||
printf("\n--- Chunk Calculation Tests ---\n");
|
||||
|
||||
/* Test 1: Exact multiple */
|
||||
uint16_t chunks = chunk_calc_total_chunks(4096, 1024);
|
||||
TEST_ASSERT(chunks == 4, "4096/1024 = 4 chunks");
|
||||
|
||||
/* Test 2: Not exact multiple */
|
||||
chunks = chunk_calc_total_chunks(4097, 1024);
|
||||
TEST_ASSERT(chunks == 5, "4097/1024 = 5 chunks");
|
||||
|
||||
/* Test 3: Last chunk payload size */
|
||||
uint16_t payload = chunk_calc_payload_size(4097, 4, 1024);
|
||||
TEST_ASSERT(payload == 1, "Last chunk of 4097 bytes = 1 byte");
|
||||
|
||||
/* Test 4: Middle chunk payload size */
|
||||
payload = chunk_calc_payload_size(4097, 2, 1024);
|
||||
TEST_ASSERT(payload == 1024, "Middle chunk = 1024 bytes");
|
||||
}
|
||||
|
||||
/* Test CRC32 table initialization */
|
||||
static void test_crc32_table(void) {
|
||||
printf("\n--- CRC32 Table Tests ---\n");
|
||||
|
||||
/* Call multiple times to verify idempotent initialization */
|
||||
chunk_crc32((uint8_t*)"test", 4);
|
||||
chunk_crc32((uint8_t*)"test", 4);
|
||||
chunk_crc32((uint8_t*)"test", 4);
|
||||
|
||||
TEST_ASSERT(1, "Multiple initializations OK");
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
printf("========================================\n");
|
||||
printf(" CRC32 Test Suite\n");
|
||||
printf("========================================\n");
|
||||
|
||||
test_crc32_basic();
|
||||
test_chunk_calculations();
|
||||
test_crc32_table();
|
||||
|
||||
printf("\n========================================\n");
|
||||
printf(" Results: %d passed, %d failed\n", passed, failed);
|
||||
printf("========================================\n");
|
||||
|
||||
return failed == 0 ? 0 : 1;
|
||||
}
|
||||
Reference in New Issue
Block a user