aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-04-21 15:38:16 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-04-21 15:46:38 +0800
commitc3a6a1dbe5432e792103916291fd837ea96e0937 (patch)
treee22d37c625ab8220ff1d96b5401f8ec93f7a5094 /openbsc
parentf4f090ee36246a2bc027aea790663670276f5e48 (diff)
[sccp] Parse the error message and add a unit test for it.
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/sccp/sccp_types.h6
-rw-r--r--openbsc/src/sccp/sccp.c20
-rw-r--r--openbsc/tests/sccp/sccp_test.c21
3 files changed, 46 insertions, 1 deletions
diff --git a/openbsc/include/sccp/sccp_types.h b/openbsc/include/sccp/sccp_types.h
index 42fda96ae..22bd70f21 100644
--- a/openbsc/include/sccp/sccp_types.h
+++ b/openbsc/include/sccp/sccp_types.h
@@ -411,4 +411,10 @@ struct sccp_data_it {
u_int8_t credit;
} __attribute__((packed));
+struct sccp_proto_err {
+ u_int8_t type;
+ struct sccp_source_reference destination_local_reference;
+ u_int8_t error_cause;
+};
+
#endif
diff --git a/openbsc/src/sccp/sccp.c b/openbsc/src/sccp/sccp.c
index e0fd02e0e..d869bfaeb 100644
--- a/openbsc/src/sccp/sccp.c
+++ b/openbsc/src/sccp/sccp.c
@@ -490,6 +490,23 @@ static int _sccp_parse_it(struct msgb *msgb, struct sccp_parse_result *result)
return 0;
}
+static int _sccp_parse_err(struct msgb *msgb, struct sccp_parse_result *result)
+{
+ static const u_int32_t header_size = sizeof(struct sccp_proto_err);
+
+ struct sccp_proto_err *err;
+
+ if (msgb_l2len(msgb) < header_size) {
+ LOGP(DSCCP, LOGL_ERROR, "msgb < header_size %u %u\n",
+ msgb_l2len(msgb), header_size);
+ return -1;
+ }
+
+ err = (struct sccp_proto_err *) msgb->l2h;
+ result->data_len = 0;
+ result->destination_local_reference = &err->destination_local_reference;
+ return 0;
+}
/*
* Send UDT. Currently we have a fixed address...
@@ -1318,6 +1335,9 @@ int sccp_parse_header(struct msgb *msg, struct sccp_parse_result *result)
case SCCP_MSG_TYPE_IT:
return _sccp_parse_it(msg, result);
break;
+ case SCCP_MSG_TYPE_ERR:
+ return _sccp_parse_err(msg, result);
+ break;
};
LOGP(DSCCP, LOGL_ERROR, "Unimplemented MSG Type: 0x%x\n", type);
diff --git a/openbsc/tests/sccp/sccp_test.c b/openbsc/tests/sccp/sccp_test.c
index 0c2adc83f..31eb47f9f 100644
--- a/openbsc/tests/sccp/sccp_test.c
+++ b/openbsc/tests/sccp/sccp_test.c
@@ -264,6 +264,10 @@ 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,
@@ -287,6 +291,21 @@ static const struct sccp_parse_header_result parse_result[] = {
.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),
+ },
};
@@ -777,7 +796,7 @@ static void test_sccp_parsing(void)
memset(&result, 0, sizeof(result));
if (sccp_parse_header(msg, &result) != 0) {
- fprintf(stderr, "Failed to parse test: %d\n", current_test);
+ 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");