オリジナル: https://github.com/lessu/open_dp100/blob/master/DP100_Protocol.md
デバイス: Alientek DP100
私は主にmacOSを使用し、次にlinux、Windowsを使用することはあまりありません。
Alientekは、唯一Windows用の.net Dllを提供するため、二次開発には非常に不便です。
そこで私は、基礎となる通信プロトコルがどのように実装されているかを確認するためにリバースエンジニアリングを行い、他の言語を使って移植を行いました。
HIDプロトコルが使われている。 HIDではないが、HIDクラスである。
ID 2e3c:af01
設定:0、インターフェース:0、設定:0
エンドポイント:アドレス:81、方向:IN、転送タイプ:割り込み
エンドポイント:アドレス:01、方向:OUT、転送タイプ:割り込み
項目 | 値 | 備考 |
---|---|---|
USBクラス | 0x03 HID | データを転送せずに、直接、裸で転送する。 |
HIDの使用法 | なし | バージョン1.1は64バイトのアプリケーションを送信します。 |
USBパケットデータ長 | 固定64 | パッケージの中身が64に満たない場合は0で補うか、気にしないか。 |
項目 | 値 | |
---|---|---|
転送サイズ 終了 | 小さい 終了 |
バイト | 0 | 1 | 2 | 3 | ... | len+4 | len+5 | ... |
---|---|---|---|---|---|---|---|---|
意味 | 転送方向 | OpCode | リザーブ | Len | Lenのデータ | crc16 | crc16 | 。 |
description | fa/fb | operation | 00 | LOW | HIGH |
例
fb300000310f00000000000000000000000000000000000000000000000000000000000...
- ホストがデバイスに渡すときは
0xfb
- デバイスがホストに渡すときは
0xfa
OpCode | 説明 | |
---|---|---|
0x10 | DEVICE_INFO | |
0x12 | START_TRANS | |
0x13 | DATA_TRANS | |
0x14 | END_TRANS | |
0x15 | DEV_UPGRADE | |
0x30 | BASIC_INFO | |
0×35 | BASIC_SET | |
0×40 | SYSTEM_INFO | |
0x45 | SYSTEM_SET | |
0x50 | SCAN_OUT | |
0x55 | SERIAL_OUT | |
0x80 | DISCONNECT |
各OpCodeの使用方法については、以下のセクションで説明する。
文字通り追従するデータの長さを意味するが、OpCode によって異なる。
実際のデータの内容で、OpCode によって意味が異なるので、以下に展開する。
E2E 認証方式 CRC-16/MODBUS、Payload は Data の先頭バイトから末尾バイトまで。
リトルエンディアンである。すなわち、0x1234 の場合、送信は 0x34 0x12 に変更する。
// CRC-16/MODBUS 計算関数
uint16_t calculate_crc16(const uint8_t *data, size_t length) {
uint16_t crc = 0xFFFF; // 初期値
for (size_t i = 0; i < length; i++) {
crc ^= data[i];
for (uint8_t j = 0; j < 8; j++) {
if (crc & 1)
crc = (crc >> 1) ^ 0xA001; // 多項式: 0xA001
else
crc >>= 1;
}
}
return crc; // 計算結果(リトルエンディアン形式)
}
sequenceDiagram
participant Host
participant Device
Host->>+Device:USB列挙等
Device->>-Host:-
Host->>+Device:Interrupt Out:fb300000310f..
Device->>-Host:Interrupt In: fa3000xxxxxxxx..
以下の情報はdllダンプからのものです。 !!!! 未テスト、未検証です!! **内容をご確認の上、ご利用ください。 ** 故障探求の目で内容を確認してください。
ホストは Len = 0 を送信
デバイスは以下のデータを送信する。
NAME | TYPE | |
---|---|---|
dev type | uint8[16] | |
hdw_ver | uint16 | origin:11 means 1.1 |
app_ver | uint16 | origin:11 means 1.2 |
boot_ver | uint16 | |
run_area | uint16 | |
dev_sn | uint8[12] | |
year | uint16 | 壊れてる? |
moon | uint8 | 壊れてる? |
day | uint8 | 壊れてる? |
未テスト、おそらく
ホストはLen = 0を送信
デバイスは Len = 0 を送信
不明
未テスト、おそらく
ホストはLen = 0を送信
デバイスは Len = 0 を送信
不明、単純なデコンパイルでは関連情報が見つからなかった。
ホストが Len = 0 を送信
デバイスが送信
NAME | TYPE | 説明 |
---|---|---|
vin | uint16 | mV |
vout | uint16 | mV |
iout | uint16 | mA |
vo_max | uint16 | mV |
temp1 | uint16 | |
temp2 | int16 | |
dc 5V | uint16 | mV |
out mode | uint8 | この列挙は試していません |
work st | uint8 | この列挙は試していません |
これは基本情報の設定ではない。 BASIC_SETのリストがあり、10セットがデバイスに格納されている。
ホスト送信 len = 1
NAME | TYPE | |
---|---|---|
index | uint8 |
でBASIC_SETを問い合わせると、デバイスが応答する。
indexの上位4ビットはフラグで、以下のように定義される。
- index=0x80: アクティブなものを問い合わせる
ホスト送信 len = 10
BASIC_SETは以下のような構造になっている。
NAME | TYPE | 説明 |
---|---|---|
index | uint8 | |
state | uint8 | 0:off 1:on |
vo_set | uint16 | |
io_set | uint16 | |
ovp_set | uint16 | |
ocp_set | int16 |
- index=20: セットを変更する
- index=80: アクティブに設定
- index=a0: セットを変更,アクティブに設定
ホストがlen = 16を送信し、ペイロードがBASIC_SET
の場合、ホストはBASIC_SET
を設定するよう要求していることになる。
デバイスは次のように応答する。
NAME | TYPE | 説明 |
---|---|---|
result | uint8 | 1 = ok |
である。
ホストはLen = 0を送信
デバイスが送信
NAME | TYPE | 説明 |
---|---|---|
blk_lev | int8 | バックライトのレベル |
opp | uint16 | オーバーパワー |
opt | uint16 | 温度過昇 |
vol_lev | int8 | ビープ音の音量 |
不明
ホストは以下を送信する。
NAME | TYPE | 説明 |
---|---|---|
on_off | ?1 byte? | |
on_time | uint16 | |
out_val | uint16 | |
scan_mode | ?1 byte? | I / V |
start | uint16 | |
end | uint16 | |
step | uint16 |
デバイスは未テストを送信
この関数はよく理解されていないので、誰かが後でUIに対して言うだろう。
ホスト送信
NAME | TYPE | 説明 |
---|---|---|
on_off | uint8 | |
on_time | uint16 | |
ser_start | uint8 | |
ser_end | uint8 | |
ser_vi | uint16 | |
ser_vo | uint16 | |
cycle_times | uint8 |
デバイスは未テストを送信
テストされていない。
ホストはLen = 0を送信
デバイスは Len = 0 を送信
制御するサンプル作った
https://gist.github.com/GOROman/6881b1ef30364a584c37eb66fd605395