diff options
author | Harald Welte <laforge@gnumonks.org> | 2009-07-28 18:40:45 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2009-07-28 18:40:45 +0200 |
commit | 2f33d01aaf24154c4f690c088b78b02b6135c206 (patch) | |
tree | 79fc539c4e6a92be9961a85d1fe7eabe6dd9fac9 /openbsc/src/gsm_04_08.c | |
parent | 3366a94d6c3cd28c71bf76133a3ead3212fd04f1 (diff) | |
parent | 15efcd2e276b4f93461eb1ea5436c093fc727117 (diff) |
Merge branch 'master' into sms
Diffstat (limited to 'openbsc/src/gsm_04_08.c')
-rw-r--r-- | openbsc/src/gsm_04_08.c | 132 |
1 files changed, 110 insertions, 22 deletions
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c index bc110a39c..690c59155 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -44,6 +44,7 @@ #include <openbsc/signal.h> #include <openbsc/trau_frame.h> #include <openbsc/trau_mux.h> +#include <openbsc/rtp_proxy.h> #include <openbsc/talloc.h> #include <openbsc/transaction.h> @@ -56,6 +57,10 @@ static void *tall_locop_ctx; +/* should ip.access BTS use direct RTP streams between each other (1), + * or should OpenBSC always act as RTP relay/proxy in between (0) ? */ +int ipacc_rtp_direct = 1; + static const struct tlv_definition rsl_att_tlvdef = { .def = { [GSM48_IE_MOBILE_ID] = { TLV_TYPE_TLV }, @@ -399,17 +404,6 @@ static int gsm0408_handle_lchan_signal(unsigned int subsys, unsigned int signal, return 0; } -/* - * This will be ran by the linker when loading the DSO. We use it to - * do system initialization, e.g. registration of signal handlers. - */ -static __attribute__((constructor)) void on_dso_load_0408(void) -{ - tall_locop_ctx = talloc_named_const(tall_bsc_ctx, 1, - "loc_updating_oper"); - register_signal_handler(SS_LCHAN, gsm0408_handle_lchan_signal, NULL); -} - static void to_bcd(u_int8_t *bcd, u_int16_t val) { bcd[2] = val % 10; @@ -1973,12 +1967,80 @@ static int setup_trig_pag_evt(unsigned int hooknum, unsigned int event, 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) +{ + struct gsm_lchan *lchan = signal_data; + struct gsm_bts_trx_ts *ts; + int rc; + + if (subsys != SS_ABISIP) + return 0; + + /* in case we use direct BTS-to-BTS RTP */ + if (ipacc_rtp_direct) + return 0; + + ts = lchan->ts; + + switch (signal) { + case S_ABISIP_BIND_ACK: + /* the BTS has successfully bound a TCH to a local ip/port, + * which means we can connect our UDP socket to it */ + if (ts->abis_ip.rtp_socket) { + rtp_socket_free(ts->abis_ip.rtp_socket); + ts->abis_ip.rtp_socket = NULL; + } + + ts->abis_ip.rtp_socket = rtp_socket_create(); + if (!ts->abis_ip.rtp_socket) + goto out_err; + + rc = rtp_socket_connect(ts->abis_ip.rtp_socket, + ts->abis_ip.bound_ip, + ts->abis_ip.bound_port); + if (rc < 0) + goto out_err; + break; + case S_ABISIP_DISC_IND: + /* the BTS tells us a RTP stream has been disconnected */ + if (ts->abis_ip.rtp_socket) { + rtp_socket_free(ts->abis_ip.rtp_socket); + ts->abis_ip.rtp_socket = NULL; + } + break; + } + + return 0; +out_err: + /* FIXME: do something */ + return 0; +} + +/* bind rtp proxy to local IP/port and tell BTS to connect to it */ +static int ipacc_connect_proxy_bind(struct gsm_lchan *lchan) +{ + struct gsm_bts_trx_ts *ts = lchan->ts; + struct rtp_socket *rs = ts->abis_ip.rtp_socket; + int rc; + + rc = rsl_ipacc_connect(lchan, ntohl(rs->rtp.sin_local.sin_addr.s_addr), + ntohs(rs->rtp.sin_local.sin_port), + ts->abis_ip.conn_id, + /* FIXME: use RTP payload of bound socket, not BTS*/ + ts->abis_ip.rtp_payload2); + + return rc; +} + /* map two ipaccess RTP streams onto each other */ static int tch_map(struct gsm_lchan *lchan, struct gsm_lchan *remote_lchan) { struct gsm_bts *bts = lchan->ts->trx->bts; struct gsm_bts *remote_bts = remote_lchan->ts->trx->bts; struct gsm_bts_trx_ts *ts; + int rc; DEBUGP(DCC, "Setting up TCH map between (bts=%u,trx=%u,ts=%u) and (bts=%u,trx=%u,ts=%u)\n", bts->nr, lchan->ts->trx->nr, lchan->ts->nr, @@ -1992,23 +2054,38 @@ static int tch_map(struct gsm_lchan *lchan, struct gsm_lchan *remote_lchan) switch (bts->type) { case GSM_BTS_TYPE_NANOBTS_900: case GSM_BTS_TYPE_NANOBTS_1800: - ts = remote_lchan->ts; - rsl_ipacc_connect(lchan, ts->abis_ip.bound_ip, - ts->abis_ip.bound_port, - lchan->ts->abis_ip.conn_id, - ts->abis_ip.rtp_payload2); - - ts = lchan->ts; - rsl_ipacc_connect(remote_lchan, ts->abis_ip.bound_ip, - ts->abis_ip.bound_port, - remote_lchan->ts->abis_ip.conn_id, - ts->abis_ip.rtp_payload2); + if (!ipacc_rtp_direct) { + /* connect the TCH's to our RTP proxy */ + rc = ipacc_connect_proxy_bind(lchan); + if (rc < 0) + return rc; + rc = ipacc_connect_proxy_bind(remote_lchan); + + /* connect them with each other */ + rtp_socket_proxy(lchan->ts->abis_ip.rtp_socket, + remote_lchan->ts->abis_ip.rtp_socket); + } else { + /* directly connect TCH RTP streams to each other */ + ts = remote_lchan->ts; + rc = rsl_ipacc_connect(lchan, ts->abis_ip.bound_ip, + ts->abis_ip.bound_port, + lchan->ts->abis_ip.conn_id, + ts->abis_ip.rtp_payload2); + if (rc < 0) + return rc; + ts = lchan->ts; + rc = rsl_ipacc_connect(remote_lchan, ts->abis_ip.bound_ip, + ts->abis_ip.bound_port, + remote_lchan->ts->abis_ip.conn_id, + ts->abis_ip.rtp_payload2); + } break; case GSM_BTS_TYPE_BS11: trau_mux_map_lchan(lchan, remote_lchan); break; default: DEBUGP(DCC, "Unknown BTS type %u\n", bts->type); + rc = -EINVAL; break; } @@ -3732,3 +3809,14 @@ int bsc_upqueue(struct gsm_network *net) return work; } +/* + * This will be ran by the linker when loading the DSO. We use it to + * do system initialization, e.g. registration of signal handlers. + */ +static __attribute__((constructor)) void on_dso_load_0408(void) +{ + tall_locop_ctx = talloc_named_const(tall_bsc_ctx, 1, + "loc_updating_oper"); + register_signal_handler(SS_LCHAN, gsm0408_handle_lchan_signal, NULL); + register_signal_handler(SS_ABISIP, handle_abisip_signal, NULL); +} |