WYSE ThinOSにおけるrdpsndの動作について

113 views
Skip to first unread message

Hiroshi Kurokawa

unread,
Sep 6, 2019, 7:19:27 AM9/6/19
to 日本xrdpユーザ会 (The "xrdp" Users' Group Japan)
お世話になります。黒川と申します。

「xrdp-chansrvのデバッグ方法」のトピックにて報告致しました
xrdpをWyseクライアントから利用した際に
RDP: virtual channel rdpsnd error, rc = 0xffffffff
が出力され、セッションが切断されるエラーについて、
対処方法が判明しましたので報告させて戴きます。
なお、本件、xrdp-channsrvのデバッグ手法とは直接的には関係ないと思われましたので、
新しくトピックを立ち上げさせて戴きましたことご容赦ください。

対処方法ですが、
sesman/chansrv/sound.cの1217行目、
sound_send_server_input_formats();
の箇所をコメントアウトします。
この手順によりWyse ThinOSからxrdp経由でGnomeのセッションにログイン出来ます。

当該の函数内の処理ですが、
MessageIDがSNDC_REC_NEGOTIATEとなっているPDUを
クライアント側に送出する処理になります。
上記のMessageIDは、RDPの仕様書であるMS-RDPEA及びMS-RDPEAIには記載されておらず
xrdpやFreeRDP独自のMessageIDと思われます。

オーディオ入力の動作は当方は確認していませんが、
MS-RDPRAIの正しい手順に沿った処理は、
audin.cに記述されているようですので、SNDC_REC_NEGOTIATEを無効化しても問題は無いだろうと予測します。

ご確認お願い致します。

また、265行目からのsound_send_server_output_formats函数で
Server Audio Formats and Version PDUを送出しています。
戻り値としてClient Audio Formats and Version PDUがクライアントから返されますが
Wyseクライアントでは、wNumberOfFormatsが0となっているPDUが返されてしまいます。
そのため、Wyseクライアントでは、サウンドの再生に失敗します。
こちらについて、何かご存じの方いらっしゃいましたら、ご教授お願い致します。



meta

unread,
Sep 6, 2019, 9:07:02 AM9/6/19
to 日本xrdpユーザ会 (The "xrdp" Users' Group Japan)


2019年9月6日金曜日 20時19分27秒 UTC+9 Hiroshi Kurokawa:

当該の函数内の処理ですが、
MessageIDがSNDC_REC_NEGOTIATEとなっているPDUを
クライアント側に送出する処理になります。
上記のMessageIDは、RDPの仕様書であるMS-RDPEA及びMS-RDPEAIには記載されておらず
xrdpやFreeRDP独自のMessageIDと思われます。

この部分は、環境変数XRDP_NO_RDPSND_RECに適当な値をセットすることで無効化できます。
sesman.ini の末尾でセッションの環境変数がセットできますので、お試しください。

Hiroshi Kurokawa

unread,
Sep 6, 2019, 11:29:19 AM9/6/19
to 日本xrdpユーザ会 (The "xrdp" Users' Group Japan)
ご連絡ありがとうございます。

XRDP_NO_RDPSND_REC=trueを
sesman.iniに追加して試しましたが、
この方法では
RDP: virtual channel rdpsnd error, rc = 0xffffffff
のエラーが発生してしまいます。

SNDC_REC_NEGOTIATE PDUは
sound_send_server_input_formats()関数内で生成されて
1493行目のsend_channel_data(g_rdpsnd_chan_id, s->data, bytes);
によりクライアントに送出されますが、
この処理はXRDP_NO_RDPSND_REC、およびg_rdpsnd_can_rec
の値に関わらず実行されてしまうようです。

なお、Wyseクライアントは、
当該の1493行目のsend_channel_data(g_rdpsnd_chan_id, s->data, bytes);
の実行を行うとエラーを出して接続を切断します。


2019年9月6日金曜日 22時07分02秒 UTC+9 meta:

meta

unread,
Sep 8, 2019, 9:53:11 PM9/8/19
to 日本xrdpユーザ会 (The "xrdp" Users' Group Japan)
2019年9月7日土曜日 0時29分19秒 UTC+9 Hiroshi Kurokawa:
ご連絡ありがとうございます。

XRDP_NO_RDPSND_REC=trueを
sesman.iniに追加して試しましたが、
この方法では
RDP: virtual channel rdpsnd error, rc = 0xffffffff
のエラーが発生してしまいます。

なるほど。このあたりはXRDP_NORDPSND_RECの実装が不十分ですね。
RDPプロトコルコンプライアントモードとして、RDPプロトコルに忠実な
応答をするスイッチを加える改修をする必要がありそうです。

ちなみに、FreeRDPですと以下のようなログが出て、知らないメッセージは
単に無視します。このあたりがWyseクライアントとの違いでしょうね。
切り分けて頂いたおかげで実装はそこまで難しくなさそうなので、upstreamで
対応してみます。

[09:06:10:365] [12598:0961d000] [INFO][com.freerdp.channels.rdpsnd.client] - Loaded mac backend for rdpsnd
[09:06:13:860] [12598:0961d000] [ERROR][com.freerdp.channels.rdpsnd.client] - unknown msgType 39

Hiroshi Kurokawa

unread,
Sep 10, 2019, 11:50:12 AM9/10/19
to 日本xrdpユーザ会 (The "xrdp" Users' Group Japan)

また、265行目からのsound_send_server_output_formats函数で
Server Audio Formats and Version PDUを送出しています。
戻り値としてClient Audio Formats and Version PDUがクライアントから返されますが
Wyseクライアントでは、wNumberOfFormatsが0となっているPDUが返されてしまいます。
そのため、Wyseクライアントでは、サウンドの再生に失敗します。

こちらについても原因が判明しました。
sound_send_server_output_formats函数で
関数内で生成されるPDUの代わりに
Windows10のRDPサーバーから送出されるServer Audio Formats and Version PDUを
Wyseクライアントに投げ、返されるPDUを観察しましたら、
下記のようなログを得ました。
xrdp-chansrv [0450248578]: sound_process_output_format:
xrdp-chansrv [0450248578]:       wFormatTag      2
xrdp-chansrv [0450248578]:       nChannels       2
xrdp-chansrv [0450248578]:       nSamplesPerSec  44100
xrdp-chansrv [0450248578]:       nAvgBytesPerSec 44359
xrdp-chansrv [0450248578]:       nBlockAlign     2048
xrdp-chansrv [0450248578]:       wBitsPerSample  4
xrdp-chansrv [0450248578]:       cbSize          32
0000 f4 07 07 00 00 01 00 00 00 02 00 ff 00 00 00 00 ................
0010 c0 00 40 00 f0 00 00 00 cc 01 30 ff 88 01 18 ff ..@.......0.....
xrdp-chansrv [0450248578]: sound_process_output_format:
xrdp-chansrv [0450248578]:       wFormatTag      2
xrdp-chansrv [0450248578]:       nChannels       2
xrdp-chansrv [0450248578]:       nSamplesPerSec  22050
xrdp-chansrv [0450248578]:       nAvgBytesPerSec 22311
xrdp-chansrv [0450248578]:       nBlockAlign     1024
xrdp-chansrv [0450248578]:       wBitsPerSample  4
xrdp-chansrv [0450248578]:       cbSize          32
0000 f4 03 07 00 00 01 00 00 00 02 00 ff 00 00 00 00 ................
0010 c0 00 40 00 f0 00 00 00 cc 01 30 ff 88 01 18 ff ..@.......0.....
xrdp-chansrv [0450248578]: sound_process_output_format:
xrdp-chansrv [0450248578]:       wFormatTag      2
xrdp-chansrv [0450248578]:       nChannels       1
xrdp-chansrv [0450248578]:       nSamplesPerSec  44100
xrdp-chansrv [0450248578]:       nAvgBytesPerSec 22179
xrdp-chansrv [0450248578]:       nBlockAlign     1024
xrdp-chansrv [0450248578]:       wBitsPerSample  4
xrdp-chansrv [0450248578]:       cbSize          32
0000 f4 07 07 00 00 01 00 00 00 02 00 ff 00 00 00 00 ................
0010 c0 00 40 00 f0 00 00 00 cc 01 30 ff 88 01 18 ff ..@.......0.....
xrdp-chansrv [0450248578]: sound_process_output_format:
xrdp-chansrv [0450248578]:       wFormatTag      2
xrdp-chansrv [0450248578]:       nChannels       2
xrdp-chansrv [0450248578]:       nSamplesPerSec  11025
xrdp-chansrv [0450248578]:       nAvgBytesPerSec 11289
xrdp-chansrv [0450248578]:       nBlockAlign     512
xrdp-chansrv [0450248578]:       wBitsPerSample  4
xrdp-chansrv [0450248578]:       cbSize          32
0000 f4 01 07 00 00 01 00 00 00 02 00 ff 00 00 00 00 ................
0010 c0 00 40 00 f0 00 00 00 cc 01 30 ff 88 01 18 ff ..@.......0.....
xrdp-chansrv [0450248578]: sound_process_output_format:
xrdp-chansrv [0450248578]:       wFormatTag      2
xrdp-chansrv [0450248578]:       nChannels       1
xrdp-chansrv [0450248578]:       nSamplesPerSec  22050
xrdp-chansrv [0450248578]:       nAvgBytesPerSec 11155
xrdp-chansrv [0450248578]:       nBlockAlign     512
xrdp-chansrv [0450248578]:       wBitsPerSample  4
xrdp-chansrv [0450248578]:       cbSize          32
0000 f4 03 07 00 00 01 00 00 00 02 00 ff 00 00 00 00 ................
0010 c0 00 40 00 f0 00 00 00 cc 01 30 ff 88 01 18 ff ..@.......0.....
xrdp-chansrv [0450248578]: sound_process_output_format:
xrdp-chansrv [0450248578]:       wFormatTag      2
xrdp-chansrv [0450248578]:       nChannels       2
xrdp-chansrv [0450248578]:       nSamplesPerSec  8000
xrdp-chansrv [0450248578]:       nAvgBytesPerSec 8192
xrdp-chansrv [0450248578]:       nBlockAlign     512
xrdp-chansrv [0450248578]:       wBitsPerSample  4
xrdp-chansrv [0450248578]:       cbSize          32
0000 f4 01 07 00 00 01 00 00 00 02 00 ff 00 00 00 00 ................
0010 c0 00 40 00 f0 00 00 00 cc 01 30 ff 88 01 18 ff ..@.......0.....
xrdp-chansrv [0450248578]: sound_process_output_format:
xrdp-chansrv [0450248578]:       wFormatTag      2
xrdp-chansrv [0450248578]:       nChannels       1
xrdp-chansrv [0450248578]:       nSamplesPerSec  11025
xrdp-chansrv [0450248578]:       nAvgBytesPerSec 5644
xrdp-chansrv [0450248578]:       nBlockAlign     256
xrdp-chansrv [0450248578]:       wBitsPerSample  4
xrdp-chansrv [0450248578]:       cbSize          32
0000 f4 01 07 00 00 01 00 00 00 02 00 ff 00 00 00 00 ................
0010 c0 00 40 00 f0 00 00 00 cc 01 30 ff 88 01 18 ff ..@.......0.....
xrdp-chansrv [0450248578]: sound_process_output_format:
xrdp-chansrv [0450248578]:       wFormatTag      2
xrdp-chansrv [0450248578]:       nChannels       1
xrdp-chansrv [0450248578]:       nSamplesPerSec  8000
xrdp-chansrv [0450248578]:       nAvgBytesPerSec 4096
xrdp-chansrv [0450248578]:       nBlockAlign     256
xrdp-chansrv [0450248578]:       wBitsPerSample  4
xrdp-chansrv [0450248578]:       cbSize          32
0000 f4 01 07 00 00 01 00 00 00 02 00 ff 00 00 00 00 ................
0010 c0 00 40 00 f0 00 00 00 cc 01 30 ff 88 01 18 ff ..@.......0.....

Wyseクライアントは、ADPCMのみ対応しているようです。
一方でxrdpでは、現状、ADPCMの入出力に対応していないため
Wyseクライアントではサウンドの再生に失敗するものと考えられます。

よろしくお願いいたします。

meta

unread,
Sep 11, 2019, 5:38:35 AM9/11/19
to 日本xrdpユーザ会 (The "xrdp" Users' Group Japan)
2019年9月11日水曜日 0時50分12秒 UTC+9 Hiroshi Kurokawa:

Wyseクライアントは、ADPCMのみ対応しているようです。
一方でxrdpでは、現状、ADPCMの入出力に対応していないため
Wyseクライアントではサウンドの再生に失敗するものと考えられます。

よろしくお願いいたします。

outputの方も調査ありがとうございます。MSのドキュメントでも、
Codecのやり取りの仕様は書かれていても実装すべきCodecについては
私の知る限り特に言及がないのが困ったところです。

LPCMなら殆どのクライアントで対応しているだろうという仮定が
あったのですが、ADPCMのみ対応なのですね。

ADPCMをいつ実装できるかはわかりませんが、TODOですね。
ところで、Wyseには詳しくないのですが対応Codecが機種ごとに
異なるということはなく、全てまたは多くのThinOSでADPCMのみ
というものなのでしょうか。

Hiroshi Kurokawa

unread,
Sep 11, 2019, 11:30:45 AM9/11/19
to 日本xrdpユーザ会 (The "xrdp" Users' Group Japan)
ご連絡ありがとうございます。
 
outputの方も調査ありがとうございます。MSのドキュメントでも、
Codecのやり取りの仕様は書かれていても実装すべきCodecについては
私の知る限り特に言及がないのが困ったところです。

こちらについては、MS-RDPEAの 2.2.2.1.1 Audio Format (AUDIO_FORMAT) に
 At a minimum, clients and servers MUST support WAVE_FORMAT_PCM (0x0001).
との記載がありますので、本来であればWyseクライアント側にも
Liner PCMは実装されていなければならないということになります。
ですので、本件についてはWyse側の責であるということになります。


ところで、Wyseには詳しくないのですが対応Codecが機種ごとに
異なるということはなく、全てまたは多くのThinOSでADPCMのみ
というものなのでしょうか。

こちらについては、私もWyseについて詳しいわけではないので、
詳細は分かりかねますが、
手持ちの2機種(Wyse C10LE(ThinOS8.3_109)及びWyse 3040(ThinOS8.4_105))にて
調査した結果、双方ともADPCMのみの対応のようです。
他の機種、他のOS等の状況について、ご存じの方がいらっしゃいましたら
ご教授お願い致します。

宜しくお願い致します。

meta

unread,
Sep 11, 2019, 10:03:11 PM9/11/19
to 日本xrdpユーザ会 (The "xrdp" Users' Group Japan)
2019年9月12日木曜日 0時30分45秒 UTC+9 Hiroshi Kurokawa:
こちらについては、MS-RDPEAの 2.2.2.1.1 Audio Format (AUDIO_FORMAT) に
 At a minimum, clients and servers MUST support WAVE_FORMAT_PCM (0x0001).
との記載がありますので、本来であればWyseクライアント側にも
Liner PCMは実装されていなければならないということになります。
ですので、本件についてはWyse側の責であるということになります

ひとまず、upstreamに記録はしておきました。

オーディオ転送のCodecについては、MP3・AAC・Opusをサポート
していますが、OpusはWindowsのmstsc.exeがサポートしておらず、
MP3とAACは特許問題があるためディストリビューションのデフォルトで
有効にされにくいという背景があります(MP3の特許は切れましたが)。

このため特許フリーのCodecとして、圧縮率はさほど高くなくても
ADPCMを代替のCodecとして追加しておいた方がいいのではないか
という話は出ています。LPCMをサポートしないWyseのためだけの
作業ではないので、実装するのは吝かではありませんが「時間があれば」
「いつかやる」程度の優先度です。

Hiroshi Kurokawa

unread,
Oct 1, 2019, 6:30:33 AM10/1/19
to 日本xrdpユーザ会 (The "xrdp" Users' Group Japan)
meta様

xrdp本家への連絡、有難う御座いました。

このため特許フリーのCodecとして、圧縮率はさほど高くなくても
ADPCMを代替のCodecとして追加しておいた方がいいのではないか
という話は出ています。LPCMをサポートしないWyseのためだけの
作業ではないので、実装するのは吝かではありませんが「時間があれば」
「いつかやる」程度の優先度です。

こちらの件、誠に差し出がましいこととは存じますが、
MicrosoftのADPCMの仕様書を参照しながら
c言語でADPCM <-> LinearPCMの相互変換を行うコードを記述致しました。
スタンドアロンでの動作は確認を行いましたが、
xrdp本体への組み込みと結合テストは未実施である事、ご承知おきください。

添付のmsadpcm.cが当該のコードになります。
当該のコードは、
「ADPCMへの圧縮処理」
「LinearPCMへの展開処理」
「RIFFヘッダのパースと生成処理」
が含まれており、スタンドアロンで動作の確認が出来るようになっております。
(引数として、入力ファイル名と、出力ファイル名を与えて実行します。
入力ファイルの内容に応じて、
圧縮処理を行うか、展開処理を行うか、自動的に判別し処理を行います)

開発はVisualStudio2019上で行い、
LinearPCM<->ADPCMの相互変換が正常に行われることを確認しました。
gcc 4.8.5@CentOS7.7で、コンパイルが通ることも確認しております。
xrdpのコード規約に準拠させたつもりですが、
仕様書に記載のある変数名に関しては、
仕様書の記載を優先し、camelCaseになっております。

LinearPCM->ADPCMへの圧縮処理は660行目までの各関数群となります。
当該の部分をsesman/chansrv/sound.cに組み込んだのち、
上位層でADPCMへの圧縮をサポートするように
sound_wave_compress_adpcm函数を呼び出すコードを記述すれば、
動作するのはないかと思われます。
同様に、661行目から931行目までのADPCM->LinearPCMの展開処理を
録音側(client -> xrdp server)のコードに組み込めば、
端末からの録音処理にも対応出来ると思われます。

圧縮処理と展開処理の実行には、やや、時間が掛かります。
XeonGold6132 * 2の実行環境下で
7分の長さの44100Hz-2chのwaveを圧縮するのにおおよそ1秒程度)
最小圧縮単位であるblockの処理は、各block毎に独立していますので、
圧縮処理は504行目、展開処理は819行目のforを並列化すれば高速化出来ます。
(例えば当該のループに#pragma omp parallel forを記述します)

何卒宜しくお願い致します。

黒川
msadpcm.c

meta

unread,
Oct 1, 2019, 8:29:26 AM10/1/19
to 日本xrdpユーザ会 (The "xrdp" Users' Group Japan)
これは大作をありがとうございます。ADPCM部分を自作されたのですね。
このままでも組み込めないことはないのですが、他のコードとの一貫性を考えるとちょっと
組み込み方に悩むところです。

私の方ではCodec部分は外部ライブラリにまかせて、sound_wave_compress_adpcm() といった
関数で外部ライブラリを呼び出して圧縮することを考えていました。

SoXというライブラリなら、複数のCodecに対応しているためそれほどコード行数を増やさず
また依存関係も最小限に2つ以上のCodecサポートを追加できます。

パフォーマンスについては検証していないのですが、ご自作のものとSoXとで比較してみたいですね。

Hiroshi Kurokawa

unread,
Oct 4, 2019, 4:16:29 AM10/4/19
to 日本xrdpユーザ会 (The "xrdp" Users' Group Japan)
meta様

SoXライブラリの活用を検討なされているとのお返事を戴いたなか、
差し出がましいことと存じましたが、
先の自作版のADPCM圧縮函数をxrdp本体に組み込み、
手元の環境で動作が確認出来ましたのでpatchを寄贈させて戴きます。
patchには、XRDP_NO_RDPSND_RECの振る舞いを厳密に処理するための
コードも含まれております。
また、スタンドアロン版のADPCM圧縮展開ソースにバグがありましたので、
併せて修正版も寄贈させて戴きます。

宜しければご検討、ご確認ください。
msadpcm.c
xrdp_adpcm_support.patch

meta

unread,
Oct 23, 2019, 3:32:54 AM10/23/19
to 日本xrdpユーザ会 (The "xrdp" Users' Group Japan)
黒川さん

ADPCM部分については、やはりSoXで行こうと思います。
黒川さん実装のものは多大に参考になりました。

ところで、MS-RDPEAIの方ですが、修正されましたので一度試してみてもらえますか?

configure時に --enable-rdpsndaudin をつけて明示的に指定しない限り、
標準の方のマイク入力(MS-RDPEAI)が使われます。つまり、デフォルトで
プロプライエタリ実装のマイク入力はデフォルトで無効です。

Hiroshi Kurokawa

unread,
Oct 23, 2019, 11:53:51 AM10/23/19
to 日本xrdpユーザ会 (The "xrdp" Users' Group Japan)
meta様

ご連絡戴き有難う御座いました。

--enable-rdpsndaudinを付けずにビルドし
WYSEクライアントからアクセスしたところ、正常にGnomeにログイン出来ました。
正しく修正されているものと思われます。

引き続き、SoX経由でのADPCMの対応の方、何卒宜しくお願い致します。

黒川
Reply all
Reply to author
Forward
0 new messages