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

#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 サーバ

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
S
Description
No description provided
Readme 42 KiB
Languages
C 65.3%
JavaScript 33.7%
Makefile 1%