Implement a global switch on the network to disable call waiting.

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
changes/20/15120/13
Keith Whyte 3 years ago committed by keith
parent 7c8df44adc
commit 991bb422d4
  1. 3
      include/osmocom/msc/gsm_data.h
  2. 22
      src/libmsc/gsm_04_08_cc.c
  3. 28
      src/libmsc/msc_vty.c
  4. 1
      src/osmo-msc/msc_main.c
  5. 2
      tests/test_nodes.vty

@ -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;

@ -1909,6 +1909,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);
@ -1922,9 +1941,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) {

@ -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);

@ -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;
}

@ -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

Loading…
Cancel
Save