libfreerdp-core: encoding of GCC create conference request + unit tests

This commit is contained in:
Marc-André Moreau 2011-07-04 19:13:01 -04:00
parent 2a13a7bc16
commit dd18348436
8 changed files with 309 additions and 4 deletions

View File

@ -27,6 +27,8 @@ add_executable(test_freerdp
test_per.h test_per.h
test_ber.c test_ber.c
test_ber.h test_ber.h
test_gcc.c
test_gcc.h
test_color.c test_color.c
test_color.h test_color.h
test_libgdi.c test_libgdi.c

View File

@ -21,6 +21,7 @@
#include "test_per.h" #include "test_per.h"
#include "test_ber.h" #include "test_ber.h"
#include "test_gcc.h"
#include "test_color.h" #include "test_color.h"
#include "test_libgdi.h" #include "test_libgdi.h"
#include "test_stream.h" #include "test_stream.h"
@ -60,16 +61,23 @@ void assert_stream(STREAM* s, uint8* data, int length, const char* func, int lin
int actual_length; int actual_length;
uint8* actual_data; uint8* actual_data;
actual_data = s->buffer;
actual_length = stream_get_length(s); actual_length = stream_get_length(s);
if (actual_length != length) if (actual_length != length)
{ {
printf("\n %s (%d): length mismatch, actual:%d, expected:%d", func, line, actual_length, length); printf("\n %s (%d): length mismatch, actual:%d, expected:%d\n", func, line, actual_length, length);
printf("\nActual:\n");
freerdp_hexdump(actual_data, actual_length);
printf("Expected:\n");
freerdp_hexdump(data, length);
CU_FAIL("assert_stream, length mismatch"); CU_FAIL("assert_stream, length mismatch");
return; return;
} }
actual_data = s->buffer;
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
{ {
if (actual_data[i] != data[i]) if (actual_data[i] != data[i])
@ -133,6 +141,10 @@ int main(int argc, char* argv[])
{ {
add_ber_suite(); add_ber_suite();
} }
else if (strcmp("gcc", argv[*pindex]) == 0)
{
add_gcc_suite();
}
*pindex = *pindex + 1; *pindex = *pindex + 1;
} }

102
cunit/test_gcc.c Normal file
View File

@ -0,0 +1,102 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* T.124 Generic Conference Control (GCC) Unit Tests
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@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.
*/
#include "gcc.h"
#include <freerdp/freerdp.h>
#include <freerdp/utils/hexdump.h>
#include <freerdp/utils/stream.h>
#include "test_gcc.h"
int init_gcc_suite(void)
{
return 0;
}
int clean_gcc_suite(void)
{
return 0;
}
int add_gcc_suite(void)
{
add_test_suite(gcc);
add_test_function(gcc_write_create_conference_request);
return 0;
}
uint8 gcc_user_data[284] =
"\x01\xc0\xd8\x00\x04\x00\x08\x00\x00\x05\x00\x04\x01\xCA\x03\xAA"
"\x09\x04\x00\x00\xCE\x0E\x00\x00\x45\x00\x4c\x00\x54\x00\x4f\x00"
"\x4e\x00\x53\x00\x2d\x00\x44\x00\x45\x00\x56\x00\x32\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00"
"\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x01\xCA\x01\x00\x00\x00\x00\x00\x18\x00\x07\x00"
"\x01\x00\x36\x00\x39\x00\x37\x00\x31\x00\x32\x00\x2d\x00\x37\x00"
"\x38\x00\x33\x00\x2d\x00\x30\x00\x33\x00\x35\x00\x37\x00\x39\x00"
"\x37\x00\x34\x00\x2d\x00\x34\x00\x32\x00\x37\x00\x31\x00\x34\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x04\xC0\x0C\x00\x0D\x00\x00\x00"
"\x00\x00\x00\x00\x02\xC0\x0C\x00\x1B\x00\x00\x00\x00\x00\x00\x00"
"\x03\xC0\x2C\x00\x03\x00\x00\x00\x72\x64\x70\x64\x72\x00\x00\x00"
"\x00\x00\x80\x80\x63\x6c\x69\x70\x72\x64\x72\x00\x00\x00\xA0\xC0"
"\x72\x64\x70\x73\x6e\x64\x00\x00\x00\x00\x00\xc0";
uint8 gcc_create_conference_request_expected[307] =
"\x00\x05\x00\x14\x7C\x00\x01\x81\x2A\x00\x08\x00\x10\x00\x01\xC0"
"\x00\x44\x75\x63\x61\x81\x1c\x01\xc0\xd8\x00\x04\x00\x08\x00\x00"
"\x05\x00\x04\x01\xCA\x03\xAA\x09\x04\x00\x00\xCE\x0E\x00\x00\x45"
"\x00\x4c\x00\x54\x00\x4f\x00\x4e\x00\x53\x00\x2d\x00\x44\x00\x45"
"\x00\x56\x00\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"
"\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xCA\x01\x00\x00"
"\x00\x00\x00\x18\x00\x07\x00\x01\x00\x36\x00\x39\x00\x37\x00\x31"
"\x00\x32\x00\x2d\x00\x37\x00\x38\x00\x33\x00\x2d\x00\x30\x00\x33"
"\x00\x35\x00\x37\x00\x39\x00\x37\x00\x34\x00\x2d\x00\x34\x00\x32"
"\x00\x37\x00\x31\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"
"\xC0\x0C\x00\x0D\x00\x00\x00\x00\x00\x00\x00\x02\xC0\x0C\x00\x1B"
"\x00\x00\x00\x00\x00\x00\x00\x03\xC0\x2C\x00\x03\x00\x00\x00\x72"
"\x64\x70\x64\x72\x00\x00\x00\x00\x00\x80\x80\x63\x6c\x69\x70\x72"
"\x64\x72\x00\x00\x00\xA0\xC0\x72\x64\x70\x73\x6e\x64\x00\x00\x00"
"\x00\x00\xc0";
void test_gcc_write_create_conference_request(void)
{
STREAM* s;
STREAM user_data;
user_data.buffer = gcc_user_data;
user_data.capacity = sizeof(gcc_user_data);
user_data.ptr = user_data.buffer + user_data.capacity;
s = stream_new(sizeof(gcc_create_conference_request_expected));
gcc_write_create_conference_request(s, &user_data);
ASSERT_STREAM(s, (uint8*) gcc_create_conference_request_expected, sizeof(gcc_create_conference_request_expected));
}

26
cunit/test_gcc.h Normal file
View File

@ -0,0 +1,26 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* T.124 Generic Conference Control (GCC) Unit Tests
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@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.
*/
#include "test_freerdp.h"
int init_gcc_suite(void);
int clean_gcc_suite(void);
int add_gcc_suite(void);
void test_gcc_write_create_conference_request(void);

View File

@ -33,6 +33,12 @@
* connectPDU OCTET_STRING * connectPDU OCTET_STRING
* } * }
* *
* Key ::= CHOICE
* {
* object OBJECT_IDENTIFIER,
* h221NonStandard H221NonStandardIdentifier
* }
*
* ConnectGCCPDU ::= CHOICE * ConnectGCCPDU ::= CHOICE
* { * {
* conferenceCreateRequest ConferenceCreateRequest, * conferenceCreateRequest ConferenceCreateRequest,
@ -45,10 +51,80 @@
* conferenceInviteResponse ConferenceInviteResponse, * conferenceInviteResponse ConferenceInviteResponse,
* ... * ...
* } * }
*
* ConferenceCreateRequest ::= SEQUENCE
* {
* conferenceName ConferenceName,
* convenerPassword Password OPTIONAL,
* password Password OPTIONAL,
* lockedConference BOOLEAN,
* listedConference BOOLEAN,
* conductibleConference BOOLEAN,
* terminationMethod TerminationMethod,
* conductorPrivileges SET OF Privilege OPTIONAL,
* conductedPrivileges SET OF Privilege OPTIONAL,
* nonConductedPrivileges SET OF Privilege OPTIONAL,
* conferenceDescription TextString OPTIONAL,
* callerIdentifier TextString OPTIONAL,
* userData UserData OPTIONAL,
* ...,
* conferencePriority ConferencePriority OPTIONAL,
* conferenceMode ConferenceMode OPTIONAL
* }
*
* ConferenceName ::= SEQUENCE
* {
* numeric SimpleNumericString
* text SimpleTextString OPTIONAL,
* ...
* }
*
* SimpleNumericString ::= NumericString (SIZE (1..255)) (FROM ("0123456789"))
*
* UserData ::= SET OF SEQUENCE
* {
* key Key,
* value OCTET_STRING OPTIONAL
* }
*
* H221NonStandardIdentifier ::= OCTET STRING (SIZE (4..255))
*
*/ */
/* http://msdn.microsoft.com/en-us/library/cc240836/ */ /* http://msdn.microsoft.com/en-us/library/cc240836/ */
uint8 t124_oid[6] = { 0, 0, 20, 124, 0, 1 }; /*
* OID = 0.0.20.124.0.1
* { itu-t(0) recommendation(0) t(20) t124(124) version(0) 1 }
* v.1 of ITU-T Recommendation T.124 (Feb 1998): "Generic Conference Control"
*/
uint8 t124_02_98_oid[6] = { 0, 0, 20, 124, 0, 1 };
void
gcc_write_create_conference_request(STREAM* s, STREAM* user_data)
{
/* ConnectData */
per_write_choice(s, 0); /* From Key select object (0) of type OBJECT_IDENTIFIER */
per_write_object_identifier(s, t124_02_98_oid); /* ITU-T T.124 (02/98) OBJECT_IDENTIFIER */
/* ConnectData::connectPDU (OCTET_STRING) */
per_write_length(s, stream_get_length(user_data) + 14); /* connectPDU length */
/* ConnectGCCPDU */
per_write_choice(s, 0); /* From ConnectGCCPDU select conferenceCreateRequest (0) of type ConferenceCreateRequest */
per_write_selection(s, 0x08); /* select optional userData from ConferenceCreateRequest */
/* ConferenceCreateRequest::conferenceName */
per_write_numeric_string(s, "1", 1, 1); /* ConferenceName::numeric */
per_write_padding(s, 1); /* padding */
/* UserData (SET OF SEQUENCE) */
per_write_number_of_sets(s, 1); /* one set of UserData */
per_write_choice(s, 0xC0); /* UserData::value present + select h221NonStandard (1) */
/* h221NonStandard */
per_write_octet_string(s, "Duca", 4, 4); /* h221NonStandard, client-to-server H.221 key, "Duca" */
/* userData::value (OCTET_STRING) */
per_write_octet_string(s, user_data->buffer, stream_get_length(user_data), 0); /* array of client data blocks */
}

