blob: dcc75f18eafc61ee7445046a9c636770287f099b [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>
28
29#define CI_UNUSED 0
30
31enum mgcp_trunk_type {
32 MGCP_TRUNK_VIRTUAL,
33 MGCP_TRUNK_E1,
34};
35
36struct mgcp_rtp_stream_state {
37 uint32_t ssrc;
38 uint16_t last_seq;
39 uint32_t last_timestamp;
40 uint32_t err_ts_counter;
41 int32_t last_tsdelta;
42 uint32_t last_arrival_time;
43};
44
45struct mgcp_rtp_state {
46 int initialized;
47 int patch_ssrc;
48
49 uint32_t orig_ssrc;
50
51 int seq_offset;
52
53 int32_t timestamp_offset;
54 uint32_t packet_duration;
55
56 struct mgcp_rtp_stream_state in_stream;
57 struct mgcp_rtp_stream_state out_stream;
58
59 /* jitter and packet loss calculation */
60 int stats_initialized;
61 uint16_t stats_base_seq;
62 uint16_t stats_max_seq;
63 uint32_t stats_ssrc;
64 uint32_t stats_jitter;
65 int32_t stats_transit;
66 int stats_cycles;
67 bool patched_first_rtp_payload; /* FIXME: drop this, see OS#2459 */
68};
69
70struct mgcp_rtp_codec {
71 uint32_t rate;
72 int channels;
73 uint32_t frame_duration_num;
74 uint32_t frame_duration_den;
75
76 int payload_type;
77 char *audio_name;
78 char *subtype_name;
79};
80
81struct mgcp_rtp_end {
82 /* statistics */
83 unsigned int packets;
84 unsigned int octets;
85 unsigned int dropped_packets;
86 struct in_addr addr;
87
88 /* in network byte order */
89 int rtp_port, rtcp_port;
90
91 /* audio codec information */
92 struct mgcp_rtp_codec codec;
93 struct mgcp_rtp_codec alt_codec; /* TODO/XXX: make it generic */
94
95 /* per endpoint data */
96 int frames_per_packet;
97 uint32_t packet_duration_ms;
98 char *fmtp_extra;
99 int output_enabled;
100 int force_output_ptime;
101
102 /* RTP patching */
103 int force_constant_ssrc; /* -1: always, 0: don't, 1: once */
104 int force_aligned_timing;
105 void *rtp_process_data;
106
107 /*
108 * Each end has a socket...
109 */
110 struct osmo_fd rtp;
111 struct osmo_fd rtcp;
112
113 int local_port;
114 int local_alloc;
115};
116
117enum {
118 MGCP_TAP_BTS_IN,
119 MGCP_TAP_BTS_OUT,
120 MGCP_TAP_NET_IN,
121 MGCP_TAP_NET_OUT,
122
123 /* last element */
124 MGCP_TAP_COUNT
125};
126
127struct mgcp_rtp_tap {
128 int enabled;
129 struct sockaddr_in forward;
130};
131
132struct mgcp_lco {
133 char *string;
134 char *codec;
135 int pkt_period_min; /* time in ms */
136 int pkt_period_max; /* time in ms */
137};
138
139enum mgcp_type {
140 MGCP_RTP_DEFAULT = 0,
141 MGCP_RTP_TRANSCODED,
142 MGCP_OSMUX_BSC,
143 MGCP_OSMUX_BSC_NAT,
144};
145
146#include <osmocom/legacy_mgcp/osmux.h>
147
148struct mgcp_endpoint {
149 int allocated;
150 uint32_t ci;
151 char *callid;
152 struct mgcp_lco local_options;
153 int conn_mode;
154 int orig_mode;
155
156 /* backpointer */
157 struct mgcp_config *cfg;
158 struct mgcp_trunk_config *tcfg;
159
160 /* port status for bts/net */
161 struct mgcp_rtp_end bts_end;
162 struct mgcp_rtp_end net_end;
163
164 /*
165 * For transcoding we will send from the local_port
166 * of trans_bts and it will arrive at trans_net from
167 * where we will forward it to the network.
168 */
169 struct mgcp_rtp_end trans_bts;
170 struct mgcp_rtp_end trans_net;
171 enum mgcp_type type;
172
173 /* sequence bits */
174 struct mgcp_rtp_state net_state;
175 struct mgcp_rtp_state bts_state;
176
177 /* fields for re-transmission */
178 char *last_trans;
179 char *last_response;
180
181 /* tap for the endpoint */
182 struct mgcp_rtp_tap taps[MGCP_TAP_COUNT];
183
184 struct {
185 /* Osmux state: disabled, activating, active */
186 enum osmux_state state;
187 /* Allocated Osmux circuit ID for this endpoint */
188 int allocated_cid;
189 /* Used Osmux circuit ID for this endpoint */
190 uint8_t cid;
191 /* handle to batch messages */
192 struct osmux_in_handle *in;
193 /* handle to unbatch messages */
194 struct osmux_out_handle out;
195 /* statistics */
196 struct {
197 uint32_t chunks;
198 uint32_t octets;
199 } stats;
200 } osmux;
201};
202
203#define for_each_line(line, save) \
204 for (line = strline_r(NULL, &save); line;\
205 line = strline_r(NULL, &save))
206
207static inline char *strline_r(char *str, char **saveptr)
208{
209 char *result;
210
211 if (str)
212 *saveptr = str;
213
214 result = *saveptr;
215
216 if (*saveptr != NULL) {
217 *saveptr = strpbrk(*saveptr, "\r\n");
218
219 if (*saveptr != NULL) {
220 char *eos = *saveptr;
221
222 if ((*saveptr)[0] == '\r' && (*saveptr)[1] == '\n')
223 (*saveptr)++;
224 (*saveptr)++;
225 if ((*saveptr)[0] == '\0')
226 *saveptr = NULL;
227
228 *eos = '\0';
229 }
230 }
231
232 return result;
233}
234
235
236
237#define ENDPOINT_NUMBER(endp) abs((int)(endp - endp->tcfg->endpoints))
238
239/**
240 * Internal structure while parsing a request
241 */
242struct mgcp_parse_data {
243 struct mgcp_config *cfg;
244 struct mgcp_endpoint *endp;
245 char *trans;
246 char *save;
247 int found;
248};
249
250int mgcp_send_dummy(struct mgcp_endpoint *endp);
251int mgcp_bind_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
252int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
253int mgcp_bind_trans_bts_rtp_port(struct mgcp_endpoint *enp, int rtp_port);
254int mgcp_bind_trans_net_rtp_port(struct mgcp_endpoint *enp, int rtp_port);
255int mgcp_free_rtp_port(struct mgcp_rtp_end *end);
256
257/* For transcoding we need to manage an in and an output that are connected */
258static inline int endp_back_channel(int endpoint)
259{
260 return endpoint + 60;
261}
262
263struct mgcp_trunk_config *mgcp_trunk_alloc(struct mgcp_config *cfg, int index);
264struct mgcp_trunk_config *mgcp_trunk_num(struct mgcp_config *cfg, int index);
265
266void mgcp_rtp_end_config(struct mgcp_endpoint *endp, int expect_ssrc_change,
267 struct mgcp_rtp_end *rtp);
268uint32_t mgcp_rtp_packet_duration(struct mgcp_endpoint *endp,
269 struct mgcp_rtp_end *rtp);
270
271void mgcp_state_calc_loss(struct mgcp_rtp_state *s, struct mgcp_rtp_end *,
272 uint32_t *expected, int *loss);
273uint32_t mgcp_state_calc_jitter(struct mgcp_rtp_state *);
274
275/* payload processing default functions */
276int mgcp_rtp_processing_default(struct mgcp_endpoint *endp, struct mgcp_rtp_end *dst_end,
277 char *data, int *len, int buf_size);
278
279int mgcp_setup_rtp_processing_default(struct mgcp_endpoint *endp,
280 struct mgcp_rtp_end *dst_end,
281 struct mgcp_rtp_end *src_end);
282
283void mgcp_get_net_downlink_format_default(struct mgcp_endpoint *endp,
284 int *payload_type,
285 const char**subtype_name,
286 const char**fmtp_extra);
287
288/* internal RTP Annex A counting */
289void mgcp_rtp_annex_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
290 const uint16_t seq, const int32_t transit,
291 const uint32_t ssrc);
292
293int mgcp_set_ip_tos(int fd, int tos);
294
295enum {
296 MGCP_DEST_NET = 0,
297 MGCP_DEST_BTS,
298};
299
300
301#define MGCP_DUMMY_LOAD 0x23
302
303
304/**
305 * SDP related information
306 */
307/* Assume audio frame length of 20ms */
308#define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20
309#define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000
310#define DEFAULT_RTP_AUDIO_PACKET_DURATION_MS 20
311#define DEFAULT_RTP_AUDIO_DEFAULT_RATE 8000
312#define DEFAULT_RTP_AUDIO_DEFAULT_CHANNELS 1
313
314#define PTYPE_UNDEFINED (-1)
315int mgcp_parse_sdp_data(struct mgcp_endpoint *endp, struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p);
316int mgcp_set_audio_info(void *ctx, struct mgcp_rtp_codec *codec,
317 int payload_type, const char *audio_name);
318
319
320/**
321 * Internal network related
322 */
323static inline const char *mgcp_net_src_addr(struct mgcp_endpoint *endp)
324{
325 if (endp->cfg->net_ports.bind_addr)
326 return endp->cfg->net_ports.bind_addr;
327 return endp->cfg->source_addr;
328}
329
330static inline const char *mgcp_bts_src_addr(struct mgcp_endpoint *endp)
331{
332 if (endp->cfg->bts_ports.bind_addr)
333 return endp->cfg->bts_ports.bind_addr;
334 return endp->cfg->source_addr;
335}
336
337int mgcp_msg_terminate_nul(struct msgb *msg);