diff options
authorNeels Hofmeyr <neels@hofmeyr.de>2018-12-20 02:59:32 +0100
committerNeels Hofmeyr <neels@hofmeyr.de>2018-12-21 01:59:24 +0100
commita8a0059c4fc9d881e8fff5262a92a5e407c98be0 (patch)
parent209ee2a699d60fa75f0c4eb886b8a85c3be7f00f (diff)
fix: incoming call during ongoing call
If a call is already busy and another call is coming in, do not try to immediately assign an lchan (before this patch, it fails because there already is an mgcp_ctx for the conn). Leave the second CC transaction waiting. When a call is hung up, as soon as the old mgcp_ctx is discarded, look for other CC transactions that are waiting. If there is one, trigger assignment, so a new mgcp_ctx is set up for the new call. This fixes the following scenario: - from A, call B. - from C, call B; B rings during ongoing call. - in B, pick up the call, choose to drop the old call. After this patch, and with osmo-bsc patch with change-id I0c00ec2c120e5008281755adcd4944a3ce4d8355 we are now able to talk to the new caller. I currently haven't tested yet what happens if there is *three* peers trying to talk to the same number, running out of lab phones (not really, just not bothering now). Possibly we should be taking over the particular call indicated by the CC TI; instead, the current patch version takes on whichever waiting call it finds first. This is fine if *one* additional call comes in on an ongoing call, and this is already a huge improvement to what we had before. Related: OS#3735 Change-Id: I0ba216b737909e92080a722db26e3577726c63cb
1 files changed, 31 insertions, 0 deletions
diff --git a/src/libmsc/msc_mgcp.c b/src/libmsc/msc_mgcp.c
index 8e2e7a97f..4c177680a 100644
--- a/src/libmsc/msc_mgcp.c
+++ b/src/libmsc/msc_mgcp.c
@@ -962,6 +962,10 @@ int msc_mgcp_try_call_assignment(struct gsm_trans *trans)
struct ran_conn *conn = trans->conn;
if (trans->cc.assignment_started)
return 0;
+ if (conn->rtp.mgcp_ctx) {
+ LOGPFSMSL(conn->fi, DMGCP, LOGL_INFO, "Another call is already ongoing, not assigning yet\n");
+ return 0;
+ }
LOGPFSMSL(conn->fi, DMGCP, LOGL_INFO, "Starting call assignment\n");
trans->cc.assignment_started = true;
return msc_mgcp_call_assignment(trans);
@@ -1152,6 +1156,23 @@ int msc_mgcp_call_complete(struct gsm_trans *trans, uint16_t port, char *addr)
return 0;
+static struct gsm_trans *find_waiting_call(struct ran_conn *conn)
+ struct gsm_trans *trans;
+ struct gsm_network *net = conn->network;
+ llist_for_each_entry(trans, &net->trans_list, entry) {
+ if (trans->conn != conn)
+ continue;
+ if (trans->protocol != GSM48_PDISC_CC)
+ continue;
+ if (trans->cc.assignment_started)
+ continue;
+ return trans;
+ }
+ return NULL;
/* Release ongoing call.
* Parameter:
* trans: connection context.
@@ -1160,6 +1181,7 @@ int msc_mgcp_call_release(struct gsm_trans *trans)
struct mgcp_ctx *mgcp_ctx;
struct ran_conn *conn = trans->conn;
+ struct gsm_trans *waiting_trans;
@@ -1203,5 +1225,14 @@ int msc_mgcp_call_release(struct gsm_trans *trans)
* all related context information */
conn->rtp.mgcp_ctx = NULL;
+ /* If there is another call still waiting to be activated, this is the time when the mgcp_ctx is available again
+ * and the other call can start assigning. */
+ waiting_trans = find_waiting_call(conn);
+ if (waiting_trans) {
+ LOGP(DMGCP, LOGL_DEBUG, "(ti %02x %s) Call waiting: starting Assignment\n",
+ waiting_trans->transaction_id, vlr_subscr_name(trans->vsub));
+ msc_mgcp_try_call_assignment(waiting_trans);
+ }
return 0;