2010-12-22 22:54:51 +00:00
|
|
|
/* mncc_builtin.c - default, minimal built-in MNCC Application for
|
2016-08-29 16:40:02 +00:00
|
|
|
* standalone bsc_hack (network-in-the-box mode) */
|
2010-12-22 22:54:51 +00:00
|
|
|
|
|
|
|
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
|
|
|
|
* (C) 2009 by Andreas Eversberg <Andreas.Eversberg@versatel.de>
|
|
|
|
* 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 <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
2017-09-04 13:04:35 +00:00
|
|
|
#include <osmocom/msc/gsm_04_08.h>
|
|
|
|
#include <osmocom/msc/debug.h>
|
|
|
|
#include <osmocom/msc/mncc.h>
|
|
|
|
#include <osmocom/msc/mncc_int.h>
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/core/talloc.h>
|
2017-09-04 13:04:35 +00:00
|
|
|
#include <osmocom/msc/gsm_data.h>
|
|
|
|
#include <osmocom/msc/transaction.h>
|
|
|
|
#include <osmocom/msc/rtp_proxy.h>
|
2010-12-22 22:54:51 +00:00
|
|
|
|
|
|
|
void *tall_call_ctx;
|
|
|
|
|
|
|
|
static LLIST_HEAD(call_list);
|
|
|
|
|
2011-04-18 15:04:00 +00:00
|
|
|
static uint32_t new_callref = 0x00000001;
|
2010-12-22 22:54:51 +00:00
|
|
|
|
2011-09-01 16:18:43 +00:00
|
|
|
struct mncc_int mncc_int = {
|
2013-12-07 17:32:28 +00:00
|
|
|
.def_codec = { GSM48_CMODE_SPEECH_V1, GSM48_CMODE_SPEECH_V1 },
|
2011-09-01 16:18:43 +00:00
|
|
|
};
|
|
|
|
|
2010-12-22 22:54:51 +00:00
|
|
|
static void free_call(struct gsm_call *call)
|
|
|
|
{
|
|
|
|
llist_del(&call->entry);
|
|
|
|
DEBUGP(DMNCC, "(call %x) Call removed.\n", call->callref);
|
|
|
|
talloc_free(call);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-04-18 15:04:00 +00:00
|
|
|
static struct gsm_call *get_call_ref(uint32_t callref)
|
2010-12-22 22:54:51 +00:00
|
|
|
{
|
|
|
|
struct gsm_call *callt;
|
|
|
|
|
|
|
|
llist_for_each_entry(callt, &call_list, entry) {
|
|
|
|
if (callt->callref == callref)
|
|
|
|
return callt;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* on incoming call, look up database and send setup to remote subscr. */
|
|
|
|
static int mncc_setup_ind(struct gsm_call *call, int msg_type,
|
|
|
|
struct gsm_mncc *setup)
|
|
|
|
{
|
|
|
|
struct gsm_mncc mncc;
|
|
|
|
struct gsm_call *remote;
|
|
|
|
|
|
|
|
memset(&mncc, 0, sizeof(struct gsm_mncc));
|
|
|
|
mncc.callref = call->callref;
|
|
|
|
|
|
|
|
/* already have remote call */
|
|
|
|
if (call->remote_ref)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* transfer mode 1 would be packet mode, which was never specified */
|
|
|
|
if (setup->bearer_cap.mode != 0) {
|
|
|
|
LOGP(DMNCC, LOGL_NOTICE, "(call %x) We don't support "
|
|
|
|
"packet mode\n", call->callref);
|
|
|
|
mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU,
|
|
|
|
GSM48_CC_CAUSE_BEARER_CA_UNAVAIL);
|
|
|
|
goto out_reject;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* we currently only do speech */
|
|
|
|
if (setup->bearer_cap.transfer != GSM_MNCC_BCAP_SPEECH) {
|
|
|
|
LOGP(DMNCC, LOGL_NOTICE, "(call %x) We only support "
|
|
|
|
"voice calls\n", call->callref);
|
|
|
|
mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU,
|
|
|
|
GSM48_CC_CAUSE_BEARER_CA_UNAVAIL);
|
|
|
|
goto out_reject;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create remote call */
|
2013-01-25 07:36:32 +00:00
|
|
|
if (!(remote = talloc_zero(tall_call_ctx, struct gsm_call))) {
|
2010-12-22 22:54:51 +00:00
|
|
|
mncc_set_cause(&mncc, GSM48_CAUSE_LOC_PRN_S_LU,
|
|
|
|
GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
|
|
|
|
goto out_reject;
|
|
|
|
}
|
|
|
|
llist_add_tail(&remote->entry, &call_list);
|
|
|
|
remote->net = call->net;
|
|
|
|
remote->callref = new_callref++;
|
|
|
|
DEBUGP(DMNCC, "(call %x) Creating new remote instance %x.\n",
|
|
|
|
call->callref, remote->callref);
|
|
|
|
|
|
|
|
/* link remote call */
|
|
|
|
call->remote_ref = remote->callref;
|
|
|
|
remote->remote_ref = call->callref;
|
|
|
|
|
2012-08-24 14:48:21 +00:00
|
|
|
/* send call proceeding */
|
|
|
|
memset(&mncc, 0, sizeof(struct gsm_mncc));
|
|
|
|
mncc.callref = call->callref;
|
|
|
|
DEBUGP(DMNCC, "(call %x) Accepting call.\n", call->callref);
|
|
|
|
mncc_tx_to_cc(call->net, MNCC_CALL_PROC_REQ, &mncc);
|
|
|
|
|
2010-12-22 22:54:51 +00:00
|
|
|
/* modify mode */
|
|
|
|
memset(&mncc, 0, sizeof(struct gsm_mncc));
|
|
|
|
mncc.callref = call->callref;
|
mscsplit: various preparations to separate MSC from BSC
Disable large parts of the code that depend on BSC presence. The code sections
disabled by #if BEFORE_MSCSPLIT shall be modified or dropped in the course of
adding the A-interface.
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.
Remove internal RTP streaming code; OsmoNITB supported that, but for OsmoMSC,
this will be done with an external MGCP gateway.
Remove LCHAN_MODIFY from internal MNCC state machine.
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.
Employ fake paging shims in order for msc_vlr_tests to still work.
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
gsm_subscriber_connection: put the LAC here, so that it is available without
accessing conn->bts. In bsc_api.c, place this lac in conn for the sake of
transition: Iu and A will use this new field to pass the LAC around, but in a
completely separate OsmoBSC this is not actually needed. It can be removed
again from osmo-bsc.git when the time has come.
Siemens MRPCI: completely drop sending the MRPCI messages for now, they shall
be added in osmo-bsc once the A-Interface code has settled. See OS#2389.
Related: OS#1845 OS#2257 OS#2389
Change-Id: Id3705236350d5f69e447046b0a764bbabc3d493c
2017-05-08 13:12:20 +00:00
|
|
|
DEBUGP(DMNCC, "(call %x) Modify channel mode\n", call->callref);
|
2010-12-22 22:57:45 +00:00
|
|
|
mncc_tx_to_cc(call->net, MNCC_LCHAN_MODIFY, &mncc);
|
2010-12-22 22:54:51 +00:00
|
|
|
|
|
|
|
/* send setup to remote */
|
|
|
|
// setup->fields |= MNCC_F_SIGNAL;
|
|
|
|
// setup->signal = GSM48_SIGNAL_DIALTONE;
|
|
|
|
setup->callref = remote->callref;
|
|
|
|
DEBUGP(DMNCC, "(call %x) Forwarding SETUP to remote.\n", call->callref);
|
2010-12-22 22:57:45 +00:00
|
|
|
return mncc_tx_to_cc(remote->net, MNCC_SETUP_REQ, setup);
|
2010-12-22 22:54:51 +00:00
|
|
|
|
|
|
|
out_reject:
|
2010-12-22 22:57:45 +00:00
|
|
|
mncc_tx_to_cc(call->net, MNCC_REJ_REQ, &mncc);
|
2010-12-22 22:54:51 +00:00
|
|
|
free_call(call);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mncc_alert_ind(struct gsm_call *call, int msg_type,
|
|
|
|
struct gsm_mncc *alert)
|
|
|
|
{
|
|
|
|
struct gsm_call *remote;
|
|
|
|
|
|
|
|
/* send alerting to remote */
|
|
|
|
if (!(remote = get_call_ref(call->remote_ref)))
|
|
|
|
return 0;
|
|
|
|
alert->callref = remote->callref;
|
|
|
|
DEBUGP(DMNCC, "(call %x) Forwarding ALERT to remote.\n", call->callref);
|
2010-12-22 22:57:45 +00:00
|
|
|
return mncc_tx_to_cc(remote->net, MNCC_ALERT_REQ, alert);
|
2010-12-22 22:54:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int mncc_notify_ind(struct gsm_call *call, int msg_type,
|
|
|
|
struct gsm_mncc *notify)
|
|
|
|
{
|
|
|
|
struct gsm_call *remote;
|
|
|
|
|
|
|
|
/* send notify to remote */
|
|
|
|
if (!(remote = get_call_ref(call->remote_ref)))
|
|
|
|
return 0;
|
|
|
|
notify->callref = remote->callref;
|
|
|
|
DEBUGP(DMNCC, "(call %x) Forwarding NOTIF to remote.\n", call->callref);
|
2010-12-22 22:57:45 +00:00
|
|
|
return mncc_tx_to_cc(remote->net, MNCC_NOTIFY_REQ, notify);
|
2010-12-22 22:54:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int mncc_setup_cnf(struct gsm_call *call, int msg_type,
|
|
|
|
struct gsm_mncc *connect)
|
|
|
|
{
|
|
|
|
struct gsm_mncc connect_ack, frame_recv;
|
|
|
|
struct gsm_network *net = call->net;
|
|
|
|
struct gsm_call *remote;
|
2015-12-03 13:59:04 +00:00
|
|
|
struct gsm_mncc_bridge bridge = { .msg_type = MNCC_BRIDGE };
|
2010-12-22 22:54:51 +00:00
|
|
|
|
|
|
|
/* acknowledge connect */
|
|
|
|
memset(&connect_ack, 0, sizeof(struct gsm_mncc));
|
|
|
|
connect_ack.callref = call->callref;
|
|
|
|
DEBUGP(DMNCC, "(call %x) Acknowledge SETUP.\n", call->callref);
|
2010-12-22 22:57:45 +00:00
|
|
|
mncc_tx_to_cc(call->net, MNCC_SETUP_COMPL_REQ, &connect_ack);
|
2010-12-22 22:54:51 +00:00
|
|
|
|
|
|
|
/* send connect message to remote */
|
|
|
|
if (!(remote = get_call_ref(call->remote_ref)))
|
|
|
|
return 0;
|
|
|
|
connect->callref = remote->callref;
|
|
|
|
DEBUGP(DMNCC, "(call %x) Sending CONNECT to remote.\n", call->callref);
|
2010-12-22 22:57:45 +00:00
|
|
|
mncc_tx_to_cc(remote->net, MNCC_SETUP_RSP, connect);
|
2010-12-22 22:54:51 +00:00
|
|
|
|
|
|
|
/* bridge tch */
|
2015-12-03 13:59:04 +00:00
|
|
|
bridge.callref[0] = call->callref;
|
|
|
|
bridge.callref[1] = call->remote_ref;
|
2010-12-22 22:54:51 +00:00
|
|
|
DEBUGP(DMNCC, "(call %x) Bridging with remote.\n", call->callref);
|
|
|
|
|
|
|
|
/* proxy mode */
|
|
|
|
if (!net->handover.active) {
|
|
|
|
/* in the no-handover case, we can bridge, i.e. use
|
|
|
|
* the old RTP proxy code */
|
2015-12-03 13:59:04 +00:00
|
|
|
return mncc_tx_to_cc(call->net, MNCC_BRIDGE, &bridge);
|
2010-12-22 22:54:51 +00:00
|
|
|
} else {
|
|
|
|
/* in case of handover, we need to re-write the RTP
|
|
|
|
* SSRC, sequence and timestamp values and thus
|
|
|
|
* need to enable RTP receive for both directions */
|
|
|
|
memset(&frame_recv, 0, sizeof(struct gsm_mncc));
|
|
|
|
frame_recv.callref = call->callref;
|
2010-12-22 22:57:45 +00:00
|
|
|
mncc_tx_to_cc(call->net, MNCC_FRAME_RECV, &frame_recv);
|
2010-12-22 22:54:51 +00:00
|
|
|
frame_recv.callref = call->remote_ref;
|
2010-12-22 22:57:45 +00:00
|
|
|
return mncc_tx_to_cc(call->net, MNCC_FRAME_RECV, &frame_recv);
|
2010-12-22 22:54:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mncc_disc_ind(struct gsm_call *call, int msg_type,
|
|
|
|
struct gsm_mncc *disc)
|
|
|
|
{
|
|
|
|
struct gsm_call *remote;
|
|
|
|
|
|
|
|
/* send release */
|
|
|
|
DEBUGP(DMNCC, "(call %x) Releasing call with cause %d\n",
|
|
|
|
call->callref, disc->cause.value);
|
2010-12-22 22:57:45 +00:00
|
|
|
mncc_tx_to_cc(call->net, MNCC_REL_REQ, disc);
|
2010-12-22 22:54:51 +00:00
|
|
|
|
|
|
|
/* send disc to remote */
|
|
|
|
if (!(remote = get_call_ref(call->remote_ref))) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
disc->callref = remote->callref;
|
|
|
|
DEBUGP(DMNCC, "(call %x) Disconnecting remote with cause %d\n",
|
|
|
|
remote->callref, disc->cause.value);
|
2010-12-22 22:57:45 +00:00
|
|
|
return mncc_tx_to_cc(remote->net, MNCC_DISC_REQ, disc);
|
2010-12-22 22:54:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int mncc_rel_ind(struct gsm_call *call, int msg_type, struct gsm_mncc *rel)
|
|
|
|
{
|
|
|
|
struct gsm_call *remote;
|
|
|
|
|
|
|
|
/* send release to remote */
|
|
|
|
if (!(remote = get_call_ref(call->remote_ref))) {
|
|
|
|
free_call(call);
|
|
|
|
return 0;
|
|
|
|
}
|
2011-01-27 14:05:45 +00:00
|
|
|
|
2010-12-22 22:54:51 +00:00
|
|
|
rel->callref = remote->callref;
|
|
|
|
DEBUGP(DMNCC, "(call %x) Releasing remote with cause %d\n",
|
|
|
|
call->callref, rel->cause.value);
|
|
|
|
|
2011-01-27 14:05:45 +00:00
|
|
|
/*
|
|
|
|
* Release this side of the call right now. Otherwise we end up
|
|
|
|
* in this method for the other call and will also try to release
|
|
|
|
* it and then we will end up with a double free and a crash
|
|
|
|
*/
|
2010-12-22 22:54:51 +00:00
|
|
|
free_call(call);
|
2011-01-27 14:05:45 +00:00
|
|
|
mncc_tx_to_cc(remote->net, MNCC_REL_REQ, rel);
|
2010-12-22 22:54:51 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mncc_rel_cnf(struct gsm_call *call, int msg_type, struct gsm_mncc *rel)
|
|
|
|
{
|
|
|
|
free_call(call);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Internal MNCC handler input function (from CC -> MNCC -> here) */
|
2010-12-23 00:07:46 +00:00
|
|
|
int int_mncc_recv(struct gsm_network *net, struct msgb *msg)
|
2010-12-22 22:54:51 +00:00
|
|
|
{
|
2010-12-23 00:07:46 +00:00
|
|
|
void *arg = msgb_data(msg);
|
2010-12-22 22:54:51 +00:00
|
|
|
struct gsm_mncc *data = arg;
|
2010-12-23 00:07:46 +00:00
|
|
|
int msg_type = data->msg_type;
|
2010-12-22 22:54:51 +00:00
|
|
|
int callref;
|
|
|
|
struct gsm_call *call = NULL, *callt;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
/* Special messages */
|
|
|
|
switch(msg_type) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/* find callref */
|
|
|
|
callref = data->callref;
|
|
|
|
llist_for_each_entry(callt, &call_list, entry) {
|
|
|
|
if (callt->callref == callref) {
|
|
|
|
call = callt;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create callref, if setup is received */
|
|
|
|
if (!call) {
|
|
|
|
if (msg_type != MNCC_SETUP_IND)
|
2010-12-23 00:07:46 +00:00
|
|
|
goto out_free; /* drop */
|
2010-12-22 22:54:51 +00:00
|
|
|
/* create call */
|
|
|
|
if (!(call = talloc_zero(tall_call_ctx, struct gsm_call))) {
|
|
|
|
struct gsm_mncc rel;
|
|
|
|
|
|
|
|
memset(&rel, 0, sizeof(struct gsm_mncc));
|
|
|
|
rel.callref = callref;
|
|
|
|
mncc_set_cause(&rel, GSM48_CAUSE_LOC_PRN_S_LU,
|
|
|
|
GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
|
2010-12-22 22:57:45 +00:00
|
|
|
mncc_tx_to_cc(net, MNCC_REL_REQ, &rel);
|
2010-12-23 00:07:46 +00:00
|
|
|
goto out_free;
|
2010-12-22 22:54:51 +00:00
|
|
|
}
|
|
|
|
llist_add_tail(&call->entry, &call_list);
|
|
|
|
call->net = net;
|
|
|
|
call->callref = callref;
|
|
|
|
DEBUGP(DMNCC, "(call %x) Call created.\n", call->callref);
|
|
|
|
}
|
|
|
|
|
2013-03-11 07:12:43 +00:00
|
|
|
if (mncc_is_data_frame(msg_type)) {
|
mscsplit: various preparations to separate MSC from BSC
Disable large parts of the code that depend on BSC presence. The code sections
disabled by #if BEFORE_MSCSPLIT shall be modified or dropped in the course of
adding the A-interface.
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.
Remove internal RTP streaming code; OsmoNITB supported that, but for OsmoMSC,
this will be done with an external MGCP gateway.
Remove LCHAN_MODIFY from internal MNCC state machine.
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.
Employ fake paging shims in order for msc_vlr_tests to still work.
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
gsm_subscriber_connection: put the LAC here, so that it is available without
accessing conn->bts. In bsc_api.c, place this lac in conn for the sake of
transition: Iu and A will use this new field to pass the LAC around, but in a
completely separate OsmoBSC this is not actually needed. It can be removed
again from osmo-bsc.git when the time has come.
Siemens MRPCI: completely drop sending the MRPCI messages for now, they shall
be added in osmo-bsc once the A-Interface code has settled. See OS#2389.
Related: OS#1845 OS#2257 OS#2389
Change-Id: Id3705236350d5f69e447046b0a764bbabc3d493c
2017-05-08 13:12:20 +00:00
|
|
|
LOGP(DMNCC, LOGL_ERROR, "(call %x) Received data frame, which is not supported.\n",
|
|
|
|
call->callref);
|
2013-03-11 07:12:43 +00:00
|
|
|
goto out_free;
|
2010-12-22 22:54:51 +00:00
|
|
|
}
|
|
|
|
|
2013-03-11 07:12:43 +00:00
|
|
|
DEBUGP(DMNCC, "(call %x) Received message %s\n", call->callref,
|
|
|
|
get_mncc_name(msg_type));
|
|
|
|
|
2010-12-22 22:54:51 +00:00
|
|
|
switch(msg_type) {
|
|
|
|
case MNCC_SETUP_IND:
|
|
|
|
rc = mncc_setup_ind(call, msg_type, arg);
|
|
|
|
break;
|
|
|
|
case MNCC_SETUP_CNF:
|
|
|
|
rc = mncc_setup_cnf(call, msg_type, arg);
|
|
|
|
break;
|
|
|
|
case MNCC_SETUP_COMPL_IND:
|
|
|
|
break;
|
|
|
|
case MNCC_CALL_CONF_IND:
|
|
|
|
/* we now need to MODIFY the channel */
|
2010-12-22 22:57:45 +00:00
|
|
|
mncc_tx_to_cc(call->net, MNCC_LCHAN_MODIFY, data);
|
2010-12-22 22:54:51 +00:00
|
|
|
break;
|
|
|
|
case MNCC_ALERT_IND:
|
|
|
|
rc = mncc_alert_ind(call, msg_type, arg);
|
|
|
|
break;
|
|
|
|
case MNCC_NOTIFY_IND:
|
|
|
|
rc = mncc_notify_ind(call, msg_type, arg);
|
|
|
|
break;
|
|
|
|
case MNCC_DISC_IND:
|
|
|
|
rc = mncc_disc_ind(call, msg_type, arg);
|
|
|
|
break;
|
|
|
|
case MNCC_REL_IND:
|
|
|
|
case MNCC_REJ_IND:
|
|
|
|
rc = mncc_rel_ind(call, msg_type, arg);
|
|
|
|
break;
|
|
|
|
case MNCC_REL_CNF:
|
|
|
|
rc = mncc_rel_cnf(call, msg_type, arg);
|
|
|
|
break;
|
|
|
|
case MNCC_FACILITY_IND:
|
|
|
|
break;
|
|
|
|
case MNCC_START_DTMF_IND:
|
2016-10-29 20:23:19 +00:00
|
|
|
rc = mncc_tx_to_cc(net, MNCC_START_DTMF_REJ, data);
|
2010-12-22 22:54:51 +00:00
|
|
|
break;
|
|
|
|
case MNCC_STOP_DTMF_IND:
|
2016-10-29 20:23:19 +00:00
|
|
|
rc = mncc_tx_to_cc(net, MNCC_STOP_DTMF_RSP, data);
|
2010-12-22 22:54:51 +00:00
|
|
|
break;
|
|
|
|
case MNCC_MODIFY_IND:
|
|
|
|
mncc_set_cause(data, GSM48_CAUSE_LOC_PRN_S_LU,
|
|
|
|
GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
|
|
|
|
DEBUGP(DMNCC, "(call %x) Rejecting MODIFY with cause %d\n",
|
|
|
|
call->callref, data->cause.value);
|
2010-12-22 22:57:45 +00:00
|
|
|
rc = mncc_tx_to_cc(net, MNCC_MODIFY_REJ, data);
|
2010-12-22 22:54:51 +00:00
|
|
|
break;
|
|
|
|
case MNCC_MODIFY_CNF:
|
|
|
|
break;
|
|
|
|
case MNCC_HOLD_IND:
|
|
|
|
mncc_set_cause(data, GSM48_CAUSE_LOC_PRN_S_LU,
|
|
|
|
GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
|
|
|
|
DEBUGP(DMNCC, "(call %x) Rejecting HOLD with cause %d\n",
|
|
|
|
call->callref, data->cause.value);
|
2010-12-22 22:57:45 +00:00
|
|
|
rc = mncc_tx_to_cc(net, MNCC_HOLD_REJ, data);
|
2010-12-22 22:54:51 +00:00
|
|
|
break;
|
|
|
|
case MNCC_RETRIEVE_IND:
|
|
|
|
mncc_set_cause(data, GSM48_CAUSE_LOC_PRN_S_LU,
|
|
|
|
GSM48_CC_CAUSE_SERV_OPT_UNIMPL);
|
|
|
|
DEBUGP(DMNCC, "(call %x) Rejecting RETRIEVE with cause %d\n",
|
|
|
|
call->callref, data->cause.value);
|
2010-12-22 22:57:45 +00:00
|
|
|
rc = mncc_tx_to_cc(net, MNCC_RETRIEVE_REJ, data);
|
2010-12-22 22:54:51 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
LOGP(DMNCC, LOGL_NOTICE, "(call %x) Message unhandled\n", callref);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-12-23 00:07:46 +00:00
|
|
|
out_free:
|
2012-03-01 19:30:32 +00:00
|
|
|
msgb_free(msg);
|
2010-12-23 00:07:46 +00:00
|
|
|
|
2010-12-22 22:54:51 +00:00
|
|
|
return rc;
|
|
|
|
}
|