/*
 * SCCP testing code
 *
 * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2009 by On-Waves
 *
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include <stdio.h>

#include <arpa/inet.h>

#include <openbsc/gsm_data.h>
#include <openbsc/debug.h>
#include <osmocore/msgb.h>

#include <sccp/sccp.h>

#define MIN(x, y) ((x) < (y) ? (x) : (y))

/* BSC -> MSC */
static const u_int8_t bssmap_reset[] = {
	0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
	0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04,
	0x01, 0x20,
};

/* MSC -> BSC reset ack */
static const u_int8_t bssmap_reset_ack[] = {
	0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
	0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x03,
	0x00, 0x01, 0x31,
};

/* MSC -> BSC paging, connection less */
static const u_int8_t bssmap_paging[] = {
	0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
	0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x10,
	0x00, 0x0e, 0x52, 0x08, 0x08, 0x29, 0x47, 0x10,
	0x02, 0x01, 0x31, 0x97, 0x61, 0x1a, 0x01, 0x06,
};

/* MSC -> BSC paging, UDT without PC  */
static const u_int8_t bssmap_udt[] = {
	0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
	0x02, 0x42, 0xfe, 0x10, 0x00, 0x0e, 0x52, 0x08,
	0x08, 0x29, 0x47, 0x10, 0x02, 0x01, 0x31, 0x97,
	0x61, 0x1a, 0x01, 0x06,
};

/* BSC -> MSC connection open */
static const u_int8_t bssmap_cr[] = {
	0x01, 0x01, 0x02, 0x03, 0x02, 0x02, 0x04, 0x02,
	0x42, 0xfe, 0x0f, 0x1f, 0x00, 0x1d, 0x57, 0x05,
	0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x12, 0xc3,
	0x50, 0x17, 0x10, 0x05, 0x24, 0x11, 0x03, 0x33,
	0x19, 0xa2, 0x08, 0x29, 0x47, 0x10, 0x02, 0x01,
	0x31, 0x97, 0x61, 0x00
};

/* MSC -> BSC connection confirm */
static const u_int8_t bssmap_cc[] = {
	0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00,
};

/* MSC -> BSC DTAP
 *
 * we fake a bit and make it BSC -> MSC... so the
 * payload does not make any sense..
 */
static const u_int8_t bssmap_dtap[] = {
	0x06, 0x00, 0x00, 0x03, 0x00, 0x01, 0x0f, 0x01, 0x00, 0x0c,
	0x03, 0x05, 0x5c, 0x08, 0x11, 0x81, 0x33, 0x66, 0x02, 0x13,
	0x45, 0xf4,
};

/* MSC -> BSC clear command */
static const u_int8_t bssmap_clear[] = {
	0x06, 0x00, 0x00, 0x03, 0x00, 0x01, 0x06, 0x00, 0x04, 0x20,
	0x04, 0x01, 0x09,
};

/* MSC -> BSC released */
static const u_int8_t bssmap_released[] = {
	0x04, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00, 0x01, 0x0f,
	0x02, 0x23, 0x42, 0x00,
};

/* BSC -> MSC released */
static const u_int8_t bssmap_release_complete[] = {
	0x05, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03
};

struct test_data {
	int length;
	const u_int8_t *data;
	int payload_start;
	int payload_length;
	u_int8_t first_byte;

        /* in case it should trigger a sccp response */
	int write;
	const u_int8_t  *response;
	int response_length;
};

