libfreerdp-core: got the server to send some dumped RemoteFX frames

This commit is contained in:
Marc-André Moreau 2011-08-26 21:44:37 -04:00
parent 9f256c8374
commit 25e761e58b
9 changed files with 104 additions and 9 deletions

3
.gitignore vendored
View File

@ -30,6 +30,9 @@ docs/api
ipch
Debug
# test files
*.pcap
# Binaries
*.a
*.so

View File

@ -23,6 +23,7 @@
#include <freerdp/rail.h>
#include <freerdp/types.h>
#include <freerdp/utils/pcap.h>
#include <freerdp/utils/stream.h>
/* Common */
@ -1064,6 +1065,7 @@ typedef void (*pcMonitoredDesktop)(rdpUpdate* update, WINDOW_ORDER_INFO* orderIn
typedef void (*pcNonMonitoredDesktop)(rdpUpdate* update, WINDOW_ORDER_INFO* orderInfo);
typedef void (*pcSurfaceBits)(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_command);
typedef void (*pcSurfaceCommand)(rdpUpdate* update, STREAM* s);
struct rdp_update
{
@ -1146,6 +1148,7 @@ struct rdp_update
pcNonMonitoredDesktop NonMonitoredDesktop;
pcSurfaceBits SurfaceBits;
pcSurfaceCommand SurfaceCommand;
BITMAP_UPDATE bitmap_update;
PALETTE_UPDATE palette_update;

View File

@ -76,6 +76,8 @@ FREERDP_API void pcap_close(rdpPcap* pcap);
FREERDP_API void pcap_add_record(rdpPcap* pcap, void* data, uint32 length);
FREERDP_API boolean pcap_has_next_record(rdpPcap* pcap);
FREERDP_API boolean pcap_get_next_record(rdpPcap* pcap, pcap_record* record);
FREERDP_API boolean pcap_get_next_record_header(rdpPcap* pcap, pcap_record* record);
FREERDP_API boolean pcap_get_next_record_content(rdpPcap* pcap, pcap_record* record);
FREERDP_API void pcap_flush(rdpPcap* pcap);
#endif /* __UTILS_PCAP_H */

View File

@ -394,7 +394,7 @@ boolean fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s)
{
/**
* If numberEvents is not provided in fpInputHeader, it will be provided
* as onee additional byte here.
* as one additional byte here.
*/
if (stream_get_left(s) < 1)
@ -475,6 +475,36 @@ boolean fastpath_send_update_pdu(rdpFastPath* fastpath, STREAM* s)
return True;
}
boolean fastpath_send_fragmented_update_pdu(rdpFastPath* fastpath, STREAM* s)
{
uint16 length;
uint32 totalLength;
STREAM* update;
totalLength = stream_get_length(s);
update = fastpath_update_pdu_init(fastpath);
if (totalLength <= FASTPATH_MAX_PACKET_SIZE)
{
stream_write_uint8(update, FASTPATH_UPDATETYPE_SURFCMDS | (FASTPATH_FRAGMENT_SINGLE << 4));
stream_write_uint16(update, totalLength);
stream_write(update, s->data, totalLength);
return fastpath_send_update_pdu(fastpath, update);
}
while (totalLength > 0)
{
if (totalLength < FASTPATH_MAX_PACKET_SIZE)
length = totalLength;
else
length = FASTPATH_MAX_PACKET_SIZE;
totalLength -= length;
}
return True;
}
boolean fastpath_send_surfcmd_frame_marker(rdpFastPath* fastpath, uint16 frameAction, uint32 frameId)
{
STREAM* s;

View File

@ -100,6 +100,7 @@ boolean fastpath_send_input_pdu(rdpFastPath* fastpath, STREAM* s);
STREAM* fastpath_update_pdu_init(rdpFastPath* fastpath);
boolean fastpath_send_update_pdu(rdpFastPath* fastpath, STREAM* s);
boolean fastpath_send_fragmented_update_pdu(rdpFastPath* fastpath, STREAM* s);
boolean fastpath_send_surfcmd_frame_marker(rdpFastPath* fastpath, uint16 frameAction, uint32 frameId);
boolean fastpath_send_surfcmd_surface_bits(rdpFastPath* fastpath, SURFACE_BITS_COMMAND* cmd);

View File

@ -23,8 +23,8 @@
static int update_recv_surfcmd_surface_bits(rdpUpdate* update, STREAM* s)
{
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
int pos;
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
stream_read_uint16(s, cmd->destLeft);
stream_read_uint16(s, cmd->destTop);
@ -62,14 +62,14 @@ boolean update_recv_surfcmds(rdpUpdate* update, uint16 size, STREAM* s)
{
uint16 cmdType;
if (update->dump_rfx)
{
pcap_add_record(update->pcap_rfx, s->p, size);
pcap_flush(update->pcap_rfx);
}
while (size > 2)
{
if (update->dump_rfx)
{
pcap_add_record(update->pcap_rfx, s->p, size);
pcap_flush(update->pcap_rfx);
}
stream_read_uint16(s, cmdType);
size -= 2;

View File

@ -322,10 +322,15 @@ static void update_end_paint(rdpUpdate* update)
{
}
static void update_send_surface_command(rdpUpdate* update, STREAM* s)
{
rdpRdp* rdp = (rdpRdp*) update->rdp;
fastpath_send_fragmented_update_pdu(rdp->fastpath, s);
}
static void update_send_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_command)
{
rdpRdp* rdp = (rdpRdp*)update->rdp;
fastpath_send_surfcmd_surface_bits(rdp->fastpath, surface_bits_command);
}
@ -362,6 +367,7 @@ void update_register_server_callbacks(rdpUpdate* update)
update->Synchronize = update_send_synchronize;
update->PointerSystem = update_send_pointer_system;
update->SurfaceBits = update_send_surface_bits;
update->SurfaceCommand = update_send_surface_command;
}
rdpUpdate* update_new(rdpRdp* rdp)

View File

@ -101,6 +101,24 @@ boolean pcap_has_next_record(rdpPcap* pcap)
return True;
}
boolean pcap_get_next_record_header(rdpPcap* pcap, pcap_record* record)
{
if (pcap_has_next_record(pcap) != True)
return False;
pcap_read_record_header(pcap, &record->header);
record->length = record->header.incl_len;
record->data = xmalloc(record->length);
return True;
}
boolean pcap_get_next_record_content(rdpPcap* pcap, pcap_record* record)
{
fread(record->data, record->length, 1, pcap->fp);
return True;
}
boolean pcap_get_next_record(rdpPcap* pcap, pcap_record* record)
{
if (pcap_has_next_record(pcap) != True)

View File

@ -232,6 +232,33 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y)
info->icon_y = y;
}
void test_peer_dump_rfx(freerdp_peer* client)
{
STREAM* s;
rdpUpdate* update;
rdpPcap* pcap_rfx;
pcap_record record;
s = stream_new(512);
update = client->update;
client->update->pcap_rfx = pcap_open("rfx_test.pcap", False);
pcap_rfx = client->update->pcap_rfx;
while (pcap_has_next_record(pcap_rfx))
{
pcap_get_next_record_header(pcap_rfx, &record);
s->data = xrealloc(s->data, record.length);
record.data = s->data;
s->size = record.length;
pcap_get_next_record_content(pcap_rfx, &record);
s->p = s->data + s->size;
update->SurfaceCommand(update, s);
}
}
boolean test_peer_post_connect(freerdp_peer* client)
{
/**
@ -259,6 +286,11 @@ boolean test_peer_post_connect(freerdp_peer* client)
test_peer_draw_background(client);
test_peer_load_icon(client);
if (client->update->dump_rfx)
{
test_peer_dump_rfx(client);
}
/* Return False here would stop the execution of the peer mainloop. */
return True;
}