blob: 956bee074655597a7105d44fc342a0a58f415a46 [file] [log] [blame]
Neels Hofmeyre9920f22017-07-10 15:07:22 +02001/* MGCP Private Data */
2
3/*
4 * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
5 * (C) 2009-2012 by On-Waves
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#pragma once
24
25#include <string.h>
26
27#include <osmocom/core/select.h>
Pau Espin Pedrolba61f682018-05-16 14:03:38 +020028#include <osmocom/netif/jibuf.h>
Neels Hofmeyre9920f22017-07-10 15:07:22 +020029
30#define CI_UNUSED 0
31
32enum mgcp_trunk_type {
33 MGCP_TRUNK_VIRTUAL,
34 MGCP_TRUNK_E1,
35};
36
37struct mgcp_rtp_stream_state {
38 uint32_t ssrc;
39 uint16_t last_seq;
40 uint32_t last_timestamp;
41 uint32_t err_ts_counter;
42 int32_t last_tsdelta;
43 uint32_t last_arrival_time;
44};
45
46struct mgcp_rtp_state {
47 int initialized;
48 int patch_ssrc;
49
50 uint32_t orig_ssrc;
51
52 int seq_offset;
53
54 int32_t timestamp_offset;
55 uint32_t packet_duration;
56
57 struct mgcp_rtp_stream_state in_stream;
58 struct mgcp_rtp_stream_state out_stream;
59
60 /* jitter and packet loss calculation */
61 int stats_initialized;
62 uint16_t stats_base_seq;
63 uint16_t stats_max_seq;
64 uint32_t stats_ssrc;
65 uint32_t stats_jitter;
66 int32_t stats_transit;
67 int stats_cycles;
68 bool patched_first_rtp_payload; /* FIXME: drop this, see OS#2459 */
69};
70
71struct mgcp_rtp_codec {
72 uint32_t rate;
73 int channels;
74 uint32_t frame_duration_num;
75 uint32_t frame_duration_den;
76
77 int payload_type;
78 char *audio_name;
79 char *subtype_name;
80};
81
82struct mgcp_rtp_end {
83 /* statistics */
84 unsigned int packets;
85 unsigned int octets;
86 unsigned int dropped_packets;
87 struct in_addr addr;
88
89 /* in network byte order */
90 int rtp_port, rtcp_port;
91
92 /* audio codec information */
93 struct mgcp_rtp_codec codec;
94 struct mgcp_rtp_codec alt_codec; /* TODO/XXX: make it generic */
95
96 /* per endpoint data */
97 int frames_per_packet;
98 uint32_t packet_duration_ms;
99 char *fmtp_extra;
100 int output_enabled;
101 int force_output_ptime;
102
103 /* RTP patching */
104 int force_constant_ssrc; /* -1: always, 0: don't, 1: once */
105 int force_aligned_timing;
106 void *rtp_process_data;
107
108 /*
109 * Each end has a socket...
110 */
111 struct osmo_fd rtp;
112 struct osmo_fd rtcp;
113
114 int local_port;
115 int local_alloc;
116};
117
118enum {
119 MGCP_TAP_BTS_IN,
120 MGCP_TAP_BTS_OUT,
121 MGCP_TAP_NET_IN,
122 MGCP_TAP_NET_OUT,
123
124 /* last element */
125 MGCP_TAP_COUNT
126};
127
128struct mgcp_rtp_tap {
129 int enabled;
130 struct sockaddr_in forward;
131};
132
133struct mgcp_lco {
134 char *string;
135 char *codec;
136 int pkt_period_min; /* time in ms */
137 int pkt_period_max; /* time in ms */
138};
139
140enum mgcp_type {
141 MGCP_RTP_DEFAULT = 0,
142 MGCP_RTP_TRANSCODED,
143 MGCP_OSMUX_BSC,
144 MGCP_OSMUX_BSC_NAT,
145};
146
147#include <osmocom/legacy_mgcp/osmux.h>
148
149struct mgcp_endpoint {
150 int allocated;
151 uint32_t ci;
152 char *callid;
153 struct mgcp_lco local_options;
154 int conn_mode;
155 int orig_mode;
156
157 /* backpointer */
158 struct mgcp_config *cfg;
159 struct mgcp_trunk_config *tcfg;
160
161 /* port status for bts/net */
162 struct mgcp_rtp_end bts_end;
163 struct mgcp_rtp_end net_end;
164
165 /*
166 * For transcoding we will send from the local_port
167 * of trans_bts and it will arrive at trans_net from
168 * where we will forward it to the network.
169 */
170 struct mgcp_rtp_end trans_bts;
171 struct mgcp_rtp_end trans_net;
172 enum mgcp_type type;
173
174 /* sequence bits */
175 struct mgcp_rtp_state net_state;
176 struct mgcp_rtp_state bts_state;
177
178 /* fields for re-transmission */
179 char *last_trans;
180 char *last_response;
181
182 /* tap for the endpoint */
183 struct mgcp_rtp_tap taps[MGCP_TAP_COUNT];
184
185 struct {
186 /* Osmux state: disabled, activating, active */
187 enum osmux_state state;
188 /* Allocated Osmux circuit ID for this endpoint */
189 int allocated_cid;
190 /* Used Osmux circuit ID for this endpoint */
191 uint8_t cid;
192 /* handle to batch messages */
193 struct osmux_in_handle *in;
194 /* handle to unbatch messages */
195 struct osmux_out_handle out;
196 /* statistics */
197 struct {
198 uint32_t chunks;
199 uint32_t octets;
200 } stats;
201 } osmux;
Pau Espin Pedrolba61f682018-05-16 14:03:38 +0200202
203 /* Jitter buffer */
204 struct osmo_jibuf* bts_jb;
205 /* Use a jitterbuffer on the bts-side receiver */
206 bool bts_use_jibuf;
207 /* Minimum and maximum buffer size for the jitter buffer, in ms */
208 uint32_t bts_jitter_delay_min;
209 uint32_t bts_jitter_delay_max;
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200210};
211
212#define for_each_line(line, save) \
213 for (line = strline_r(NULL, &save); line;\
214 line = strline_r(NULL, &save))
215
216static inline char *strline_r(char *str, char **saveptr)
217{
218 char *result;
219
220 if (str)
221 *saveptr = str;
222
223 result = *saveptr;
224
225 if (*saveptr != NULL) {
226 *saveptr = strpbrk(*saveptr, "\r\n");
227
228 if (*saveptr != NULL) {
229 char *eos = *saveptr;
230
231 if ((*saveptr)[0] == '\r' && (*saveptr)[1] == '\n')
232 (*saveptr)++;
233 (*saveptr)++;
234 if ((*saveptr)[0] == '\0')
235 *saveptr = NULL;
236
237 *eos = '\0';
238 }
239 }
240
241 return result;
242}
243
244
245
246#define ENDPOINT_NUMBER(endp) abs((int)(endp - endp->tcfg->endpoints))
247
248/**
249 * Internal structure while parsing a request
250 */
251struct mgcp_parse_data {
252 struct mgcp_config *cfg;
253 struct mgcp_endpoint *endp;
254 char *trans;
255 char *save;
256 int found;
257};
258
259int mgcp_send_dummy(struct mgcp_endpoint *endp);
260int mgcp_bind_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
261int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
262int mgcp_bind_trans_bts_rtp_port(struct mgcp_endpoint *enp, int rtp_port);
263int mgcp_bind_trans_net_rtp_port(struct mgcp_endpoint *enp, int rtp_port);
264int mgcp_free_rtp_port(struct mgcp_rtp_end *end);
265
266/* For transcoding we need to manage an in and an output that are connected */
267static inline int endp_back_channel(int endpoint)
268{
269 return endpoint + 60;
270}
271
272struct mgcp_trunk_config *mgcp_trunk_alloc(struct mgcp_config *cfg, int index);
273struct mgcp_trunk_config *mgcp_trunk_num(struct mgcp_config *cfg, int index);
274
275void mgcp_rtp_end_config(struct mgcp_endpoint *endp, int expect_ssrc_change,
276 struct mgcp_rtp_end *rtp);
277uint32_t mgcp_rtp_packet_duration(struct mgcp_endpoint *endp,
278 struct mgcp_rtp_end *rtp);
279
280void mgcp_state_calc_loss(struct mgcp_rtp_state *s, struct mgcp_rtp_end *,
281 uint32_t *expected, int *loss);
282uint32_t mgcp_state_calc_jitter(struct mgcp_rtp_state *);
283
284/* payload processing default functions */
285int mgcp_rtp_processing_default(struct mgcp_endpoint *endp, struct mgcp_rtp_end *dst_end,
286 char *data, int *len, int buf_size);
287
288int mgcp_setup_rtp_processing_default(struct mgcp_endpoint *endp,
289 struct mgcp_rtp_end *dst_end,
290 struct mgcp_rtp_end *src_end);
291
292void mgcp_get_net_downlink_format_default(struct mgcp_endpoint *endp,
293 int *payload_type,
294 const char**subtype_name,
295 const char**fmtp_extra);
296
297/* internal RTP Annex A counting */
298void mgcp_rtp_annex_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
299 const uint16_t seq, const int32_t transit,
300 const uint32_t ssrc);
301
302int mgcp_set_ip_tos(int fd, int tos);
303
304enum {
305 MGCP_DEST_NET = 0,
306 MGCP_DEST_BTS,
307};
308
309
310#define MGCP_DUMMY_LOAD 0x23
311
312
313/**
314 * SDP related information
315 */
316/* Assume audio frame length of 20ms */
317#define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20
318#define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000
319#define DEFAULT_RTP_AUDIO_PACKET_DURATION_MS 20
320#define DEFAULT_RTP_AUDIO_DEFAULT_RATE 8000
321#define DEFAULT_RTP_AUDIO_DEFAULT_CHANNELS 1
322
323#define PTYPE_UNDEFINED (-1)
324int mgcp_parse_sdp_data(struct mgcp_endpoint *endp, struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p);
325int mgcp_set_audio_info(void *ctx, struct mgcp_rtp_codec *codec,
326 int payload_type, const char *audio_name);
327
328
329/**
330 * Internal network related
331 */
332static inline const char *mgcp_net_src_addr(struct mgcp_endpoint *endp)
333{
334 if (endp->cfg->net_ports.bind_addr)
335 return endp->cfg->net_ports.bind_addr;
336 return endp->cfg->source_addr;
337}
338
339static inline const char *mgcp_bts_src_addr(struct mgcp_endpoint *endp)
340{
341 if (endp->cfg->bts_ports.bind_addr)
342 return endp->cfg->bts_ports.bind_addr;
343 return endp->cfg->source_addr;
344}
345
346int mgcp_msg_terminate_nul(struct msgb *msg);
Pau Espin Pedrolba61f682018-05-16 14:03:38 +0200347
348/**
349 * Internal jitter buffer related
350 */
351void mgcp_dejitter_udp_send(struct msgb *msg, void *data);