static const struct test_data test_data[] = {
	{
		.length		= ARRAY_SIZE(bssmap_reset),
		.data		= &bssmap_reset[0],
		.payload_start	= 12,
		.payload_length = ARRAY_SIZE(bssmap_reset) - 12,
		.first_byte	= 0x0,
	},
	{
		.length		= ARRAY_SIZE(bssmap_reset_ack),
		.data		= &bssmap_reset_ack[0],
		.payload_start	= 16,
		.payload_length = ARRAY_SIZE(bssmap_reset_ack) - 16,
		.first_byte	= 0x0,
	},
	{
		.length		= ARRAY_SIZE(bssmap_paging),
		.data		= &bssmap_paging[0],
		.payload_start	= 16,
		.payload_length = ARRAY_SIZE(bssmap_paging) - 16,
		.first_byte	= 0x0,
	},
	{
		.length		= ARRAY_SIZE(bssmap_cr),
		.data		= &bssmap_cr[0],
		.payload_start	= 12,
		/* 0x00 is end of optional data, subtract this byte */
		.payload_length = 31,
		.first_byte	= 0x0,

		/* the connection request should trigger a connection confirm */
		.write		= 1,
		.response	= &bssmap_cc[0],
		.response_length= ARRAY_SIZE(bssmap_cc),
	},
	{
		.length		= ARRAY_SIZE(bssmap_dtap),
		.data		= &bssmap_dtap[0],
		.payload_start	= 7,
		.payload_length = 15,
		.first_byte	= 0x01,
	},
	{
		.length		= ARRAY_SIZE(bssmap_clear),
		.data		= &bssmap_clear[0],
		.payload_start	= 7,
		.payload_length = 6,
		.first_byte	= 0x00,
	},
	{
		.length		= ARRAY_SIZE(bssmap_released),
		.data		= &bssmap_released[0],
		.payload_length = 2,
		.payload_start  = 11,
		.first_byte	= 0x23,

		.write		= 1,
		.response	= &bssmap_release_complete[0],
		.response_length= ARRAY_SIZE(bssmap_release_complete),
	},
};

/* we will send UDTs and verify they look like this */
static const struct test_data send_data[] = {
	{
		.length		= ARRAY_SIZE(bssmap_udt),
		.data		= &bssmap_udt[0],
		.payload_start	= 12,
		.payload_length = ARRAY_SIZE(bssmap_udt) - 12,
		.first_byte	= 0x0,
	},
	{
		.length		= ARRAY_SIZE(bssmap_reset),
		.data		= &bssmap_reset[0],
		.payload_start	= 12,
		.payload_length = ARRAY_SIZE(bssmap_reset) - 12,
		.first_byte	= 0x0,
	},
};

struct connection_test {
	/* should the connection be refused? */
	int refuse;

	int with_data;

	/* on which side to close the connection? */
	int close_side;
	int close_cause;
};

/* sccp connection handling we want to test */
static const struct connection_test connection_tests[] = {
	{
		.refuse	= 1,
	},
	{
		.refuse	= 1,
		.with_data = 1,
	},
	{
		.refuse = 0,
		.close_side = 0,
		.close_cause = 5,
	},
	{
		.refuse = 0,
		.close_side = 0,
		.close_cause = 5,
		.with_data = 1,
	},
	{
		.refuse = 0,
		.close_side = 1,
		.close_cause = 5,
	},
	{
		.refuse = 0,
		.close_side = 1,
		.close_cause = 5,
		.with_data = 1,
	},
};

struct sccp_parse_header_result {
	/* results */
	int msg_type;
	int wanted_len;
	int src_ssn;
	int dst_ssn;

	int has_src_ref, has_dst_ref;
	struct sccp_source_reference src_ref;
	struct sccp_source_reference dst_ref;

	/* the input */
	const u_int8_t *input;
	int input_len;
};

static const u_int8_t it_test[] = {
0x10, 0x01, 0x07, 
0x94, 0x01, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00 };

static const u_int8_t proto_err[] = {
0x0f, 0x0c, 0x04, 0x00, 0x00,
};

static const struct sccp_parse_header_result parse_result[] = {
	{
		.msg_type	= SCCP_MSG_TYPE_IT,
		.wanted_len	= 0,
		.src_ssn	= -1,
		.dst_ssn	= -1,
		.has_src_ref	= 1,
		.has_dst_ref	= 1,

		.src_ref	= {
			.octet1 = 0x01,
			.octet2 = 0x04,
			.octet3 = 0x00
		},
		.dst_ref	= {
			.octet1 = 0x01,
			.octet2 = 0x07,
			.octet3 = 0x94,
		},

		.input		= it_test,
		.input_len	= sizeof(it_test),
	},
	{
		.msg_type	= SCCP_MSG_TYPE_ERR,
		.wanted_len	= 0,
		.src_ssn	= -1,
		.dst_ssn	= -1,
		.has_src_ref	= 0,
		.has_dst_ref	= 1,
		.dst_ref	= {
			.octet1 = 0x0c,
			.octet2 = 0x04,
			.octet3 = 0x00,
		},
		.input		= proto_err,
		.input_len	= sizeof(proto_err),
	},
};


