+ tsmf: OSS initial suppot (not work yet)

* tsmf: fix video playback on FreeBSD (proper shared object name)
* tsmf: renamed args: audio->sys, audio-dev->dev
* audin: OSS fix, now it work
* cmdline: add syntax help for /audin, /rdpsnd, /tsmf
* add debug messages
This commit is contained in:
ivan-83
2015-03-17 05:10:58 +03:00
parent a2e0746f15
commit 94a7abd2af
17 changed files with 486 additions and 97 deletions

View File

@@ -52,7 +52,7 @@
typedef struct _AudinOSSDevice {
IAudinDevice iface;
FREERDP_DSP_CONTEXT* dsp_context;
FREERDP_DSP_CONTEXT *dsp_context;
HANDLE thread;
HANDLE stopEvent;
@@ -145,7 +145,8 @@ static void audin_oss_set_format(IAudinDevice *device, audinFormat *format, UINT
static void *audin_oss_thread_func(void *arg)
{
char dev_name[PATH_MAX] = "/dev/dsp";
int pcm_handle = -1;
char mixer_name[PATH_MAX] = "/dev/mixer";
int pcm_handle = -1, mixer_handle;
BYTE *buffer = NULL, *encoded_data;
int tmp, buffer_size, encoded_size;
AudinOSSDevice *oss = (AudinOSSDevice*)arg;
@@ -153,13 +154,28 @@ static void *audin_oss_thread_func(void *arg)
if (arg == NULL)
goto err_out;
if (oss->dev_unit != -1)
if (oss->dev_unit != -1) {
snprintf(dev_name, (PATH_MAX - 1), "/dev/dsp%i", oss->dev_unit);
snprintf(mixer_name, PATH_MAX - 1, "/dev/mixer%i", oss->dev_unit);
}
WLog_INFO(TAG, "open: %s", dev_name);
if ((pcm_handle = open(dev_name, O_RDONLY)) < 0) {
OSS_LOG_ERR("sound dev open failed", errno);
goto err_out;
}
/* Set rec volume to 100%. */
if ((mixer_handle = open(mixer_name, O_RDWR)) < 0) {
OSS_LOG_ERR("mixer open failed, not critical", errno);
} else {
tmp = (100 | (100 << 8));
if (ioctl(mixer_handle, MIXER_WRITE(SOUND_MIXER_MIC), &tmp) == -1)
OSS_LOG_ERR("WRITE_MIXER - SOUND_MIXER_MIC, not critical", errno);
tmp = (100 | (100 << 8));
if (ioctl(mixer_handle, MIXER_WRITE(SOUND_MIXER_RECLEV), &tmp) == -1)
OSS_LOG_ERR("WRITE_MIXER - SOUND_MIXER_RECLEV, not critical", errno);
close(mixer_handle);
}
#if 0 /* FreeBSD OSS implementation at this moment (2015.03) does not set PCM_CAP_INPUT flag. */
tmp = 0;
if (ioctl(pcm_handle, SNDCTL_DSP_GETCAPS, &tmp) == -1) {
@@ -220,13 +236,15 @@ static void *audin_oss_thread_func(void *arg)
encoded_size = buffer_size;
break;
}
if (0 != oss->receive(encoded_data, encoded_size, oss->user_data))
if (0 == oss->receive(encoded_data, encoded_size, oss->user_data))
break;
}
err_out:
if (pcm_handle != -1)
if (pcm_handle != -1) {
WLog_INFO(TAG, "close: %s", dev_name);
close(pcm_handle);
}
free(buffer);
ExitThread(0);

View File

@@ -158,14 +158,14 @@ static void rdpsnd_oss_set_format(rdpsndDevicePlugin *device, AUDIO_FORMAT *form
static void rdpsnd_oss_open_mixer(rdpsndOssPlugin *oss) {
int devmask = 0;
char mixer[PATH_MAX] = "/dev/mixer";
char mixer_name[PATH_MAX] = "/dev/mixer";
if (oss->mixer_handle != -1)
return;
if (oss->dev_unit != -1)
snprintf(mixer, PATH_MAX - 1, "/dev/mixer%i", oss->dev_unit);
if ((oss->mixer_handle = open(mixer, O_RDWR)) < 0) {
snprintf(mixer_name, PATH_MAX - 1, "/dev/mixer%i", oss->dev_unit);
if ((oss->mixer_handle = open(mixer_name, O_RDWR)) < 0) {
OSS_LOG_ERR("mixer open failed", errno);
oss->mixer_handle = -1;
return;
@@ -223,11 +223,13 @@ static void rdpsnd_oss_close(rdpsndDevicePlugin *device) {
return;
if (oss->pcm_handle != -1) {
WLog_INFO(TAG, "close: dsp");
close(oss->pcm_handle);
oss->pcm_handle = -1;
}
if (oss->mixer_handle != -1) {
WLog_INFO(TAG, "close: mixer");
close(oss->mixer_handle);
oss->mixer_handle = -1;
}
@@ -278,8 +280,8 @@ static void rdpsnd_oss_set_volume(rdpsndDevicePlugin *device, UINT32 value) {
if (device == NULL || oss->mixer_handle == -1)
return;
left = (value & 0xFFFF);
right = ((value >> 16) & 0xFFFF);
left = (((value & 0xFFFF) * 100) / 0xFFFF);
right = ((((value >> 16) & 0xFFFF) * 100) / 0xFFFF);
if (left < 0)
left = 0;

View File

@@ -62,6 +62,10 @@ if(WITH_GSTREAMER_0_10 OR WITH_GSTREAMER_1_0)
endif()
endif()
if(WITH_OSS)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "oss" "audio")
endif()
if(WITH_ALSA)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "alsa" "audio")
endif()

View File

@@ -68,8 +68,7 @@ static BOOL tsmf_alsa_open(ITSMFAudioDevice *audio, const char *device)
TSMFAlsaAudioDevice *alsa = (TSMFAlsaAudioDevice *) audio;
if(!device)
{
if(!alsa->device[0])
strncpy(alsa->device, "default", sizeof(alsa->device));
strncpy(alsa->device, "default", sizeof(alsa->device));
}
else
{

View File

@@ -25,6 +25,9 @@
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <err.h>
#include <errno.h>
#include <winpr/thread.h>
#include <gst/gst.h>
@@ -61,8 +64,8 @@ struct X11Handle
static const char* get_shm_id()
{
static char shm_id[64];
snprintf(shm_id, sizeof(shm_id), "com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId());
static char shm_id[128];
snprintf(shm_id, sizeof(shm_id), "/com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId());
return shm_id;
}
@@ -87,34 +90,25 @@ int tsmf_platform_create(TSMFGstreamerDecoder* decoder)
return -1;
hdl = calloc(1, sizeof(struct X11Handle));
if (!hdl)
{
if (!hdl) {
WLog_ERR(TAG, "Could not allocate handle.");
return -1;
}
decoder->platform = hdl;
hdl->shmid = shm_open(get_shm_id(), O_RDWR, PROT_READ | PROT_WRITE);;
if (hdl->shmid < 0)
{
WLog_ERR(TAG, "failed to get access to shared memory - shmget()");
hdl->shmid = shm_open(get_shm_id(), (O_RDWR | O_CREAT), (PROT_READ | PROT_WRITE));
if (hdl->shmid == -1) {
WLog_ERR(TAG, "failed to get access to shared memory - shmget(%s): %i - %s", get_shm_id(), errno, strerror(errno));
return -2;
}
else
{
hdl->xfwin = mmap(0, sizeof(void *), PROT_READ | PROT_WRITE, MAP_SHARED, hdl->shmid, 0);
}
if (hdl->xfwin == (int*)-1)
{
hdl->xfwin = mmap(0, sizeof(void *), PROT_READ | PROT_WRITE, MAP_SHARED, hdl->shmid, 0);
if (hdl->xfwin == MAP_FAILED) {
WLog_ERR(TAG, "shmat failed!");
return -3;
}
hdl->disp = XOpenDisplay(NULL);
if (!hdl->disp)
{
WLog_ERR(TAG, "Failed to open display");

View File

@@ -0,0 +1,32 @@
# FreeRDP: A Remote Desktop Protocol Implementation
# FreeRDP cmake build script
#
# Copyright (c) 2015 Rozhuk Ivan <rozhuk.im@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
define_channel_client_subsystem("tsmf" "oss" "audio")
set(${MODULE_PREFIX}_SRCS
tsmf_oss.c)
include_directories(..)
include_directories(${OSS_INCLUDE_DIRS})
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
target_link_libraries(${MODULE_NAME} freerdp ${OSS_LIBRARIES})
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH} EXPORT FreeRDPTargets)

View File

@@ -0,0 +1,233 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Video Redirection Virtual Channel - OSS Audio Device
*
* Copyright (c) 2015 Rozhuk Ivan <rozhuk.im@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <winpr/crt.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <limits.h>
#include <unistd.h>
#include <sys/soundcard.h>
#include <sys/ioctl.h>
#include <freerdp/types.h>
#include <freerdp/codec/dsp.h>
#include "tsmf_audio.h"
typedef struct _TSMFOSSAudioDevice {
ITSMFAudioDevice iface;
char dev_name[PATH_MAX];
int pcm_handle;
UINT32 sample_rate;
UINT32 channels;
UINT32 bits_per_sample;
UINT32 data_size_last;
} TSMFOssAudioDevice;
#define OSS_LOG_ERR(_text, _error) \
if (_error != 0) \
WLog_ERR(TAG, "%s: %i - %s", _text, _error, strerror(_error));
static BOOL tsmf_oss_open_device(TSMFOssAudioDevice *oss) {
int tmp;
int error;
if (oss == NULL || oss->pcm_handle != -1)
return FALSE;
if ((oss->pcm_handle = open(oss->dev_name, O_WRONLY)) < 0) {
OSS_LOG_ERR("sound dev open failed", errno);
oss->pcm_handle = -1;
return FALSE;
}
#if 0 /* FreeBSD OSS implementation at this moment (2015.03) does not set PCM_CAP_OUTPUT flag. */
tmp = 0;
if (ioctl(oss->pcm_handle, SNDCTL_DSP_GETCAPS, &mask) == -1) {
OSS_LOG_ERR("SNDCTL_DSP_GETCAPS failed, try ignory", errno);
} else if ((mask & PCM_CAP_OUTPUT) == 0) {
OSS_LOG_ERR("Device does not supports playback", EOPNOTSUPP);
close(oss->pcm_handle);
oss->pcm_handle = -1;
return FALSE;
}
#endif
tmp = 0;
if (ioctl(oss->pcm_handle, SNDCTL_DSP_GETFMTS, &tmp) == -1) {
OSS_LOG_ERR("SNDCTL_DSP_GETFMTS failed", errno);
close(oss->pcm_handle);
oss->pcm_handle = -1;
return FALSE;
}
if ((AFMT_S16_LE & tmp) == 0) {
OSS_LOG_ERR("SNDCTL_DSP_GETFMTS - AFMT_S16_LE", EOPNOTSUPP);
close(oss->pcm_handle);
oss->pcm_handle = -1;
return FALSE;
}
WLog_INFO(TAG, "open: %s", oss->dev_name);
return TRUE;
}
static BOOL tsmf_oss_open(ITSMFAudioDevice *audio, const char *device) {
TSMFOssAudioDevice *oss = (TSMFOssAudioDevice*)audio;
if (oss == NULL || oss->pcm_handle != -1)
return FALSE;
if (device == NULL) {
strncpy(oss->dev_name, "/dev/dsp", sizeof(oss->dev_name));
} else {
strncpy(oss->dev_name, device, sizeof(oss->dev_name));
}
return tsmf_oss_open_device(oss);
}
static BOOL tsmf_oss_set_format(ITSMFAudioDevice *audio, UINT32 sample_rate, UINT32 channels, UINT32 bits_per_sample) {
int tmp;
TSMFOssAudioDevice *oss = (TSMFOssAudioDevice*)audio;
WLog_INFO(TAG, "tsmf_oss_set_format");
if (oss == NULL || oss->pcm_handle == -1)
return FALSE;
oss->sample_rate = sample_rate;
oss->channels = channels;
oss->bits_per_sample = bits_per_sample;
tmp = AFMT_S16_LE;
if (ioctl(oss->pcm_handle, SNDCTL_DSP_SETFMT, &tmp) == -1)
OSS_LOG_ERR("SNDCTL_DSP_SETFMT failed", errno);
tmp = channels;
if (ioctl(oss->pcm_handle, SNDCTL_DSP_CHANNELS, &tmp) == -1)
OSS_LOG_ERR("SNDCTL_DSP_CHANNELS failed", errno);
tmp = bits_per_sample;
if (ioctl(oss->pcm_handle, SNDCTL_DSP_SPEED, &tmp) == -1)
OSS_LOG_ERR("SNDCTL_DSP_SPEED failed", errno);
tmp = 4096;//((bits_per_sample / 8) * channels * sample_rate);
if (ioctl(oss->pcm_handle, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1)
OSS_LOG_ERR("SNDCTL_DSP_SETFRAGMENT failed", errno);
DEBUG_TSMF("sample_rate %d channels %d bits_per_sample %d",
sample_rate, channels, bits_per_sample);
WLog_INFO(TAG, "tsmf_oss_set_format: sample_rate %d channels %d bits_per_sample %d",
sample_rate, channels, bits_per_sample);
return TRUE;
}
static BOOL tsmf_oss_play(ITSMFAudioDevice *audio, BYTE *data, UINT32 data_size) {
int status;
UINT32 offset;
TSMFOssAudioDevice *oss = (TSMFOssAudioDevice*)audio;
DEBUG_TSMF("tsmf_oss_play: data_size %d", data_size);
WLog_INFO(TAG, "tsmf_oss_play: data_size %d", data_size);
if (oss == NULL || oss->pcm_handle == -1)
return FALSE;
if (data == NULL || data_size == 0) {
free(data);
return TRUE;
}
offset = 0;
oss->data_size_last = data_size;
while (offset < data_size) {
status = write(oss->pcm_handle, &data[offset], (data_size - offset));
if (status < 0) {
OSS_LOG_ERR("write fail", errno);
free(data);
return FALSE;
}
offset += status;
}
WLog_INFO(TAG, "tsmf_oss_play");
free(data);
return TRUE;
}
static UINT64 tsmf_oss_get_latency(ITSMFAudioDevice *audio) {
UINT64 latency = 0;
TSMFOssAudioDevice *oss = (TSMFOssAudioDevice*)audio;
if (oss == NULL)
return 0;
//latency = ((oss->data_size_last / (oss->bits_per_sample / 8)) * oss->sample_rate);
WLog_INFO(TAG, "latency: %zu", latency);
return latency;
}
static void tsmf_oss_flush(ITSMFAudioDevice *audio)
{
}
static void tsmf_oss_free(ITSMFAudioDevice *audio) {
TSMFOssAudioDevice *oss = (TSMFOssAudioDevice*)audio;
if (oss == NULL)
return;
if (oss->pcm_handle != -1) {
WLog_INFO(TAG, "close: %s", oss->dev_name);
close(oss->pcm_handle);
}
free(oss);
}
#ifdef STATIC_CHANNELS
#define freerdp_tsmf_client_audio_subsystem_entry oss_freerdp_tsmf_client_audio_subsystem_entry
#endif
ITSMFAudioDevice *freerdp_tsmf_client_audio_subsystem_entry(void)
{
TSMFOssAudioDevice *oss;
oss = (TSMFOssAudioDevice*)malloc(sizeof(TSMFOssAudioDevice));
ZeroMemory(oss, sizeof(TSMFOssAudioDevice));
oss->iface.Open = tsmf_oss_open;
oss->iface.SetFormat = tsmf_oss_set_format;
oss->iface.Play = tsmf_oss_play;
oss->iface.GetLatency = tsmf_oss_get_latency;
oss->iface.Flush = tsmf_oss_flush;
oss->iface.Free = tsmf_oss_free;
oss->pcm_handle = -1;
return (ITSMFAudioDevice*)oss;
}

View File

@@ -45,10 +45,12 @@ static ITSMFAudioDevice* tsmf_load_audio_device_by_name(const char* name, const
return NULL;
}
if (!audio->Open(audio, device))
{
if (!audio->Open(audio, device)) {
audio->Free(audio);
audio = NULL;
WLog_ERR(TAG, "tsmf_load_audio_device_by_name: failed to open, name: %s, device: %s", name, device);
} else {
WLog_DBG(TAG, "tsmf_load_audio_device_by_name: name: %s, device: %s", name, device);
}
return audio;
@@ -56,7 +58,7 @@ static ITSMFAudioDevice* tsmf_load_audio_device_by_name(const char* name, const
ITSMFAudioDevice* tsmf_load_audio_device(const char* name, const char* device)
{
ITSMFAudioDevice* audio;
ITSMFAudioDevice* audio = NULL;
if (name)
{
@@ -64,10 +66,26 @@ ITSMFAudioDevice* tsmf_load_audio_device(const char* name, const char* device)
}
else
{
audio = tsmf_load_audio_device_by_name("pulse", device);
#if defined(WITH_PULSE)
if (!audio)
audio = tsmf_load_audio_device_by_name("pulse", device);
#endif
#if defined(WITH_OSS)
if (!audio)
audio = tsmf_load_audio_device_by_name("oss", device);
#endif
#if defined(WITH_ALSA)
if (!audio)
audio = tsmf_load_audio_device_by_name("alsa", device);
#endif
}
if (audio == NULL) {
WLog_ERR(TAG, "no sound device.");
} else {
WLog_DBG(TAG, "tsmf_load_audio_device: name: %s, device: %s", name, device);
}
return audio;

View File

@@ -362,8 +362,8 @@ static int tsmf_plugin_terminated(IWTSPlugin* pPlugin)
COMMAND_LINE_ARGUMENT_A tsmf_args[] =
{
{ "audio", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "audio subsystem" },
{ "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" },
{ "sys", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "audio subsystem" },
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" },
{ "decoder", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "decoder subsystem" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
@@ -386,11 +386,11 @@ static void tsmf_process_addin_args(IWTSPlugin *pPlugin, ADDIN_ARGV *args)
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
continue;
CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "audio")
CommandLineSwitchCase(arg, "sys")
{
tsmf->audio_name = _strdup(arg->Value);
}
CommandLineSwitchCase(arg, "audio-dev")
CommandLineSwitchCase(arg, "dev")
{
tsmf->audio_device = _strdup(arg->Value);
}

View File

@@ -425,13 +425,13 @@ static void tsmf_sample_playback_audio(TSMF_SAMPLE* sample)
DEBUG_TSMF("MessageId %d EndTime %d consumed.",
sample->sample_id, (int)sample->end_time);
if (sample->stream->audio && sample->data)
if (stream->audio && sample->data)
{
sample->stream->audio->Play(sample->stream->audio, sample->data, sample->decoded_size);
stream->audio->Play(stream->audio, sample->data, sample->decoded_size);
sample->data = NULL;
sample->decoded_size = 0;
if (stream->audio && stream->audio->GetLatency)
if (stream->audio->GetLatency)
latency = stream->audio->GetLatency(stream->audio);
}
else

View File

@@ -335,7 +335,7 @@ static void xf_SetWindowPID(xfContext* xfc, Window window, pid_t pid)
static const char* get_shm_id()
{
static char shm_id[64];
snprintf(shm_id, sizeof(shm_id), "com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId());
snprintf(shm_id, sizeof(shm_id), "/com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId());
return shm_id;
}
@@ -368,7 +368,7 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs);
window->shmid = shm_open(get_shm_id(), O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE);
window->shmid = shm_open(get_shm_id(), (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE));
if (window->shmid < 0)
{
@@ -382,7 +382,7 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int heig
mem = mmap(0, sizeof(window->handle), PROT_READ | PROT_WRITE, MAP_SHARED, window->shmid, 0);
if (mem == ((int*) -1))
if (mem == MAP_FAILED)
{
DEBUG_X11("xf_CreateDesktopWindow: failed to assign pointer to the memory address - shmat()\n");
}

View File

@@ -91,10 +91,10 @@ COMMAND_LINE_ARGUMENT_A args[] =
{ "compression-level", COMMAND_LINE_VALUE_REQUIRED, "<level>", NULL, NULL, -1, NULL, "Compression level (0,1,2)" },
{ "shell", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Alternate shell" },
{ "shell-dir", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Shell working directory" },
{ "sound", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, "audio", "Audio output (sound)" },
{ "microphone", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, "mic", "Audio input (microphone)" },
{ "sound", COMMAND_LINE_VALUE_OPTIONAL, "[sys][dev][format][rate][channel][latency][quality]", NULL, NULL, -1, "audio", "Audio output (sound)" },
{ "microphone", COMMAND_LINE_VALUE_OPTIONAL, "[sys][dev][format][rate][channel]", NULL, NULL, -1, "mic", "Audio input (microphone)" },
{ "audio-mode", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Audio output mode" },
{ "multimedia", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, "mmr", "Redirect multimedia (video)" },
{ "multimedia", COMMAND_LINE_VALUE_OPTIONAL, "[sys][dev][decoder]", NULL, NULL, -1, "mmr", "Redirect multimedia (video)" },
{ "network", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Network connection type" },
{ "drive", COMMAND_LINE_VALUE_REQUIRED, NULL, NULL, NULL, -1, NULL, "Redirect drive" },
{ "drives", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Redirect all drives" },
@@ -264,10 +264,13 @@ int freerdp_client_print_command_line_help(int argc, char** argv)
printf("Printer Redirection: /printer:<device>,<driver>\n");
printf("\n");
printf("Audio Output Redirection: /sound:sys:oss,dev:1,format:1\n");
printf("Audio Output Redirection: /sound:sys:alsa\n");
printf("Audio Input Redirection: /microphone:sys:oss,dev:1,format:1\n");
printf("Audio Input Redirection: /microphone:sys:alsa\n");
printf("\n");
printf("Multimedia Redirection: /multimedia:sys:oss,dev:/dev/dsp1,decoder:ffmpeg\n");
printf("Multimedia Redirection: /multimedia:sys:alsa\n");
printf("USB Device Redirection: /usb:id,dev:054c:0268\n");
printf("\n");

View File

@@ -262,25 +262,31 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
switch (updateCode)
{
case FASTPATH_UPDATETYPE_ORDERS:
if (!fastpath_recv_orders(fastpath, s))
if (!fastpath_recv_orders(fastpath, s)) {
WLog_DBG(TAG, "fastpath_recv_update: FASTPATH_UPDATETYPE_ORDERS - fastpath_recv_orders()");
return -1;
}
break;
case FASTPATH_UPDATETYPE_BITMAP:
case FASTPATH_UPDATETYPE_PALETTE:
if (!fastpath_recv_update_common(fastpath, s))
if (!fastpath_recv_update_common(fastpath, s)) {
WLog_DBG(TAG, "fastpath_recv_update: FASTPATH_UPDATETYPE_ORDERS - fastpath_recv_orders()");
return -1;
}
break;
case FASTPATH_UPDATETYPE_SYNCHRONIZE:
if (!fastpath_recv_update_synchronize(fastpath, s))
WLog_ERR(TAG, "fastpath_recv_update_synchronize failure but we continue");
WLog_ERR(TAG, "fastpath_recv_update: fastpath_recv_update_synchronize failure but we continue");
else
IFCALL(update->Synchronize, context);
break;
case FASTPATH_UPDATETYPE_SURFCMDS:
status = update_recv_surfcmds(update, size, s);
if (status < 0)
WLog_DBG(TAG, "fastpath_recv_update: FASTPATH_UPDATETYPE_SURFCMDS - update_recv_surfcmds() - %i", status);
break;
case FASTPATH_UPDATETYPE_PTR_NULL:
@@ -291,30 +297,37 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 s
case FASTPATH_UPDATETYPE_PTR_DEFAULT:
update->pointer->pointer_system.type = SYSPTR_DEFAULT;
IFCALL(pointer->PointerSystem, context, &pointer->pointer_system);
break;
case FASTPATH_UPDATETYPE_PTR_POSITION:
if (!update_read_pointer_position(s, &pointer->pointer_position))
if (!update_read_pointer_position(s, &pointer->pointer_position)) {
WLog_DBG(TAG, "fastpath_recv_update: FASTPATH_UPDATETYPE_PTR_POSITION - update_read_pointer_position()");
return -1;
}
IFCALL(pointer->PointerPosition, context, &pointer->pointer_position);
break;
case FASTPATH_UPDATETYPE_COLOR:
if (!update_read_pointer_color(s, &pointer->pointer_color, 24))
if (!update_read_pointer_color(s, &pointer->pointer_color, 24)) {
WLog_DBG(TAG, "fastpath_recv_update: FASTPATH_UPDATETYPE_COLOR - update_read_pointer_color()");
return -1;
}
IFCALL(pointer->PointerColor, context, &pointer->pointer_color);
break;
case FASTPATH_UPDATETYPE_CACHED:
if (!update_read_pointer_cached(s, &pointer->pointer_cached))
if (!update_read_pointer_cached(s, &pointer->pointer_cached)) {
WLog_DBG(TAG, "fastpath_recv_update: FASTPATH_UPDATETYPE_CACHED - update_read_pointer_cached()");
return -1;
}
IFCALL(pointer->PointerCached, context, &pointer->pointer_cached);
break;
case FASTPATH_UPDATETYPE_POINTER:
if (!update_read_pointer_new(s, &pointer->pointer_new))
if (!update_read_pointer_new(s, &pointer->pointer_new)) {
WLog_DBG(TAG, "fastpath_recv_update: FASTPATH_UPDATETYPE_POINTER - update_read_pointer_new()");
return -1;
}
IFCALL(pointer->PointerNew, context, &pointer->pointer_new);
break;
@@ -370,8 +383,10 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
Stream_Read_UINT16(s, size);
if (Stream_GetRemainingLength(s) < size)
if (Stream_GetRemainingLength(s) < size) {
WLog_DBG(TAG, "fastpath_recv_update_data: Stream_GetRemainingLength() < size");
return -1;
}
cs = s;
next_pos = Stream_GetPosition(s) + size;
@@ -380,7 +395,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
if (bulkStatus < 0)
{
WLog_ERR(TAG, "bulk_decompress() failed");
WLog_ERR(TAG, "fastpath_recv_update_data: bulk_decompress() failed");
return -1;
}
@@ -402,15 +417,17 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
{
if (fastpath->fragmentation != -1)
{
WLog_ERR(TAG, "Unexpected FASTPATH_FRAGMENT_SINGLE");
WLog_ERR(TAG, "fastpath_recv_update_data: Unexpected FASTPATH_FRAGMENT_SINGLE");
goto out_fail;
}
totalSize = size;
status = fastpath_recv_update(fastpath, updateCode, totalSize, cs);
if (status < 0)
if (status < 0) {
WLog_DBG(TAG, "fastpath_recv_update_data: fastpath_recv_update() - %i", status);
goto out_fail;
}
}
else
{
@@ -418,7 +435,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
{
if (fastpath->fragmentation != -1)
{
WLog_ERR(TAG, "Unexpected FASTPATH_FRAGMENT_FIRST");
WLog_ERR(TAG, "fastpath_recv_update_data: Unexpected FASTPATH_FRAGMENT_FIRST");
goto out_fail;
}
@@ -428,7 +445,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
if (totalSize > transport->settings->MultifragMaxRequestSize)
{
WLog_ERR(TAG, "Total size (%d) exceeds MultifragMaxRequestSize (%d)",
WLog_ERR(TAG, "fastpath_recv_update_data: Total size (%d) exceeds MultifragMaxRequestSize (%d)",
totalSize, transport->settings->MultifragMaxRequestSize);
goto out_fail;
}
@@ -445,7 +462,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
if ((fastpath->fragmentation != FASTPATH_FRAGMENT_FIRST) &&
(fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT))
{
WLog_ERR(TAG, "Unexpected FASTPATH_FRAGMENT_NEXT");
WLog_ERR(TAG, "fastpath_recv_update_data: Unexpected FASTPATH_FRAGMENT_NEXT");
goto out_fail;
}
@@ -455,7 +472,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
if (totalSize > transport->settings->MultifragMaxRequestSize)
{
WLog_ERR(TAG, "Total size (%d) exceeds MultifragMaxRequestSize (%d)",
WLog_ERR(TAG, "fastpath_recv_update_data: Total size (%d) exceeds MultifragMaxRequestSize (%d)",
totalSize, transport->settings->MultifragMaxRequestSize);
goto out_fail;
}
@@ -473,7 +490,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
if ((fastpath->fragmentation != FASTPATH_FRAGMENT_FIRST) &&
(fastpath->fragmentation != FASTPATH_FRAGMENT_NEXT))
{
WLog_ERR(TAG, "Unexpected FASTPATH_FRAGMENT_LAST");
WLog_ERR(TAG, "fastpath_recv_update_data: Unexpected FASTPATH_FRAGMENT_LAST");
goto out_fail;
}
@@ -483,7 +500,7 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
if (totalSize > transport->settings->MultifragMaxRequestSize)
{
WLog_ERR(TAG, "Total size (%d) exceeds MultifragMaxRequestSize (%d)",
WLog_ERR(TAG, "fastpath_recv_update_data: Total size (%d) exceeds MultifragMaxRequestSize (%d)",
totalSize, transport->settings->MultifragMaxRequestSize);
goto out_fail;
}
@@ -503,8 +520,10 @@ static int fastpath_recv_update_data(rdpFastPath* fastpath, wStream* s)
Stream_Release(fastpath->updateData);
if (status < 0)
if (status < 0) {
WLog_DBG(TAG, "fastpath_recv_update_data: fastpath_recv_update() - %i", status);
goto out_fail;
}
}
}
@@ -526,20 +545,21 @@ out_fail:
int fastpath_recv_updates(rdpFastPath* fastpath, wStream* s)
{
int status = 0;
rdpUpdate* update = fastpath->rdp->update;
IFCALL(update->BeginPaint, update->context);
while (Stream_GetRemainingLength(s) >= 3)
{
if (fastpath_recv_update_data(fastpath, s) < 0)
if (fastpath_recv_update_data(fastpath, s) < 0) {
WLog_DBG(TAG, "fastpath_recv_updates: fastpath_recv_update_data() fail");
return -1;
}
}
IFCALL(update->EndPaint, update->context);
return status;
return 0;
}
static BOOL fastpath_read_input_event_header(wStream* s, BYTE* eventFlags, BYTE* eventCode)

View File

@@ -210,6 +210,7 @@ BOOL freerdp_check_fds(freerdp* instance)
TerminateEventArgs e;
rdpContext* context = instance->context;
WLog_DBG(TAG, "freerdp_check_fds: rdp_check_fds() - %i", status);
EventArgsInit(&e, "freerdp");
e.code = 0;
PubSub_OnTerminate(context->pubSub, context, &e);
@@ -243,10 +244,16 @@ BOOL freerdp_check_event_handles(rdpContext* context)
status = freerdp_check_fds(context->instance);
if (!status)
if (!status) {
WLog_DBG(TAG, "freerdp_check_event_handles: freerdp_check_fds() - %i", status);
return FALSE;
}
status = freerdp_channels_check_fds(context->channels, context->instance);
if (!status) {
WLog_DBG(TAG, "freerdp_check_event_handles: freerdp_channels_check_fds() - %i", status);
return FALSE;
}
return status;
}

View File

@@ -458,8 +458,10 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
switch (rdp->state)
{
case CONNECTION_STATE_INITIAL:
if (!rdp_server_accept_nego(rdp, s))
if (!rdp_server_accept_nego(rdp, s)) {
WLog_DBG(TAG, "peer_recv_callback: CONNECTION_STATE_INITIAL - rdp_server_accept_nego() fail");
return -1;
}
if (rdp->nego->SelectedProtocol & PROTOCOL_NLA)
{
@@ -476,30 +478,40 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
break;
case CONNECTION_STATE_NEGO:
if (!rdp_server_accept_mcs_connect_initial(rdp, s))
if (!rdp_server_accept_mcs_connect_initial(rdp, s)) {
WLog_DBG(TAG, "peer_recv_callback: CONNECTION_STATE_NEGO - rdp_server_accept_mcs_connect_initial() fail");
return -1;
}
break;
case CONNECTION_STATE_MCS_CONNECT:
if (!rdp_server_accept_mcs_erect_domain_request(rdp, s))
if (!rdp_server_accept_mcs_erect_domain_request(rdp, s)) {
WLog_DBG(TAG, "peer_recv_callback: CONNECTION_STATE_MCS_CONNECT - rdp_server_accept_mcs_erect_domain_request() fail");
return -1;
}
break;
case CONNECTION_STATE_MCS_ERECT_DOMAIN:
if (!rdp_server_accept_mcs_attach_user_request(rdp, s))
if (!rdp_server_accept_mcs_attach_user_request(rdp, s)) {
WLog_DBG(TAG, "peer_recv_callback: CONNECTION_STATE_MCS_ERECT_DOMAIN - rdp_server_accept_mcs_attach_user_request() fail");
return -1;
}
break;
case CONNECTION_STATE_MCS_ATTACH_USER:
if (!rdp_server_accept_mcs_channel_join_request(rdp, s))
if (!rdp_server_accept_mcs_channel_join_request(rdp, s)) {
WLog_DBG(TAG, "peer_recv_callback: CONNECTION_STATE_MCS_ATTACH_USER - rdp_server_accept_mcs_channel_join_request() fail");
return -1;
}
break;
case CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT:
if (rdp->settings->UseRdpSecurityLayer)
{
if (!rdp_server_establish_keys(rdp, s))
if (!rdp_server_establish_keys(rdp, s)) {
WLog_DBG(TAG, "peer_recv_callback: CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT - rdp_server_establish_keys() fail");
return -1;
}
}
rdp_server_transition_to_state(rdp, CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE);
@@ -508,9 +520,10 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
break;
case CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE:
if (!rdp_recv_client_info(rdp, s))
if (!rdp_recv_client_info(rdp, s)) {
WLog_DBG(TAG, "peer_recv_callback: CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE - rdp_recv_client_info() fail");
return -1;
}
rdp_server_transition_to_state(rdp, CONNECTION_STATE_LICENSING);
return peer_recv_callback(transport, NULL, extra);
@@ -518,9 +531,10 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
break;
case CONNECTION_STATE_LICENSING:
if (!license_send_valid_client_error_packet(rdp->license))
if (!license_send_valid_client_error_packet(rdp->license)) {
WLog_DBG(TAG, "peer_recv_callback: CONNECTION_STATE_LICENSING - license_send_valid_client_error_packet() fail");
return FALSE;
}
rdp_server_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE);
return peer_recv_callback(transport, NULL, extra);
@@ -533,15 +547,19 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
{
IFCALL(client->Capabilities, client);
if (!rdp_send_demand_active(rdp))
if (!rdp_send_demand_active(rdp)) {
WLog_DBG(TAG, "peer_recv_callback: CONNECTION_STATE_CAPABILITIES_EXCHANGE - rdp_send_demand_active() fail");
return -1;
}
rdp->AwaitCapabilities = TRUE;
if (s)
{
if (peer_recv_pdu(client, s) < 0)
if (peer_recv_pdu(client, s) < 0) {
WLog_DBG(TAG, "peer_recv_callback: CONNECTION_STATE_CAPABILITIES_EXCHANGE - peer_recv_pdu() fail");
return -1;
}
}
}
else
@@ -551,20 +569,26 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
* before receiving the Deactivate All PDU. We need to process them as usual.
*/
if (peer_recv_pdu(client, s) < 0)
if (peer_recv_pdu(client, s) < 0) {
WLog_DBG(TAG, "peer_recv_callback: CONNECTION_STATE_CAPABILITIES_EXCHANGE - peer_recv_pdu() fail");
return -1;
}
}
break;
case CONNECTION_STATE_FINALIZATION:
if (peer_recv_pdu(client, s) < 0)
if (peer_recv_pdu(client, s) < 0) {
WLog_DBG(TAG, "peer_recv_callback: CONNECTION_STATE_FINALIZATION - peer_recv_pdu() fail");
return -1;
}
break;
case CONNECTION_STATE_ACTIVE:
if (peer_recv_pdu(client, s) < 0)
if (peer_recv_pdu(client, s) < 0) {
WLog_DBG(TAG, "peer_recv_callback: CONNECTION_STATE_ACTIVE - peer_recv_pdu() fail");
return -1;
}
break;
default:

View File

@@ -1077,7 +1077,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
if (!rdp_read_header(rdp, s, &length, &channelId))
{
WLog_ERR(TAG, "Incorrect RDP header.");
WLog_ERR(TAG, "rdp_recv_tpkt_pdu: Incorrect RDP header.");
return -1;
}
@@ -1091,14 +1091,16 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
if (rdp->settings->UseRdpSecurityLayer)
{
if (!rdp_read_security_header(s, &securityFlags))
if (!rdp_read_security_header(s, &securityFlags)) {
WLog_DBG(TAG, "rdp_recv_tpkt_pdu: rdp_read_security_header() fail");
return -1;
}
if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT))
{
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
{
WLog_ERR(TAG, "rdp_decrypt failed");
WLog_ERR(TAG, "rdp_recv_tpkt_pdu: rdp_decrypt failed");
return -1;
}
}
@@ -1121,8 +1123,10 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
{
nextPosition = Stream_GetPosition(s);
if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource)) {
WLog_DBG(TAG, "rdp_recv_tpkt_pdu: rdp_read_share_control_header() fail");
return -1;
}
nextPosition += pduLength;
@@ -1139,8 +1143,10 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
break;
case PDU_TYPE_DEACTIVATE_ALL:
if (!rdp_recv_deactivate_all(rdp, s))
if (!rdp_recv_deactivate_all(rdp, s)) {
WLog_DBG(TAG, "rdp_recv_tpkt_pdu: rdp_recv_deactivate_all() fail");
return -1;
}
break;
case PDU_TYPE_SERVER_REDIRECTION:
@@ -1166,8 +1172,10 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
}
else
{
if (!freerdp_channel_process(rdp->instance, s, channelId))
if (!freerdp_channel_process(rdp->instance, s, channelId)) {
WLog_DBG(TAG, "rdp_recv_tpkt_pdu: freerdp_channel_process() fail");
return -1;
}
}
return 0;
@@ -1180,8 +1188,10 @@ static int rdp_recv_fastpath_pdu(rdpRdp* rdp, wStream* s)
fastpath = rdp->fastpath;
if (!fastpath_read_header_rdp(fastpath, s, &length))
if (!fastpath_read_header_rdp(fastpath, s, &length)) {
WLog_DBG(TAG, "rdp_recv_fastpath_pdu: fastpath_read_header_rdp() fail");
return -1;
}
if ((length == 0) || (length > Stream_GetRemainingLength(s)))
{
@@ -1198,8 +1208,10 @@ static int rdp_recv_fastpath_pdu(rdpRdp* rdp, wStream* s)
{
UINT16 flags = (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM) ? SEC_SECURE_CHECKSUM : 0;
if (!rdp_decrypt(rdp, s, length, flags))
if (!rdp_decrypt(rdp, s, length, flags)) {
WLog_DBG(TAG, "rdp_recv_fastpath_pdu: rdp_decrypt() fail");
return -1;
}
}
return fastpath_recv_updates(rdp->fastpath, s);
@@ -1233,8 +1245,10 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
switch (rdp->state)
{
case CONNECTION_STATE_NLA:
if (nla_recv_pdu(rdp->nla, s) < 1)
if (nla_recv_pdu(rdp->nla, s) < 1) {
WLog_DBG(TAG, "rdp_recv_callback: CONNECTION_STATE_NLA - nla_recv_pdu() fail");
return -1;
}
if (rdp->nla->state == NLA_STATE_AUTH_INFO)
{
@@ -1243,8 +1257,10 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
nla_free(rdp->nla);
rdp->nla = NULL;
if (!mcs_client_begin(rdp->mcs))
if (!mcs_client_begin(rdp->mcs)) {
WLog_DBG(TAG, "rdp_recv_callback: CONNECTION_STATE_NLA - mcs_client_begin() fail");
return -1;
}
}
break;
@@ -1288,16 +1304,22 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
break;
case CONNECTION_STATE_MCS_CHANNEL_JOIN:
if (!rdp_client_connect_mcs_channel_join_confirm(rdp, s))
if (!rdp_client_connect_mcs_channel_join_confirm(rdp, s)) {
WLog_DBG(TAG, "rdp_recv_callback: CONNECTION_STATE_MCS_CHANNEL_JOIN - rdp_client_connect_mcs_channel_join_confirm() fail");
status = -1;
}
break;
case CONNECTION_STATE_LICENSING:
status = rdp_client_connect_license(rdp, s);
if (status < 0)
WLog_DBG(TAG, "rdp_recv_callback: CONNECTION_STATE_LICENSING - rdp_client_connect_license() - %i", status);
break;
case CONNECTION_STATE_CAPABILITIES_EXCHANGE:
status = rdp_client_connect_demand_active(rdp, s);
if (status < 0)
WLog_DBG(TAG, "rdp_recv_callback: CONNECTION_STATE_CAPABILITIES_EXCHANGE - rdp_client_connect_demand_active() - %i", status);
break;
case CONNECTION_STATE_FINALIZATION:
@@ -1308,10 +1330,14 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
rdp_client_transition_to_state(rdp, CONNECTION_STATE_ACTIVE);
return 2;
}
if (status < 0)
WLog_DBG(TAG, "rdp_recv_callback: CONNECTION_STATE_FINALIZATION - rdp_recv_pdu() - %i", status);
break;
case CONNECTION_STATE_ACTIVE:
status = rdp_recv_pdu(rdp, s);
if (status < 0)
WLog_DBG(TAG, "rdp_recv_callback: CONNECTION_STATE_ACTIVE - rdp_recv_pdu() - %i", status);
break;
default:
@@ -1356,8 +1382,10 @@ int rdp_check_fds(rdpRdp* rdp)
status = tsg_check_event_handles(tsg);
if (status < 0)
if (status < 0) {
WLog_DBG(TAG, "rdp_check_fds: tsg_check_event_handles() - %i", status);
return -1;
}
if (tsg->state != TSG_STATE_PIPE_CREATED)
return status;
@@ -1369,6 +1397,8 @@ int rdp_check_fds(rdpRdp* rdp)
{
status = rdp_client_redirect(rdp); /* session redirection */
}
if (status < 0)
WLog_DBG(TAG, "rdp_check_fds: transport_check_fds() - %i", status);
return status;
}

View File

@@ -768,6 +768,7 @@ int transport_check_fds(rdpTransport* transport)
*/
if ((status = transport_read_pdu(transport, transport->ReceiveBuffer)) <= 0)
{
WLog_DBG(TAG, "transport_check_fds: transport_read_pdu() - %i", status);
return status;
}
@@ -789,8 +790,10 @@ int transport_check_fds(rdpTransport* transport)
return recv_status;
}
if (recv_status < 0)
if (recv_status < 0) {
WLog_DBG(TAG, "transport_check_fds: transport->ReceiveCallback() - %i", recv_status);
return -1;
}
}
return 0;
@@ -921,6 +924,7 @@ static void* transport_client_thread(void* arg)
if (transport->layer == TRANSPORT_LAYER_CLOSED)
{
WLog_DBG(TAG, "transport_client: TRANSPORT_LAYER_CLOSED");
rdp_set_error_info(rdp, ERRINFO_PEER_DISCONNECTED);
break;
}
@@ -934,6 +938,7 @@ static void* transport_client_thread(void* arg)
{
if (!freerdp_check_event_handles(context))
{
WLog_DBG(TAG, "transport_client: freerdp_check_event_handles()");
rdp_set_error_info(rdp, ERRINFO_PEER_DISCONNECTED);
break;
}