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:
km
2026-03-30 06:35:25 +09:00
commit b1c3ec3af4
10 changed files with 1522 additions and 0 deletions
+123
View File
@@ -0,0 +1,123 @@
# OTA-Chunk-Transfer
レジューム可能な分割転送プロトコル
## プロトコル仕様
### パケット形式
```
+------------+----------------+----------+
| chunk_idx | payload (N B) | crc32 |
| 2 B | N B | 4 B |
+------------+----------------+----------+
```
- **chunk_idx**: 2 バイト(最大 65535 チャンク = 67MB まで対応、1024B/チャンク)
- **payload**: 可変長(デフォルト 1024B)
- **crc32**: 4 バイト(IEEE 802.3 ポリノミアル)
### コントロールメッセージ
#### Client → Server
```
GET /ota?file=<filename> // ファイル転送リクエスト
GET /ota/resume?file=<filename>&chunk=<index> // レジューム
```
#### Server → Client
```
200 OK + chunk data // チャンク転送
206 Partial Content // レジューム応答
404 Not Found // ファイル不存在
416 Range Not Satisfiable // 無効なレジューム位置
```
### 転送フロー
```
Client Server
| |
|-- GET /ota?file=test.bin ---->| // ファイルサイズ確認
|<-- 200 OK (Content-Length) ---| // ファイルサイズ返信
| |
|-- GET /ota?file=test.bin&chunk=0 -->| // チャンク 0 要求
|<-- 200 OK + chunk data -------| // チャンクデータ
| |
|-- GET /ota?file=test.bin&chunk=1 -->| // チャンク 1 要求
|<-- 200 OK + chunk data -------| // チャンクデータ
| |
... |
| |
// 通信断情况后
| |
|-- GET /ota/resume?file=test.bin&chunk=50 -->| // チャンク 50 から再開
|<-- 200 OK + chunk data -------| // チャンク 50 データ
| |
```
## ファイル構成
```
ota-chunk-transfer/
├── protocol/
│ ├── protocol.h // プロトコル定義
│ ├── chunk_client.c // C クライアント実装
│ ├── chunk_server.c // C サーバ実装(参照用)
│ └── crc32.c // CRC32 実装
├── server/
│ └── server.js // Node.js サーバ
├── tests/
│ ├── test_crc32.c
│ ├── test_chunk_client.c
│ └── test_server.js
├── Makefile
└── README.md
```
## 使用例
### C クライアント(ESP32
```c
#include "protocol.h"
void chunk_received(uint16_t chunk_idx, uint8_t *data, uint16_t len, void *user_ctx);
void transfer_complete(uint32_t total_bytes, void *user_ctx);
void transfer_error(int err_code, void *user_ctx);
chunk_client_config_t config = {
.server_url = "http://192.168.1.100:8080",
.chunk_size = 1024,
.on_chunk_received = chunk_received,
.on_complete = transfer_complete,
.on_error = transfer_error,
.user_ctx = NULL
};
chunk_client_init(&config);
chunk_client_download("firmware.bin");
```
### Node.js サーバ
```javascript
const server = require('./server');
server.start(8080, '/path/to/ota/files');
```
## パフォーマンス
| チャンクサイズ | ヘッダ比率 | 64MB ファイルのチャンク数 |
|---------------|-----------|----------------------|
| 512 B | 1.17% | 131,072 |
| 1024 B | 0.59% | 65,536 |
| 2048 B | 0.30% | 32,768 |
## TODO
- [ ] プロトコル定義
- [ ] CRC32 実装
- [ ] C クライアント実装
- [ ] Node.js サーバ実装
- [ ] テストスイート
- [ ] 圧縮オプション(gzip
- [ ] 暗号化オプション(TLS