View File

@ -24,6 +24,7 @@
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
void
gcc_write_create_conference_request(STREAM* s, STREAM* user_data);
#endif /* __GCC_H */ #endif /* __GCC_H */

View File

@ -28,6 +28,33 @@ per_write_length(STREAM* s, int length)
stream_write_uint8(s, length); stream_write_uint8(s, length);
} }
void
per_write_choice(STREAM* s, uint8 choice)
{
stream_write_uint8(s, choice);
}
void
per_write_selection(STREAM* s, uint8 selection)
{
stream_write_uint8(s, selection);
}
void
per_write_number_of_sets(STREAM* s, uint8 number)
{
stream_write_uint8(s, number);
}
void
per_write_padding(STREAM* s, int length)
{
int i;
for (i = 0; i < length; i++)
stream_write_uint8(s, 0);
}
void void
per_write_object_identifier(STREAM* s, uint8 oid[6]) per_write_object_identifier(STREAM* s, uint8 oid[6])
{ {
@ -39,3 +66,50 @@ per_write_object_identifier(STREAM* s, uint8 oid[6])
stream_write_uint8(s, oid[4]); /* tuple 5 */ stream_write_uint8(s, oid[4]); /* tuple 5 */
stream_write_uint8(s, oid[5]); /* tuple 6 */ stream_write_uint8(s, oid[5]); /* tuple 6 */
} }
void
per_write_string(STREAM* s, uint8* str, int length)
{
int i;
for (i = 0; i < length; i++)
stream_write_uint8(s, str[i]);
}
void
per_write_octet_string(STREAM* s, uint8* oct_str, int length, int min)
{
int i;
int mlength;
mlength = (length - min >= 0) ? length - min : min;
per_write_length(s, mlength);
for (i = 0; i < length; i++)
stream_write_uint8(s, oct_str[i]);
}
void
per_write_numeric_string(STREAM* s, uint8* num_str, int length, int min)
{
int i;
int mlength;
uint8 num, c1, c2;
mlength = (length - min >= 0) ? length - min : min;
per_write_length(s, mlength);
for (i = 0; i < length; i += 2)
{
c1 = num_str[i];
c2 = ((i + 1) < length) ? num_str[i + 1] : 0x30;
c1 = (c1 - 0x30) % 10;
c2 = (c2 - 0x30) % 10;
num = (c1 << 4) | c2;
stream_write_uint8(s, num); /* string */
}
}

View File

@ -25,6 +25,18 @@
void void
per_write_length(STREAM* s, int length); per_write_length(STREAM* s, int length);
void void
per_write_choice(STREAM* s, uint8 choice);
void
per_write_selection(STREAM* s, uint8 selection);
void
per_write_number_of_sets(STREAM* s, uint8 number);
void
per_write_padding(STREAM* s, int length);
void
per_write_object_identifier(STREAM* s, uint8 oid[6]); per_write_object_identifier(STREAM* s, uint8 oid[6]);
void
per_write_octet_string(STREAM* s, uint8* oct_str, int length, int min);
void
per_write_numeric_string(STREAM* s, uint8* num_str, int length, int min);
#endif /* __PER_H */ #endif /* __PER_H */