aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2013-05-13 21:08:36 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2013-05-13 21:08:36 +0200
commit4db78de76e3127c80fc41009ee4767155d215c73 (patch)
tree1ce7e8585f6038599d4349f2897c20a044c5d2f2
parentb566c79d82416f66169a6ee1c2d21920fc9acb7f (diff)
patching: Add a VTY option to hardcode the assignment complete message
For some equipment it is the easiest to patch the assignment complete message transported to the MSC. Add a VTY config to enable this patching, create a testcase that tests that the original message is truncated. The setting of the VTY option has been manually tested. The entire system has not been end to end tested.
-rw-r--r--include/ss7_application.h7
-rw-r--r--src/bss_patch.c14
-rw-r--r--src/vty_interface.c27
-rw-r--r--tests/patching/patching_test.c58
-rw-r--r--tests/patching/patching_test.ok1
5 files changed, 102 insertions, 5 deletions
diff --git a/include/ss7_application.h b/include/ss7_application.h
index 3d25165..b762cac 100644
--- a/include/ss7_application.h
+++ b/include/ss7_application.h
@@ -81,6 +81,13 @@ struct ss7_application {
/* mgcp handling for the cellmgr and stp */
char *mgcp_domain_name;
char *trunk_name;
+
+ /* various hacks/quirks to deal with broken equipment */
+ /*
+ * Some equipments do not look into the codec list but only the
+ * size of it.
+ */
+ unsigned fixed_ass_cmpl_reply : 1;
};
diff --git a/src/bss_patch.c b/src/bss_patch.c
index cc897b6..e0a6362 100644
--- a/src/bss_patch.c
+++ b/src/bss_patch.c
@@ -1,7 +1,7 @@
/* Patch GSM 08.08 messages for the network and BS */
/*
- * (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010-2011 by On-Waves
+ * (C) 2010-2013 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010-2013 by On-Waves
* All Rights Reserved
*
* This program is free software: you can redistribute it and/or modify
@@ -21,6 +21,7 @@
#include <bss_patch.h>
#include <cellmgr_debug.h>
+#include <ss7_application.h>
#include <string.h>
@@ -71,7 +72,14 @@ static void patch_ass_cmpl(struct ss7_application *app, struct msgb *msg, int le
struct tlv_parsed tp;
uint8_t *data;
- if (length == 1) {
+ if (length == 1 || app->fixed_ass_cmpl_reply) {
+ /* We need to truncate the message to only include the codec */
+ if (length > 1 && app->fixed_ass_cmpl_reply) {
+ uint8_t *old = msg->tail;
+ msg->tail = &msg->l3h[1];
+ msg->len = old - msg->tail;
+ }
+
LOGP(DMSC, LOGL_ERROR, "Hacking the Assignment Complete.\n");
msgb_v_put(msg, 0x21);
msgb_v_put(msg, 0x09);
diff --git a/src/vty_interface.c b/src/vty_interface.c
index 09b796e..93ebc6a 100644
--- a/src/vty_interface.c
+++ b/src/vty_interface.c
@@ -1,7 +1,7 @@
/* VTY code for the osmo-stp */
/*
- * (C) 2010-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010-2012 by On-Waves
+ * (C) 2010-2013 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010-2013 by On-Waves
* All Rights Reserved
*
* This program is free software: you can redistribute it and/or modify
@@ -298,6 +298,9 @@ static void write_application(struct vty *vty, struct ss7_application *app)
vty_out(vty, " description %s%s", name, VTY_NEWLINE);
vty_out(vty, " type %s%s", app_type(app->type), VTY_NEWLINE);
+ if (app->fixed_ass_cmpl_reply)
+ vty_out(vty, " hardcode-assignment-complete%s", VTY_NEWLINE);
+
if (app->type == APP_STP) {
vty_out(vty, " isup-pass-through %d%s", app->isup_pass, VTY_NEWLINE);
if (app->trunk_name)
@@ -1077,6 +1080,24 @@ DEFUN(cfg_app_no_forward_only, cfg_app_no_forward_only_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_app_hardcode_ass, cfg_app_hardcode_ass_cmd,
+ "hardcode-assignment-complete",
+ "Hardcode the assignment complete message to HR3\n")
+{
+ struct ss7_application *app = vty->index;
+ app->fixed_ass_cmpl_reply = 1;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_app_no_hardcode_ass, cfg_app_no_hardcode_ass_cmd,
+ "no hardcode-assignment-complete",
+ "Hardcode the assignment complete message to HR3\n")
+{
+ struct ss7_application *app = vty->index;
+ app->fixed_ass_cmpl_reply = 0;
+ return CMD_SUCCESS;
+}
+
static void install_defaults(int node)
{
install_default(node);
@@ -1156,6 +1177,8 @@ void cell_vty_init(void)
install_element(APP_NODE, &cfg_app_no_trunk_name_cmd);
install_element(APP_NODE, &cfg_app_forward_only_cmd);
install_element(APP_NODE, &cfg_app_no_forward_only_cmd);
+ install_element(APP_NODE, &cfg_app_hardcode_ass_cmd);
+ install_element(APP_NODE, &cfg_app_no_hardcode_ass_cmd);
cell_vty_init_cmds();
}
diff --git a/tests/patching/patching_test.c b/tests/patching/patching_test.c
index e97d568..9208788 100644
--- a/tests/patching/patching_test.c
+++ b/tests/patching/patching_test.c
@@ -170,6 +170,11 @@ static const uint8_t dt1_ass_compl_patched[] = {
0x03, 0x02, 0x40, 0x25,
};
+static const uint8_t dt1_ass_compl_hardcoded[] = {
+ 0x06, 0x01, 0x02, 0x47, 0x00, 0x01, 0x09, 0x00,
+ 0x07, 0x02, 0x21, 0x09, 0x2c, 0x02, 0x40, 0x25,
+};
+
static struct result rewrite_results_to_msc[] = {
{
.input = udt_with_poi,
@@ -327,6 +332,58 @@ static void test_rewrite_msc(void)
}
}
+static void test_rewrite_msc_fixed_ass_cmpl(void)
+{
+ struct sccp_parse_result result;
+ struct msgb *inp;
+ struct msgb *outp;
+ int rc;
+
+ struct ss7_application app;
+ memset(&app, 0, sizeof(app));
+ app.fixed_ass_cmpl_reply = 1;
+
+ printf("Testing fixed response\n");
+
+ outp = msgb_alloc_headroom(256, 8, "test2");
+ inp = msgb_alloc_headroom(256, 8, "test1");
+ msgb_put(inp, 1);
+ inp->l2h = msgb_put(inp, sizeof(dt1_ass_compl));
+ memcpy(inp->l2h, dt1_ass_compl, msgb_l2len(inp));
+
+ rc = bss_patch_filter_msg(&app, inp, &result, BSS_DIR_MSC);
+ if (rc < 0) {
+ printf("Failed to parse header msg\n");
+ abort();
+ }
+
+ bss_rewrite_header_for_msc(rc, outp, inp, &result);
+
+ memset(&result, 0, sizeof(result));
+ rc = bss_patch_filter_msg(&app, outp, &result, BSS_DIR_MSC);
+ if (rc < 0) {
+ printf("Patched message doesn't work\n");
+ printf("hex: %s\n", osmo_hexdump(outp->l2h, msgb_l2len(outp)));
+ abort();
+ }
+
+ if (msgb_l2len(outp) != sizeof(dt1_ass_compl_hardcoded)) {
+ printf("The length's don't match on %u != %u\n",
+ msgb_l2len(outp), sizeof(dt1_ass_compl_hardcoded));
+ printf("hex: %s\n", osmo_hexdump(outp->l2h, msgb_l2len(outp)));
+ abort();
+ }
+
+ if (memcmp(outp->l2h, dt1_ass_compl_hardcoded, msgb_l2len(outp)) != 0) {
+ printf("Expected results don't match\n");
+ printf("hex: %s\n", osmo_hexdump(outp->l2h, msgb_l2len(outp)));
+ abort();
+ }
+
+ msgb_free(outp);
+ msgb_free(inp);
+}
+
static void test_rewrite_bsc(void)
{
int i;
@@ -361,6 +418,7 @@ int main(int argc, char **argv)
test_patch_filter();
test_rewrite_msc();
+ test_rewrite_msc_fixed_ass_cmpl();
test_rewrite_bsc();
printf("All tests passed.\n");
return 0;
diff --git a/tests/patching/patching_test.ok b/tests/patching/patching_test.ok
index 0e681b2..498d268 100644
--- a/tests/patching/patching_test.ok
+++ b/tests/patching/patching_test.ok
@@ -1,4 +1,5 @@
Testing patching of GSM messages to the MSC.
Testing rewriting the SCCP header.
+Testing fixed response
Testing rewriting the SCCP header for BSC.
All tests passed.