diff --git a/include/openbsc/Makefile.am b/include/openbsc/Makefile.am index 2558d7c1c..995f02d09 100644 --- a/include/openbsc/Makefile.am +++ b/include/openbsc/Makefile.am @@ -37,6 +37,7 @@ noinst_HEADERS = \ gprs_utils.h \ gsm_04_08.h \ gsm_04_11.h \ + gsm_04_14.h \ gsm_04_80.h \ gsm_data.h \ gsm_data_shared.h \ diff --git a/include/openbsc/gsm_04_14.h b/include/openbsc/gsm_04_14.h new file mode 100644 index 000000000..3cdbe0469 --- /dev/null +++ b/include/openbsc/gsm_04_14.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +int gsm0414_tx_close_tch_loop_cmd(struct gsm_subscriber_connection *conn, + enum gsm414_tch_loop_mode loop_mode); +int gsm0414_tx_open_loop_cmd(struct gsm_subscriber_connection *conn); +int gsm0414_tx_act_emmi_cmd(struct gsm_subscriber_connection *conn); +int gsm0414_tx_test_interface(struct gsm_subscriber_connection *conn, + uint8_t tested_devs); +int gsm0414_tx_reset_ms_pos_store(struct gsm_subscriber_connection *conn, + uint8_t technology); + +int gsm0414_rcv_test(struct gsm_subscriber_connection *conn, + struct msgb *msg); diff --git a/src/libmsc/Makefile.am b/src/libmsc/Makefile.am index 16154ff97..4726bbe4b 100644 --- a/src/libmsc/Makefile.am +++ b/src/libmsc/Makefile.am @@ -30,6 +30,7 @@ libmsc_a_SOURCES = \ db.c \ gsm_04_08.c \ gsm_04_11.c \ + gsm_04_14.c \ gsm_04_80.c \ gsm_subscriber.c \ iucs.c \ diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c index 58c561058..28cba5b85 100644 --- a/src/libmsc/gsm_04_08.c +++ b/src/libmsc/gsm_04_08.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -3079,6 +3080,9 @@ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg) case GSM48_PDISC_NC_SS: rc = handle_rcv_ussd(conn, msg); break; + case GSM48_PDISC_TEST: + rc = gsm0414_rcv_test(conn, msg); + break; default: LOGP(DRLL, LOGL_NOTICE, "Unknown " "GSM 04.08 discriminator 0x%02x\n", pdisc); diff --git a/src/libmsc/gsm_04_14.c b/src/libmsc/gsm_04_14.c new file mode 100644 index 000000000..b529f4c72 --- /dev/null +++ b/src/libmsc/gsm_04_14.c @@ -0,0 +1,133 @@ +/* GSM MS Testing Layer 3 messages + * 3GPP TS 44.014 / GSM TS 04.14 */ + +/* (C) 2017 by Harald Welte + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include + +#include "bscconfig.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static struct msgb *create_gsm0414_msg(uint8_t msg_type) +{ + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.14"); + struct gsm48_hdr *gh; + + gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); + gh->proto_discr = GSM48_PDISC_TEST; + gh->msg_type = msg_type; + return msg; +} + +static int gsm0414_conn_sendmsg(struct gsm_subscriber_connection *conn, struct msgb *msg) +{ + return msc_tx_dtap(conn, msg); +} + +static int gsm0414_tx_simple(struct gsm_subscriber_connection *conn, uint8_t msg_type) +{ + struct msgb *msg = create_gsm0414_msg(msg_type); + + return gsm0414_conn_sendmsg(conn, msg); +} + + +/* Send a CLOSE_TCH_LOOOP_CMD according to Section 8.1 */ +int gsm0414_tx_close_tch_loop_cmd(struct gsm_subscriber_connection *conn, + enum gsm414_tch_loop_mode loop_mode) +{ + struct msgb *msg = create_gsm0414_msg(GSM414_MT_CLOSE_TCH_LOOP_CMD); + uint8_t subch; + + subch = (loop_mode << 1); + msgb_put_u8(msg, subch); + + msg->lchan = conn->lchan; + return gsm0414_conn_sendmsg(conn, msg); +} + +/* Send a OPEN_LOOP_CMD according to Section 8.3 */ +int gsm0414_tx_open_loop_cmd(struct gsm_subscriber_connection *conn) +{ + return gsm0414_tx_simple(conn, GSM414_MT_OPEN_LOOP_CMD); +} + +/* Send a ACT_EMMI_CMD according to Section 8.8 */ +int gsm0414_tx_act_emmi_cmd(struct gsm_subscriber_connection *conn) +{ + return gsm0414_tx_simple(conn, GSM414_MT_ACT_EMMI_CMD); +} + +/* Send a DEACT_EMMI_CMD according to Section 8.10 */ +int gsm0414_tx_deact_emmi_cmd(struct gsm_subscriber_connection *conn) +{ + return gsm0414_tx_simple(conn, GSM414_MT_DEACT_EMMI_CMD); +} + +/* Send a TEST_INTERFACE according to Section 8.11 */ +int gsm0414_tx_test_interface(struct gsm_subscriber_connection *conn, + uint8_t tested_devs) +{ + struct msgb *msg = create_gsm0414_msg(GSM414_MT_TEST_INTERFACE); + msgb_put_u8(msg, tested_devs); + return gsm0414_conn_sendmsg(conn, msg); +} + +/* Send a RESET_MS_POSITION_STORED according to Section 8.11 */ +int gsm0414_tx_reset_ms_pos_store(struct gsm_subscriber_connection *conn, + uint8_t technology) +{ + struct msgb *msg = create_gsm0414_msg(GSM414_MT_RESET_MS_POS_STORED); + msgb_put_u8(msg, technology); + return gsm0414_conn_sendmsg(conn, msg); +} + + + +/* Entry point for incoming GSM48_PDISC_TEST received from MS */ +int gsm0414_rcv_test(struct gsm_subscriber_connection *conn, + struct msgb *msg) +{ + struct gsm48_hdr *gh = msgb_l3(msg); + + if (msgb_l3len(msg) < sizeof(*gh)) + return -1; + + LOGP(DMM, LOGL_NOTICE, "%s: Received TEST class message '%s'\n", "FIXME", + get_value_string(gsm414_msgt_names, gh->msg_type)); + + return 0; +}