/* testing procedure:
 *	- we will use sccp_write and see what will be set in the
 *	  outgoing callback
 *	- we will call sccp_system_incoming and see which calls
 *	  are made. And then compare it to the ones we expect. We
 *	  want the payload to arrive, or callbacks to be called.
 *	- we will use sccp_connection_socket and sccp_connection_write
 *	  and verify state handling of connections
 */

static int current_test;

/*
 * test state...
 */
static int called  = 0;
static int matched = 0;
static int write_called = 0;

#define FAIL(x, args...) printf("FAILURE in %s:%d: " x, __FILE__, __LINE__, ## args)

/*
 * writing these packets and expecting a result
 */
int sccp_read_cb(struct msgb *data, unsigned len, void *context)
{
	u_int16_t payload_length = test_data[current_test].payload_length;
	const u_int8_t *got, *wanted;
	int i;

	called = 1;

	if (msgb_l3len(data) < len) {
		/* this should never be reached */
		FAIL("Something horrible happened.. invalid packet..\n");
		exit(-1);
	}

	if (len == 0 || len != payload_length) {
		FAIL("length mismatch: got: %d wanted: %d\n", msgb_l3len(data), payload_length);
		return -1;
	}

	if (data->l3h[0] !=  test_data[current_test].first_byte) {
		FAIL("The first bytes of l3 do not match: 0x%x 0x%x\n",
			data->l3h[0], test_data[current_test].first_byte);
		return -1;
	}

	got = &data->l3h[0];
	wanted = test_data[current_test].data + test_data[current_test].payload_start;

	for (i = 0; i < len; ++i) {
		if (got[i] != wanted[i]) {
			FAIL("Failed to compare byte. Got: 0x%x Wanted: 0x%x at %d\n",
			     got[i], wanted[i], i);
			return -1;
		}
	}

	matched = 1;
	return 0;
}

void sccp_write_cb(struct msgb *data, void *ctx)
{
	int i = 0;
	const u_int8_t *got, *wanted;

	if (test_data[current_test].response == NULL) {
		FAIL("Didn't expect write callback\n");
		goto exit;
	} else if (test_data[current_test].response_length != msgb_l2len(data)) {
		FAIL("Size does not match. Got: %d Wanted: %d\n",
		     msgb_l2len(data), test_data[current_test].response_length);
	}

	got = &data->l2h[0];
	wanted = test_data[current_test].response;

	for (i = 0; i < msgb_l2len(data); ++i) {
		if (got[i] != wanted[i]) {
			FAIL("Failed to compare byte. Got: 0x%x Wanted: 0x%x at %d\n",
			     got[i], wanted[i], i);
			goto exit;
		}
	}

	write_called = 1;

exit:
	msgb_free(data);
}

void sccp_c_read(struct sccp_connection *connection, struct msgb *msgb, unsigned int len)
{
	sccp_read_cb(msgb, len, connection->data_ctx);
}

void sccp_c_state(struct sccp_connection *connection, int old_state)
{
	if (connection->connection_state >= SCCP_CONNECTION_STATE_RELEASE_COMPLETE)
		sccp_connection_free(connection);
}

int sccp_accept_cb(struct sccp_connection *connection, void *user_data)
{
	called = 1;
	unsigned int ref = 0;
	ref |= connection->destination_local_reference.octet1 << 24;
	ref |= connection->destination_local_reference.octet2 << 16;
	ref |= connection->destination_local_reference.octet3 <<  8;
	ref = ntohl(ref);

	connection->data_cb = sccp_c_read;
	connection->state_cb = sccp_c_state;

	/* accept this */
	return 0;
}

static void sccp_udt_write_cb(struct msgb *data, void *context)
{
	const u_int8_t *got, *wanted;
	int i;

	write_called = 1;

	if (send_data[current_test].length != msgb_l2len(data)) {
		FAIL("Size does not match. Got: %d Wanted: %d\n",
		     msgb_l2len(data), send_data[current_test].length);
		goto exit;
	}

	got = &data->l2h[0];
	wanted = send_data[current_test].data;

	for (i = 0; i < msgb_l2len(data); ++i) {
		if (got[i] != wanted[i]) {
			FAIL("Failed to compare byte. Got: 0x%x Wanted: 0x%x at %d\n",
			     got[i], wanted[i], i);
			goto exit;
		}
	}

	matched = 1;

exit:
	msgb_free(data);
}

