Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-core / tpdu.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * X.224 Transport Protocol Data Units (TPDUs)
4  *
5  * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
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
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 #include <stdio.h>
21
22 #include "tpdu.h"
23
24 /**
25  * TPDUs are defined in:
26  *
27  * http://www.itu.int/rec/T-REC-X.224-199511-I/
28  * X.224: Information technology - Open Systems Interconnection - Protocol for providing the connection-mode transport service
29  *
30  * RDP uses only TPDUs of class 0, the "simple class" defined in section 8 of X.224
31  *
32  *       TPDU Header
33  *  ____________________   byte
34  * |                    |
35  * |         LI         |   1
36  * |____________________|
37  * |                    |
38  * |        Code        |   2
39  * |____________________|
40  * |                    |
41  * |                    |   3
42  * |_______DST-REF______|
43  * |                    |
44  * |                    |   4
45  * |____________________|
46  * |                    |
47  * |                    |   5
48  * |_______SRC-REF______|
49  * |                    |
50  * |                    |   6
51  * |____________________|
52  * |                    |
53  * |        Class       |   7
54  * |____________________|
55  * |         ...        |
56  */
57
58 /**
59  * Read TPDU header.
60  * @param s stream
61  * @param code variable pointer to receive TPDU code
62  * @return TPDU length indicator (LI)
63  */
64
65 uint8
66 tpdu_read_header(STREAM* s, uint8* code)
67 {
68         uint8 li;
69
70         stream_read_uint8(s, li); /* LI */
71         stream_read_uint8(s, *code); /* Code */
72
73         if (*code == X224_TPDU_DATA)
74         {
75                 /* EOT (1 byte) */
76                 stream_seek(s, 1);
77         }
78         else
79         {
80                 /* DST-REF (2 bytes) */
81                 /* SRC-REF (2 bytes) */
82                 /* Class 0 (1 byte) */
83                 stream_seek(s, 5);
84         }
85
86         return li;
87 }
88
89 /**
90  * Write TDPU header.
91  * @param s stream
92  * @param length length
93  * @param code TPDU code
94  */
95
96 void
97 tpdu_write_header(STREAM* s, uint16 length, uint8 code)
98 {
99         stream_write_uint8(s, length); /* LI */
100         stream_write_uint8(s, code); /* code */
101
102         if (code == X224_TPDU_DATA)
103         {
104                 stream_write_uint8(s, 0x80); /* EOT */
105         }
106         else
107         {
108                 stream_write_uint16(s, 0); /* DST-REF */
109                 stream_write_uint16(s, 0); /* SRC-REF */
110                 stream_write_uint8(s, 0); /* Class 0 */
111         }
112 }
113
114 /**
115  * Read Connection Request TPDU
116  * @param s stream
117  * @return length indicator (LI)
118  */
119
120 uint8 tpdu_read_connection_request(STREAM* s)
121 {
122         uint8 li;
123         uint8 code;
124
125         li = tpdu_read_header(s, &code);
126
127         if (code != X224_TPDU_CONNECTION_REQUEST)
128         {
129                 printf("Error: expected X224_TPDU_CONNECTION_REQUEST\n");
130                 return 0;
131         }
132
133         return li;
134 }
135
136 /**
137  * Write Connection Request TPDU.
138  * @param s stream
139  * @param length TPDU length
140  */
141
142 void
143 tpdu_write_connection_request(STREAM* s, uint16 length)
144 {
145         tpdu_write_header(s, length, X224_TPDU_CONNECTION_REQUEST);
146 }
147
148 /**
149  * Read Connection Confirm TPDU.
150  * @param s stream
151  * @return length indicator (LI)
152  */
153
154 uint8
155 tpdu_read_connection_confirm(STREAM* s)
156 {
157         uint8 li;
158         uint8 code;
159
160         li = tpdu_read_header(s, &code);
161
162         if (code != X224_TPDU_CONNECTION_CONFIRM)
163         {
164                 printf("Error: expected X224_TPDU_CONNECTION_CONFIRM\n");
165                 return 0;
166         }
167
168         return li;
169 }
170
171 /**
172  * Write Connection Confirm TPDU.
173  * @param s stream
174  * @param length TPDU length
175  */
176
177 void
178 tpdu_write_connection_confirm(STREAM* s, uint16 length)
179 {
180         tpdu_write_header(s, length, X224_TPDU_CONNECTION_CONFIRM);
181 }
182
183 /**
184  * Write Disconnect Request TPDU.
185  * @param s stream
186  * @param length TPDU length
187  */
188
189 void
190 tpdu_write_disconnect_request(STREAM* s, uint16 length)
191 {
192         tpdu_write_header(s, length, X224_TPDU_DISCONNECT_REQUEST);
193 }
194
195 /**
196  * Write Data TPDU.
197  * @param s stream
198  */
199
200 void
201 tpdu_write_data(STREAM* s)
202 {
203         tpdu_write_header(s, 2, X224_TPDU_DATA);
204 }
205
206 /**
207  * Read Data TPDU.
208  * @param s stream
209  */
210
211 uint16
212 tpdu_read_data(STREAM* s)
213 {
214         uint8 code;
215         uint16 li;
216
217         li = tpdu_read_header(s, &code);
218
219         if (code != X224_TPDU_DATA)
220                 return 0;
221
222         return li;
223 }