aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmsc/gsm_04_08.c
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2012-12-26 10:17:42 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2012-12-26 10:32:02 +0100
commitc121bb3188445dfc23a6daef3444031f447395bb (patch)
treeffc105ad751a96d11816414bba8d0f60dea7acb8 /openbsc/src/libmsc/gsm_04_08.c
parent006e3d87e019b202a38c5393ab8f5b6df763e664 (diff)
handover: Fix the handover signalling for IP based BTSes
This was reported by Kevin when he was testing handover. The problem is the order of the signal handlers for S_ABISIP_CRCX_ACK. Right now the handover signal handler is called before the one inside the libmsc gsm_04_08.c. This means S_HANDOVER_ACK is signalled _before_ there is a rtp socket created for the channel. The result is that the MDCX will never be sent and the called will not be properly switched _after_ the handover detection. I do not want to play with the order of signal handlers, remove the CRCX ack handling from the handover_logic.c and force the NITB (and later the BSC) to check if the lchan is involved with a handover and do the switching in there. This means right now we do what two signal handlers did in one. Reproduced and tested with the FakeBTS Handover test. Log message: <0004> abis_rsl.c:1954 (bts=1,trx=0,ts=3,ss=0) IPAC_CRCX_ACK ... <000c> gsm_04_08.c:1400 no RTP socket for new_lchan <001a> rtp_proxy.c:533 rtp_socket_create(): success <001a> rtp_proxy.c:615 rtp_socket_bind(rs=0x48703c8, IP=0.0.0.0): ...
Diffstat (limited to 'openbsc/src/libmsc/gsm_04_08.c')
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index d1dfa4a72..65e6fcc99 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -2,7 +2,7 @@
* 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
- * (C) 2008-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2008-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
*
* All Rights Reserved
*
@@ -51,6 +51,7 @@
#include <openbsc/silent_call.h>
#include <openbsc/bsc_api.h>
#include <openbsc/osmo_msc.h>
+#include <openbsc/handover.h>
#include <osmocom/abis/e1_input.h>
#include <osmocom/core/bitvec.h>
@@ -1378,14 +1379,10 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
static int tch_recv_mncc(struct gsm_network *net, uint32_t callref, int enable);
/* handle audio path for handover */
-static int handle_ho_signal(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data)
+static int switch_for_handover(struct gsm_lchan *old_lchan,
+ struct gsm_lchan *new_lchan)
{
struct rtp_socket *old_rs, *new_rs, *other_rs;
- struct ho_signal_data *sig = signal_data;
-
- if (subsys != SS_HO || signal != S_HANDOVER_ACK)
- return 0;
if (ipacc_rtp_direct) {
LOGP(DHO, LOGL_ERROR, "unable to handover in direct RTP mode\n");
@@ -1393,15 +1390,15 @@ static int handle_ho_signal(unsigned int subsys, unsigned int signal,
}
/* RTP Proxy mode */
- new_rs = sig->new_lchan->abis_ip.rtp_socket;
- old_rs = sig->old_lchan->abis_ip.rtp_socket;
+ new_rs = new_lchan->abis_ip.rtp_socket;
+ old_rs = old_lchan->abis_ip.rtp_socket;
if (!new_rs) {
LOGP(DHO, LOGL_ERROR, "no RTP socket for new_lchan\n");
return -EIO;
}
- rsl_ipacc_mdcx_to_rtpsock(sig->new_lchan);
+ rsl_ipacc_mdcx_to_rtpsock(new_lchan);
if (!old_rs) {
LOGP(DHO, LOGL_ERROR, "no RTP socket for old_lchan\n");
@@ -1413,7 +1410,7 @@ static int handle_ho_signal(unsigned int subsys, unsigned int signal,
new_rs->tx_action = old_rs->tx_action;
new_rs->transmit = old_rs->transmit;
- switch (sig->old_lchan->abis_ip.rtp_socket->rx_action) {
+ switch (old_lchan->abis_ip.rtp_socket->rx_action) {
case RTP_PROXY:
other_rs = old_rs->proxy.other_sock;
rtp_socket_proxy(new_rs, other_rs);
@@ -1435,7 +1432,7 @@ static int handle_ho_signal(unsigned int subsys, unsigned int signal,
static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
{
- struct gsm_lchan *lchan = signal_data;
+ struct gsm_lchan *lchan = signal_data, *old_lchan;
int rc;
struct gsm_network *net;
struct gsm_trans *trans;
@@ -1476,6 +1473,17 @@ static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
tch_recv_mncc(net, trans->callref, 1);
}
}
+
+ /*
+ * TODO: this appears to be too early? Why not until after
+ * the handover detect or the handover complete?
+ *
+ * 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);
break;
case S_ABISIP_DLCX_IND:
/* the BTS tells us a RTP stream has been disconnected */
@@ -3253,6 +3261,5 @@ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg)
*/
static __attribute__((constructor)) void on_dso_load_0408(void)
{
- osmo_signal_register_handler(SS_HO, handle_ho_signal, NULL);
osmo_signal_register_handler(SS_ABISIP, handle_abisip_signal, NULL);
}