static void test_sccp_system(void)
{
	sccp_system_init(sccp_write_cb, NULL);
	sccp_set_read(&sccp_ssn_bssap, sccp_read_cb, NULL);
	sccp_connection_set_incoming(&sccp_ssn_bssap, sccp_accept_cb, NULL);

	for (current_test = 0; current_test < ARRAY_SIZE(test_data); ++current_test) {
		unsigned int length = test_data[current_test].length;
		struct msgb *msg = msgb_alloc_headroom(length + 2, 2, __func__);
		msg->l2h = msgb_put(msg, length);
		memcpy(msg->l2h, test_data[current_test].data, length);

		called = matched = write_called = 0;
		printf("Testing packet: %d\n", current_test);
		sccp_system_incoming(msg);

		if (!called || !matched || (test_data[current_test].write != write_called))
			FAIL("current test: %d called: %d matched: %d write: %d\n",
			     current_test, called, matched, write_called);

		msgb_free(msg);
	}
}

/* test sending of udt */
static void test_sccp_send_udt(void)
{
	sccp_system_init(sccp_udt_write_cb, NULL);
	sccp_set_read(NULL, NULL, NULL);
	sccp_connection_set_incoming(NULL, NULL, NULL);

	for (current_test = 0; current_test < ARRAY_SIZE(send_data); ++current_test) {
		const struct test_data *test = &send_data[current_test];

		struct msgb *msg = msgb_alloc(test->payload_length, __func__);
		msg->l3h = msgb_put(msg, test->payload_length);
		memcpy(msg->l3h, test->data + test->payload_start, test->payload_length);

		matched = write_called = 0;
		printf("Testing packet: %d\n", current_test);
		sccp_write(msg, &sccp_ssn_bssap, &sccp_ssn_bssap, 0);

		if (!matched || !write_called)
			FAIL("current test: %d matched: %d write: %d\n",
			     current_test, matched, write_called);

		msgb_free(msg);
	}
}

/* send udt from one end to another */
static unsigned int test_value = 0x2442;
static int sccp_udt_read(struct msgb *data, unsigned int len, void *context)
{
	unsigned int *val;

	if (len != 4) {
		FAIL("Wrong size: %d\n", msgb_l3len(data));
		return -1;
	}

	val = (unsigned int*)data->l3h;
	matched = test_value == *val;

	return 0;
}

static void sccp_write_loop(struct msgb *data, void *context)
{
	/* send it back to us */
	sccp_system_incoming(data);
	msgb_free(data);
}

static void test_sccp_udt_communication(void)
{
	struct msgb *data;
	unsigned int *val;

	sccp_system_init(sccp_write_loop, NULL);
	sccp_set_read(&sccp_ssn_bssap, sccp_udt_read, NULL);
	sccp_connection_set_incoming(NULL, NULL, NULL);


	data = msgb_alloc(4, "test data");
	data->l3h = &data->data[0];
	val = (unsigned int *)msgb_put(data, 4);
	*val = test_value;

	matched = 0;
	sccp_write(data, &sccp_ssn_bssap, &sccp_ssn_bssap, 0);

	if (!matched)
	    FAIL("Talking with us didn't work\n");

	msgb_free(data);
}


/* connection testing... open, send, close */
static const struct connection_test *current_con_test;
static struct sccp_connection *outgoing_con;
static struct sccp_connection *incoming_con;
static int outgoing_data, incoming_data, incoming_state, outgoing_state;

static struct msgb *test_data1, *test_data2, *test_data3;

static void sccp_conn_in_state(struct sccp_connection *conn, int old_state)
{
	printf("\tincome: %d -> %d\n", old_state, conn->connection_state);
	if (conn->connection_state >= SCCP_CONNECTION_STATE_RELEASE_COMPLETE) {
		if (conn == incoming_con) {
			sccp_connection_free(conn);
			incoming_con = NULL;
		}
	}
}

