2009-10-09 05:08:11 +00:00
|
|
|
/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
|
|
|
|
|
|
|
|
/*
|
2012-11-29 11:54:22 +00:00
|
|
|
* (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
|
|
|
|
* (C) 2009-2012 by On-Waves
|
2009-10-09 05:08:11 +00:00
|
|
|
* All Rights Reserved
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
2011-01-01 14:25:50 +00:00
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
2009-10-09 05:08:11 +00:00
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2011-01-01 14:25:50 +00:00
|
|
|
* GNU Affero General Public License for more details.
|
2009-10-09 05:08:11 +00:00
|
|
|
*
|
2011-01-01 14:25:50 +00:00
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2009-10-09 05:08:11 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2010-02-03 10:03:45 +00:00
|
|
|
#ifndef OPENBSC_MGCP_H
|
|
|
|
#define OPENBSC_MGCP_H
|
|
|
|
|
2011-03-22 15:47:59 +00:00
|
|
|
#include <osmocom/core/msgb.h>
|
|
|
|
#include <osmocom/core/write_queue.h>
|
2013-12-19 17:53:07 +00:00
|
|
|
#include <osmocom/core/timer.h>
|
2017-07-10 13:07:22 +00:00
|
|
|
#include <osmocom/core/logging.h>
|
2010-09-19 17:07:23 +00:00
|
|
|
|
2010-02-20 20:21:02 +00:00
|
|
|
#include <arpa/inet.h>
|
2015-08-01 23:35:19 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netinet/in.h>
|
2010-02-20 20:21:02 +00:00
|
|
|
|
2010-02-03 07:50:33 +00:00
|
|
|
#define RTP_PORT_DEFAULT 4000
|
2010-08-04 20:10:21 +00:00
|
|
|
#define RTP_PORT_NET_DEFAULT 16000
|
2009-10-09 05:08:11 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculate the RTP audio port for the given multiplex
|
|
|
|
* and the direction. This allows a semi static endpoint
|
|
|
|
* to port calculation removing the need for the BSC
|
|
|
|
* and the MediaGateway to communicate.
|
|
|
|
*
|
|
|
|
* Port usage explained:
|
|
|
|
* base + (multiplex * 2) + 0 == local port to wait for network packets
|
|
|
|
* base + (multiplex * 2) + 1 == local port for rtcp
|
|
|
|
*
|
|
|
|
* The above port will receive packets from the BTS that need
|
|
|
|
* to be patched and forwarded to the network.
|
|
|
|
* The above port will receive packets from the network that
|
|
|
|
* need to be patched and forwarded to the BTS.
|
|
|
|
*
|
|
|
|
* We assume to have a static BTS IP address so we can differentiate
|
|
|
|
* network and BTS.
|
|
|
|
*
|
|
|
|
*/
|
2010-02-03 07:50:33 +00:00
|
|
|
static inline int rtp_calculate_port(int multiplex, int base)
|
2009-10-09 05:08:11 +00:00
|
|
|
{
|
|
|
|
return base + (multiplex * 2);
|
|
|
|
}
|
2010-02-03 07:50:33 +00:00
|
|
|
|
2010-02-03 10:03:45 +00:00
|
|
|
|
2010-02-20 20:21:02 +00:00
|
|
|
/*
|
|
|
|
* Handling of MGCP Endpoints and the MGCP Config
|
|
|
|
*/
|
|
|
|
struct mgcp_endpoint;
|
|
|
|
struct mgcp_config;
|
2011-02-27 23:56:17 +00:00
|
|
|
struct mgcp_trunk_config;
|
2014-03-13 13:24:52 +00:00
|
|
|
struct mgcp_rtp_end;
|
2010-02-03 08:54:43 +00:00
|
|
|
|
|
|
|
#define MGCP_ENDP_CRCX 1
|
|
|
|
#define MGCP_ENDP_DLCX 2
|
|
|
|
#define MGCP_ENDP_MDCX 3
|
|
|
|
|
2010-02-26 12:37:05 +00:00
|
|
|
/*
|
|
|
|
* what to do with the msg?
|
|
|
|
* - continue as usual?
|
|
|
|
* - reject and send a failure code?
|
|
|
|
* - defer? do not send anything
|
|
|
|
*/
|
|
|
|
#define MGCP_POLICY_CONT 4
|
|
|
|
#define MGCP_POLICY_REJECT 5
|
|
|
|
#define MGCP_POLICY_DEFER 6
|
|
|
|
|
2011-02-27 23:56:17 +00:00
|
|
|
typedef int (*mgcp_realloc)(struct mgcp_trunk_config *cfg, int endpoint);
|
|
|
|
typedef int (*mgcp_change)(struct mgcp_trunk_config *cfg, int endpoint, int state);
|
|
|
|
typedef int (*mgcp_policy)(struct mgcp_trunk_config *cfg, int endpoint, int state, const char *transactio_id);
|
2011-06-09 22:04:55 +00:00
|
|
|
typedef int (*mgcp_reset)(struct mgcp_trunk_config *cfg);
|
2012-12-07 14:04:07 +00:00
|
|
|
typedef int (*mgcp_rqnt)(struct mgcp_endpoint *endp, char tone);
|
2010-02-20 20:21:02 +00:00
|
|
|
|
2014-06-27 17:27:38 +00:00
|
|
|
/**
|
|
|
|
* Return:
|
|
|
|
* < 0 in case no audio was processed
|
|
|
|
* >= 0 in case audio was processed. The remaining payload
|
|
|
|
* length will be returned.
|
|
|
|
*/
|
2014-04-14 08:31:47 +00:00
|
|
|
typedef int (*mgcp_processing)(struct mgcp_endpoint *endp,
|
|
|
|
struct mgcp_rtp_end *dst_end,
|
2014-03-13 13:24:52 +00:00
|
|
|
char *data, int *len, int buf_size);
|
|
|
|
typedef int (*mgcp_processing_setup)(struct mgcp_endpoint *endp,
|
|
|
|
struct mgcp_rtp_end *dst_end,
|
|
|
|
struct mgcp_rtp_end *src_end);
|
2014-03-17 11:40:07 +00:00
|
|
|
|
|
|
|
typedef void (*mgcp_get_format)(struct mgcp_endpoint *endp,
|
|
|
|
int *payload_type,
|
|
|
|
const char**subtype_name,
|
|
|
|
const char**fmtp_extra);
|
|
|
|
|
2010-08-04 23:10:56 +00:00
|
|
|
#define PORT_ALLOC_STATIC 0
|
|
|
|
#define PORT_ALLOC_DYNAMIC 1
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This holds information on how to allocate ports
|
|
|
|
*/
|
|
|
|
struct mgcp_port_range {
|
|
|
|
int mode;
|
|
|
|
|
2015-08-20 13:15:50 +00:00
|
|
|
/* addr or NULL to fall-back to default */
|
|
|
|
char *bind_addr;
|
|
|
|
|
2010-08-04 23:10:56 +00:00
|
|
|
/* pre-allocated from a base? */
|
|
|
|
int base_port;
|
2010-08-04 23:20:09 +00:00
|
|
|
|
|
|
|
/* dynamically allocated */
|
|
|
|
int range_start;
|
|
|
|
int range_end;
|
|
|
|
int last_port;
|
2010-08-04 23:10:56 +00:00
|
|
|
};
|
|
|
|
|
2013-12-19 17:53:07 +00:00
|
|
|
#define MGCP_KEEPALIVE_ONCE (-1)
|
|
|
|
|
2011-02-27 23:56:17 +00:00
|
|
|
struct mgcp_trunk_config {
|
2011-02-28 11:11:02 +00:00
|
|
|
struct llist_head entry;
|
|
|
|
|
2011-02-27 23:56:17 +00:00
|
|
|
struct mgcp_config *cfg;
|
|
|
|
|
|
|
|
int trunk_nr;
|
|
|
|
int trunk_type;
|
|
|
|
|
2012-09-02 22:07:39 +00:00
|
|
|
char *audio_fmtp_extra;
|
2011-02-27 23:56:17 +00:00
|
|
|
char *audio_name;
|
|
|
|
int audio_payload;
|
2013-12-10 12:09:37 +00:00
|
|
|
int audio_send_ptime;
|
2014-11-19 15:04:45 +00:00
|
|
|
int audio_send_name;
|
2011-02-27 23:56:17 +00:00
|
|
|
int audio_loop;
|
|
|
|
|
2015-04-24 20:03:55 +00:00
|
|
|
int no_audio_transcoding;
|
|
|
|
|
2012-05-11 11:00:45 +00:00
|
|
|
int omit_rtcp;
|
2013-12-19 17:53:07 +00:00
|
|
|
int keepalive_interval;
|
2012-05-11 11:00:45 +00:00
|
|
|
|
2013-12-03 13:43:34 +00:00
|
|
|
/* RTP patching */
|
|
|
|
int force_constant_ssrc; /* 0: don't, 1: once */
|
2013-12-18 11:54:51 +00:00
|
|
|
int force_aligned_timing;
|
2013-12-03 13:43:34 +00:00
|
|
|
|
2011-02-27 23:56:17 +00:00
|
|
|
/* spec handling */
|
|
|
|
int force_realloc;
|
|
|
|
|
2013-12-19 17:53:07 +00:00
|
|
|
/* timer */
|
|
|
|
struct osmo_timer_list keepalive_timer;
|
|
|
|
|
2011-02-27 23:56:17 +00:00
|
|
|
unsigned int number_endpoints;
|
|
|
|
struct mgcp_endpoint *endpoints;
|
|
|
|
};
|
|
|
|
|
2013-08-02 19:14:14 +00:00
|
|
|
enum mgcp_role {
|
|
|
|
MGCP_BSC = 0,
|
|
|
|
MGCP_BSC_NAT,
|
|
|
|
};
|
|
|
|
|
2016-05-20 19:59:55 +00:00
|
|
|
enum mgcp_connection_mode {
|
|
|
|
MGCP_CONN_NONE = 0,
|
|
|
|
MGCP_CONN_RECV_ONLY = 1,
|
|
|
|
MGCP_CONN_SEND_ONLY = 2,
|
|
|
|
MGCP_CONN_RECV_SEND = MGCP_CONN_RECV_ONLY | MGCP_CONN_SEND_ONLY,
|
|
|
|
MGCP_CONN_LOOPBACK = 4 | MGCP_CONN_RECV_SEND,
|
|
|
|
};
|
|
|
|
|
2010-02-20 20:21:02 +00:00
|
|
|
struct mgcp_config {
|
|
|
|
int source_port;
|
|
|
|
char *local_ip;
|
|
|
|
char *source_addr;
|
|
|
|
char *bts_ip;
|
2010-03-31 09:46:41 +00:00
|
|
|
char *call_agent_addr;
|
2010-02-20 20:21:02 +00:00
|
|
|
|
|
|
|
struct in_addr bts_in;
|
2010-08-04 23:10:56 +00:00
|
|
|
|
2010-09-18 20:21:39 +00:00
|
|
|
/* transcoder handling */
|
|
|
|
char *transcoder_ip;
|
|
|
|
struct in_addr transcoder_in;
|
|
|
|
int transcoder_remote_base;
|
|
|
|
|
2014-03-13 13:24:52 +00:00
|
|
|
/* RTP processing */
|
|
|
|
mgcp_processing rtp_processing_cb;
|
|
|
|
mgcp_processing_setup setup_rtp_processing_cb;
|
|
|
|
|
2014-03-17 11:40:07 +00:00
|
|
|
mgcp_get_format get_net_downlink_format_cb;
|
|
|
|
|
2011-05-06 10:09:47 +00:00
|
|
|
struct osmo_wqueue gw_fd;
|
2010-09-18 12:40:22 +00:00
|
|
|
|
2010-08-04 23:10:56 +00:00
|
|
|
struct mgcp_port_range bts_ports;
|
|
|
|
struct mgcp_port_range net_ports;
|
2010-09-17 15:35:53 +00:00
|
|
|
struct mgcp_port_range transcoder_ports;
|
2010-07-27 12:34:45 +00:00
|
|
|
int endp_dscp;
|
2010-02-20 20:21:02 +00:00
|
|
|
|
2014-04-14 08:31:47 +00:00
|
|
|
int bts_force_ptime;
|
|
|
|
|
2010-02-20 20:21:02 +00:00
|
|
|
mgcp_change change_cb;
|
2010-02-26 12:37:05 +00:00
|
|
|
mgcp_policy policy_cb;
|
2010-03-31 04:39:35 +00:00
|
|
|
mgcp_reset reset_cb;
|
2010-08-06 09:54:27 +00:00
|
|
|
mgcp_realloc realloc_cb;
|
2012-11-29 11:54:22 +00:00
|
|
|
mgcp_rqnt rqnt_cb;
|
2010-02-26 12:37:05 +00:00
|
|
|
void *data;
|
2010-02-20 20:21:02 +00:00
|
|
|
|
2010-08-06 00:26:54 +00:00
|
|
|
uint32_t last_call_id;
|
2011-02-27 23:56:17 +00:00
|
|
|
|
|
|
|
/* trunk handling */
|
|
|
|
struct mgcp_trunk_config trunk;
|
2011-02-28 11:11:02 +00:00
|
|
|
struct llist_head trunks;
|
2011-02-28 13:46:01 +00:00
|
|
|
|
|
|
|
/* only used for start with a static configuration */
|
|
|
|
int last_net_port;
|
|
|
|
int last_bts_port;
|
2013-08-02 19:14:14 +00:00
|
|
|
|
|
|
|
enum mgcp_role role;
|
mgcp: add voice muxer support
This patch adds the voice muxer. You can use this to batch RTP
traffic to reduce bandwidth comsuption. Basically, osmux transforms
RTP flows to a compact batch format, that is later on decompacted
to its original form. Port UDP/1984 is used for the muxer traffic
between osmo-bsc_nat and osmo-bsc_mgcp (in the BSC side). This
feature depends on libosmo-netif, which contains the osmux core
support.
Osmux is requested on-demand via the MGCP CRCX/MDCX messages (using
the vendor-specific extension X-Osmux: on) coming from the BSC-NAT,
so you can selectively enable osmux per BSC from one the bsc-nat.cfg
file, so we have a centralized point to enable/disable osmux.
First thing you need to do is to accept requests to use Osmux,
this can be done from VTY interface of osmo-bsc_nat and
osmo-bsc_mgcp by adding the following line:
mgcp
...
osmux on
osmux batch-factor 4
This just initializes the osmux engine. You still have to specify
what BSC uses osmux from osmo-bsc_nat configuration file:
...
bsc 1
osmux on
bsc 2
...
bsc 3
osmux on
In this case, bsc 1 and 3 should use osmux if possible, bsc 2 does
not have osmux enabled.
Thus, you can selectively enable osmux depending on the BSC, and
we have a centralized point for configuration from the bsc-nat to
enable osmux on demand, as suggested by Holger.
At this moment, this patch contains heavy debug logging for each
RTP packet that can be removed later to save cycles.
The RTP ssrc/seqnum/timestamp is randomly allocated for each MDCX that
is received to configure an endpoint.
2014-02-05 17:56:17 +00:00
|
|
|
|
|
|
|
/* osmux translator: 0 means disabled, 1 means enabled */
|
|
|
|
int osmux;
|
2015-10-12 18:06:16 +00:00
|
|
|
/* addr to bind the server to */
|
|
|
|
char *osmux_addr;
|
mgcp: add voice muxer support
This patch adds the voice muxer. You can use this to batch RTP
traffic to reduce bandwidth comsuption. Basically, osmux transforms
RTP flows to a compact batch format, that is later on decompacted
to its original form. Port UDP/1984 is used for the muxer traffic
between osmo-bsc_nat and osmo-bsc_mgcp (in the BSC side). This
feature depends on libosmo-netif, which contains the osmux core
support.
Osmux is requested on-demand via the MGCP CRCX/MDCX messages (using
the vendor-specific extension X-Osmux: on) coming from the BSC-NAT,
so you can selectively enable osmux per BSC from one the bsc-nat.cfg
file, so we have a centralized point to enable/disable osmux.
First thing you need to do is to accept requests to use Osmux,
this can be done from VTY interface of osmo-bsc_nat and
osmo-bsc_mgcp by adding the following line:
mgcp
...
osmux on
osmux batch-factor 4
This just initializes the osmux engine. You still have to specify
what BSC uses osmux from osmo-bsc_nat configuration file:
...
bsc 1
osmux on
bsc 2
...
bsc 3
osmux on
In this case, bsc 1 and 3 should use osmux if possible, bsc 2 does
not have osmux enabled.
Thus, you can selectively enable osmux depending on the BSC, and
we have a centralized point for configuration from the bsc-nat to
enable osmux on demand, as suggested by Holger.
At this moment, this patch contains heavy debug logging for each
RTP packet that can be removed later to save cycles.
The RTP ssrc/seqnum/timestamp is randomly allocated for each MDCX that
is received to configure an endpoint.
2014-02-05 17:56:17 +00:00
|
|
|
/* The BSC-NAT may ask for enabling osmux on demand. This tells us if
|
|
|
|
* the osmux socket is already initialized.
|
|
|
|
*/
|
|
|
|
int osmux_init;
|
|
|
|
/* osmux batch factor: from 1 to 4 maximum */
|
|
|
|
int osmux_batch;
|
2014-08-29 10:30:38 +00:00
|
|
|
/* osmux batch size (in bytes) */
|
|
|
|
int osmux_batch_size;
|
2014-08-28 14:43:38 +00:00
|
|
|
/* osmux port */
|
|
|
|
uint16_t osmux_port;
|
2015-07-17 19:56:23 +00:00
|
|
|
/* Pad circuit with dummy messages until we see the first voice
|
|
|
|
* message.
|
|
|
|
*/
|
|
|
|
uint16_t osmux_dummy;
|
2018-05-16 12:03:38 +00:00
|
|
|
|
|
|
|
/* Use a jitterbuffer on the bts-side receiver */
|
|
|
|
bool bts_use_jibuf;
|
|
|
|
/* Minimum and maximum buffer size for the jitter buffer, in ms */
|
|
|
|
uint32_t bts_jitter_delay_min;
|
|
|
|
uint32_t bts_jitter_delay_max;
|
2010-02-20 20:21:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* config management */
|
|
|
|
struct mgcp_config *mgcp_config_alloc(void);
|
2013-08-02 19:14:14 +00:00
|
|
|
int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
|
|
|
|
enum mgcp_role role);
|
2010-02-20 20:21:02 +00:00
|
|
|
int mgcp_vty_init(void);
|
2011-02-28 13:37:03 +00:00
|
|
|
int mgcp_endpoints_allocate(struct mgcp_trunk_config *cfg);
|
2014-07-22 13:00:52 +00:00
|
|
|
void mgcp_release_endp(struct mgcp_endpoint *endp);
|
|
|
|
void mgcp_initialize_endp(struct mgcp_endpoint *endp);
|
2010-09-18 20:36:07 +00:00
|
|
|
int mgcp_reset_transcoder(struct mgcp_config *cfg);
|
2012-09-14 15:18:12 +00:00
|
|
|
void mgcp_format_stats(struct mgcp_endpoint *endp, char *stats, size_t size);
|
2012-10-24 19:53:40 +00:00
|
|
|
int mgcp_parse_stats(struct msgb *msg, uint32_t *ps, uint32_t *os, uint32_t *pr, uint32_t *_or, int *loss, uint32_t *jitter);
|
2010-02-20 20:21:02 +00:00
|
|
|
|
2013-12-19 17:53:07 +00:00
|
|
|
void mgcp_trunk_set_keepalive(struct mgcp_trunk_config *tcfg, int interval);
|
|
|
|
|
2010-02-20 20:21:02 +00:00
|
|
|
/*
|
|
|
|
* format helper functions
|
|
|
|
*/
|
|
|
|
struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg);
|
|
|
|
|
2010-03-31 07:27:04 +00:00
|
|
|
/* adc helper */
|
|
|
|
static inline int mgcp_timeslot_to_endpoint(int multiplex, int timeslot)
|
|
|
|
{
|
2010-09-19 17:07:23 +00:00
|
|
|
if (timeslot == 0) {
|
2017-07-10 13:07:22 +00:00
|
|
|
LOGP(DLMGCP, LOGL_ERROR, "Timeslot should not be 0\n");
|
2010-09-19 17:07:23 +00:00
|
|
|
timeslot = 255;
|
|
|
|
}
|
|
|
|
|
2010-08-10 12:24:24 +00:00
|
|
|
return timeslot + (32 * multiplex);
|
2010-03-31 07:27:04 +00:00
|
|
|
}
|
|
|
|
|
2010-08-28 09:59:15 +00:00
|
|
|
static inline void mgcp_endpoint_to_timeslot(int endpoint, int *multiplex, int *timeslot)
|
|
|
|
{
|
|
|
|
*multiplex = endpoint / 32;
|
|
|
|
*timeslot = endpoint % 32;
|
|
|
|
}
|
|
|
|
|
2012-01-26 23:46:49 +00:00
|
|
|
int mgcp_send_reset_ep(struct mgcp_endpoint *endp, int endpoint);
|
|
|
|
int mgcp_send_reset_all(struct mgcp_config *cfg);
|
|
|
|
|
2010-02-03 10:03:45 +00:00
|
|
|
|
mgcp: add voice muxer support
This patch adds the voice muxer. You can use this to batch RTP
traffic to reduce bandwidth comsuption. Basically, osmux transforms
RTP flows to a compact batch format, that is later on decompacted
to its original form. Port UDP/1984 is used for the muxer traffic
between osmo-bsc_nat and osmo-bsc_mgcp (in the BSC side). This
feature depends on libosmo-netif, which contains the osmux core
support.
Osmux is requested on-demand via the MGCP CRCX/MDCX messages (using
the vendor-specific extension X-Osmux: on) coming from the BSC-NAT,
so you can selectively enable osmux per BSC from one the bsc-nat.cfg
file, so we have a centralized point to enable/disable osmux.
First thing you need to do is to accept requests to use Osmux,
this can be done from VTY interface of osmo-bsc_nat and
osmo-bsc_mgcp by adding the following line:
mgcp
...
osmux on
osmux batch-factor 4
This just initializes the osmux engine. You still have to specify
what BSC uses osmux from osmo-bsc_nat configuration file:
...
bsc 1
osmux on
bsc 2
...
bsc 3
osmux on
In this case, bsc 1 and 3 should use osmux if possible, bsc 2 does
not have osmux enabled.
Thus, you can selectively enable osmux depending on the BSC, and
we have a centralized point for configuration from the bsc-nat to
enable osmux on demand, as suggested by Holger.
At this moment, this patch contains heavy debug logging for each
RTP packet that can be removed later to save cycles.
The RTP ssrc/seqnum/timestamp is randomly allocated for each MDCX that
is received to configure an endpoint.
2014-02-05 17:56:17 +00:00
|
|
|
int mgcp_create_bind(const char *source_addr, struct osmo_fd *fd, int port);
|
|
|
|
int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp, struct sockaddr_in *addr, char *buf, int rc);
|
|
|
|
int mgcp_udp_send(int fd, struct in_addr *addr, int port, char *buf, int len);
|
|
|
|
|
2010-02-03 10:03:45 +00:00
|
|
|
#endif
|