diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2012-12-26 10:17:42 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2012-12-26 10:32:02 +0100 |
commit | c121bb3188445dfc23a6daef3444031f447395bb (patch) | |
tree | ffc105ad751a96d11816414bba8d0f60dea7acb8 /openbsc/src/libmsc/gsm_04_08.c | |
parent | 006e3d87e019b202a38c5393ab8f5b6df763e664 (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.c | 33 |
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); } |