static void sccp_conn_in_data(struct sccp_connection *conn, struct msgb *msg, unsigned int len)
{
	/* compare the data */
	++incoming_data;
	printf("\tincoming data: %d\n", len);

	/* compare the data */
	if (len != 4) {
		FAIL("Length of packet is wrong: %u %u\n", msgb_l3len(msg), len);
		return;
	}

	if (incoming_data == 1) {
		if (memcmp(msg->l3h, test_data1->l3h, len) != 0) {
			FAIL("Comparing the data failed: %d\n", incoming_data);
			incoming_state = 0;
			printf("Got:    %s\n", hexdump(msg->l3h, len));
			printf("Wanted: %s\n", hexdump(test_data1->l3h, len));

		}
	} else if (incoming_data == 2) {
		if (memcmp(msg->l3h, test_data2->l3h, len) != 0) {
			FAIL("Comparing the data failed: %d\n", incoming_data);
			incoming_state = 0;
			printf("Got:    %s\n", hexdump(msg->l3h, len));
			printf("Wanted: %s\n", hexdump(test_data2->l3h, len));
		}
	}

	/* sending out data */
	if (incoming_data == 2) {
		printf("\tReturning data3\n");
		sccp_connection_write(conn, test_data3);
	}
}

static int sccp_conn_accept(struct sccp_connection *conn, void *ctx)
{
	printf("\taccept: %p\n", conn);
	conn->state_cb = sccp_conn_in_state;
	conn->data_cb = sccp_conn_in_data;

	if (current_con_test->refuse)
		return -1;

	incoming_con = conn;
	return 0;
}

/* callbacks for the outgoing side */
static void sccp_conn_out_state(struct sccp_connection *conn, int old_state)
{
	printf("\toutgoing: %p %d -> %d\n", conn, old_state, conn->connection_state);

	if (conn->connection_state >= SCCP_CONNECTION_STATE_RELEASE_COMPLETE) {
		if (conn == outgoing_con) {
			sccp_connection_free(conn);
			outgoing_con = NULL;
		}
	}
}

static void sccp_conn_out_data(struct sccp_connection *conn, struct msgb *msg, unsigned int len)
{
	++outgoing_data;
	printf("\toutgoing data: %p %d\n", conn, len);

	if (len != 4)
		FAIL("Length of packet is wrong: %u %u\n", msgb_l3len(msg), len);

	if (outgoing_data == 1) {
		if (memcmp(msg->l3h, test_data3->l3h, len) != 0) {
			FAIL("Comparing the data failed\n");
			outgoing_state = 0;
		}
	}
}

static void do_test_sccp_connection(const struct connection_test *test)
{
	int ret;

	current_con_test = test;
	outgoing_con = incoming_con = 0;

	outgoing_con = sccp_connection_socket();
	if (!outgoing_con) {
		FAIL("Connection is NULL\n");
		return;
	}

	outgoing_con->state_cb = sccp_conn_out_state;
	outgoing_con->data_cb = sccp_conn_out_data;
	outgoing_data = incoming_data = 0;
	incoming_state = outgoing_state = 1;

	/* start testing */
	if (test->with_data) {
		if (sccp_connection_connect(outgoing_con, &sccp_ssn_bssap, test_data1) != 0)
			FAIL("Binding failed\n");
	} else {
		++incoming_data;
		if (sccp_connection_connect(outgoing_con, &sccp_ssn_bssap, NULL) != 0)
			FAIL("Binding failed\n");
	}

	if (test->refuse) {
		if (outgoing_con)
			FAIL("Outgoing connection should have been refused.\n");
	} else {
		if (!incoming_con)
			FAIL("Creating incoming didn't work.\n");

		printf("\tWriting test data2\n");
		sccp_connection_write(outgoing_con, test_data2);
		sccp_connection_send_it(outgoing_con);

		/* closing connection */
		if (test->close_side == 0)
			ret = sccp_connection_close(outgoing_con, 0);
		else
			ret = sccp_connection_close(incoming_con, 0);

		if (ret != 0)
			FAIL("Closing the connection failed\n");
	}

	/* outgoing should be gone now */
	if (outgoing_con)
		FAIL("Outgoing connection was not properly closed\n");

	if (incoming_con)
		FAIL("Incoming connection was not propery closed.\n");

	if (test->refuse == 0) {
		if (outgoing_data != 1 || incoming_data != 2) {
			FAIL("Data sending failed: %d/%d %d/%d\n",
			     outgoing_data, 1,
			     incoming_data, 2);
		}
	}

	if (!incoming_state || !outgoing_state)
		FAIL("Failure with the state transition. %d %d\n",
		     outgoing_state, incoming_state);
}

