0

Bluetooth プロトコルを解析するために Python コンストラクト ライブラリを使用しています。ライブラリのリンクはこちら

プロトコルは非常に複雑であるため、1 つの巨大な構造を構築する代わりに、解析を複数の段階に分割しました。今、私はすでに大きな生データをこの構造に解析しています:

Container({'CRC': 'd\xcbT',
 'CRC_OK': 1,
 'Channel': 38,
 'RSSI': 43,
 'access_addr': 2391391958L,
 'header': Container({'TxAdd': False, 'PDU_length': 34, 'PDU_Type': 'ADV_IND', 'RxAdd': False}),
 'payload': '2\x15\x00a\x02\x00\x02\x01\x06\x07\x03\x03\x18\x02\x18\x04\x18\x03\x19\x00\x02\x02\n\xfe\t\tAS-D1532'})

ご覧のとおり、ペイロードの長さは 34 である PDU_length として示されます。ペイロードには次の構造があります。

[最初の 6 オクテット: AdvertAddress][0 ~ 31 オクテットの残りのデータ: AdvertData]

しかし、ペイロードをスタンドアロン構造として解析し始めたとき、ペイロードの構成のコンテキストで長さ 34 を失いました。最初の 6 オクテクトを AdvertAddress として解析し、残りのデータを AdvertData としてグループ化する構造を作成するにはどうすればよいですか?

私の現在のソリューションは次のようになります。

length = len(payload) #I didn't use PDU_length but len(payload) gives me back 34 also.
ADVERT_PAYLOAD = Struct("ADVERT_PAYLOAD",
    Field("AdvertAddress",6),
    Field("AdvertData",length-6),
)
print ADVERT_PAYLOAD.parse(payload)

これにより、正しい出力が得られます。しかし、明らかにすべてのペイロードのサイズが 34 というわけではありません。この方法ではADVERT_PAYLOAD、新しいペイロードを解析する必要があるたびに構築する必要があります。

ドキュメントを何度も読みましたが、関連するものは見つかりませんでした。ペイロードの長さの知識を のコンテキストに渡す方法も、メソッドADVERT_PAYLOADに渡された引数の長さを取得するparse方法もありません。

たぶん、この問題の解決策はありません。それでは、ほとんどの人はそのようなプロトコル データをどのように解析するのでしょうか? ペイロードをさらに進めると、より多くの型に細分され、それらを解析するためのより小さな構成体が必要になります。さらに小さな構造を埋め込む小さな構造を埋め込んで、親構造を構築する必要がありますか? こんな大きなものをどうやって作るのか想像もつきません。

前もって感謝します。

4

1 に答える 1

1

GreedyRangechar のリストを取得し、JoinAdapterすべての char を結合します。

class JoinAdapter(Adapter):
    def _decode(self, obj, context):
        return "".join(obj)

ADVERT_PAYLOAD = Struct("ADVERT_PAYLOAD",
    Field("AdvertAddress",6),
    JoinAdapter(GreedyRange(Field("AdvertData", 1)))
)

payload = '2\x15\x00a\x02\x00\x02\x01\x06\x07\x03\x03\x18\x02\x18\x04\x18\x03\x19\x00\x02\x02\n\xfe\t\tAS-D1532'
print ADVERT_PAYLOAD.parse(payload)

出力:

Container:
    AdvertAddress = '2\x15\x00a\x02\x00'
    AdvertData = '\x02\x01\x06\x07\x03\x03\x18\x02\x18\x04\x18\x03\x19\x00\x02\x02\n\xfe\t\tAS-D1532'
于 2013-03-21T05:06:55.017 に答える