2016-05-02 11 views
2

組み込みシステム(STM32F4)で開発中で、単純なWindowsフォームクライアントPC側のプログラム。文字ベースの文字列形式を使用したときはすべてうまくいっていましたが、パフォーマンスを向上させるためにバイナリパッケージに変更したときに、エスケープ文字に問題が発生しました。バイナリパッケージのエスケープ文字(0x1b/27)がWi-Fi経由で送信されず、送信中にメッセージが破損する

私はnanopbを使用して送信用のGoogles Protocol Bufferを実装していますが、パッケージの5%で、クライアントプログラムで例外が発生し、パッケージが破損していることがわかりました。

私はWireSharkでデバッグし、この破損したパッケージでは、サイズが元のパッケージサイズより2〜4バイト小さいことがわかりました。さらに調べると、破損したパッケージには常にバイナリ値27が含まれており、他のパッケージにはこの値が含まれていないことが分かりました。私はそれを探して、この値がエスケープ文字を表し、これが問題につながる可能性があることを見出しました。

私が使用しているWi-Fiモジュールの技術文書(Gainspan GSM2100)には、コマンドの前にエスケープ文字があるので、私のパッケージでこの値を取り除く必要があると言われています。

私の問題の解決策を見つけることができなかったので、経験豊かな人がこの問題を解決する正しい方法に導くことができたらうれしいです。

答えて

2

どのようにデータを送信していますか?ライブラリを使用しているか、生のバイトを送信していますか? the manualによると、あなたのデータコマンドは、エスケープシーケンスを開始するだけでなく、持っている必要がありデータ長指定:データサイズに関する

// Each escape sequence starts with the ASCII character 27 (0x1B), 
// the equivalent to the ESC key. The contents of < > are a byte or byte stream. 
// - Cid is connection id (udp, tcp, etc) 
// - Data Length is 4 ASCII char represents decimal value 
// i.e. 1400 bytes would be '1' '4' '0' '0' (0x31 0x34 0x30 0x30). 
// - Data size must match with specified length. 
// Ignore all command or esc sequence in between data pay load. 
<Esc>Z<Cid><Data Length xxxx 4 ascii char><data> 

注発言:「データペイロードの間にあるすべてのコマンドまたはESCシーケンスを無視"

// Including a trailing 0 that snprintf insists to write 
uint8_t header[8]; 

// Prepare header: <esc> Z <cid> <ascii length> 
snprintf((char*)header, sizeof(header), "\x1bZ%x%04d", cid, len); 

// First, write the escape sequence up to the cid. After this, the 
// module responds with <ESC>O or <ESC>F. 
writeRaw(header, 3); 

if (!readDataResponse()) { 
    if (GS_LOG_ERRORS && this->error) 
     this->error->println("Sending bulk data frame failed"); 
    return false; 
} 

// Then, write the rest of the escape sequence (-1 to not write the 
// trailing 0) 
writeRaw(header + 3, sizeof(header) - 1 - 3);+ 

// And write the actual data 
writeRaw(buf, len); 

これべき最も可能性の高い仕事を:

例えば、これはGSCore::writeData function in GSCore.cppがどのように見えるかです。代わりに、汚れたハック送信する前にエスケープ文字をエスケープする、つまり送信する前に2つの文字(0x27 0x27)で各0x27を置き換えることができます - しかし、これは野生の推測であり、あなたは手動で確認する必要があります。

+0

私はライブラリnanopbを使用してデータをパックしています。ありがとう、私はあなたのアイデアを試し、それがうまくいったら報告します! – Unfixable

+1

ありがとうございました!データサイズに関するあなたの提案は、私を問題の根源に導いてくれました。前 私は Y リモートアドレスに変更: UCIDリモートアドレス: リモートポートIは、メッセージ・タイプを使用 リモート・ポート:<データ レン4桁 ASCII>。 データサイズを含めると、モジュールはそのエスケープ文字を実行できませんでした! – Unfixable

関連する問題