2 * FreeRDP: A Remote Desktop Protocol Client
3 * T.124 Generic Conference Control (GCC)
5 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
23 * T.124 GCC is defined in:
25 * http://www.itu.int/rec/T-REC-T.124-199802-S/en
26 * ITU-T T.124 (02/98): Generic Conference Control
30 * ConnectData ::= SEQUENCE
33 * connectPDU OCTET_STRING
38 * object OBJECT_IDENTIFIER,
39 * h221NonStandard H221NonStandardIdentifier
42 * ConnectGCCPDU ::= CHOICE
44 * conferenceCreateRequest ConferenceCreateRequest,
45 * conferenceCreateResponse ConferenceCreateResponse,
46 * conferenceQueryRequest ConferenceQueryRequest,
47 * conferenceQueryResponse ConferenceQueryResponse,
48 * conferenceJoinRequest ConferenceJoinRequest,
49 * conferenceJoinResponse ConferenceJoinResponse,
50 * conferenceInviteRequest ConferenceInviteRequest,
51 * conferenceInviteResponse ConferenceInviteResponse,
55 * ConferenceCreateRequest ::= SEQUENCE
57 * conferenceName ConferenceName,
58 * convenerPassword Password OPTIONAL,
59 * password Password OPTIONAL,
60 * lockedConference BOOLEAN,
61 * listedConference BOOLEAN,
62 * conductibleConference BOOLEAN,
63 * terminationMethod TerminationMethod,
64 * conductorPrivileges SET OF Privilege OPTIONAL,
65 * conductedPrivileges SET OF Privilege OPTIONAL,
66 * nonConductedPrivileges SET OF Privilege OPTIONAL,
67 * conferenceDescription TextString OPTIONAL,
68 * callerIdentifier TextString OPTIONAL,
69 * userData UserData OPTIONAL,
71 * conferencePriority ConferencePriority OPTIONAL,
72 * conferenceMode ConferenceMode OPTIONAL
75 * ConferenceName ::= SEQUENCE
77 * numeric SimpleNumericString
78 * text SimpleTextString OPTIONAL,
82 * SimpleNumericString ::= NumericString (SIZE (1..255)) (FROM ("0123456789"))
84 * UserData ::= SET OF SEQUENCE
87 * value OCTET_STRING OPTIONAL
90 * H221NonStandardIdentifier ::= OCTET STRING (SIZE (4..255))
95 * OID = 0.0.20.124.0.1
96 * { itu-t(0) recommendation(0) t(20) t124(124) version(0) 1 }
97 * v.1 of ITU-T Recommendation T.124 (Feb 1998): "Generic Conference Control"
99 uint8 t124_02_98_oid[6] = { 0, 0, 20, 124, 0, 1 };
102 * Write a GCC Conference Create Request.\n
105 * @param user_data client data blocks
109 gcc_write_create_conference_request(STREAM* s, STREAM* user_data)
112 per_write_choice(s, 0); /* From Key select object (0) of type OBJECT_IDENTIFIER */
113 per_write_object_identifier(s, t124_02_98_oid); /* ITU-T T.124 (02/98) OBJECT_IDENTIFIER */
115 /* ConnectData::connectPDU (OCTET_STRING) */
116 per_write_length(s, stream_get_length(user_data) + 14); /* connectPDU length */
119 per_write_choice(s, 0); /* From ConnectGCCPDU select conferenceCreateRequest (0) of type ConferenceCreateRequest */
120 per_write_selection(s, 0x08); /* select optional userData from ConferenceCreateRequest */
122 /* ConferenceCreateRequest::conferenceName */
123 per_write_numeric_string(s, "1", 1, 1); /* ConferenceName::numeric */
124 per_write_padding(s, 1); /* padding */
126 /* UserData (SET OF SEQUENCE) */
127 per_write_number_of_sets(s, 1); /* one set of UserData */
128 per_write_choice(s, 0xC0); /* UserData::value present + select h221NonStandard (1) */
130 /* h221NonStandard */
131 per_write_octet_string(s, "Duca", 4, 4); /* h221NonStandard, client-to-server H.221 key, "Duca" */
133 /* userData::value (OCTET_STRING) */
134 per_write_octet_string(s, user_data->buffer, stream_get_length(user_data), 0); /* array of client data blocks */
138 * Write a user data header (TS_UD_HEADER).\n
141 * @param type data block type
142 * @param length data block length
146 gcc_write_user_data_header(STREAM* s, uint16 type, uint16 length)
148 stream_write_uint16(s, type); /* type */
149 stream_write_uint16(s, length); /* length */
153 * Write a client core data block (TS_UD_CS_CORE).\n
156 * @param settings rdp settings
160 gcc_write_client_core_data(STREAM* s, rdpSettings *settings)
163 uint16 highColorDepth;
164 uint16 supportedColorDepths;
165 uint16 earlyCapabilityFlags;
166 uint8 connectionType;
168 gcc_write_user_data_header(s, CS_CORE, 216);
170 version = settings->rdp_version >= 5 ? RDP_VERSION_5_PLUS : RDP_VERSION_4;
172 stream_write_uint32(s, version); /* version */
173 stream_write_uint16(s, settings->width); /* desktopWidth */
174 stream_write_uint16(s, settings->height); /* desktopHeight */
175 stream_write_uint16(s, RNS_UD_COLOR_8BPP); /* colorDepth, ignored because of postBeta2ColorDepth */
176 stream_write_uint16(s, RNS_UD_SAS_DEL); /* SASSequence (Secure Access Sequence) */
177 stream_write_uint32(s, settings->kbd_layout); /* keyboardLayout */
178 stream_write_uint32(s, 2600); /* clientBuild */
180 stream_write_padding(s, 32); /* clientName */
182 stream_write_uint32(s, settings->kbd_type); /* keyboardType */
183 stream_write_uint32(s, settings->kbd_subtype); /* keyboardSubType */
184 stream_write_uint32(s, settings->kbd_fn_keys); /* keyboardFunctionKey */
186 stream_write_padding(s, 64); /* imeFileName */
188 stream_write_uint16(s, RNS_UD_COLOR_8BPP); /* postBeta2ColorDepth */
189 stream_write_uint16(s, 1); /* clientProductID */
190 stream_write_uint16(s, 0); /* serialNumber (should be initialized to 0) */
192 highColorDepth = MIN(settings->color_depth, 24);
193 supportedColorDepths = RNS_UD_32BPP_SUPPORT | RNS_UD_24BPP_SUPPORT | RNS_UD_16BPP_SUPPORT | RNS_UD_15BPP_SUPPORT;
195 stream_write_uint16(s, highColorDepth); /* highColorDepth */
196 stream_write_uint16(s, supportedColorDepths); /* supportedColorDepths */
199 earlyCapabilityFlags = RNS_UD_CS_SUPPORT_ERRINFO_PDU;
201 if (settings->performance_flags == PERF_FLAG_NONE)
203 earlyCapabilityFlags |= RNS_UD_CS_VALID_CONNECTION_TYPE;
204 connectionType = CONNECTION_TYPE_LAN;
207 if (settings->color_depth == 32)
208 earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION;
210 stream_write_uint16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */
211 stream_write_padding(s, 64); /* clientDigProductId (64 bytes) */
213 stream_write_uint8(s, connectionType); /* connectionType */
214 stream_write_uint8(s, 0); /* pad1octet */
216 stream_write_uint32(s, settings->selected_protocol); /* serverSelectedProtocol */
220 * Write a client security data block (TS_UD_CS_SEC).\n
223 * @param settings rdp settings
227 gcc_write_client_security_data(STREAM* s, rdpSettings *settings)
229 uint16 encryptionMethods;
231 gcc_write_user_data_header(s, CS_SECURITY, 12);
233 encryptionMethods = ENCRYPTION_40BIT_FLAG | ENCRYPTION_128BIT_FLAG;
235 if (settings->encryption)
237 stream_write_uint32(s, encryptionMethods); /* encryptionMethods */
238 stream_write_uint32(s, 0); /* extEncryptionMethods */
242 /* French locale, disable encryption */
243 stream_write_uint32(s, 0); /* encryptionMethods */
244 stream_write_uint32(s, encryptionMethods); /* extEncryptionMethods */
249 * Write a client network data block (TS_UD_CS_NET).\n
252 * @param settings rdp settings
256 gcc_write_client_network_data(STREAM* s, rdpSettings *settings)
261 if (settings->num_channels > 0)
263 length = settings->num_channels * 12 + 8;
264 gcc_write_user_data_header(s, CS_NET, length);
266 stream_write_uint32(s, settings->num_channels); /* channelCount */
268 /* channelDefArray */
269 for (i = 0; i < settings->num_channels; i++)
272 stream_write(s, settings->channels[i].name, 8); /* name (8 bytes) */
273 stream_write_uint32(s, settings->channels[i].options); /* options (4 bytes) */
279 * Write a client cluster data block (TS_UD_CS_CLUSTER).\n
282 * @param settings rdp settings
286 gcc_write_client_cluster_data(STREAM* s, rdpSettings *settings)
289 uint32 redirectedSessionID;
291 gcc_write_user_data_header(s, CS_CLUSTER, 12);
293 flags = REDIRECTION_SUPPORTED | REDIRECTION_VERSION4;
295 if (settings->console_session || settings->session_id)
296 flags |= REDIRECTED_SESSIONID_FIELD_VALID;
298 stream_write_uint32(s, flags); /* flags */
299 stream_write_uint32(s, settings->session_id); /* redirectedSessionID */
303 * Write a client monitor data block (TS_UD_CS_MONITOR).\n
306 * @param settings rdp settings
310 gcc_write_client_monitor_data(STREAM* s, rdpSettings *settings)
314 uint32 left, top, right, bottom, flags;
316 if (settings->num_monitors > 1)
318 length = (20 * settings->num_monitors) + 12;
319 gcc_write_user_data_header(s, CS_MONITOR, length);
321 stream_write_uint32(s, 0); /* flags */
322 stream_write_uint32(s, settings->num_monitors); /* monitorCount */
324 for (i = 0; i < settings->num_monitors; i++)
326 left = settings->monitors[i].x;
327 top = settings->monitors[i].y;
328 right = settings->monitors[i].x + settings->monitors[i].width - 1;
329 bottom = settings->monitors[i].y + settings->monitors[i].height - 1;
330 flags = settings->monitors[i].is_primary ? MONITOR_PRIMARY : 0;
332 stream_write_uint32(s, left); /* left */
333 stream_write_uint32(s, top); /* top */
334 stream_write_uint32(s, right); /* right */
335 stream_write_uint32(s, bottom); /* bottom */
336 stream_write_uint32(s, flags); /* flags */