aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Whyte <keith@rhizomatica.org>2019-08-08 15:43:40 +0200
committergsmevent admin <admin@gsmevent.box>2019-08-24 15:48:42 +0200
commit5b47ac2bf6c97cc4fbbbd5567bcec61478a2eb55 (patch)
treed24d641c9b77c0b58539e3cc28ba695a05021198
parent9e6ec575879050db9878e31fe801017222be5542 (diff)
Implement a global switch on the network to disable call waiting.cccamp2019
Add a network -> callwaiting VTY command as boolean. When this is enabled (default) there is no change to operation previous to this commit. When this switch is disabled with "no call-waiting" in vty then when a call arrives, we will check if we have an active call transaction for this subscriber, no matter if it is establishing, established, or alerting, in any of these cases we will return USER BUSY to the calling party. Change-Id: I3eb6f23f7103e3002874fb5d3a30c9de952202ae
-rw-r--r--include/osmocom/msc/gsm_data.h3
-rw-r--r--src/libmsc/gsm_04_08_cc.c22
-rw-r--r--src/libmsc/msc_vty.c28
-rw-r--r--src/osmo-msc/msc_main.c1
-rw-r--r--tests/test_nodes.vty2
5 files changed, 53 insertions, 3 deletions
diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h
index a90b732af..11b6e8237 100644
--- a/include/osmocom/msc/gsm_data.h
+++ b/include/osmocom/msc/gsm_data.h
@@ -258,6 +258,9 @@ struct gsm_network {
/* Whether we want to use Osmux against BSCs. Controlled via VTY */
enum osmux_usage use_osmux;
+
+ /* Whether to use call waiting on the network */
+ bool call_waiting;
};
struct osmo_esme;
diff --git a/src/libmsc/gsm_04_08_cc.c b/src/libmsc/gsm_04_08_cc.c
index c941a7a29..71871bfaa 100644
--- a/src/libmsc/gsm_04_08_cc.c
+++ b/src/libmsc/gsm_04_08_cc.c
@@ -1904,6 +1904,25 @@ static int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg)
GSM48_CAUSE_LOC_PRN_S_LU,
GSM48_CC_CAUSE_DEST_OOO);
}
+
+ /* Find valid conn */
+ msc_a = msc_a_for_vsub(vsub, true);
+
+ /* If subscriber is BUSY and we do not DO call in call aka "call-waiting" */
+ if (!net->call_waiting && msc_a) {
+ struct gsm_trans *existing_cc_trans = trans_find_by_type(msc_a, TRANS_CC);
+ if (existing_cc_trans && existing_cc_trans->cc.state != GSM_CSTATE_NULL) {
+ LOG_TRANS_CAT(existing_cc_trans, DCC, LOGL_NOTICE,
+ "rx '%s' for subscriber %s with trans state (%s)"
+ " rejecting with USER_BUSY\n",
+ get_mncc_name(msg->msg_type), data->called.number,
+ gsm48_cc_state_name(existing_cc_trans->cc.state));
+ return mncc_release_ind(net, NULL, data->callref,
+ GSM48_CAUSE_LOC_PRN_S_LU,
+ GSM48_CC_CAUSE_USER_BUSY);
+ }
+ }
+
/* Create transaction */
trans = trans_alloc(net, vsub, TRANS_CC,
TRANS_ID_UNASSIGNED, data->callref);
@@ -1917,9 +1936,6 @@ static int mncc_tx_to_gsm_cc(struct gsm_network *net, const union mncc_msg *msg)
return -ENOMEM;
}
- /* Find valid conn */
- msc_a = msc_a_for_vsub(vsub, true);
-
/* If subscriber has no conn */
if (!msc_a) {
diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c
index 4674e2e68..09aef9168 100644
--- a/src/libmsc/msc_vty.c
+++ b/src/libmsc/msc_vty.c
@@ -330,6 +330,29 @@ DEFUN(cfg_net_no_per_loc_upd, cfg_net_no_per_loc_upd_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_net_call_wait, cfg_net_call_wait_cmd,
+ "call-waiting",
+ "Enable Call Waiting on the Network\n")
+{
+ struct gsm_network *net = vty->index;
+
+ net->call_waiting = true;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_net_no_call_wait, cfg_net_no_call_wait_cmd,
+ "no call-waiting",
+ NO_STR
+ "Disable Call Waiting on the Network\n")
+{
+ struct gsm_network *net = vty->index;
+
+ net->call_waiting = false;
+
+ return CMD_SUCCESS;
+}
+
static int config_write_net(struct vty *vty)
{
int i;
@@ -376,6 +399,9 @@ static int config_write_net(struct vty *vty)
gsmnet->emergency.route_to_msisdn, VTY_NEWLINE);
}
+ if (!gsmnet->call_waiting)
+ vty_out(vty, " no call-waiting%s", VTY_NEWLINE);
+
return CMD_SUCCESS;
}
@@ -1946,6 +1972,8 @@ void msc_vty_init(struct gsm_network *msc_network)
install_element(GSMNET_NODE, &cfg_net_no_timezone_cmd);
install_element(GSMNET_NODE, &cfg_net_per_loc_upd_cmd);
install_element(GSMNET_NODE, &cfg_net_no_per_loc_upd_cmd);
+ install_element(GSMNET_NODE, &cfg_net_call_wait_cmd);
+ install_element(GSMNET_NODE, &cfg_net_no_call_wait_cmd);
install_element(CONFIG_NODE, &cfg_msc_cmd);
install_node(&msc_node, config_write_msc);
diff --git a/src/osmo-msc/msc_main.c b/src/osmo-msc/msc_main.c
index 1083271a9..3860589e7 100644
--- a/src/osmo-msc/msc_main.c
+++ b/src/osmo-msc/msc_main.c
@@ -216,6 +216,7 @@ struct gsm_network *msc_network_alloc(void *ctx,
mgcp_client_conf_init(&net->mgw.conf);
net->mgw.tdefs = g_mgw_tdefs;
+ net->call_waiting = true;
return net;
}
diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty
index 0ad390fc5..a4e0e15db 100644
--- a/tests/test_nodes.vty
+++ b/tests/test_nodes.vty
@@ -26,6 +26,8 @@ OsmoMSC(config-net)# list
no timezone
periodic location update <6-1530>
no periodic location update
+ call-waiting
+ no call-waiting
OsmoMSC(config-net)# encryption?
encryption Encryption options