summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2015-08-04 14:41:21 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2015-08-04 14:57:55 +0200
commit14a088a92162fd6abb3031e025ce59fba40af718 (patch)
tree2f2d4b308cfe9573250924a3319e4b161872e5d0
parent05a09059145ff4bfb1a09ec50e22fb75f2f4ca1e (diff)
mncc: Implement CRCX->MDCX for handover for direct rtp mode
Implement sending MDCX on the newly allocated channel and send the data to the same destination as the currently connected one. This way the receiver can implement RTP RFC Appendix A.1 and deal with the new source.
-rw-r--r--openbsc/include/openbsc/gsm_data.h1
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c34
2 files changed, 29 insertions, 6 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index bed04e3..c167c49 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -123,6 +123,7 @@ struct gsm_subscriber_connection {
/* MNCC rtp bridge markers */
int mncc_rtp_bridge;
int mncc_rtp_create_pending;
+ int mncc_rtp_connect_pending;
/* bsc structures */
struct osmo_bsc_sccp_con *sccp_con;
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index f20eb08..f71d43c 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -1465,6 +1465,15 @@ static int switch_for_handover(struct gsm_lchan *old_lchan,
{
struct rtp_socket *old_rs, *new_rs, *other_rs;
+ /* Ask the new socket to send to the already known port. */
+ if (new_lchan->conn->mncc_rtp_bridge) {
+ LOGP(DHO, LOGL_DEBUG, "Forwarding RTP\n");
+ rsl_ipacc_mdcx(new_lchan,
+ old_lchan->abis_ip.connect_ip,
+ old_lchan->abis_ip.connect_port, 0);
+ return 0;
+ }
+
if (ipacc_rtp_direct) {
LOGP(DHO, LOGL_ERROR, "unable to handover in direct RTP mode\n");
return 0;
@@ -1509,11 +1518,19 @@ static int switch_for_handover(struct gsm_lchan *old_lchan,
return 0;
}
+static void maybe_switch_for_handover(struct gsm_lchan *lchan)
+{
+ struct gsm_lchan *old_lchan;
+ old_lchan = bsc_handover_pending(lchan);
+ if (old_lchan)
+ switch_for_handover(old_lchan, lchan);
+}
+
/* some other part of the code sends us a signal */
static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
- struct gsm_lchan *lchan = signal_data, *old_lchan;
+ struct gsm_lchan *lchan = signal_data;
int rc;
struct gsm_network *net;
struct gsm_trans *trans;
@@ -1566,9 +1583,7 @@ static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
* Do we have a handover pending for this new lchan? In that
* case re-route the audio from the old channel to the new one.
*/
- old_lchan = bsc_handover_pending(lchan);
- if (old_lchan)
- switch_for_handover(old_lchan, lchan);
+ maybe_switch_for_handover(lchan);
break;
case S_ABISIP_DLCX_IND:
/* the BTS tells us a RTP stream has been disconnected */
@@ -3070,6 +3085,7 @@ static int tch_rtp_connect(struct gsm_network *net, void *arg)
* complains about both rtp and rtp payload2 being present in the
* same package!
*/
+ trans->conn->mncc_rtp_connect_pending = 1;
return rsl_ipacc_mdcx(lchan, rtp->ip, rtp->port, 0);
}
@@ -3082,7 +3098,7 @@ static int tch_rtp_signal(struct gsm_lchan *lchan, int signal)
llist_for_each_entry(tmp, &net->trans_list, entry) {
if (!tmp->conn)
continue;
- if (tmp->conn->lchan != lchan)
+ if (tmp->conn->lchan != lchan && tmp->conn->ho_lchan != lchan)
continue;
trans = tmp;
break;
@@ -3102,9 +3118,15 @@ static int tch_rtp_signal(struct gsm_lchan *lchan, int signal)
gsm_lchan_name(lchan));
mncc_recv_rtp_sock(net, trans, MNCC_RTP_CREATE);
}
+ /*
+ * TODO: this appears to be too early? Why not until after
+ * the handover detect or the handover complete?
+ */
+ maybe_switch_for_handover(lchan);
break;
case S_ABISIP_MDCX_ACK:
- if (lchan->conn->mncc_rtp_bridge) {
+ if (lchan->conn->mncc_rtp_connect_pending) {
+ lchan->conn->mncc_rtp_connect_pending = 0;
LOGP(DMNCC, LOGL_NOTICE, "%s sending pending RTP connect ind.\n",
gsm_lchan_name(lchan));
mncc_recv_rtp_sock(net, trans, MNCC_RTP_CONNECT);