mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
+ 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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
|
||||
32
channels/tsmf/client/oss/CMakeLists.txt
Normal file
32
channels/tsmf/client/oss/CMakeLists.txt
Normal 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)
|
||||
233
channels/tsmf/client/oss/tsmf_oss.c
Normal file
233
channels/tsmf/client/oss/tsmf_oss.c
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user