blob: 982c168bee9620237c21a89f9905dd5e640de145 [file] [log] [blame]
Holger Hans Peter Freytherac967702009-07-29 07:37:48 +02001/*
2 * SCCP testing code
3 *
4 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
Holger Hans Peter Freyther6ae65722010-02-03 18:10:07 +01005 * (C) 2009 by On-Waves
Holger Hans Peter Freytherac967702009-07-29 07:37:48 +02006 *
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 *
23 */
24
25#include <stdio.h>
26
27#include <arpa/inet.h>
28
Holger Hans Peter Freytherac967702009-07-29 07:37:48 +020029#include <openbsc/gsm_data.h>
30#include <openbsc/debug.h>
Harald Weltef98a4972010-02-20 17:29:27 +010031#include <osmocore/msgb.h>
Holger Hans Peter Freyther8a69cb22010-02-12 22:44:50 +010032
33#include <sccp/sccp.h>
Holger Hans Peter Freytherac967702009-07-29 07:37:48 +020034
35#define MIN(x, y) ((x) < (y) ? (x) : (y))
36
37/* BSC -> MSC */
38static const u_int8_t bssmap_reset[] = {
39 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
40 0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04,
41 0x01, 0x20,
42};
43
44/* MSC -> BSC reset ack */
45static const u_int8_t bssmap_reset_ack[] = {
46 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
47 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x03,
48 0x00, 0x01, 0x31,
49};
50
51/* MSC -> BSC paging, connection less */
52static const u_int8_t bssmap_paging[] = {
53 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
54 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x10,
55 0x00, 0x0e, 0x52, 0x08, 0x08, 0x29, 0x47, 0x10,
56 0x02, 0x01, 0x31, 0x97, 0x61, 0x1a, 0x01, 0x06,
57};
58
59/* MSC -> BSC paging, UDT without PC */
60static const u_int8_t bssmap_udt[] = {
61 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
62 0x02, 0x42, 0xfe, 0x10, 0x00, 0x0e, 0x52, 0x08,
63 0x08, 0x29, 0x47, 0x10, 0x02, 0x01, 0x31, 0x97,
64 0x61, 0x1a, 0x01, 0x06,
65};
66
67/* BSC -> MSC connection open */
68static const u_int8_t bssmap_cr[] = {
69 0x01, 0x01, 0x02, 0x03, 0x02, 0x02, 0x04, 0x02,
70 0x42, 0xfe, 0x0f, 0x1f, 0x00, 0x1d, 0x57, 0x05,
71 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x12, 0xc3,
72 0x50, 0x17, 0x10, 0x05, 0x24, 0x11, 0x03, 0x33,
73 0x19, 0xa2, 0x08, 0x29, 0x47, 0x10, 0x02, 0x01,
74 0x31, 0x97, 0x61, 0x00
75};
76
77/* MSC -> BSC connection confirm */
78static const u_int8_t bssmap_cc[] = {
79 0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00,
80};
81
82/* MSC -> BSC DTAP
83 *
84 * we fake a bit and make it BSC -> MSC... so the
85 * payload does not make any sense..
86 */
87static const u_int8_t bssmap_dtap[] = {
88 0x06, 0x00, 0x00, 0x03, 0x00, 0x01, 0x0f, 0x01, 0x00, 0x0c,
89 0x03, 0x05, 0x5c, 0x08, 0x11, 0x81, 0x33, 0x66, 0x02, 0x13,
90 0x45, 0xf4,
91};
92
93/* MSC -> BSC clear command */
94static const u_int8_t bssmap_clear[] = {
95 0x06, 0x00, 0x00, 0x03, 0x00, 0x01, 0x06, 0x00, 0x04, 0x20,
96 0x04, 0x01, 0x09,
97};
98
99/* MSC -> BSC released */
100static const u_int8_t bssmap_released[] = {
101 0x04, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00, 0x01, 0x0f,
102 0x02, 0x23, 0x42, 0x00,
103};
104
105/* BSC -> MSC released */
106static const u_int8_t bssmap_release_complete[] = {
107 0x05, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03
108};
109
110struct test_data {
111 int length;
112 const u_int8_t *data;
113 int payload_start;
114 int payload_length;
115 u_int8_t first_byte;
116
117 /* in case it should trigger a sccp response */
118 int write;
119 const u_int8_t *response;
120 int response_length;
121};
122
123static const struct test_data test_data[] = {
124 {
125 .length = ARRAY_SIZE(bssmap_reset),
126 .data = &bssmap_reset[0],
127 .payload_start = 12,
128 .payload_length = ARRAY_SIZE(bssmap_reset) - 12,
129 .first_byte = 0x0,
130 },
131 {
132 .length = ARRAY_SIZE(bssmap_reset_ack),
133 .data = &bssmap_reset_ack[0],
134 .payload_start = 16,
135 .payload_length = ARRAY_SIZE(bssmap_reset_ack) - 16,
136 .first_byte = 0x0,
137 },
138 {
139 .length = ARRAY_SIZE(bssmap_paging),
140 .data = &bssmap_paging[0],
141 .payload_start = 16,
142 .payload_length = ARRAY_SIZE(bssmap_paging) - 16,
143 .first_byte = 0x0,
144 },
145 {
146 .length = ARRAY_SIZE(bssmap_cr),
147 .data = &bssmap_cr[0],
148 .payload_start = 12,
149 /* 0x00 is end of optional data, subtract this byte */
150 .payload_length = 31,
151 .first_byte = 0x0,
152
153 /* the connection request should trigger a connection confirm */
154 .write = 1,
155 .response = &bssmap_cc[0],
156 .response_length= ARRAY_SIZE(bssmap_cc),
157 },
158 {
159 .length = ARRAY_SIZE(bssmap_dtap),
160 .data = &bssmap_dtap[0],
161 .payload_start = 7,
162 .payload_length = 15,
163 .first_byte = 0x01,
164 },
165 {
166 .length = ARRAY_SIZE(bssmap_clear),
167 .data = &bssmap_clear[0],
168 .payload_start = 7,
169 .payload_length = 6,
170 .first_byte = 0x00,
171 },
172 {
173 .length = ARRAY_SIZE(bssmap_released),
174 .data = &bssmap_released[0],
175 .payload_length = 2,
176 .payload_start = 11,
177 .first_byte = 0x23,
178
179 .write = 1,
180 .response = &bssmap_release_complete[0],
181 .response_length= ARRAY_SIZE(bssmap_release_complete),
182 },
183};
184
185/* we will send UDTs and verify they look like this */
186static const struct test_data send_data[] = {
187 {
188 .length = ARRAY_SIZE(bssmap_udt),
189 .data = &bssmap_udt[0],
190 .payload_start = 12,
191 .payload_length = ARRAY_SIZE(bssmap_udt) - 12,
192 .first_byte = 0x0,
193 },
194 {
195 .length = ARRAY_SIZE(bssmap_reset),
196 .data = &bssmap_reset[0],
197 .payload_start = 12,
198 .payload_length = ARRAY_SIZE(bssmap_reset) - 12,
199 .first_byte = 0x0,
200 },
201};
202
203struct connection_test {
204 /* should the connection be refused? */
205 int refuse;
206
207 int with_data;
208
209 /* on which side to close the connection? */
210 int close_side;
211 int close_cause;
212};
213
214/* sccp connection handling we want to test */
215static const struct connection_test connection_tests[] = {
216 {
217 .refuse = 1,
218 },
219 {
220 .refuse = 1,
221 .with_data = 1,
222 },
223 {
224 .refuse = 0,
225 .close_side = 0,
226 .close_cause = 5,
227 },
228 {
229 .refuse = 0,
230 .close_side = 0,
231 .close_cause = 5,
232 .with_data = 1,
233 },
234 {
235 .refuse = 0,
236 .close_side = 1,
237 .close_cause = 5,
238 },
239 {
240 .refuse = 0,
241 .close_side = 1,
242 .close_cause = 5,
243 .with_data = 1,
244 },
245};
246
247/* testing procedure:
248 * - we will use sccp_write and see what will be set in the
249 * outgoing callback
250 * - we will call sccp_system_incoming and see which calls
251 * are made. And then compare it to the ones we expect. We
252 * want the payload to arrive, or callbacks to be called.
253 * - we will use sccp_connection_socket and sccp_connection_write
254 * and verify state handling of connections
255 */
256
257static int current_test;
258
259/*
260 * test state...
261 */
262static int called = 0;
263static int matched = 0;
264static int write_called = 0;
265
266#define FAIL(x, args...) printf("FAILURE in %s:%d: " x, __FILE__, __LINE__, ## args)
267
268/*
269 * writing these packets and expecting a result
270 */
271int sccp_read_cb(struct msgb *data, unsigned len, void *context)
272{
273 u_int16_t payload_length = test_data[current_test].payload_length;
274 const u_int8_t *got, *wanted;
275 int i;
276
277 called = 1;
278
279 if (msgb_l3len(data) < len) {
280 /* this should never be reached */
281 FAIL("Something horrible happened.. invalid packet..\n");
282 exit(-1);
283 }
284
285 if (len == 0 || len != payload_length) {
286 FAIL("length mismatch: got: %d wanted: %d\n", msgb_l3len(data), payload_length);
287 return -1;
288 }
289
290 if (data->l3h[0] != test_data[current_test].first_byte) {
291 FAIL("The first bytes of l3 do not match: 0x%x 0x%x\n",
292 data->l3h[0], test_data[current_test].first_byte);
293 return -1;
294 }
295
296 got = &data->l3h[0];
297 wanted = test_data[current_test].data + test_data[current_test].payload_start;
298
299 for (i = 0; i < len; ++i) {
300 if (got[i] != wanted[i]) {
301 FAIL("Failed to compare byte. Got: 0x%x Wanted: 0x%x at %d\n",
302 got[i], wanted[i], i);
303 return -1;
304 }
305 }
306
307 matched = 1;
308 return 0;
309}
310
311int sccp_write_cb(struct msgb *data, void *ctx)
312{
313 int i = 0;
314 const u_int8_t *got, *wanted;
315
316 if (test_data[current_test].response == NULL) {
317 FAIL("Didn't expect write callback\n");
318 return -1;
319 } else if (test_data[current_test].response_length != msgb_l2len(data)) {
320 FAIL("Size does not match. Got: %d Wanted: %d\n",
321 msgb_l2len(data), test_data[current_test].response_length);
322 }
323
324 got = &data->l2h[0];
325 wanted = test_data[current_test].response;
326
327 for (i = 0; i < msgb_l2len(data); ++i) {
328 if (got[i] != wanted[i]) {
329 FAIL("Failed to compare byte. Got: 0x%x Wanted: 0x%x at %d\n",
330 got[i], wanted[i], i);
331 return -1;
332 }
333 }
334
335 write_called = 1;
336 return 0;
337}
338
339void sccp_c_read(struct sccp_connection *connection, struct msgb *msgb, unsigned int len)
340{
341 sccp_read_cb(msgb, len, connection->data_ctx);
342}
343
344void sccp_c_state(struct sccp_connection *connection, int old_state)
345{
346 if (connection->connection_state >= SCCP_CONNECTION_STATE_RELEASE_COMPLETE)
347 sccp_connection_free(connection);
348}
349
350int sccp_accept_cb(struct sccp_connection *connection, void *user_data)
351{
352 called = 1;
353 unsigned int ref = 0;
354 ref |= connection->destination_local_reference.octet1 << 24;
355 ref |= connection->destination_local_reference.octet2 << 16;
356 ref |= connection->destination_local_reference.octet3 << 8;
357 ref = ntohl(ref);
358
359 connection->data_cb = sccp_c_read;
360 connection->state_cb = sccp_c_state;
361
362 /* accept this */
363 return 0;
364}
365
366static int sccp_udt_write_cb(struct msgb *data, void *context)
367{
368 const u_int8_t *got, *wanted;
369 int i;
370
371 write_called = 1;
372
373 if (send_data[current_test].length != msgb_l2len(data)) {
374 FAIL("Size does not match. Got: %d Wanted: %d\n",
375 msgb_l2len(data), send_data[current_test].length);
376 return -1;
377 }
378
379 got = &data->l2h[0];
380 wanted = send_data[current_test].data;
381
382 for (i = 0; i < msgb_l2len(data); ++i) {
383 if (got[i] != wanted[i]) {
384 FAIL("Failed to compare byte. Got: 0x%x Wanted: 0x%x at %d\n",
385 got[i], wanted[i], i);
386 return -1;
387 }
388 }
389
390 matched = 1;
391 return 0;
392}
393
394static void test_sccp_system(void)
395{
396 sccp_system_init(sccp_write_cb, NULL);
397 sccp_set_read(&sccp_ssn_bssap, sccp_read_cb, NULL);
398 sccp_connection_set_incoming(&sccp_ssn_bssap, sccp_accept_cb, NULL);
399
400 for (current_test = 0; current_test < ARRAY_SIZE(test_data); ++current_test) {
401 unsigned int length = test_data[current_test].length;
402 struct msgb *msg = msgb_alloc_headroom(length + 2, 2, __func__);
403 msg->l2h = msgb_put(msg, length);
404 memcpy(msg->l2h, test_data[current_test].data, length);
405
406 called = matched = write_called = 0;
407 printf("Testing packet: %d\n", current_test);
408 sccp_system_incoming(msg);
409
410 if (!called || !matched || (test_data[current_test].write != write_called))
411 FAIL("current test: %d called: %d matched: %d write: %d\n",
412 current_test, called, matched, write_called);
413
414 msgb_free(msg);
415 }
416}
417
418/* test sending of udt */
419static void test_sccp_send_udt(void)
420{
421 sccp_system_init(sccp_udt_write_cb, NULL);
422 sccp_set_read(NULL, NULL, NULL);
423 sccp_connection_set_incoming(NULL, NULL, NULL);
424
425 for (current_test = 0; current_test < ARRAY_SIZE(send_data); ++current_test) {
426 const struct test_data *test = &send_data[current_test];
427
428 struct msgb *msg = msgb_alloc(test->payload_length, __func__);
429 msg->l3h = msgb_put(msg, test->payload_length);
430 memcpy(msg->l3h, test->data + test->payload_start, test->payload_length);
431
432 matched = write_called = 0;
433 printf("Testing packet: %d\n", current_test);
434 sccp_write(msg, &sccp_ssn_bssap, &sccp_ssn_bssap, 0);
435
436 if (!matched || !write_called)
437 FAIL("current test: %d matched: %d write: %d\n",
438 current_test, matched, write_called);
439
440 msgb_free(msg);
441 }
442}
443
444/* send udt from one end to another */
445static unsigned int test_value = 0x2442;
446static int sccp_udt_read(struct msgb *data, unsigned int len, void *context)
447{
448 unsigned int *val;
449
450 if (len != 4) {
451 FAIL("Wrong size: %d\n", msgb_l3len(data));
452 return -1;
453 }
454
455 val = (unsigned int*)data->l3h;
456 matched = test_value == *val;
457
458 return 0;
459}
460
461static int sccp_write_loop(struct msgb *data, void *context)
462{
463 /* send it back to us */
464 sccp_system_incoming(data);
465 return 0;
466}
467
468static void test_sccp_udt_communication(void)
469{
470 struct msgb *data;
471 unsigned int *val;
472
473 sccp_system_init(sccp_write_loop, NULL);
474 sccp_set_read(&sccp_ssn_bssap, sccp_udt_read, NULL);
475 sccp_connection_set_incoming(NULL, NULL, NULL);
476
477
478 data = msgb_alloc(4, "test data");
479 data->l3h = &data->data[0];
480 val = (unsigned int *)msgb_put(data, 4);
481 *val = test_value;
482
483 matched = 0;
484 sccp_write(data, &sccp_ssn_bssap, &sccp_ssn_bssap, 0);
485
486 if (!matched)
487 FAIL("Talking with us didn't work\n");
488
489 msgb_free(data);
490}
491
492
493/* connection testing... open, send, close */
494static const struct connection_test *current_con_test;
495static struct sccp_connection *outgoing_con;
496static struct sccp_connection *incoming_con;
497static int outgoing_data, incoming_data, incoming_state, outgoing_state;
498
499static struct msgb *test_data1, *test_data2, *test_data3;
500
501static void sccp_conn_in_state(struct sccp_connection *conn, int old_state)
502{
503 printf("\tincome: %d -> %d\n", old_state, conn->connection_state);
504 if (conn->connection_state >= SCCP_CONNECTION_STATE_RELEASE_COMPLETE) {
505 if (conn == incoming_con) {
506 sccp_connection_free(conn);
507 incoming_con = NULL;
508 }
509 }
510}
511
512static void sccp_conn_in_data(struct sccp_connection *conn, struct msgb *msg, unsigned int len)
513{
514 /* compare the data */
515 ++incoming_data;
516 printf("\tincoming data: %d\n", len);
517
518 /* compare the data */
519 if (len != 4) {
520 FAIL("Length of packet is wrong: %u %u\n", msgb_l3len(msg), len);
521 return;
522 }
523
524 if (incoming_data == 1) {
525 if (memcmp(msg->l3h, test_data1->l3h, len) != 0) {
526 FAIL("Comparing the data failed: %d\n", incoming_data);
527 incoming_state = 0;
528 printf("Got: %s\n", hexdump(msg->l3h, len));
529 printf("Wanted: %s\n", hexdump(test_data1->l3h, len));
530
531 }
532 } else if (incoming_data == 2) {
533 if (memcmp(msg->l3h, test_data2->l3h, len) != 0) {
534 FAIL("Comparing the data failed: %d\n", incoming_data);
535 incoming_state = 0;
536 printf("Got: %s\n", hexdump(msg->l3h, len));
537 printf("Wanted: %s\n", hexdump(test_data2->l3h, len));
538 }
539 }
540
541 /* sending out data */
542 if (incoming_data == 2) {
543 printf("\tReturning data3\n");
544 sccp_connection_write(conn, test_data3);
545 }
546}
547
548static int sccp_conn_accept(struct sccp_connection *conn, void *ctx)
549{
550 printf("\taccept: %p\n", conn);
551 conn->state_cb = sccp_conn_in_state;
552 conn->data_cb = sccp_conn_in_data;
553
554 if (current_con_test->refuse)
555 return -1;
556
557 incoming_con = conn;
558 return 0;
559}
560
561/* callbacks for the outgoing side */
562static void sccp_conn_out_state(struct sccp_connection *conn, int old_state)
563{
564 printf("\toutgoing: %p %d -> %d\n", conn, old_state, conn->connection_state);
565
566 if (conn->connection_state >= SCCP_CONNECTION_STATE_RELEASE_COMPLETE) {
567 if (conn == outgoing_con) {
568 sccp_connection_free(conn);
569 outgoing_con = NULL;
570 }
571 }
572}
573
574static void sccp_conn_out_data(struct sccp_connection *conn, struct msgb *msg, unsigned int len)
575{
576 ++outgoing_data;
577 printf("\toutgoing data: %p %d\n", conn, len);
578
579 if (len != 4)
580 FAIL("Length of packet is wrong: %u %u\n", msgb_l3len(msg), len);
581
582 if (outgoing_data == 1) {
583 if (memcmp(msg->l3h, test_data3->l3h, len) != 0) {
584 FAIL("Comparing the data failed\n");
585 outgoing_state = 0;
586 }
587 }
588}
589
590static void do_test_sccp_connection(const struct connection_test *test)
591{
592 int ret;
593
594 current_con_test = test;
595 outgoing_con = incoming_con = 0;
596
597 outgoing_con = sccp_connection_socket();
598 if (!outgoing_con) {
599 FAIL("Connection is NULL\n");
600 return;
601 }
602
603 outgoing_con->state_cb = sccp_conn_out_state;
604 outgoing_con->data_cb = sccp_conn_out_data;
605 outgoing_data = incoming_data = 0;
606 incoming_state = outgoing_state = 1;
607
608 /* start testing */
609 if (test->with_data) {
610 if (sccp_connection_connect(outgoing_con, &sccp_ssn_bssap, test_data1) != 0)
611 FAIL("Binding failed\n");
612 } else {
613 ++incoming_data;
614 if (sccp_connection_connect(outgoing_con, &sccp_ssn_bssap, NULL) != 0)
615 FAIL("Binding failed\n");
616 }
617
618 if (test->refuse) {
619 if (outgoing_con)
620 FAIL("Outgoing connection should have been refused.\n");
621 } else {
622 if (!incoming_con)
623 FAIL("Creating incoming didn't work.\n");
624
625 printf("\tWriting test data2\n");
626 sccp_connection_write(outgoing_con, test_data2);
Holger Hans Peter Freyther3b9516e2009-11-18 22:11:28 +0100627 sccp_connection_send_it(outgoing_con);
Holger Hans Peter Freytherac967702009-07-29 07:37:48 +0200628
629 /* closing connection */
630 if (test->close_side == 0)
631 ret = sccp_connection_close(outgoing_con, 0);
632 else
633 ret = sccp_connection_close(incoming_con, 0);
634
635 if (ret != 0)
636 FAIL("Closing the connection failed\n");
637 }
638
639 /* outgoing should be gone now */
640 if (outgoing_con)
641 FAIL("Outgoing connection was not properly closed\n");
642
643 if (incoming_con)
644 FAIL("Incoming connection was not propery closed.\n");
645
646 if (test->refuse == 0) {
647 if (outgoing_data != 1 || incoming_data != 2) {
648 FAIL("Data sending failed: %d/%d %d/%d\n",
649 outgoing_data, 1,
650 incoming_data, 2);
651 }
652 }
653
654 if (!incoming_state || !outgoing_state)
655 FAIL("Failure with the state transition. %d %d\n",
656 outgoing_state, incoming_state);
657}
658
659static void test_sccp_connection(void)
660{
661 sccp_system_init(sccp_write_loop, NULL);
662 sccp_set_read(NULL, NULL, NULL);
663 sccp_connection_set_incoming(&sccp_ssn_bssap, sccp_conn_accept, NULL);
664
665 test_data1 = msgb_alloc(4, "data1");
666 test_data1->l3h = msgb_put(test_data1, 4);
667 *((unsigned int*)test_data1->l3h) = 0x23421122;
668
669 test_data2 = msgb_alloc(4, "data2");
670 test_data2->l3h = msgb_put(test_data2, 4);
671 *((unsigned int*)test_data2->l3h) = 0x42232211;
672
673 test_data3 = msgb_alloc(4, "data3");
674 test_data3->l3h = msgb_put(test_data3, 4);
675 *((unsigned int*)test_data3->l3h) = 0x2323ff55;
676
677
678 for (current_test = 0; current_test < ARRAY_SIZE(connection_tests); ++current_test) {
679 printf("Testing %d refuse: %d with_data: %d\n",
680 current_test, connection_tests[current_test].refuse,
681 connection_tests[current_test].with_data);
682 do_test_sccp_connection(&connection_tests[current_test]);
683 }
684
685 msgb_free(test_data1);
686 msgb_free(test_data2);
687 msgb_free(test_data3);
688}
689
690/* invalid input */
691static void test_sccp_system_crash(void)
692{
693 printf("trying to provoke a crash with invalid input\n");
694 sccp_set_read(&sccp_ssn_bssap, sccp_read_cb, NULL);
695 sccp_connection_set_incoming(&sccp_ssn_bssap, sccp_accept_cb, NULL);
696
697 for (current_test = 0; current_test < ARRAY_SIZE(test_data); ++current_test) {
698 int original_length = test_data[current_test].length;
699 int length = original_length + 2;
700 int i;
701
702 printf("Testing packet: %d\n", current_test);
703
704 for (i = length; i >= 0; --i) {
705 unsigned int length = MIN(test_data[current_test].length, i);
706 struct msgb *msg = msgb_alloc_headroom(length + 2, 2, __func__);
707 msg->l2h = msgb_put(msg, length);
708 memcpy(msg->l2h, test_data[current_test].data, length);
709 sccp_system_incoming(msg);
710 msgb_free(msg);
711 }
712 }
713
714 printf("survived\n");
715}
716
717
718int main(int argc, char **argv)
719{
720 test_sccp_system();
721 test_sccp_send_udt();
722 test_sccp_udt_communication();
723 test_sccp_connection();
724 test_sccp_system_crash();
725 return 0;
726}
Holger Hans Peter Freyther5dbd71e2009-12-23 05:13:48 +0100727
728void db_store_counter() {}