aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmsc
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-05-08 15:12:20 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-06-18 17:48:57 +0200
commit58774cba12ec4675e32fa524cfa631bdc690a9da (patch)
treee1a1540be4e96503e721c2124b90f782de86a4ff /openbsc/src/libmsc
parentfd01ea2b6a778b8f610203b8de38d1677d7f02ac (diff)
mscsplit: various preparations to separate MSC from BSC
Disable large parts of the code that depend on BSC presence. Don't set msg->lchan nor msg->dst. Don't use lchan in libmsc. Decouple lac from bts. Prepare entry/exit point for MSC -> BSC and MSC -> RNC communication: Add msc_ifaces.[hc], a_iface.c, with a general msc_tx_dtap() to redirect to different interfaces depending on the actual subscriber connection. While iu_tx() is going to be functional fairly soon, the a_tx() is going to be just a dummy for some time (see comment). Add Iu specific fields in gsm_subscriber_connection: the UE connection pointer and an indicator for the Integrity Protection status on Iu (to be fully implemented in later commits). Add lac member to gsm_subscriber_connection, to allow decoupling from bts->location_area_code. The conn->lac will actually be set in iu.c in an upcoming commit ("add iucs.[hc]"). move to libcommon-cs: gsm48_extract_mi(), gsm48_paging_extract_mi(). libmsc: duplicate gsm0808 / gsm48 functions (towards BSC). In osmo-nitb, libmsc would directly call the functions on the BSC level, not always via the bsc_api. When separating libmsc from libbsc, some functions are missing from the linkage. Hence duplicate these functions to libmsc, add an msc_ prefix for clarity, also add a _tx to gsm0808_cipher_mode(): * add msc_gsm0808_tx_cipher_mode() (dummy/stub) * add msc_gsm48_tx_mm_serv_ack() * add msc_gsm48_tx_mm_serv_rej() Call these from libmsc instead of * gsm0808_cipher_mode() * gsm48_tx_mm_serv_ack() * gsm48_tx_mm_serv_rej() Also add a comment related to msc_gsm0808_tx_cipher_mode() in two places. Temporarily disable all paging to be able to link libmsc without libbsc. Skip the paging part of channel_test because the paging is now disabled. In osmo-nitb, paging is done on BSC level and MSC level "at the same time". When the new MSC is fully operational, paging will be controlled separately on the MSC level, and the BSC (RNC) level will be instructed over an IuCS or A-interface to negotiate paging with the MS (UE). This MSC level paging does not yet exist and will be added in subsequent commits. msc_compl_l3(): publish in .h, tweak return value. Use new libmsc enum values for return val, to avoid dependency on libbsc headers. Make callable from other scopes: publish in osmo_msc.h and remove 'static' in osmo_msc.c add gsm_encr to subscr_conn move subscr_request to gsm_subscriber.h subscr_request_channel() -> subscr_request_conn() move to libmsc: osmo_stats_vty_add_cmds() gsm_04_08: remove apply_codec_restrictions() gsm0408_test: use NULL for root ctx move to libbsc: gsm_bts_neighbor() move to libbsc: lchan_next_meas_rep() move vty config for t3212 to network level (periodic lu) remove unneccessary linking from some tests remove handle_abisip_signal() abis_rsl.c: don't use libvlr from libbsc Change-Id: I9cf80f9c2c8a53a29e42f000029e680a9922cb41
Diffstat (limited to 'openbsc/src/libmsc')
-rw-r--r--openbsc/src/libmsc/Makefile.am2
-rw-r--r--openbsc/src/libmsc/a_iface.c45
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c239
-rw-r--r--openbsc/src/libmsc/gsm_04_11.c8
-rw-r--r--openbsc/src/libmsc/gsm_subscriber.c27
-rw-r--r--openbsc/src/libmsc/mncc_builtin.c7
-rw-r--r--openbsc/src/libmsc/msc_ifaces.c83
-rw-r--r--openbsc/src/libmsc/osmo_msc.c22
-rw-r--r--openbsc/src/libmsc/silent_call.c9
-rw-r--r--openbsc/src/libmsc/smpp_openbsc.c4
-rw-r--r--openbsc/src/libmsc/vty_interface_layer3.c14
11 files changed, 276 insertions, 184 deletions
diff --git a/openbsc/src/libmsc/Makefile.am b/openbsc/src/libmsc/Makefile.am
index 3f4174ca5..7ab30d029 100644
--- a/openbsc/src/libmsc/Makefile.am
+++ b/openbsc/src/libmsc/Makefile.am
@@ -23,6 +23,7 @@ noinst_LIBRARIES = \
$(NULL)
libmsc_a_SOURCES = \
+ a_iface.c \
auth.c \
db.c \
gsm_04_08.c \
@@ -32,6 +33,7 @@ libmsc_a_SOURCES = \
mncc.c \
mncc_builtin.c \
mncc_sock.c \
+ msc_ifaces.c \
rrlp.c \
silent_call.c \
sms_queue.c \
diff --git a/openbsc/src/libmsc/a_iface.c b/openbsc/src/libmsc/a_iface.c
new file mode 100644
index 000000000..1f471f97b
--- /dev/null
+++ b/openbsc/src/libmsc/a_iface.c
@@ -0,0 +1,45 @@
+/* A-interface implementation, from MSC to BSC */
+
+/* (C) 2016 by sysmocom s.m.f.c GmbH <info@sysmocom.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+
+#include <openbsc/debug.h>
+
+#include <openbsc/gsm_data.h>
+#include <openbsc/msc_ifaces.h>
+#include <openbsc/debug.h>
+
+int a_tx(struct msgb *msg)
+{
+ LOGP(DMSC, LOGL_ERROR, "message to be sent to BSC, but A-interface"
+ " not implemented.\n%s\n", osmo_hexdump(msg->data, msg->len));
+ return -1;
+}
+
+int msc_gsm0808_tx_cipher_mode(struct gsm_subscriber_connection *conn, int cipher,
+ const uint8_t *key, int len, int include_imeisv)
+{
+ /* TODO generalize for A- and Iu interfaces, don't name after 08.08 */
+ LOGP(DMSC, LOGL_ERROR, "gsm0808_cipher_mode(): message to be sent to"
+ " BSC, but A interface not yet implemented.\n");
+ return -1;
+}
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 9591ddb0a..f8d47e4da 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -59,6 +59,7 @@
#include <osmocom/abis/e1_input.h>
#include <osmocom/core/bitvec.h>
#include <openbsc/vlr.h>
+#include <openbsc/msc_ifaces.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/gsm0480.h>
@@ -71,10 +72,17 @@
#include <assert.h>
+
+/* These debug statements were removed during the BSC/MSC split. It may make
+ * sense to replace them with debug statements that do not access BTS data. */
+#define BEFORE_MSCSPLIT 0
+
void *tall_locop_ctx;
void *tall_authciphop_ctx;
+#if BEFORE_MSCSPLIT
static int tch_rtp_signal(struct gsm_lchan *lchan, int signal);
+#endif
static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn,
uint32_t send_tmsi);
@@ -87,29 +95,6 @@ struct gsm_lai {
uint16_t lac;
};
-static int apply_codec_restrictions(struct gsm_bts *bts,
- struct gsm_mncc_bearer_cap *bcap)
-{
- int i, j;
-
- /* remove unsupported speech versions from list */
- for (i = 0, j = 0; bcap->speech_ver[i] >= 0; i++) {
- if (bcap->speech_ver[i] == GSM48_BCAP_SV_FR)
- bcap->speech_ver[j++] = GSM48_BCAP_SV_FR;
- if (bcap->speech_ver[i] == GSM48_BCAP_SV_EFR && bts->codec.efr)
- bcap->speech_ver[j++] = GSM48_BCAP_SV_EFR;
- if (bcap->speech_ver[i] == GSM48_BCAP_SV_AMR_F && bts->codec.amr)
- bcap->speech_ver[j++] = GSM48_BCAP_SV_AMR_F;
- if (bcap->speech_ver[i] == GSM48_BCAP_SV_HR && bts->codec.hr)
- bcap->speech_ver[j++] = GSM48_BCAP_SV_HR;
- if (bcap->speech_ver[i] == GSM48_BCAP_SV_AMR_H && bts->codec.amr)
- bcap->speech_ver[j++] = GSM48_BCAP_SV_AMR_H;
- }
- bcap->speech_ver[j] = -1;
-
- return 0;
-}
-
static uint32_t new_callref = 0x80000001;
void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg)
@@ -126,27 +111,6 @@ static int gsm48_conn_sendmsg(struct msgb *msg, struct gsm_subscriber_connection
* work that the caller no longer has to do */
if (trans) {
gh->proto_discr = trans->protocol | (trans->transaction_id << 4);
- msg->lchan = trans->conn->lchan;
- }
-
- if (msg->lchan) {
- struct e1inp_sign_link *sign_link =
- msg->lchan->ts->trx->rsl_link;
-
- msg->dst = sign_link;
- if (gsm48_hdr_pdisc(gh) == GSM48_PDISC_CC)
- DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x) "
- "Sending '%s' to MS.\n",
- sign_link->trx->bts->nr,
- sign_link->trx->nr, msg->lchan->ts->nr,
- gh->proto_discr & 0xf0,
- gsm48_cc_msg_name(gh->msg_type));
- else
- DEBUGP(DCC, "(bts %d trx %d ts %d pd %02x) "
- "Sending 0x%02x to MS.\n",
- sign_link->trx->bts->nr,
- sign_link->trx->nr, msg->lchan->ts->nr,
- gh->proto_discr, gh->msg_type);
}
return gsm0808_submit_dtap(conn, msg, 0, 0);
@@ -187,7 +151,6 @@ void gsm0408_clear_all_trans(struct gsm_network *net, int protocol)
/* Chapter 9.2.14 : Send LOCATION UPDATING REJECT */
int gsm0408_loc_upd_rej(struct gsm_subscriber_connection *conn, uint8_t cause)
{
- struct gsm_bts *bts = conn->bts;
struct msgb *msg;
msg = gsm48_create_loc_upd_rej(cause);
@@ -196,11 +159,8 @@ int gsm0408_loc_upd_rej(struct gsm_subscriber_connection *conn, uint8_t cause)
return -1;
}
- msg->lchan = conn->lchan;
-
- LOGP(DMM, LOGL_INFO, "Subscriber %s: LOCATION UPDATING REJECT "
- "LAC=%u BTS=%u\n", vlr_subscr_name(conn->vsub),
- bts->location_area_code, bts->nr);
+ LOGP(DMM, LOGL_INFO, "Subscriber %s: LOCATION UPDATING REJECT\n",
+ vlr_subscr_name(conn->vsub));
return gsm48_conn_sendmsg(msg, conn, NULL);
}
@@ -214,8 +174,6 @@ static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn,
struct gsm48_loc_area_id *lai;
uint8_t *mid;
- msg->lchan = conn->lchan;
-
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
gh->proto_discr = GSM48_PDISC_MM;
gh->msg_type = GSM48_MT_MM_LOC_UPD_ACCEPT;
@@ -223,7 +181,7 @@ static int gsm0408_loc_upd_acc(struct gsm_subscriber_connection *conn,
lai = (struct gsm48_loc_area_id *) msgb_put(msg, sizeof(*lai));
gsm48_generate_lai(lai, conn->network->country_code,
conn->network->network_code,
- conn->bts->location_area_code);
+ conn->lac);
if (send_tmsi == GSM_RESERVED_TMSI) {
/* we did not allocate a TMSI to the MS, so we need to
@@ -258,8 +216,6 @@ static int mm_tx_identity_req(struct gsm_subscriber_connection *conn, uint8_t id
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 ID REQ");
struct gsm48_hdr *gh;
- msg->lchan = conn->lchan;
-
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1);
gh->proto_discr = GSM48_PDISC_MM;
gh->msg_type = GSM48_MT_MM_ID_REQ;
@@ -437,8 +393,6 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn)
int tzunits;
int dst = 0;
- msg->lchan = conn->lchan;
-
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
gh->proto_discr = GSM48_PDISC_MM;
gh->msg_type = GSM48_MT_MM_INFO;
@@ -588,7 +542,6 @@ int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, uint8_t *rand,
if (autn)
DEBUGP(DMM, " AUTH REQ (autn = %s)\n", osmo_hexdump_nospc(autn, 16));
- msg->lchan = conn->lchan;
gh->proto_discr = GSM48_PDISC_MM;
gh->msg_type = GSM48_MT_MM_AUTH_REQ;
@@ -669,7 +622,7 @@ accept_reuse:
* b) Try to parse the TMSI. If we do not have one reject
* c) Check that we know the subscriber with the TMSI otherwise reject
* with a HLR cause
- * d) Set the subscriber on the gsm_lchan and accept
+ * d) Set the subscriber on the conn and accept
*
* Keep this function non-static for direct invocation by unit tests.
*/
@@ -699,14 +652,14 @@ int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct msgb *ms
DEBUGP(DMM, "<- CM SERVICE REQUEST ");
if (msg->data_len < sizeof(struct gsm48_service_request*)) {
DEBUGPC(DMM, "wrong sized message\n");
- return gsm48_tx_mm_serv_rej(conn,
- GSM48_REJECT_INCORRECT_MESSAGE);
+ return msc_gsm48_tx_mm_serv_rej(conn,
+ GSM48_REJECT_INCORRECT_MESSAGE);
}
if (msg->data_len < req->mi_len + 6) {
DEBUGPC(DMM, "does not fit in packet\n");
- return gsm48_tx_mm_serv_rej(conn,
- GSM48_REJECT_INCORRECT_MESSAGE);
+ return msc_gsm48_tx_mm_serv_rej(conn,
+ GSM48_REJECT_INCORRECT_MESSAGE);
}
gsm48_mi_to_string(mi_string, sizeof(mi_string), mi, mi_len);
@@ -722,8 +675,8 @@ int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct msgb *ms
mi_string);
} else {
DEBUGPC(DMM, "mi_type is not expected: %d\n", mi_type);
- return gsm48_tx_mm_serv_rej(conn,
- GSM48_REJECT_INCORRECT_MESSAGE);
+ return msc_gsm48_tx_mm_serv_rej(conn,
+ GSM48_REJECT_INCORRECT_MESSAGE);
}
osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, (classmark2 + classmark2_len));
@@ -748,8 +701,12 @@ int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct msgb *ms
return rc;
}
+#if BEFORE_MSCSPLIT
+ /* see mail on openbsc@ 9 Feb 2016 22:30:15 +0100
+ * We need to hook sending of MRPCI to Siemens BS11 somewhere else */
if (is_siemens_bts(conn->bts))
send_siemens_mrpci(msg->lchan, classmark2-1);
+#endif
vlr_proc_acc_req(conn->conn_fsm,
SUBSCR_CONN_E_ACCEPTED,
@@ -801,7 +758,6 @@ static int gsm48_rx_mm_imsi_detach_ind(struct gsm_subscriber_connection *conn, s
break;
}
-
/* TODO? We used to remember the subscriber's classmark1 here and
* stored it in the old sqlite db, but now we store it in a conn that
* will be discarded anyway: */
@@ -1195,8 +1151,6 @@ int gsm48_send_rr_app_info(struct gsm_subscriber_connection *conn, uint8_t apdu_
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 APP INF");
struct gsm48_hdr *gh;
- msg->lchan = conn->lchan;
-
DEBUGP(DRR, "TX APPLICATION INFO id=0x%02x, len=%u\n",
apdu_id, apdu_len);
@@ -1288,8 +1242,6 @@ static int gsm48_tx_simple(struct gsm_subscriber_connection *conn,
struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 TX SIMPLE");
struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
- msg->lchan = conn->lchan;
-
gh->proto_discr = pdisc;
gh->msg_type = msg_type;
@@ -1311,6 +1263,7 @@ static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans,
struct msgb *msg;
unsigned char *data;
+#if BEFORE_MSCSPLIT
if (trans)
if (trans->conn && trans->conn->lchan)
DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) "
@@ -1328,6 +1281,7 @@ static int mncc_recvmsg(struct gsm_network *net, struct gsm_trans *trans,
else
DEBUGP(DCC, "(bts - trx - ts - ti -- sub -) "
"Sending '%s' to MNCC.\n", get_mncc_name(msg_type));
+#endif
mncc->msg_type = msg_type;
@@ -1371,8 +1325,10 @@ void _gsm48_cc_trans_free(struct gsm_trans *trans)
}
if (trans->cc.state != GSM_CSTATE_NULL)
new_cc_state(trans, GSM_CSTATE_NULL);
+#if BEFORE_MSCSPLIT
if (trans->conn)
trau_mux_unmap(&trans->conn->lchan->ts->e1_link, trans->callref);
+#endif
}
static int gsm48_cc_tx_setup(struct gsm_trans *trans, void *arg);
@@ -1386,13 +1342,12 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
OSMO_ASSERT(!transt->conn);
- /* check all tranactions (without lchan) for subscriber */
switch (event) {
case GSM_PAGING_SUCCEEDED:
DEBUGP(DCC, "Paging subscr %s succeeded!\n",
vlr_subscr_msisdn_or_name(transt->vsub));
OSMO_ASSERT(conn);
- /* Assign lchan */
+ /* Assign conn */
transt->conn = conn;
/* send SETUP request to called party */
gsm48_cc_tx_setup(transt, &transt->cc.msg);
@@ -1421,6 +1376,7 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable);
+#if BEFORE_MSCSPLIT
/* handle audio path for handover */
static int switch_for_handover(struct gsm_lchan *old_lchan,
struct gsm_lchan *new_lchan)
@@ -1488,77 +1444,6 @@ static void maybe_switch_for_handover(struct gsm_lchan *lchan)
switch_for_handover(old_lchan, lchan);
}
-/* some other part of the code sends us a signal */
-static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data)
-{
- struct gsm_lchan *lchan = signal_data;
- int rc;
- struct gsm_network *net;
- struct gsm_trans *trans;
-
- if (subsys != SS_ABISIP)
- return 0;
-
- /* RTP bridge handling */
- if (lchan->conn && lchan->conn->mncc_rtp_bridge)
- return tch_rtp_signal(lchan, signal);
-
- /* in case we use direct BTS-to-BTS RTP */
- if (ipacc_rtp_direct)
- return 0;
-
- switch (signal) {
- case S_ABISIP_CRCX_ACK:
- /* in case we don't use direct BTS-to-BTS RTP */
- /* the BTS has successfully bound a TCH to a local ip/port,
- * which means we can connect our UDP socket to it */
- if (lchan->abis_ip.rtp_socket) {
- rtp_socket_free(lchan->abis_ip.rtp_socket);
- lchan->abis_ip.rtp_socket = NULL;
- }
-
- lchan->abis_ip.rtp_socket = rtp_socket_create();
- if (!lchan->abis_ip.rtp_socket)
- return -EIO;
-
- rc = rtp_socket_connect(lchan->abis_ip.rtp_socket,
- lchan->abis_ip.bound_ip,
- lchan->abis_ip.bound_port);
- if (rc < 0)
- return -EIO;
-
- /* check if any transactions on this lchan still have
- * a tch_recv_mncc request pending */
- net = lchan->ts->trx->bts->network;
- llist_for_each_entry(trans, &net->trans_list, entry) {
- if (trans->conn && trans->conn->lchan == lchan && trans->tch_recv) {
- DEBUGP(DCC, "pending tch_recv_mncc request\n");
- tch_recv_mncc(net, trans->callref, 1);
- }
- }
-
- /*
- * TODO: this appears to be too early? Why not until after
- * the handover detect or the handover complete?
- *
- * Do we have a handover pending for this new lchan? In that
- * case re-route the audio from the old channel to the new one.
- */
- maybe_switch_for_handover(lchan);
- break;
- case S_ABISIP_DLCX_IND:
- /* the BTS tells us a RTP stream has been disconnected */
- if (lchan->abis_ip.rtp_socket) {
- rtp_socket_free(lchan->abis_ip.rtp_socket);
- lchan->abis_ip.rtp_socket = NULL;
- }
-
- break;
- }
-
- return 0;
-}
/* map two ipaccess RTP streams onto each other */
static int tch_map(struct gsm_lchan *lchan, struct gsm_lchan *remote_lchan)
@@ -1647,6 +1532,7 @@ static int tch_map(struct gsm_lchan *lchan, struct gsm_lchan *remote_lchan)
return 0;
}
+#endif
/* bridge channels of two transactions */
static int tch_bridge(struct gsm_network *net, struct gsm_mncc_bridge *bridge)
@@ -1663,13 +1549,19 @@ static int tch_bridge(struct gsm_network *net, struct gsm_mncc_bridge *bridge)
/* Which subscriber do we want to track trans1 or trans2? */
log_set_context(LOG_CTX_VLR_SUBSCR, trans1->vsub);
+#if BEFORE_MSCSPLIT
/* through-connect channel */
return tch_map(trans1->conn->lchan, trans2->conn->lchan);
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
}
/* enable receive of channels to MNCC upqueue */
static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable)
{
+#if BEFORE_MSCSPLIT
struct gsm_trans *trans;
struct gsm_lchan *lchan;
struct gsm_bts *bts;
@@ -1738,6 +1630,10 @@ static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable)
}
return 0;
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
}
static int gsm48_cc_rx_status_enq(struct gsm_trans *trans, struct msgb *msg)
@@ -1877,7 +1773,11 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
memset(&setup, 0, sizeof(struct gsm_mncc));
setup.callref = trans->callref;
+#if BEFORE_MSCSPLIT
setup.lchan_type = trans->conn->lchan->type;
+#else
+ setup.lchan_type = GSM_LCHAN_NONE;
+#endif
tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
/* emergency setup is identified by msg_type */
if (msg_type == GSM48_MT_CC_EMERG_SETUP)
@@ -1893,7 +1793,6 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
setup.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&setup.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
- apply_codec_restrictions(trans->conn->bts, &setup.bearer_cap);
}
/* facility */
if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
@@ -2033,7 +1932,11 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg)
memset(&call_conf, 0, sizeof(struct gsm_mncc));
call_conf.callref = trans->callref;
+#if BEFORE_MSCSPLIT
call_conf.lchan_type = trans->conn->lchan->type;
+#else
+ call_conf.lchan_type = GSM_LCHAN_NONE;
+#endif
tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
#if 0
/* repeat */
@@ -2047,7 +1950,6 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg)
call_conf.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&call_conf.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
- apply_codec_restrictions(trans->conn->bts, &call_conf.bearer_cap);
}
/* cause */
if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
@@ -2737,7 +2639,6 @@ static int gsm48_cc_rx_modify(struct gsm_trans *trans, struct msgb *msg)
modify.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&modify.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
- apply_codec_restrictions(trans->conn->bts, &modify.bearer_cap);
}
new_cc_state(trans, GSM_CSTATE_MO_ORIG_MODIFY);
@@ -2780,7 +2681,6 @@ static int gsm48_cc_rx_modify_complete(struct gsm_trans *trans, struct msgb *msg
modify.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&modify.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
- apply_codec_restrictions(trans->conn->bts, &modify.bearer_cap);
}
new_cc_state(trans, GSM_CSTATE_ACTIVE);
@@ -2821,7 +2721,6 @@ static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg)
modify.fields |= GSM48_IE_BEARER_CAP;
gsm48_decode_bearer_cap(&modify.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
- apply_codec_restrictions(trans->conn->bts, &modify.bearer_cap);
}
/* cause */
if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
@@ -2926,6 +2825,7 @@ static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg)
static int _gsm48_lchan_modify(struct gsm_trans *trans, void *arg)
{
+#if BEFORE_MSCSPLIT
struct gsm_mncc *mode = arg;
struct gsm_lchan *lchan = trans->conn->lchan;
@@ -2941,8 +2841,14 @@ static int _gsm48_lchan_modify(struct gsm_trans *trans, void *arg)
return gsm0808_assign_req(trans->conn, mode->lchan_mode,
trans->conn->lchan->type != GSM_LCHAN_TCH_H);
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
+
}
+#if BEFORE_MSCSPLIT
static void mncc_recv_rtp(struct gsm_network *net, uint32_t callref,
int cmd, uint32_t addr, uint16_t port, uint32_t payload_type,
uint32_t payload_msg_type)
@@ -2999,9 +2905,11 @@ static void mncc_recv_rtp_err(struct gsm_network *net, uint32_t callref, int cmd
{
return mncc_recv_rtp(net, callref, cmd, 0, 0, 0, 0);
}
+#endif
static int tch_rtp_create(struct gsm_network *net, uint32_t callref)
{
+#if BEFORE_MSCSPLIT
struct gsm_bts *bts;
struct gsm_lchan *lchan;
struct gsm_trans *trans;
@@ -3055,10 +2963,15 @@ static int tch_rtp_create(struct gsm_network *net, uint32_t callref)
mncc_recv_rtp_sock(trans->net, trans, MNCC_RTP_CREATE);
return 0;
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
}
static int tch_rtp_connect(struct gsm_network *net, void *arg)
{
+#if BEFORE_MSCSPLIT
struct gsm_lchan *lchan;
struct gsm_trans *trans;
struct gsm_mncc_rtp *rtp = arg;
@@ -3096,8 +3009,13 @@ static int tch_rtp_connect(struct gsm_network *net, void *arg)
*/
trans->conn->mncc_rtp_connect_pending = 1;
return rsl_ipacc_mdcx(lchan, rtp->ip, rtp->port, 0);
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
}
+#if BEFORE_MSCSPLIT
static int tch_rtp_signal(struct gsm_lchan *lchan, int signal)
{
struct gsm_network *net;
@@ -3145,6 +3063,7 @@ static int tch_rtp_signal(struct gsm_lchan *lchan, int signal)
return 0;
}
+#endif
static struct downstate {
@@ -3214,7 +3133,9 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
int i, rc = 0;
struct gsm_trans *trans = NULL, *transt;
struct gsm_subscriber_connection *conn = NULL;
+#if BEFORE_MSCSPLIT
struct gsm_bts *bts = NULL;
+#endif
struct gsm_mncc *data = arg, rel;
DEBUGP(DMNCC, "receive message %s\n", get_mncc_name(msg_type));
@@ -3252,6 +3173,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
LOGP(DMNCC, LOGL_NOTICE, "TCH frame for trans without conn\n");
return 0;
}
+#if BEFORE_MSCSPLIT
if (!trans->conn->lchan) {
LOGP(DMNCC, LOGL_NOTICE, "TCH frame for trans without lchan\n");
return 0;
@@ -3281,6 +3203,10 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
LOGP(DCC, LOGL_ERROR, "Unknown BTS type %u\n", bts->type);
}
return -EINVAL;
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
}
memset(&rel, 0, sizeof(struct gsm_mncc));
@@ -3356,14 +3282,15 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
return -ENOMEM;
}
- /* Find lchan */
+
+ /* Find conn */
conn = connection_for_subscr(vsub);
- /* If subscriber has no lchan */
+ /* If subscriber has no conn */
if (!conn) {
/* find transaction with this subscriber already paging */
llist_for_each_entry(transt, &net->trans_list, entry) {
- /* Transaction of our lchan? */
+ /* Transaction of our conn? */
if (transt == trans ||
transt->vsub != vsub)
continue;
@@ -3395,6 +3322,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
vlr_subscr_put(vsub);
return 0;
}
+
/* Assign lchan */
trans->conn = msc_subscr_conn_get(conn);
vlr_subscr_put(vsub);
@@ -3408,7 +3336,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
/* if paging did not respond yet */
if (!conn) {
- DEBUGP(DCC, "(bts - trx - ts - ti -- sub %s) "
+ DEBUGP(DCC, "(sub %s) "
"Received '%s' from MNCC in paging state\n",
vlr_subscr_msisdn_or_name(trans->vsub),
get_mncc_name(msg_type));
@@ -3423,9 +3351,8 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
return rc;
}
- DEBUGP(DCC, "(bts %d trx %d ts %d ti %02x sub %s) "
+ DEBUGP(DCC, "(ti %02x sub %s) "
"Received '%s' from MNCC in state %d (%s)\n",
- conn->bts->nr, conn->lchan->ts->trx->nr, conn->lchan->ts->nr,
trans->transaction_id,
vlr_subscr_msisdn_or_name(trans->conn->vsub),
get_mncc_name(msg_type), trans->cc.state,
@@ -3522,12 +3449,14 @@ static int gsm0408_rcv_cc(struct gsm_subscriber_connection *conn, struct msgb *m
/* Find transaction */
trans = trans_find_by_id(conn, GSM48_PDISC_CC, transaction_id);
+#if BEFORE_MSCSPLIT
DEBUGP(DCC, "(bts %d trx %d ts %d ti %x sub %s) "
"Received '%s' from MS in state %d (%s)\n",
conn->bts->nr, conn->lchan->ts->trx->nr, conn->lchan->ts->nr,
transaction_id, vlr_subscr_msisdn_or_name(conn->vsub),
gsm48_cc_msg_name(msg_type), trans?(trans->cc.state):0,
gsm48_cc_state_name(trans?(trans->cc.state):0));
+#endif
/* Create transaction */
if (!trans) {
@@ -3845,6 +3774,7 @@ int msc_vlr_start(struct gsm_network *net)
net->gsup_server_port);
}
+#if BEFORE_MSCSPLIT
/*
* This will be run by the linker when loading the DSO. We use it to
* do system initialization, e.g. registration of signal handlers.
@@ -3853,3 +3783,4 @@ static __attribute__((constructor)) void on_dso_load_0408(void)
{
osmo_signal_register_handler(SS_ABISIP, handle_abisip_signal, NULL);
}
+#endif
diff --git a/openbsc/src/libmsc/gsm_04_11.c b/openbsc/src/libmsc/gsm_04_11.c
index 6ad944b50..3255a3b6f 100644
--- a/openbsc/src/libmsc/gsm_04_11.c
+++ b/openbsc/src/libmsc/gsm_04_11.c
@@ -878,7 +878,7 @@ int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn,
}
/* Take a SMS in gsm_sms structure and send it through an already
- * existing lchan. We also assume that the caller ensured this lchan already
+ * existing conn. We also assume that the caller ensured this conn already
* has a SAPI3 RLL connection! */
int gsm411_send_sms(struct gsm_subscriber_connection *conn, struct gsm_sms *sms)
{
@@ -1004,7 +1004,7 @@ int gsm411_send_sms_subscr(struct vlr_subscr *vsub,
struct gsm_subscriber_connection *conn;
void *res;
- /* check if we already have an open lchan to the subscriber.
+ /* check if we already have an open conn to the subscriber.
* if yes, send the SMS this way */
conn = connection_for_subscr(vsub);
if (conn) {
@@ -1016,8 +1016,8 @@ int gsm411_send_sms_subscr(struct vlr_subscr *vsub,
/* if not, we have to start paging */
LOGP(DLSMS, LOGL_DEBUG, "Sending SMS: no connection open, start paging %s\n",
vlr_subscr_name(vsub));
- res = subscr_request_channel(vsub, RSL_CHANNEED_SDCCH,
- paging_cb_send_sms, sms);
+ res = subscr_request_conn(vsub, RSL_CHANNEED_SDCCH, paging_cb_send_sms,
+ sms);
if (!res) {
send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, GSM_PAGING_BUSY);
sms_free(sms);
diff --git a/openbsc/src/libmsc/gsm_subscriber.c b/openbsc/src/libmsc/gsm_subscriber.c
index e9b2e0e5d..f425058f0 100644
--- a/openbsc/src/libmsc/gsm_subscriber.c
+++ b/openbsc/src/libmsc/gsm_subscriber.c
@@ -46,21 +46,6 @@ void *tall_sub_req_ctx;
int gsm48_secure_channel(struct gsm_subscriber_connection *conn, int key_seq,
gsm_cbfn *cb, void *cb_data);
-
-/*
- * Struct for pending channel requests. This is managed in the
- * llist_head requests of each subscriber. The reference counting
- * should work in such a way that a subscriber with a pending request
- * remains in memory.
- */
-struct subscr_request {
- struct llist_head entry;
-
- /* the callback data */
- gsm_cbfn *cbfn;
- void *param;
-};
-
static struct bsc_subscr *vlr_subscr_to_bsc_sub(struct llist_head *bsc_subscribers,
struct vlr_subscr *vsub)
{
@@ -74,6 +59,10 @@ static struct bsc_subscr *vlr_subscr_to_bsc_sub(struct llist_head *bsc_subscribe
return sub;
}
+#if 0
+TODO implement paging response in libmsc!
+Excluding this to be able to link without libbsc:
+
/*
* We got the channel assigned and can now hand this channel
* over to one of our callbacks.
@@ -139,9 +128,16 @@ struct subscr_request *subscr_request_channel(struct vlr_subscr *vsub,
if (!vsub->cs.is_paging) {
LOGP(DMM, LOGL_DEBUG, "Subscriber %s not paged yet.\n",
vlr_subscr_name(vsub));
+#if 0
+ TODO implement paging response in libmsc!
+ Excluding this to be able to link without libbsc:
+
bsub = vlr_subscr_to_bsc_sub(net->bsc_subscribers, vsub);
rc = paging_request(net, bsub, channel_type, NULL, NULL);
bsc_subscr_put(bsub);
+#else
+ rc = -ENOTSUP;
+#endif
if (rc <= 0) {
LOGP(DMM, LOGL_ERROR, "Subscriber %s paging failed: %d\n",
vlr_subscr_name(vsub), rc);
@@ -181,3 +177,4 @@ struct gsm_subscriber_connection *connection_for_subscr(struct vlr_subscr *vsub)
return NULL;
}
+#endif
diff --git a/openbsc/src/libmsc/mncc_builtin.c b/openbsc/src/libmsc/mncc_builtin.c
index 067cc92f8..7f613c4a4 100644
--- a/openbsc/src/libmsc/mncc_builtin.c
+++ b/openbsc/src/libmsc/mncc_builtin.c
@@ -207,9 +207,11 @@ static int mncc_setup_cnf(struct gsm_call *call, int msg_type,
bridge.callref[1] = call->remote_ref;
DEBUGP(DMNCC, "(call %x) Bridging with remote.\n", call->callref);
+#if BEFORE_MSCSPLIT
/* in direct mode, we always have to bridge the channels */
if (ipacc_rtp_direct)
return mncc_tx_to_cc(call->net, MNCC_BRIDGE, &bridge);
+#endif
/* proxy mode */
if (!net->handover.active) {
@@ -293,11 +295,16 @@ static int mncc_rcv_data(struct gsm_call *call, int msg_type,
return -EIO;
}
+#if BEFORE_MSCSPLIT
/* RTP socket of remote end has meanwhile died */
if (!remote_trans->conn->lchan->abis_ip.rtp_socket)
return -EIO;
return rtp_send_frame(remote_trans->conn->lchan->abis_ip.rtp_socket, dfr);
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
}
diff --git a/openbsc/src/libmsc/msc_ifaces.c b/openbsc/src/libmsc/msc_ifaces.c
new file mode 100644
index 000000000..500c99c2e
--- /dev/null
+++ b/openbsc/src/libmsc/msc_ifaces.c
@@ -0,0 +1,83 @@
+/* Implementation for MSC decisions which interface to send messages out on. */
+
+/* (C) 2016 by sysmocom s.m.f.c GmbH <info@sysmocom.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <osmocom/core/logging.h>
+
+#include <openbsc/debug.h>
+#include <openbsc/gsm_data.h>
+#include <openbsc/msc_ifaces.h>
+
+static int msc_tx(struct gsm_subscriber_connection *conn, struct msgb *msg)
+{
+ switch (conn->via_ran) {
+ case RAN_GERAN_A:
+ msg->dst = conn;
+ return a_tx(msg);
+
+ case RAN_UTRAN_IU:
+ msg->dst = conn->iu.ue_ctx;
+ return iu_tx(msg, 0);
+
+ default:
+ LOGP(DMSC, LOGL_ERROR,
+ "msc_tx(): conn->via_ran invalid (%d)\n",
+ conn->via_ran);
+ return -1;
+ }
+}
+
+
+int msc_tx_dtap(struct gsm_subscriber_connection *conn,
+ struct msgb *msg)
+{
+ return msc_tx(conn, msg);
+}
+
+
+/* 9.2.5 CM service accept */
+int msc_gsm48_tx_mm_serv_ack(struct gsm_subscriber_connection *conn)
+{
+ struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 SERV ACC");
+ struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
+
+ gh->proto_discr = GSM48_PDISC_MM;
+ gh->msg_type = GSM48_MT_MM_CM_SERV_ACC;
+
+ DEBUGP(DMM, "-> CM SERVICE ACCEPT\n");
+
+ return msc_tx_dtap(conn, msg);
+}
+
+/* 9.2.6 CM service reject */
+int msc_gsm48_tx_mm_serv_rej(struct gsm_subscriber_connection *conn,
+ enum gsm48_reject_value value)
+{
+ struct msgb *msg;
+
+ msg = gsm48_create_mm_serv_rej(value);
+ if (!msg) {
+ LOGP(DMM, LOGL_ERROR, "Failed to allocate CM Service Reject.\n");
+ return -1;
+ }
+
+ DEBUGP(DMM, "-> CM SERVICE Reject cause: %d\n", value);
+
+ return msc_tx_dtap(conn, msg);
+}
diff --git a/openbsc/src/libmsc/osmo_msc.c b/openbsc/src/libmsc/osmo_msc.c
index 21c8ec246..ab53b0be7 100644
--- a/openbsc/src/libmsc/osmo_msc.c
+++ b/openbsc/src/libmsc/osmo_msc.c
@@ -21,6 +21,7 @@
*
*/
+#include <openbsc/osmo_msc.h>
#include <openbsc/bsc_api.h>
#include <openbsc/debug.h>
#include <openbsc/transaction.h>
@@ -69,9 +70,10 @@ static void subscr_conn_bump(struct gsm_subscriber_connection *conn)
osmo_fsm_inst_dispatch(conn->conn_fsm, SUBSCR_CONN_E_BUMP, NULL);
}
-/* Receive a COMPLETE LAYER3 INFO from BSC */
-static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg,
- uint16_t chosen_channel)
+/* receive a Level 3 Complete message and return MSC_CONN_ACCEPT or
+ * MSC_CONN_REJECT */
+enum msc_compl_l3_rc msc_compl_l3(struct gsm_subscriber_connection *conn,
+ struct msgb *msg, uint16_t chosen_channel)
{
/* Ownership of the gsm_subscriber_connection is still a bit mucky
* between libbsc and libmsc. In libmsc, we use ref counting, but not
@@ -87,7 +89,7 @@ static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg
/* keep the use_count reserved, libbsc will discard. If we
* released the ref count and discarded here, libbsc would
* double-free. And we will not change bsc_api semantics. */
- return BSC_API_CONN_POL_REJECT;
+ return MSC_CONN_REJECT;
}
DEBUGP(DMM, "compl_l3: Keeping conn\n");
@@ -96,7 +98,7 @@ static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg
/* If this should be kept, the conn->conn_fsm has placed a use_count */
msc_subscr_conn_put(conn);
- return BSC_API_CONN_POL_ACCEPT;
+ return MSC_CONN_ACCEPT;
#if 0
/*
@@ -105,14 +107,14 @@ static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg
* pending transaction or ongoing operation.
*/
if (conn->silent_call)
- return BSC_API_CONN_POL_ACCEPT;
- if (conn->sec_operation || conn->anch_operation)
- return BSC_API_CONN_POL_ACCEPT;
+ return MSC_CONN_ACCEPT;
+ if (conn->loc_operation || conn->sec_operation || conn->anch_operation)
+ return MSC_CONN_ACCEPT;
if (trans_has_conn(conn))
- return BSC_API_CONN_POL_ACCEPT;
+ return MSC_CONN_ACCEPT;
LOGP(DRR, LOGL_INFO, "MSC Complete L3: Rejecting connection.\n");
- return BSC_API_CONN_POL_REJECT;
+ return MSC_CONN_REJECT;
#endif
}
diff --git a/openbsc/src/libmsc/silent_call.c b/openbsc/src/libmsc/silent_call.c
index 6f3fbf264..76816c29d 100644
--- a/openbsc/src/libmsc/silent_call.c
+++ b/openbsc/src/libmsc/silent_call.c
@@ -52,8 +52,10 @@ static int paging_cb_silent(unsigned int hooknum, unsigned int event,
switch (event) {
case GSM_PAGING_SUCCEEDED:
+#if BEFORE_MSCSPLIT
DEBUGPC(DLSMS, "success, using Timeslot %u on ARFCN %u\n",
conn->lchan->ts->nr, conn->lchan->ts->trx->arfcn);
+#endif
conn->silent_call = 1;
msc_subscr_conn_get(conn);
/* increment lchan reference count */
@@ -126,7 +128,10 @@ int gsm_silent_call_start(struct vlr_subscr *vsub, void *data, int type)
{
struct subscr_request *req;
- req = subscr_request_channel(vsub, type, paging_cb_silent, data);
+ /* FIXME the VTY command allows selecting a silent call channel type.
+ * This doesn't apply to the situation after MSCSPLIT with an
+ * A-interface. */
+ req = subscr_request_conn(vsub, type, paging_cb_silent, data);
return req != NULL;
}
@@ -143,8 +148,10 @@ int gsm_silent_call_stop(struct vlr_subscr *vsub)
if (!conn->silent_call)
return -EINVAL;
+#if BEFORE_MSCSPLIT
DEBUGPC(DLSMS, "Stopping silent call using Timeslot %u on ARFCN %u\n",
conn->lchan->ts->nr, conn->lchan->ts->trx->arfcn);
+#endif
conn->silent_call = 0;
msc_subscr_conn_put(conn);
diff --git a/openbsc/src/libmsc/smpp_openbsc.c b/openbsc/src/libmsc/smpp_openbsc.c
index f06eb7d93..42ba7f990 100644
--- a/openbsc/src/libmsc/smpp_openbsc.c
+++ b/openbsc/src/libmsc/smpp_openbsc.c
@@ -423,6 +423,7 @@ void append_tlv_u16(tlv_t **req_tlv, uint16_t tag, uint16_t val)
build_tlv(req_tlv, &tlv);
}
+#if BEFORE_MSCSPLIT
/* Append the Osmocom vendor-specific additional TLVs to a SMPP msg */
static void append_osmo_tlvs(tlv_t **req_tlv, const struct gsm_lchan *lchan)
{
@@ -461,6 +462,7 @@ static void append_osmo_tlvs(tlv_t **req_tlv, const struct gsm_lchan *lchan)
(uint8_t *)vsub->imei, imei_len+1);
}
}
+#endif
struct {
uint32_t smpp_status_code;
@@ -680,8 +682,10 @@ static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms,
memcpy(deliver.short_message, sms->user_data, deliver.sm_length);
}
+#if BEFORE_MSCSPLIT
if (esme->acl && esme->acl->osmocom_ext && conn->lchan)
append_osmo_tlvs(&deliver.tlv, conn->lchan);
+#endif
ret = smpp_tx_deliver(esme, &deliver);
if (ret < 0)
diff --git a/openbsc/src/libmsc/vty_interface_layer3.c b/openbsc/src/libmsc/vty_interface_layer3.c
index faadbb16e..df2d1e4ad 100644
--- a/openbsc/src/libmsc/vty_interface_layer3.c
+++ b/openbsc/src/libmsc/vty_interface_layer3.c
@@ -559,6 +559,7 @@ DEFUN(ena_subscr_handover,
SUBSCR_HELP "Handover the active connection\n"
"Number of the BTS to handover to\n")
{
+#if BEFORE_MSCSPLIT
int ret;
struct gsm_subscriber_connection *conn;
struct gsm_bts *bts;
@@ -602,6 +603,10 @@ DEFUN(ena_subscr_handover,
vlr_subscr_put(vsub);
return CMD_SUCCESS;
+#else
+ vty_out(vty, "%% Not implemented!%s", VTY_NEWLINE);
+ return -1;
+#endif
}
#define A3A8_ALG_TYPES "(none|xor|comp128v1)"
@@ -647,6 +652,7 @@ DEFUN(subscriber_update,
static int scall_cbfn(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
+#if BEFORE_MSCSPLIT
struct scall_signal_data *sigdata = signal_data;
struct vty *vty = sigdata->data;
@@ -661,6 +667,10 @@ static int scall_cbfn(unsigned int subsys, unsigned int signal,
break;
}
return 0;
+#else
+ /* not implemented yet! */
+ return -1;
+#endif
}
DEFUN(show_stats,
@@ -670,7 +680,11 @@ DEFUN(show_stats,
{
struct gsm_network *net = gsmnet_from_vty(vty);
+#if 0
+ TODO implement statistics specifically for libmsc!
+ Excluding this to be able to link without libbsc:
openbsc_vty_print_statistics(vty, net);
+#endif
vty_out(vty, "Location Update : %lu attach, %lu normal, %lu periodic%s",
net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_ATTACH].current,
net->msc_ctrs->ctr[MSC_CTR_LOC_UPDATE_TYPE_NORMAL].current,