MWXライブラリの twe_twelite.network に NWK_LAYERED、 twe_twelite.network2 に NWK_SIMPLEを動作させることで、レイヤーツリーネット (TWELITE PAL, ARIAなど)のパケットを含む、さまざまな種類のパケットを受信、解釈できます。
ただし無線パケットは、同一チャネルであることと、同一アプリケーションIDであることが条件です。
setup(), loop()、受信パケットのコールバック関数 on_rx_packet()を記述しています。
これらのオブジェクトは pkt_handler.cpp で宣言され setup()中でpnew()により初期化されます。主にパケットのペイロード(データ)を解釈します。
mwx::pnew(g_pkt_pal);
mwx::pnew(g_pkt_apptwelite);
mwx::pnew(g_pkt_actsamples);
mwx::pnew(g_pkt_unknown);
2つのネットワークオブジェクトを生成しています。必ず the_twelite.networkにNWK_LAYEREDにします。
auto&& nwk_ly = the_twelite.network.use<NWK_LAYERED>();
auto&& nwk_sm = the_twelite.network2.use<NWK_SIMPLE>();
このサンプルではloop()の処理で重要なのは約1秒おきに行っている .refresh() 処理です。g_pkt_apptwelite().refresh()のみ重複チェッカのタイムアウト処理を行っています。それ以外のオブジェクトは何もしません。
if (TickTimer.available()) {
static unsigned t;
if (!(++t & 0x3FF)) {
g_pkt_pal.refresh();
g_pkt_apptwelite.refresh();
g_pkt_actsamples.refresh();
g_pkt_unknown.refresh();
}
}
このサンプルコードで最も重要な部分です。auto type = rx.get_network_type();によりパケットの種別を判定しています。
mwx::NETWORK::LAYERED : NWK_LAYERED レイヤーツリーネットのケット
mwx::NETWORK::SIMPLE : NWK_SIMPLEのパケット
mwx::NETWORK::NONE : ネットワークなし(App_Tweliteなど)
mwx::NETWORK::NONE の場合は、再送などで複数送信されうる同一パケットの重複チェッカ等の処理は MWX ライブラリ内部で行われません。これらの対応を記述する必要があります。本サンプルでは dup_checker.hpp, dup_checker.cpp を用意しています。
パケットの解釈はtsRxDataApp*をラップした packet_rx& オブジェクトを参照します。packet_rxクラス自体は特別な機能はなく、get_psRxDataApp()を用いてtsRxDataApp*から得られる一部の情報へのアクセス手段を定義しているのみです。
パケット解釈部分のインタフェースを統一する目的で定義しています。
analyze() : パケットのペイロードを解釈する。
refresh() : 1秒おきの処理を記述します。
さらにパケット解釈クラス(上記例 pkt_handler_apptwelite)には、メンバーオブジェクトの pkt が含まれます。実際のパケットの解釈部分は、pkt_???.cpp にある各々の analyze() の実装を参照してください。
pkt_???.hpp, pkt_???.cpp
パケット種別ごとのパケット解釈部 analyze() と、データ構造 data が定義されています。メンバーdataは、構造体ですがPktDataCommonの共通構造体を継承しています。この共通部を用いてパケットのデータのシリアル出力のコードを簡潔に記述しています。
PAL関連のパケットに対応します。PALのパケット構造は複雑なデータ構造を持っています。ここでは EASTL のコンテナを用いた実装を行っています。
_vect_pal_sensors : _pal_sensorオブジェクトのプール。このオブジェクトは instusive map で使用するための専用クラスです。
_map_pal_sensors : センサーデータを効率よく検索するための intrusive map 構造。
1パケット中の複数データに対して各々が追加されるたびに_vect_pal_sensors にエントリを確保して値を格納します。パケット中のすべてのデータを解釈した時点でセンサータイプをキーとした_map_pal_sensorsを構築します。
重複チェッカーを実装します。チェッカーの動作はテンプレート引数によってカスタマイズできます。
MODE : MODE_REJECT_SAME_SEQを指定すると、同じシーケンス番号のパケットを除外します。パケット順が並び変わるような場合に使用します。MODE_REJECT_OLDER_SEQはより新しい番号を採用します。
TIMEOUT_ms : 重複データベースの初期化を行う間隔です。1000と指定すると1秒経過したデータは抹消されます。直前では除外されていたパケットも、重複データベースの初期化されると再び採用されることになります。
N_ENTRIES : データ構造に最大確保される要素数です。
N_BUCKET_HASH : ハッシュ値の最大数です。素数を指定します。受信される無線ノードの種類をもとに決めます。
_mmap_entries : intrusive ハッシュ マルチ マップ構造です。検索キーは無線ノードのシリアル番号です。
_vect_pool : マップ構造で用いられる要素を固定数(N_ENTRIES)を確保します。
_ring_vecant_idx : _mmap_entries に利用されていない_vect_pool の要素を配列インデックス番号で管理します。リングバッファの構造で、要素を追加するときはリングバッファから値を一つ取り出し、削除するときはリングバッファに値を返します。
マルチマップ構造からデータを検索するには .equal_range() を呼び出します。得られた r はイテレータで、同一のシリアル番号の要素を列挙します。
各要素(_dup_checker_entry)にはタイムスタンプやシーケンス番号が記録されています。この値に従い重複を確認します。