aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmsc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmsc')
-rw-r--r--src/libmsc/gsm_04_08_cc.c22
-rw-r--r--src/libmsc/msc_vty.c28
2 files changed, 47 insertions, 3 deletions
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);