aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-01-06 13:31:41 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2011-01-06 14:31:16 +0100
commit6c4d2443b478e51741901676c990db8af1ec2ca2 (patch)
tree70b957fe701039d618d805ddbef86e84942a3017
parent04d362f79d0e24a8ef45eddb9ed217834efdd20d (diff)
rtp: Move the RTP Proxy code out of RSL into the BSC/MSC domain
Instead of creating the sockets in the RSL code we will do this in the CRCX_ACK, MDCX_ACK, DLCX_IND signal handler of gsm_04_08. Introduce a handover signal so we can repatch the RTP sockets in the gsm_04_08 as well.
-rw-r--r--openbsc/include/openbsc/signal.h11
-rw-r--r--openbsc/src/Makefile.am4
-rw-r--r--openbsc/src/abis_rsl.c30
-rw-r--r--openbsc/src/gsm_04_08.c81
-rw-r--r--openbsc/src/handover_logic.c46
5 files changed, 98 insertions, 74 deletions
diff --git a/openbsc/include/openbsc/signal.h b/openbsc/include/openbsc/signal.h
index 3363db556..8baada3fd 100644
--- a/openbsc/include/openbsc/signal.h
+++ b/openbsc/include/openbsc/signal.h
@@ -46,6 +46,7 @@ enum signal_subsystems {
SS_IPAC_NWL,
SS_RF,
SS_MSC,
+ SS_HO,
};
/* SS_PAGING signals */
@@ -211,5 +212,15 @@ struct msc_signal_data {
struct osmo_msc_data *data;
};
+/* handover */
+enum signal_ho {
+ S_HANDOVER_ACK,
+};
+
+struct ho_signal_data {
+ struct gsm_lchan *old_lchan;
+ struct gsm_lchan *new_lchan;
+};
+
#endif
diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am
index cc69a729d..c86fc26c9 100644
--- a/openbsc/src/Makefile.am
+++ b/openbsc/src/Makefile.am
@@ -22,7 +22,7 @@ libbsc_a_SOURCES = abis_rsl.c abis_nm.c gsm_data.c gsm_04_08_utils.c \
trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c \
input/misdn.c input/ipaccess.c handover_logic.c \
talloc_ctx.c system_information.c rest_octets.c \
- rtp_proxy.c bts_siemens_bs11.c bts_ipaccess_nanobts.c \
+ bts_siemens_bs11.c bts_ipaccess_nanobts.c \
bts_unknown.c bsc_version.c bsc_api.c bsc_vty.c meas_rep.c gsm_04_80.c
libmsc_a_SOURCES = gsm_subscriber.c db.c \
@@ -30,7 +30,7 @@ libmsc_a_SOURCES = gsm_subscriber.c db.c \
gsm_04_08.c gsm_04_11.c transaction.c \
token_auth.c rrlp.c ussd.c silent_call.c \
handover_decision.c auth.c \
- osmo_msc.c
+ osmo_msc.c rtp_proxy.c
libvty_a_SOURCES = common_vty.c
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c
index aa3d78a58..261181f01 100644
--- a/openbsc/src/abis_rsl.c
+++ b/openbsc/src/abis_rsl.c
@@ -1768,32 +1768,9 @@ static int abis_rsl_rx_ipacc_crcx_ack(struct msgb *msg)
ipac_parse_rtp(lchan, &tv);
- /* in case we don't use direct BTS-to-BTS RTP */
- if (!ipacc_rtp_direct) {
- int rc;
- /* the BTS has successfully bound a TCH to a local ip/port,
- * which means we can connect our UDP socket to it */
- if (lchan->abis_ip.rtp_socket) {
- rtp_socket_free(lchan->abis_ip.rtp_socket);
- lchan->abis_ip.rtp_socket = NULL;
- }
-
- lchan->abis_ip.rtp_socket = rtp_socket_create();
- if (!lchan->abis_ip.rtp_socket)
- goto out_err;
-
- rc = rtp_socket_connect(lchan->abis_ip.rtp_socket,
- lchan->abis_ip.bound_ip,
- lchan->abis_ip.bound_port);
- if (rc < 0)
- goto out_err;
- }
-
dispatch_signal(SS_ABISIP, S_ABISIP_CRCX_ACK, msg->lchan);
return 0;
-out_err:
- return -EIO;
}
static int abis_rsl_rx_ipacc_mdcx_ack(struct msgb *msg)
@@ -1817,7 +1794,6 @@ static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
{
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
struct tlv_parsed tv;
- struct gsm_lchan *lchan = msg->lchan;
rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
@@ -1825,12 +1801,6 @@ static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
TLVP_LEN(&tv, RSL_IE_CAUSE));
- /* the BTS tells us a RTP stream has been disconnected */
- if (lchan->abis_ip.rtp_socket) {
- rtp_socket_free(lchan->abis_ip.rtp_socket);
- lchan->abis_ip.rtp_socket = NULL;
- }
-
dispatch_signal(SS_ABISIP, S_ABISIP_DLCX_IND, msg->lchan);
return 0;
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index e364a1719..b5ab8aae6 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -1452,6 +1452,60 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event,
static int tch_recv_mncc(struct gsm_network *net, u_int32_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)
+{
+ 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");
+ return 0;
+ }
+
+ /* RTP Proxy mode */
+ new_rs = sig->new_lchan->abis_ip.rtp_socket;
+ old_rs = sig->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);
+
+ if (!old_rs) {
+ LOGP(DHO, LOGL_ERROR, "no RTP socket for old_lchan\n");
+ return -EIO;
+ }
+
+ /* copy rx_action and reference to other sock */
+ new_rs->rx_action = old_rs->rx_action;
+ new_rs->tx_action = old_rs->tx_action;
+ new_rs->transmit = old_rs->transmit;
+
+ switch (sig->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);
+ /* delete reference to other end socket to prevent
+ * rtp_socket_free() from removing the inverse reference */
+ old_rs->proxy.other_sock = NULL;
+ break;
+ case RTP_RECV_UPSTREAM:
+ new_rs->receive = old_rs->receive;
+ break;
+ case RTP_NONE:
+ break;
+ }
+
+ return 0;
+}
+
/* 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)
@@ -1470,6 +1524,24 @@ static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
switch (signal) {
case S_ABISIP_CRCX_ACK:
+ /* in case we don't use direct BTS-to-BTS RTP */
+ /* the BTS has successfully bound a TCH to a local ip/port,
+ * which means we can connect our UDP socket to it */
+ if (lchan->abis_ip.rtp_socket) {
+ rtp_socket_free(lchan->abis_ip.rtp_socket);
+ lchan->abis_ip.rtp_socket = NULL;
+ }
+
+ lchan->abis_ip.rtp_socket = rtp_socket_create();
+ if (!lchan->abis_ip.rtp_socket)
+ return -EIO;
+
+ rc = rtp_socket_connect(lchan->abis_ip.rtp_socket,
+ lchan->abis_ip.bound_ip,
+ lchan->abis_ip.bound_port);
+ if (rc < 0)
+ return -EIO;
+
/* check if any transactions on this lchan still have
* a tch_recv_mncc request pending */
net = lchan->ts->trx->bts->network;
@@ -1480,6 +1552,14 @@ static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
}
}
break;
+ case S_ABISIP_DLCX_IND:
+ /* the BTS tells us a RTP stream has been disconnected */
+ if (lchan->abis_ip.rtp_socket) {
+ rtp_socket_free(lchan->abis_ip.rtp_socket);
+ lchan->abis_ip.rtp_socket = NULL;
+ }
+
+ break;
}
return 0;
@@ -3226,5 +3306,6 @@ int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg)
*/
static __attribute__((constructor)) void on_dso_load_0408(void)
{
+ register_signal_handler(SS_HO, handle_ho_signal, NULL);
register_signal_handler(SS_ABISIP, handle_abisip_signal, NULL);
}
diff --git a/openbsc/src/handover_logic.c b/openbsc/src/handover_logic.c
index 8e8b9db10..44a69331c 100644
--- a/openbsc/src/handover_logic.c
+++ b/openbsc/src/handover_logic.c
@@ -332,7 +332,7 @@ static int ho_rsl_detect(struct gsm_lchan *new_lchan)
static int ho_ipac_crcx_ack(struct gsm_lchan *new_lchan)
{
struct bsc_handover *ho;
- struct rtp_socket *old_rs, *new_rs, *other_rs;
+ struct ho_signal_data sig_ho;
ho = bsc_ho_by_new_lchan(new_lchan);
if (!ho) {
@@ -340,47 +340,9 @@ static int ho_ipac_crcx_ack(struct gsm_lchan *new_lchan)
return 0;
}
- if (ipacc_rtp_direct) {
- LOGP(DHO, LOGL_ERROR, "unable to handover in direct RTP mode\n");
- return 0;
- }
-
- /* RTP Proxy mode */
- new_rs = new_lchan->abis_ip.rtp_socket;
- old_rs = ho->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(new_lchan);
-
- if (!old_rs) {
- LOGP(DHO, LOGL_ERROR, "no RTP socket for old_lchan\n");
- return -EIO;
- }
-
- /* copy rx_action and reference to other sock */
- new_rs->rx_action = old_rs->rx_action;
- new_rs->tx_action = old_rs->tx_action;
- new_rs->transmit = old_rs->transmit;
-
- switch (ho->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);
- /* delete reference to other end socket to prevent
- * rtp_socket_free() from removing the inverse reference */
- old_rs->proxy.other_sock = NULL;
- break;
- case RTP_RECV_UPSTREAM:
- new_rs->receive = old_rs->receive;
- break;
- case RTP_NONE:
- break;
- }
-
+ sig_ho.old_lchan = ho->old_lchan;
+ sig_ho.new_lchan = new_lchan;
+ dispatch_signal(SS_HO, S_HANDOVER_ACK, &sig_ho);
return 0;
}