blob: 7e5e97b518e756e5e167701966bb696860f5e4d0 [file] [log] [blame]
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +01001/*
2 * (C) 2012 by Holger Hans Peter Freyther
3 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 */
20
21#include <osmocom/gsm/gsm0808.h>
22
23#include <stdio.h>
24#include <stdlib.h>
25
26#define VERIFY(msg, data, len) \
27 if (msgb_l3len(msg) != len) { \
28 printf("%s:%d Length don't match: %d vs. %d. %s\n", \
29 __func__, __LINE__, msgb_l3len(msg), len, \
30 osmo_hexdump(msg->l3h, msgb_l3len(msg))); \
31 abort(); \
32 } else if (memcmp(msg->l3h, data, len) != 0) { \
33 printf("%s:%d didn't match: got: %s\n", \
34 __func__, __LINE__, \
35 osmo_hexdump(msg->l3h, msgb_l3len(msg))); \
36 abort(); \
37 }
38
39
40static void test_create_layer3(void)
41{
42 static const uint8_t res[] = {
43 0x00, 0x0e, 0x57, 0x05, 0x08, 0x00, 0x77, 0x62,
44 0x83, 0x33, 0x66, 0x44, 0x88, 0x17, 0x01, 0x23 };
45 struct msgb *msg, *in_msg;
46 printf("Testing creating Layer3\n");
47
48 in_msg = msgb_alloc_headroom(512, 128, "foo");
49 in_msg->l3h = in_msg->data;
50 msgb_v_put(in_msg, 0x23);
51
52 msg = gsm0808_create_layer3(in_msg, 0x1122, 0x2244, 0x3366, 0x4488);
53 VERIFY(msg, res, ARRAY_SIZE(res));
54 msgb_free(msg);
55 msgb_free(in_msg);
56}
57
58static void test_create_reset()
59{
60 static const uint8_t res[] = { 0x00, 0x04, 0x30, 0x04, 0x01, 0x20 };
61 struct msgb *msg;
62
63 printf("Testing creating Reset\n");
64 msg = gsm0808_create_reset();
65 VERIFY(msg, res, ARRAY_SIZE(res));
66 msgb_free(msg);
67}
68
69static void test_create_clear_command()
70{
71 static const uint8_t res[] = { 0x20, 0x04, 0x01, 0x23 };
72 struct msgb *msg;
73
74 printf("Testing creating Clear Command\n");
75 msg = gsm0808_create_clear_command(0x23);
76 VERIFY(msg, res, ARRAY_SIZE(res));
77 msgb_free(msg);
78}
79
80static void test_create_clear_complete()
81{
82 static const uint8_t res[] = { 0x00, 0x01, 0x21 };
83 struct msgb *msg;
84
85 printf("Testing creating Clear Complete\n");
86 msg = gsm0808_create_clear_complete();
87 VERIFY(msg, res, ARRAY_SIZE(res));
88 msgb_free(msg);
89}
90
91static void test_create_cipher_complete()
92{
93 static const uint8_t res1[] = {
94 0x00, 0x08, 0x55, 0x20, 0x03, 0x23, 0x42, 0x21, 0x2c, 0x04 };
95 static const uint8_t res2[] = { 0x00, 0x03, 0x55, 0x2c, 0x04};
96 struct msgb *l3, *msg;
97
98 printf("Testing creating Cipher Complete\n");
99 l3 = msgb_alloc_headroom(512, 128, "l3h");
100 l3->l3h = l3->data;
101 msgb_v_put(l3, 0x23);
102 msgb_v_put(l3, 0x42);
103 msgb_v_put(l3, 0x21);
104
105 /* with l3 data */
106 msg = gsm0808_create_cipher_complete(l3, 4);
107 VERIFY(msg, res1, ARRAY_SIZE(res1));
108 msgb_free(msg);
109
110 /* with l3 data but short */
111 l3->len -= 1;
112 l3->tail -= 1;
113 msg = gsm0808_create_cipher_complete(l3, 4);
114 VERIFY(msg, res2, ARRAY_SIZE(res2));
115 msgb_free(msg);
116
117 /* without l3 data */
118 msg = gsm0808_create_cipher_complete(NULL, 4);
119 VERIFY(msg, res2, ARRAY_SIZE(res2));
120 msgb_free(msg);
121
122
123 msgb_free(l3);
124}
125
126static void test_create_cipher_reject()
127{
128 static const uint8_t res[] = { 0x00, 0x02, 0x59, 0x23 };
129 struct msgb *msg;
130
131 printf("Testing creating Cipher Reject\n");
132 msg = gsm0808_create_cipher_reject(0x23);
133 VERIFY(msg, res, ARRAY_SIZE(res));
134 msgb_free(msg);
135}
136
137static void test_create_cm_u()
138{
Harald Welte07b625d2012-01-23 10:02:58 +0100139 static const uint8_t res[] = {
140 0x00, 0x07, 0x54, 0x12, 0x01, 0x23, 0x13, 0x01, 0x42 };
141 static const uint8_t res2o[] = {
142 0x00, 0x04, 0x54, 0x12, 0x01, 0x23 };
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100143 struct msgb *msg;
Harald Welte07b625d2012-01-23 10:02:58 +0100144 const uint8_t cm2 = 0x23;
145 const uint8_t cm3 = 0x42;
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100146
147 printf("Testing creating CM U\n");
Harald Welte07b625d2012-01-23 10:02:58 +0100148 msg = gsm0808_create_classmark_update(&cm2, 1, &cm3, 1);
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100149 VERIFY(msg, res, ARRAY_SIZE(res));
Harald Welte07b625d2012-01-23 10:02:58 +0100150
151 msg = gsm0808_create_classmark_update(&cm2, 1, NULL, 0);
152 VERIFY(msg, res2o, ARRAY_SIZE(res2o));
153
Holger Hans Peter Freyther97510812012-01-22 13:36:52 +0100154 msgb_free(msg);
155}
156
157static void test_create_sapi_reject()
158{
159 static const uint8_t res[] = { 0x00, 0x03, 0x25, 0x03, 0x25 };
160 struct msgb *msg;
161
162 printf("Testing creating SAPI Reject\n");
163 msg = gsm0808_create_sapi_reject(3);
164 VERIFY(msg, res, ARRAY_SIZE(res));
165 msgb_free(msg);
166}
167
168static void test_create_ass_compl()
169{
170 static const uint8_t res1[] = {
171 0x00, 0x09, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c,
172 0x11, 0x40, 0x22 };
173 static const uint8_t res2[] = {
174 0x00, 0x07, 0x02, 0x15, 0x23, 0x21, 0x42, 0x2c, 0x11};
175 struct msgb *msg;
176
177 printf("Testing creating Assignment Complete\n");
178 msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0x22);
179 VERIFY(msg, res1, ARRAY_SIZE(res1));
180 msgb_free(msg);
181
182 msg = gsm0808_create_assignment_completed(0x23, 0x42, 0x11, 0);
183 VERIFY(msg, res2, ARRAY_SIZE(res2));
184 msgb_free(msg);
185}
186
187static void test_create_ass_fail()
188{
189 static const uint8_t res1[] = { 0x00, 0x04, 0x03, 0x04, 0x01, 0x23 };
190 static const uint8_t res2[] = {
191 0x00, 0x06, 0x03, 0x04, 0x01, 0x23, 0x15, 0x02};
192 uint8_t rr_res = 2;
193 struct msgb *msg;
194
195 printf("Testing creating Assignment Failure\n");
196 msg = gsm0808_create_assignment_failure(0x23, NULL);
197 VERIFY(msg, res1, ARRAY_SIZE(res1));
198 msgb_free(msg);
199
200 msg = gsm0808_create_assignment_failure(0x23, &rr_res);
201 VERIFY(msg, res2, ARRAY_SIZE(res2));
202 msgb_free(msg);
203}
204
205static void test_create_clear_rqst()
206{
207 static const uint8_t res[] = { 0x00, 0x04, 0x22, 0x04, 0x01, 0x23 };
208 struct msgb *msg;
209
210 printf("Testing creating Clear Request\n");
211 msg = gsm0808_create_clear_rqst(0x23);
212 VERIFY(msg, res, ARRAY_SIZE(res));
213 msgb_free(msg);
214}
215
216static void test_create_dtap()
217{
218 static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
219 struct msgb *msg, *l3;
220
221 printf("Testing creating DTAP\n");
222 l3 = msgb_alloc_headroom(512, 128, "test");
223 l3->l3h = l3->data;
224 msgb_v_put(l3, 0x23);
225 msgb_v_put(l3, 0x42);
226
227 msg = gsm0808_create_dtap(l3, 0x3);
228 VERIFY(msg, res, ARRAY_SIZE(res));
229 msgb_free(msg);
230 msgb_free(l3);
231}
232
233static void test_prepend_dtap()
234{
235 static const uint8_t res[] = { 0x01, 0x03, 0x02, 0x23, 0x42 };
236 struct msgb *in_msg;
237
238 printf("Testing prepend DTAP\n");
239
240 in_msg = msgb_alloc_headroom(512, 128, "test");
241 msgb_v_put(in_msg, 0x23);
242 msgb_v_put(in_msg, 0x42);
243
244 gsm0808_prepend_dtap_header(in_msg, 0x3);
245 in_msg->l3h = in_msg->data;
246 VERIFY(in_msg, res, ARRAY_SIZE(res));
247 msgb_free(in_msg);
248}
249
250int main(int argc, char **argv)
251{
252 printf("Testing generation of GSM0808 messages\n");
253 test_create_layer3();
254 test_create_reset();
255 test_create_clear_command();
256 test_create_clear_complete();
257 test_create_cipher_complete();
258 test_create_cipher_reject();
259 test_create_cm_u();
260 test_create_sapi_reject();
261 test_create_ass_compl();
262 test_create_ass_fail();
263 test_create_clear_rqst();
264 test_create_dtap();
265 test_prepend_dtap();
266
267 printf("Done\n");
268 return EXIT_SUCCESS;
269}