aboutsummaryrefslogtreecommitdiffstats
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-09-14 10:12:29 +0200
commitc21dcb20e5a7e5f9317ac797d03639c191de4eae (patch)
tree2a40ae26c286b4282a6e8a2acc9b659adbcf0c91
parentc8a6c13e4ee0c4355a685a03b892dce5e5e07752 (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 bed04e38..c167c494 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 776a11d0..4cfba1c1 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -1460,6 +1460,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;
@@ -1504,11 +1513,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;
@@ -1561,9 +1578,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 */
@@ -3065,6 +3080,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);
}
@@ -3077,7 +3093,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;
@@ -3097,9 +3113,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);