static void test_sccp_connection(void)
{
	sccp_system_init(sccp_write_loop, NULL);
	sccp_set_read(NULL, NULL, NULL);
	sccp_connection_set_incoming(&sccp_ssn_bssap, sccp_conn_accept, NULL);

	test_data1 = msgb_alloc(4, "data1");
	test_data1->l3h = msgb_put(test_data1, 4);
	*((unsigned int*)test_data1->l3h) = 0x23421122;

	test_data2 = msgb_alloc(4, "data2");
	test_data2->l3h = msgb_put(test_data2, 4);
	*((unsigned int*)test_data2->l3h) = 0x42232211;

	test_data3 = msgb_alloc(4, "data3");
	test_data3->l3h = msgb_put(test_data3, 4);
	*((unsigned int*)test_data3->l3h) = 0x2323ff55;


	for (current_test = 0; current_test < ARRAY_SIZE(connection_tests); ++current_test) {
		printf("Testing %d refuse: %d with_data: %d\n",
			current_test, connection_tests[current_test].refuse,
			connection_tests[current_test].with_data);
		do_test_sccp_connection(&connection_tests[current_test]);
	}

	msgb_free(test_data1);
	msgb_free(test_data2);
	msgb_free(test_data3);
}

/* invalid input */
static void test_sccp_system_crash(void)
{
	printf("trying to provoke a crash with invalid input\n");
	sccp_set_read(&sccp_ssn_bssap, sccp_read_cb, NULL);
	sccp_connection_set_incoming(&sccp_ssn_bssap, sccp_accept_cb, NULL);

	for (current_test = 0; current_test < ARRAY_SIZE(test_data); ++current_test) {
		int original_length = test_data[current_test].length;
		int length = original_length + 2;
		int i;

		printf("Testing packet: %d\n", current_test);

		for (i = length; i >= 0; --i) {
			unsigned int length = MIN(test_data[current_test].length, i);
			struct msgb *msg = msgb_alloc_headroom(length + 2, 2, __func__);
			msg->l2h = msgb_put(msg, length);
			memcpy(msg->l2h, test_data[current_test].data, length);
			sccp_system_incoming(msg);
			msgb_free(msg);
		}
	}

	printf("survived\n");
}

static void test_sccp_parsing(void)
{
	for (current_test = 0; current_test < ARRAY_SIZE(parse_result); ++current_test) {
		struct msgb *msg;
		struct sccp_parse_result result;

		msg = msgb_alloc_headroom(1024, 128, "parse-test");
		msgb_put(msg, 1);
		msg->l2h = msgb_put(msg, parse_result[current_test].input_len);
		memcpy(msg->l2h, parse_result[current_test].input, msgb_l2len(msg));

		memset(&result, 0, sizeof(result));
		if (sccp_parse_header(msg, &result) != 0) {
			fprintf(stderr, "Failed to sccp parse test: %d\n", current_test);
		} else {
			if (parse_result[current_test].wanted_len != result.data_len) {
				fprintf(stderr, "Unexpected data length.\n");
				abort();
			}

			if (parse_result[current_test].has_src_ref) {
				if (memcmp(result.source_local_reference,
					   &parse_result[current_test].src_ref,
					   sizeof(struct sccp_source_reference)) != 0) {
					fprintf(stderr, "SRC REF did not match\n");
					abort();
				}
			}

			if (parse_result[current_test].has_dst_ref) {
				if (memcmp(result.destination_local_reference,
					   &parse_result[current_test].dst_ref,
					   sizeof(struct sccp_source_reference)) != 0) {
					fprintf(stderr, "DST REF did not match\n");
					abort();
				}
			}

			if (parse_result[current_test].src_ssn != -1) {
				fprintf(stderr, "Not implemented.\n");
				abort();
			}

			if (parse_result[current_test].dst_ssn != -1) {
				fprintf(stderr, "Not implemented.\n");
				abort();
			}
		}

		msgb_free(msg);
	}
}


int main(int argc, char **argv)
{
	test_sccp_system();
	test_sccp_send_udt();
	test_sccp_udt_communication();
	test_sccp_connection();
	test_sccp_system_crash();
	test_sccp_parsing();
	return 0;
}

void db_store_counter() {}
