aboutsummaryrefslogtreecommitdiffstats
path: root/src/bssap_sccp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bssap_sccp.c')
-rw-r--r--src/bssap_sccp.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/bssap_sccp.c b/src/bssap_sccp.c
new file mode 100644
index 0000000..72e24ae
--- /dev/null
+++ b/src/bssap_sccp.c
@@ -0,0 +1,150 @@
+/* Create GSM 08.08 messages */
+/*
+ * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2010 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 <bssap_sccp.h>
+
+#include <laf0rge1/msgb.h>
+#include <laf0rge1/debug.h>
+
+#include <openbsc_nat/bssap.h>
+
+#include <string.h>
+
+
+struct msgb *create_clear_command(struct sccp_source_reference *dest_ref)
+{
+ struct sccp_data_form1 *form1;
+ struct msgb *msg;
+
+ msg = msgb_alloc_headroom(4096, 128, "clear command");
+ if (!msg) {
+ LOGP(DINP, LOGL_ERROR, "Failed to allocate clear command.\n");
+ return NULL;
+ }
+
+ msg->l2h = msgb_put(msg, sizeof(*form1));
+ form1 = (struct sccp_data_form1 *) msg->l2h;
+ form1->type = SCCP_MSG_TYPE_DT1;
+ form1->destination_local_reference = *dest_ref;
+ form1->segmenting = 0;
+ form1->variable_start = 1;
+
+ /* create a Clear Command Call Control msg */
+ msg->l3h = msgb_put(msg, 7);
+ msg->l3h[0] = msgb_l3len(msg) - 1;
+ msg->l3h[1] = BSSAP_MSG_BSS_MANAGEMENT;
+ msg->l3h[2] = msg->l3h[0] - 2;
+ msg->l3h[3] = BSS_MAP_MSG_CLEAR_CMD;
+ msg->l3h[4] = 4;
+ msg->l3h[5] = 1;
+ msg->l3h[6] = 0x09;
+
+ return msg;
+}
+
+struct msgb *create_sccp_rlsd(struct sccp_source_reference *src_ref,
+ struct sccp_source_reference *dst_ref)
+{
+ struct sccp_connection_released *rel;
+ struct msgb *msg;
+
+ msg = msgb_alloc_headroom(4096, 128, "rlsd");
+ if (!msg) {
+ LOGP(DINP, LOGL_ERROR, "Failed to allocate clear command.\n");
+ return NULL;
+ }
+
+ msg->l2h = msgb_put(msg, sizeof(*rel));
+ rel = (struct sccp_connection_released *) msg->l2h;
+ rel->type = SCCP_MSG_TYPE_RLSD;
+ rel->release_cause = SCCP_RELEASE_CAUSE_END_USER_ORIGINATED;
+ rel->destination_local_reference = *dst_ref;
+ rel->source_local_reference = *src_ref;
+
+ return msg;
+}
+
+struct msgb *create_sccp_rlc(struct sccp_source_reference *src_ref,
+ struct sccp_source_reference *dst_ref)
+{
+ struct sccp_connection_release_complete *rlc;
+ struct msgb *msg;
+
+ msg = msgb_alloc_headroom(4096, 128, "rlc");
+ if (!msg) {
+ LOGP(DINP, LOGL_ERROR, "Failed to allocate rlc.\n");
+ return NULL;
+ }
+
+ msg->l2h = msgb_put(msg, sizeof(*rlc));
+ rlc = (struct sccp_connection_release_complete *) msg->l2h;
+ rlc->type = SCCP_MSG_TYPE_RLC;
+ rlc->destination_local_reference = *dst_ref;
+ rlc->source_local_reference = *src_ref;
+
+ return msg;
+}
+
+struct msgb *create_sccp_refuse(struct sccp_source_reference *dest_ref)
+{
+ struct sccp_connection_refused *ref;
+ struct msgb *msg;
+
+ msg = msgb_alloc_headroom(4096, 128, "rlsd");
+ if (!msg) {
+ LOGP(DINP, LOGL_ERROR, "Failed to allocate connection refuse.\n");
+ return NULL;
+ }
+
+ msg->l2h = msgb_put(msg, sizeof(*ref));
+ ref = (struct sccp_connection_refused *) msg->l2h;
+ ref->type = SCCP_MSG_TYPE_CREF;
+ ref->destination_local_reference = *dest_ref;
+ ref->cause = SCCP_REFUSAL_END_USER_ORIGINATED;
+ ref->optional_start = 1;
+
+ msg->l3h = msgb_put(msg, 1);
+ msg->l3h[0] = SCCP_PNC_END_OF_OPTIONAL;
+
+ return msg;
+}
+
+struct msgb *create_reset()
+{
+ static const u_int8_t reset[] = {
+ 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
+ 0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04,
+ 0x01, 0x20
+ };
+
+ struct msgb *msg;
+
+ msg = msgb_alloc_headroom(4096, 128, "reset");
+ if (!msg) {
+ LOGP(DMSC, LOGL_ERROR, "Failed to allocate reset msg.\n");
+ return NULL;
+ }
+
+ msg->l2h = msgb_put(msg, sizeof(reset));
+ memcpy(msg->l2h, reset, msgb_l2len(msg));
+ return msg;
+}