blob: 7b161d279b498ec0c20663e89e6d45eade785aec [file] [log] [blame]
Neels Hofmeyre9920f22017-07-10 15:07:22 +02001/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
2/* The protocol implementation */
3
4/*
5 * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
6 * (C) 2009-2012 by On-Waves
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Affero General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
24#include <string.h>
25#include <stdlib.h>
26#include <unistd.h>
27#include <errno.h>
28#include <time.h>
29#include <limits.h>
30
31#include <sys/socket.h>
32#include <arpa/inet.h>
33
34#include <osmocom/core/msgb.h>
35#include <osmocom/core/select.h>
36
37#include <osmocom/netif/rtp.h>
38
39#include <osmocom/legacy_mgcp/mgcp.h>
40#include <osmocom/legacy_mgcp/mgcp_internal.h>
41
42#include <osmocom/legacy_mgcp/osmux.h>
43
44#warning "Make use of the rtp proxy code"
45
46
47#define RTP_SEQ_MOD (1 << 16)
48#define RTP_MAX_DROPOUT 3000
49#define RTP_MAX_MISORDER 100
50#define RTP_BUF_SIZE 4096
51
52enum {
53 MGCP_PROTO_RTP,
54 MGCP_PROTO_RTCP,
55};
56
57/**
58 * This does not need to be a precision timestamp and
59 * is allowed to wrap quite fast. The returned value is
60 * 1/unit seconds.
61 */
62static uint32_t get_current_ts(unsigned unit)
63{
64 struct timespec tp;
65 uint64_t ret;
66
67 if (!unit)
68 return 0;
69
70 memset(&tp, 0, sizeof(tp));
71 if (clock_gettime(CLOCK_MONOTONIC, &tp) != 0)
72 LOGP(DLMGCP, LOGL_NOTICE,
73 "Getting the clock failed.\n");
74
75 /* convert it to 1/unit seconds */
76 ret = tp.tv_sec;
77 ret *= unit;
78 ret += (int64_t)tp.tv_nsec * unit / 1000 / 1000 / 1000;
79
80 return ret;
81}
82
83int mgcp_udp_send(int fd, struct in_addr *addr, int port, char *buf, int len)
84{
85 struct sockaddr_in out;
86 out.sin_family = AF_INET;
87 out.sin_port = port;
88 memcpy(&out.sin_addr, addr, sizeof(*addr));
89
90 return sendto(fd, buf, len, 0, (struct sockaddr *)&out, sizeof(out));
91}
92
93int mgcp_send_dummy(struct mgcp_endpoint *endp)
94{
95 static char buf[] = { MGCP_DUMMY_LOAD };
96 int rc;
97 int was_rtcp = 0;
98
99 rc = mgcp_udp_send(endp->net_end.rtp.fd, &endp->net_end.addr,
100 endp->net_end.rtp_port, buf, 1);
101
102 if (rc == -1)
103 goto failed;
104
105 if (endp->tcfg->omit_rtcp)
106 return rc;
107
108 was_rtcp = 1;
109 rc = mgcp_udp_send(endp->net_end.rtcp.fd, &endp->net_end.addr,
110 endp->net_end.rtcp_port, buf, 1);
111
112 if (rc >= 0)
113 return rc;
114
115failed:
116 LOGP(DLMGCP, LOGL_ERROR,
117 "Failed to send dummy %s packet: %s on: 0x%x to %s:%d\n",
118 was_rtcp ? "RTCP" : "RTP",
119 strerror(errno), ENDPOINT_NUMBER(endp), inet_ntoa(endp->net_end.addr),
120 was_rtcp ? endp->net_end.rtcp_port : endp->net_end.rtp_port);
121
122 return -1;
123}
124
125static int32_t compute_timestamp_aligment_error(struct mgcp_rtp_stream_state *sstate,
126 int ptime, uint32_t timestamp)
127{
128 int32_t timestamp_delta;
129
130 if (ptime == 0)
131 return 0;
132
133 /* Align according to: T - Tlast = k * Tptime */
134 timestamp_delta = timestamp - sstate->last_timestamp;
135
136 return timestamp_delta % ptime;
137}
138
139static int check_rtp_timestamp(struct mgcp_endpoint *endp,
140 struct mgcp_rtp_state *state,
141 struct mgcp_rtp_stream_state *sstate,
142 struct mgcp_rtp_end *rtp_end,
143 struct sockaddr_in *addr,
144 uint16_t seq, uint32_t timestamp,
145 const char *text, int32_t *tsdelta_out)
146{
147 int32_t tsdelta;
148 int32_t timestamp_error;
149
150 /* Not fully intialized, skip */
151 if (sstate->last_tsdelta == 0 && timestamp == sstate->last_timestamp)
152 return 0;
153
154 if (seq == sstate->last_seq) {
155 if (timestamp != sstate->last_timestamp) {
156 sstate->err_ts_counter += 1;
157 LOGP(DLMGCP, LOGL_ERROR,
158 "The %s timestamp delta is != 0 but the sequence "
159 "number %d is the same, "
160 "TS offset: %d, SeqNo offset: %d "
161 "on 0x%x SSRC: %u timestamp: %u "
162 "from %s:%d in %d\n",
163 text, seq,
164 state->timestamp_offset, state->seq_offset,
165 ENDPOINT_NUMBER(endp), sstate->ssrc, timestamp,
166 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
167 endp->conn_mode);
168 }
169 return 0;
170 }
171
172 tsdelta =
173 (int32_t)(timestamp - sstate->last_timestamp) /
174 (int16_t)(seq - sstate->last_seq);
175
176 if (tsdelta == 0) {
177 /* Don't update *tsdelta_out */
178 LOGP(DLMGCP, LOGL_NOTICE,
179 "The %s timestamp delta is %d "
180 "on 0x%x SSRC: %u timestamp: %u "
181 "from %s:%d in %d\n",
182 text, tsdelta,
183 ENDPOINT_NUMBER(endp), sstate->ssrc, timestamp,
184 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
185 endp->conn_mode);
186
187 return 0;
188 }
189
190 if (sstate->last_tsdelta != tsdelta) {
191 if (sstate->last_tsdelta) {
192 LOGP(DLMGCP, LOGL_INFO,
193 "The %s timestamp delta changes from %d to %d "
194 "on 0x%x SSRC: %u timestamp: %u from %s:%d in %d\n",
195 text, sstate->last_tsdelta, tsdelta,
196 ENDPOINT_NUMBER(endp), sstate->ssrc, timestamp,
197 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
198 endp->conn_mode);
199 }
200 }
201
202 if (tsdelta_out)
203 *tsdelta_out = tsdelta;
204
205 timestamp_error =
206 compute_timestamp_aligment_error(sstate, state->packet_duration,
207 timestamp);
208
209 if (timestamp_error) {
210 sstate->err_ts_counter += 1;
211 LOGP(DLMGCP, LOGL_NOTICE,
212 "The %s timestamp has an alignment error of %d "
213 "on 0x%x SSRC: %u "
214 "SeqNo delta: %d, TS delta: %d, dTS/dSeq: %d "
215 "from %s:%d in mode %d. ptime: %d\n",
216 text, timestamp_error,
217 ENDPOINT_NUMBER(endp), sstate->ssrc,
218 (int16_t)(seq - sstate->last_seq),
219 (int32_t)(timestamp - sstate->last_timestamp),
220 tsdelta,
221 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
222 endp->conn_mode, state->packet_duration);
223 }
224 return 1;
225}
226
227/* Set the timestamp offset according to the packet duration. */
228static int adjust_rtp_timestamp_offset(struct mgcp_endpoint *endp,
229 struct mgcp_rtp_state *state,
230 struct mgcp_rtp_end *rtp_end,
231 struct sockaddr_in *addr,
232 int16_t delta_seq, uint32_t in_timestamp)
233{
234 int32_t tsdelta = state->packet_duration;
235 int timestamp_offset;
236 uint32_t out_timestamp;
237
238 if (tsdelta == 0) {
239 tsdelta = state->out_stream.last_tsdelta;
240 if (tsdelta != 0) {
241 LOGP(DLMGCP, LOGL_NOTICE,
242 "A fixed packet duration is not available on 0x%x, "
243 "using last output timestamp delta instead: %d "
244 "from %s:%d in %d\n",
245 ENDPOINT_NUMBER(endp), tsdelta,
246 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
247 endp->conn_mode);
248 } else {
249 tsdelta = rtp_end->codec.rate * 20 / 1000;
250 LOGP(DLMGCP, LOGL_NOTICE,
251 "Fixed packet duration and last timestamp delta "
252 "are not available on 0x%x, "
253 "using fixed 20ms instead: %d "
254 "from %s:%d in %d\n",
255 ENDPOINT_NUMBER(endp), tsdelta,
256 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
257 endp->conn_mode);
258 }
259 }
260
261 out_timestamp = state->out_stream.last_timestamp + delta_seq * tsdelta;
262 timestamp_offset = out_timestamp - in_timestamp;
263
264 if (state->timestamp_offset != timestamp_offset) {
265 state->timestamp_offset = timestamp_offset;
266
267 LOGP(DLMGCP, LOGL_NOTICE,
268 "Timestamp offset change on 0x%x SSRC: %u "
269 "SeqNo delta: %d, TS offset: %d, "
270 "from %s:%d in %d\n",
271 ENDPOINT_NUMBER(endp), state->in_stream.ssrc,
272 delta_seq, state->timestamp_offset,
273 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
274 endp->conn_mode);
275 }
276
277 return timestamp_offset;
278}
279
280/* Set the timestamp offset according to the packet duration. */
281static int align_rtp_timestamp_offset(struct mgcp_endpoint *endp,
282 struct mgcp_rtp_state *state,
283 struct mgcp_rtp_end *rtp_end,
284 struct sockaddr_in *addr,
285 uint32_t timestamp)
286{
287 int timestamp_error = 0;
288 int ptime = state->packet_duration;
289
290 /* Align according to: T + Toffs - Tlast = k * Tptime */
291
292 timestamp_error = compute_timestamp_aligment_error(
293 &state->out_stream, ptime,
294 timestamp + state->timestamp_offset);
295
296 if (timestamp_error) {
297 state->timestamp_offset += ptime - timestamp_error;
298
299 LOGP(DLMGCP, LOGL_NOTICE,
300 "Corrected timestamp alignment error of %d on 0x%x SSRC: %u "
301 "new TS offset: %d, "
302 "from %s:%d in %d\n",
303 timestamp_error,
304 ENDPOINT_NUMBER(endp), state->in_stream.ssrc,
305 state->timestamp_offset, inet_ntoa(addr->sin_addr),
306 ntohs(addr->sin_port), endp->conn_mode);
307 }
308
309 OSMO_ASSERT(compute_timestamp_aligment_error(&state->out_stream, ptime,
310 timestamp + state->timestamp_offset) == 0);
311
312 return timestamp_error;
313}
314
315int mgcp_rtp_processing_default(struct mgcp_endpoint *endp, struct mgcp_rtp_end *dst_end,
316 char *data, int *len, int buf_size)
317{
318 return 0;
319}
320
321int mgcp_setup_rtp_processing_default(struct mgcp_endpoint *endp,
322 struct mgcp_rtp_end *dst_end,
323 struct mgcp_rtp_end *src_end)
324{
325 return 0;
326}
327
328void mgcp_get_net_downlink_format_default(struct mgcp_endpoint *endp,
329 int *payload_type,
330 const char**audio_name,
331 const char**fmtp_extra)
332{
333 /* Use the BTS side parameters when passing the SDP data (for
334 * downlink) to the net peer.
335 */
336 *payload_type = endp->bts_end.codec.payload_type;
337 *audio_name = endp->bts_end.codec.audio_name;
338 *fmtp_extra = endp->bts_end.fmtp_extra;
339}
340
341
342void mgcp_rtp_annex_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
343 const uint16_t seq, const int32_t transit,
344 const uint32_t ssrc)
345{
346 int32_t d;
347
348 /* initialize or re-initialize */
349 if (!state->stats_initialized || state->stats_ssrc != ssrc) {
350 state->stats_initialized = 1;
351 state->stats_base_seq = seq;
352 state->stats_max_seq = seq - 1;
353 state->stats_ssrc = ssrc;
354 state->stats_jitter = 0;
355 state->stats_transit = transit;
356 state->stats_cycles = 0;
357 } else {
358 uint16_t udelta;
359
360 /*
361 * The below takes the shape of the validation of
362 * Appendix A. Check if there is something weird with
363 * the sequence number, otherwise check for a wrap
364 * around in the sequence number.
365 * It can't wrap during the initialization so let's
366 * skip it here. The Appendix A probably doesn't have
367 * this issue because of the probation.
368 */
369 udelta = seq - state->stats_max_seq;
370 if (udelta < RTP_MAX_DROPOUT) {
371 if (seq < state->stats_max_seq)
372 state->stats_cycles += RTP_SEQ_MOD;
373 } else if (udelta <= RTP_SEQ_MOD - RTP_MAX_MISORDER) {
374 LOGP(DLMGCP, LOGL_NOTICE,
375 "RTP seqno made a very large jump on 0x%x delta: %u\n",
376 ENDPOINT_NUMBER(endp), udelta);
377 }
378 }
379
380 /*
381 * Calculate the jitter between the two packages. The TS should be
382 * taken closer to the read function. This was taken from the
383 * Appendix A of RFC 3550. Timestamp and arrival_time have a 1/rate
384 * resolution.
385 */
386 d = transit - state->stats_transit;
387 state->stats_transit = transit;
388 if (d < 0)
389 d = -d;
390 state->stats_jitter += d - ((state->stats_jitter + 8) >> 4);
391 state->stats_max_seq = seq;
392}
393
394
395
396/**
397 * The RFC 3550 Appendix A assumes there are multiple sources but
398 * some of the supported endpoints (e.g. the nanoBTS) can only handle
399 * one source and this code will patch RTP header to appear as if there
400 * is only one source.
401 * There is also no probation period for new sources. Every RTP header
402 * we receive will be seen as a switch in streams.
403 */
404void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
405 struct mgcp_rtp_end *rtp_end, struct sockaddr_in *addr,
406 char *data, int len)
407{
408 uint32_t arrival_time;
409 int32_t transit;
410 uint16_t seq;
411 uint32_t timestamp, ssrc;
412 struct rtp_hdr *rtp_hdr;
413 int payload = rtp_end->codec.payload_type;
414
415 if (len < sizeof(*rtp_hdr))
416 return;
417
418 rtp_hdr = (struct rtp_hdr *) data;
419 seq = ntohs(rtp_hdr->sequence);
420 timestamp = ntohl(rtp_hdr->timestamp);
421 arrival_time = get_current_ts(rtp_end->codec.rate);
422 ssrc = ntohl(rtp_hdr->ssrc);
423 transit = arrival_time - timestamp;
424
425 mgcp_rtp_annex_count(endp, state, seq, transit, ssrc);
426
427 if (!state->initialized) {
428 state->initialized = 1;
429 state->in_stream.last_seq = seq - 1;
430 state->in_stream.ssrc = state->orig_ssrc = ssrc;
431 state->in_stream.last_tsdelta = 0;
432 state->packet_duration = mgcp_rtp_packet_duration(endp, rtp_end);
433 state->out_stream = state->in_stream;
434 state->out_stream.last_timestamp = timestamp;
435 state->out_stream.ssrc = ssrc - 1; /* force output SSRC change */
436 LOGP(DLMGCP, LOGL_INFO,
437 "Initializing stream on 0x%x SSRC: %u timestamp: %u "
438 "pkt-duration: %d, from %s:%d in %d\n",
439 ENDPOINT_NUMBER(endp), state->in_stream.ssrc,
440 state->seq_offset, state->packet_duration,
441 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
442 endp->conn_mode);
443 if (state->packet_duration == 0) {
444 state->packet_duration = rtp_end->codec.rate * 20 / 1000;
445 LOGP(DLMGCP, LOGL_NOTICE,
446 "Fixed packet duration is not available on 0x%x, "
447 "using fixed 20ms instead: %d from %s:%d in %d\n",
448 ENDPOINT_NUMBER(endp), state->packet_duration,
449 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
450 endp->conn_mode);
451 }
452 } else if (state->in_stream.ssrc != ssrc) {
453 LOGP(DLMGCP, LOGL_NOTICE,
454 "The SSRC changed on 0x%x: %u -> %u "
455 "from %s:%d in %d\n",
456 ENDPOINT_NUMBER(endp),
457 state->in_stream.ssrc, rtp_hdr->ssrc,
458 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
459 endp->conn_mode);
460
461 state->in_stream.ssrc = ssrc;
462 if (rtp_end->force_constant_ssrc) {
463 int16_t delta_seq;
464
465 /* Always increment seqno by 1 */
466 state->seq_offset =
467 (state->out_stream.last_seq + 1) - seq;
468
469 /* Estimate number of packets that would have been sent */
470 delta_seq =
471 (arrival_time - state->in_stream.last_arrival_time
472 + state->packet_duration/2) /
473 state->packet_duration;
474
475 adjust_rtp_timestamp_offset(endp, state, rtp_end, addr,
476 delta_seq, timestamp);
477
478 state->patch_ssrc = 1;
479 ssrc = state->orig_ssrc;
480 if (rtp_end->force_constant_ssrc != -1)
481 rtp_end->force_constant_ssrc -= 1;
482
483 LOGP(DLMGCP, LOGL_NOTICE,
484 "SSRC patching enabled on 0x%x SSRC: %u "
485 "SeqNo offset: %d, TS offset: %d "
486 "from %s:%d in %d\n",
487 ENDPOINT_NUMBER(endp), state->in_stream.ssrc,
488 state->seq_offset, state->timestamp_offset,
489 inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
490 endp->conn_mode);
491 }
492
493 state->in_stream.last_tsdelta = 0;
494 } else {
495 /* Compute current per-packet timestamp delta */
496 check_rtp_timestamp(endp, state, &state->in_stream, rtp_end, addr,
497 seq, timestamp, "input",
498 &state->in_stream.last_tsdelta);
499
500 if (state->patch_ssrc)
501 ssrc = state->orig_ssrc;
502 }
503
504 /* Save before patching */
505 state->in_stream.last_timestamp = timestamp;
506 state->in_stream.last_seq = seq;
507 state->in_stream.last_arrival_time = arrival_time;
508
509 if (rtp_end->force_aligned_timing &&
510 state->out_stream.ssrc == ssrc && state->packet_duration)
511 /* Align the timestamp offset */
512 align_rtp_timestamp_offset(endp, state, rtp_end, addr, timestamp);
513
514 /* Store the updated SSRC back to the packet */
515 if (state->patch_ssrc)
516 rtp_hdr->ssrc = htonl(ssrc);
517
518 /* Apply the offset and store it back to the packet.
519 * This won't change anything if the offset is 0, so the conditional is
520 * omitted. */
521 seq += state->seq_offset;
522 rtp_hdr->sequence = htons(seq);
523 timestamp += state->timestamp_offset;
524 rtp_hdr->timestamp = htonl(timestamp);
525
526 /* Check again, whether the timestamps are still valid */
527 if (state->out_stream.ssrc == ssrc)
528 check_rtp_timestamp(endp, state, &state->out_stream, rtp_end,
529 addr, seq, timestamp, "output",
530 &state->out_stream.last_tsdelta);
531
532 /* Save output values */
533 state->out_stream.last_seq = seq;
534 state->out_stream.last_timestamp = timestamp;
535 state->out_stream.ssrc = ssrc;
536
537 if (payload < 0)
538 return;
539
540#if 0
541 DEBUGP(DLMGCP, "Payload hdr payload %u -> endp payload %u\n",
542 rtp_hdr->payload_type, payload);
543 rtp_hdr->payload_type = payload;
544#endif
545}
546
547/*
548 * The below code is for dispatching. We have a dedicated port for
549 * the data coming from the net and one to discover the BTS.
550 */
551static int forward_data(int fd, struct mgcp_rtp_tap *tap, const char *buf, int len)
552{
553 if (!tap->enabled)
554 return 0;
555
556 return sendto(fd, buf, len, 0,
557 (struct sockaddr *)&tap->forward, sizeof(tap->forward));
558}
559
560static int mgcp_send_transcoder(struct mgcp_rtp_end *end,
561 struct mgcp_config *cfg, int is_rtp,
562 const char *buf, int len)
563{
564 int rc;
565 int port;
566 struct sockaddr_in addr;
567
568 port = is_rtp ? end->rtp_port : end->rtcp_port;
569
570 addr.sin_family = AF_INET;
571 addr.sin_addr = cfg->transcoder_in;
572 addr.sin_port = port;
573
574 rc = sendto(is_rtp ?
575 end->rtp.fd :
576 end->rtcp.fd, buf, len, 0,
577 (struct sockaddr *) &addr, sizeof(addr));
578
579 if (rc != len)
580 LOGP(DLMGCP, LOGL_ERROR,
581 "Failed to send data to the transcoder: %s\n",
582 strerror(errno));
583
584 return rc;
585}
586
Pau Espin Pedrolba61f682018-05-16 14:03:38 +0200587void mgcp_dejitter_udp_send(struct msgb *msg, void *data)
588{
589 struct mgcp_rtp_end *rtp_end = (struct mgcp_rtp_end *) data;
590
591 int rc = mgcp_udp_send(rtp_end->rtp.fd, &rtp_end->addr,
592 rtp_end->rtp_port, (char*) msg->data, msg->len);
593 if (rc != msg->len)
594 LOGP(DLMGCP, LOGL_ERROR,
595 "Failed to send data after jitter buffer: %d\n", rc);
596 msgb_free(msg);
597}
598
599static int enqueue_dejitter(struct osmo_jibuf *jb, struct mgcp_rtp_end *rtp_end, char *buf, int len)
600{
601 struct msgb *msg;
602 msg = msgb_alloc(len, "mgcp-jibuf");
603 if (!msg)
604 return -1;
605
606 memcpy(msg->data, buf, len);
607 msgb_put(msg, len);
608
609 if (osmo_jibuf_enqueue(jb, msg) < 0) {
610 rtp_end->dropped_packets += 1;
611 msgb_free(msg);
612 }
613
614 return len;
615}
616
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200617int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp,
618 struct sockaddr_in *addr, char *buf, int rc)
619{
620 struct mgcp_trunk_config *tcfg = endp->tcfg;
621 struct mgcp_rtp_end *rtp_end;
622 struct mgcp_rtp_state *rtp_state;
623 int tap_idx;
Pau Espin Pedrolba61f682018-05-16 14:03:38 +0200624 struct osmo_jibuf *jb;
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200625
626 LOGP(DLMGCP, LOGL_DEBUG,
627 "endpoint %x dest %s tcfg->audio_loop %d endp->conn_mode %d (== loopback: %d)\n",
628 ENDPOINT_NUMBER(endp),
629 dest == MGCP_DEST_NET? "net" : "bts",
630 tcfg->audio_loop,
631 endp->conn_mode,
632 endp->conn_mode == MGCP_CONN_LOOPBACK);
633
634 /* For loop toggle the destination and then dispatch. */
635 if (tcfg->audio_loop)
636 dest = !dest;
637
638 /* Loop based on the conn_mode, maybe undoing the above */
639 if (endp->conn_mode == MGCP_CONN_LOOPBACK)
640 dest = !dest;
641
642 if (dest == MGCP_DEST_NET) {
643 rtp_end = &endp->net_end;
644 rtp_state = &endp->bts_state;
645 tap_idx = MGCP_TAP_NET_OUT;
Pau Espin Pedrolba61f682018-05-16 14:03:38 +0200646 jb = endp->bts_jb;
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200647 } else {
648 rtp_end = &endp->bts_end;
649 rtp_state = &endp->net_state;
650 tap_idx = MGCP_TAP_BTS_OUT;
Pau Espin Pedrolba61f682018-05-16 14:03:38 +0200651 jb = NULL;
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200652 }
653 LOGP(DLMGCP, LOGL_DEBUG,
654 "endpoint %x dest %s net_end %s %d %d bts_end %s %d %d rtp_end %s %d %d\n",
655 ENDPOINT_NUMBER(endp),
656 dest == MGCP_DEST_NET? "net" : "bts",
657
658 inet_ntoa(endp->net_end.addr),
659 ntohs(endp->net_end.rtp_port),
660 ntohs(endp->net_end.rtcp_port),
661
662 inet_ntoa(endp->bts_end.addr),
663 ntohs(endp->bts_end.rtp_port),
664 ntohs(endp->bts_end.rtcp_port),
665
666 inet_ntoa(rtp_end->addr),
667 ntohs(rtp_end->rtp_port),
668 ntohs(rtp_end->rtcp_port)
669 );
670
671 if (!rtp_end->output_enabled) {
672 rtp_end->dropped_packets += 1;
673 LOGP(DLMGCP, LOGL_DEBUG,
674 "endpoint %x output disabled, drop to %s %s %d %d\n",
675 ENDPOINT_NUMBER(endp),
676 dest == MGCP_DEST_NET? "net" : "bts",
677 inet_ntoa(rtp_end->addr),
678 ntohs(rtp_end->rtp_port),
679 ntohs(rtp_end->rtcp_port)
680 );
681 } else if (is_rtp) {
682 int cont;
683 int nbytes = 0;
684 int len = rc;
685 do {
686 cont = endp->cfg->rtp_processing_cb(endp, rtp_end,
687 buf, &len, RTP_BUF_SIZE);
688 if (cont < 0)
689 break;
690
691 mgcp_patch_and_count(endp, rtp_state, rtp_end, addr, buf, len);
692 LOGP(DLMGCP, LOGL_DEBUG,
693 "endpoint %x process/send to %s %s %d %d\n",
694 ENDPOINT_NUMBER(endp),
695 (dest == MGCP_DEST_NET)? "net" : "bts",
696 inet_ntoa(rtp_end->addr),
697 ntohs(rtp_end->rtp_port),
698 ntohs(rtp_end->rtcp_port)
699 );
700 forward_data(rtp_end->rtp.fd, &endp->taps[tap_idx],
701 buf, len);
702
703 /* FIXME: HACK HACK HACK. See OS#2459.
704 * The ip.access nano3G needs the first RTP payload's first two bytes to read hex
705 * 'e400', or it will reject the RAB assignment. It seems to not harm other femto
706 * cells (as long as we patch only the first RTP payload in each stream).
707 */
708 if (tap_idx == MGCP_TAP_BTS_OUT
709 && !rtp_state->patched_first_rtp_payload) {
710 uint8_t *data = (uint8_t*)&buf[12];
711 data[0] = 0xe4;
712 data[1] = 0x00;
713 rtp_state->patched_first_rtp_payload = true;
714 }
715
Pau Espin Pedrolba61f682018-05-16 14:03:38 +0200716 if (jb)
717 rc = enqueue_dejitter(jb, rtp_end, buf, len);
718 else
719 rc = mgcp_udp_send(rtp_end->rtp.fd,
720 &rtp_end->addr,
721 rtp_end->rtp_port, buf, len);
Neels Hofmeyre9920f22017-07-10 15:07:22 +0200722
723 if (rc <= 0)
724 return rc;
725 nbytes += rc;
726 len = cont;
727 } while (len > 0);
728 return nbytes;
729 } else if (!tcfg->omit_rtcp) {
730 LOGP(DLMGCP, LOGL_DEBUG,
731 "endpoint %x send to %s %s %d %d\n",
732 ENDPOINT_NUMBER(endp),
733 dest == MGCP_DEST_NET? "net" : "bts",
734 inet_ntoa(rtp_end->addr),
735 ntohs(rtp_end->rtp_port),
736 ntohs(rtp_end->rtcp_port)
737 );
738
739 return mgcp_udp_send(rtp_end->rtcp.fd,
740 &rtp_end->addr,
741 rtp_end->rtcp_port, buf, rc);
742 }
743
744 return 0;
745}
746
747static int receive_from(struct mgcp_endpoint *endp, int fd, struct sockaddr_in *addr,
748 char *buf, int bufsize)
749{
750 int rc;
751 socklen_t slen = sizeof(*addr);
752
753 rc = recvfrom(fd, buf, bufsize, 0,
754 (struct sockaddr *) addr, &slen);
755 if (rc < 0) {
756 LOGP(DLMGCP, LOGL_ERROR, "Failed to receive message on: 0x%x errno: %d/%s\n",
757 ENDPOINT_NUMBER(endp), errno, strerror(errno));
758 return -1;
759 }
760
761 /* do not forward aynthing... maybe there is a packet from the bts */
762 if (!endp->allocated)
763 return -1;
764
765 #warning "Slight spec violation. With connection mode recvonly we should attempt to forward."
766
767 return rc;
768}
769
770static int rtp_data_net(struct osmo_fd *fd, unsigned int what)
771{
772 char buf[RTP_BUF_SIZE];
773 struct sockaddr_in addr;
774 struct mgcp_endpoint *endp;
775 int rc, proto;
776
777 endp = (struct mgcp_endpoint *) fd->data;
778
779 rc = receive_from(endp, fd->fd, &addr, buf, sizeof(buf));
780 if (rc <= 0)
781 return -1;
782
783 LOGP(DLMGCP, LOGL_DEBUG,
784 "endpoint %x",
785 ENDPOINT_NUMBER(endp));
786 LOGPC(DLMGCP, LOGL_DEBUG,
787 " from net %s %d",
788 inet_ntoa(addr.sin_addr),
789 ntohs(addr.sin_port));
790 LOGPC(DLMGCP, LOGL_DEBUG,
791 " net_end %s %d %d",
792 inet_ntoa(endp->net_end.addr),
793 ntohs(endp->net_end.rtp_port),
794 ntohs(endp->net_end.rtcp_port));
795 LOGPC(DLMGCP, LOGL_DEBUG,
796 " bts_end %s %d %d\n",
797 inet_ntoa(endp->bts_end.addr),
798 ntohs(endp->bts_end.rtp_port),
799 ntohs(endp->bts_end.rtcp_port)
800 );
801
802 if (memcmp(&addr.sin_addr, &endp->net_end.addr, sizeof(addr.sin_addr)) != 0) {
803 LOGP(DLMGCP, LOGL_ERROR,
804 "rtp_data_net: Endpoint 0x%x data from wrong address %s vs. ",
805 ENDPOINT_NUMBER(endp), inet_ntoa(addr.sin_addr));
806 LOGPC(DLMGCP, LOGL_ERROR,
807 "%s\n", inet_ntoa(endp->net_end.addr));
808 return -1;
809 }
810
811 switch(endp->type) {
812 case MGCP_RTP_DEFAULT:
813 case MGCP_RTP_TRANSCODED:
814 if (endp->net_end.rtp_port != addr.sin_port &&
815 endp->net_end.rtcp_port != addr.sin_port) {
816 LOGP(DLMGCP, LOGL_ERROR,
817 "rtp_data_net: Data from wrong source port %d on 0x%x\n",
818 ntohs(addr.sin_port), ENDPOINT_NUMBER(endp));
819 return -1;
820 }
821 break;
822 case MGCP_OSMUX_BSC:
823 case MGCP_OSMUX_BSC_NAT:
824 break;
825 }
826
827 LOGP(DLMGCP, LOGL_DEBUG,
828 "rtp_data_net: Endpoint %x data from %s %d\n",
829 ENDPOINT_NUMBER(endp),
830 inet_ntoa(addr.sin_addr),
831 ntohs(addr.sin_port));
832
833 /* throw away the dummy message */
834 if (rc == 1 && buf[0] == MGCP_DUMMY_LOAD) {
835 LOGP(DLMGCP, LOGL_NOTICE, "Filtered dummy from network on 0x%x\n",
836 ENDPOINT_NUMBER(endp));
837 return 0;
838 }
839
840 proto = fd == &endp->net_end.rtp ? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;
841 endp->net_end.packets += 1;
842 endp->net_end.octets += rc;
843
844 forward_data(fd->fd, &endp->taps[MGCP_TAP_NET_IN], buf, rc);
845
846 switch (endp->type) {
847 case MGCP_RTP_DEFAULT:
848 return mgcp_send(endp, MGCP_DEST_BTS, proto == MGCP_PROTO_RTP,
849 &addr, buf, rc);
850 case MGCP_RTP_TRANSCODED:
851 return mgcp_send_transcoder(&endp->trans_net, endp->cfg,
852 proto == MGCP_PROTO_RTP, buf, rc);
853 case MGCP_OSMUX_BSC_NAT:
854 return osmux_xfrm_to_osmux(MGCP_DEST_BTS, buf, rc, endp);
855 case MGCP_OSMUX_BSC: /* Should not happen */
856 break;
857 }
858
859 LOGP(DLMGCP, LOGL_ERROR, "Bad MGCP type %u on endpoint %u\n",
860 endp->type, ENDPOINT_NUMBER(endp));
861 return 0;
862}
863
864static void discover_bts(struct mgcp_endpoint *endp, int proto, struct sockaddr_in *addr)
865{
866 struct mgcp_config *cfg = endp->cfg;
867
868 if (proto == MGCP_PROTO_RTP && endp->bts_end.rtp_port == 0) {
869 if (!cfg->bts_ip ||
870 memcmp(&addr->sin_addr,
871 &cfg->bts_in, sizeof(cfg->bts_in)) == 0 ||
872 memcmp(&addr->sin_addr,
873 &endp->bts_end.addr, sizeof(endp->bts_end.addr)) == 0) {
874
875 endp->bts_end.rtp_port = addr->sin_port;
876 endp->bts_end.addr = addr->sin_addr;
877
878 LOGP(DLMGCP, LOGL_NOTICE,
879 "Found BTS for endpoint: 0x%x on port: %d/%d of %s\n",
880 ENDPOINT_NUMBER(endp), ntohs(endp->bts_end.rtp_port),
881 ntohs(endp->bts_end.rtcp_port), inet_ntoa(addr->sin_addr));
882 }
883 } else if (proto == MGCP_PROTO_RTCP && endp->bts_end.rtcp_port == 0) {
884 if (memcmp(&endp->bts_end.addr, &addr->sin_addr,
885 sizeof(endp->bts_end.addr)) == 0) {
886 endp->bts_end.rtcp_port = addr->sin_port;
887 }
888 }
889}
890
891static int rtp_data_bts(struct osmo_fd *fd, unsigned int what)
892{
893 char buf[RTP_BUF_SIZE];
894 struct sockaddr_in addr;
895 struct mgcp_endpoint *endp;
896 int rc, proto;
897
898 endp = (struct mgcp_endpoint *) fd->data;
899
900 rc = receive_from(endp, fd->fd, &addr, buf, sizeof(buf));
901 if (rc <= 0)
902 return -1;
903
904 proto = fd == &endp->bts_end.rtp ? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;
905
906 /* We have no idea who called us, maybe it is the BTS. */
907 /* it was the BTS... */
908 discover_bts(endp, proto, &addr);
909
910 if (memcmp(&endp->bts_end.addr, &addr.sin_addr, sizeof(addr.sin_addr)) != 0) {
911 LOGP(DLMGCP, LOGL_ERROR,
912 "rtp_data_bts: Data from wrong bts %s on 0x%x\n",
913 inet_ntoa(addr.sin_addr), ENDPOINT_NUMBER(endp));
914 return -1;
915 }
916
917 if (endp->bts_end.rtp_port != addr.sin_port &&
918 endp->bts_end.rtcp_port != addr.sin_port) {
919 LOGP(DLMGCP, LOGL_ERROR,
920 "rtp_data_bts: ata from wrong bts source port %d on 0x%x\n",
921 ntohs(addr.sin_port), ENDPOINT_NUMBER(endp));
922 return -1;
923 }
924
925 LOGP(DLMGCP, LOGL_DEBUG,
926 "rtp_data_bts: Endpoint %x data from %s %d\n",
927 ENDPOINT_NUMBER(endp),
928 inet_ntoa(addr.sin_addr),
929 ntohs(addr.sin_port));
930
931 /* throw away the dummy message */
932 if (rc == 1 && buf[0] == MGCP_DUMMY_LOAD) {
933 LOGP(DLMGCP, LOGL_NOTICE, "Filtered dummy from bts on 0x%x\n",
934 ENDPOINT_NUMBER(endp));
935 return 0;
936 }
937
938 /* do this before the loop handling */
939 endp->bts_end.packets += 1;
940 endp->bts_end.octets += rc;
941
942 forward_data(fd->fd, &endp->taps[MGCP_TAP_BTS_IN], buf, rc);
943
944 switch (endp->type) {
945 case MGCP_RTP_DEFAULT:
946 LOGP(DLMGCP, LOGL_DEBUG,
947 "rtp_data_bts: Endpoint %x MGCP_RTP_DEFAULT\n",
948 ENDPOINT_NUMBER(endp));
949 return mgcp_send(endp, MGCP_DEST_NET, proto == MGCP_PROTO_RTP,
950 &addr, buf, rc);
951 case MGCP_RTP_TRANSCODED:
952 return mgcp_send_transcoder(&endp->trans_bts, endp->cfg,
953 proto == MGCP_PROTO_RTP, buf, rc);
954 case MGCP_OSMUX_BSC:
955 /* OSMUX translation: BTS -> BSC */
956 return osmux_xfrm_to_osmux(MGCP_DEST_NET, buf, rc, endp);
957 case MGCP_OSMUX_BSC_NAT:
958 break; /* Should not happen */
959 }
960
961 LOGP(DLMGCP, LOGL_ERROR, "Bad MGCP type %u on endpoint %u\n",
962 endp->type, ENDPOINT_NUMBER(endp));
963 return 0;
964}
965
966static int rtp_data_transcoder(struct mgcp_rtp_end *end, struct mgcp_endpoint *_endp,
967 int dest, struct osmo_fd *fd)
968{
969 char buf[RTP_BUF_SIZE];
970 struct sockaddr_in addr;
971 struct mgcp_config *cfg;
972 int rc, proto;
973
974 cfg = _endp->cfg;
975 rc = receive_from(_endp, fd->fd, &addr, buf, sizeof(buf));
976 if (rc <= 0)
977 return -1;
978
979 proto = fd == &end->rtp ? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;
980
981 if (memcmp(&addr.sin_addr, &cfg->transcoder_in, sizeof(addr.sin_addr)) != 0) {
982 LOGP(DLMGCP, LOGL_ERROR,
983 "Data not coming from transcoder dest: %d %s on 0x%x\n",
984 dest, inet_ntoa(addr.sin_addr), ENDPOINT_NUMBER(_endp));
985 return -1;
986 }
987
988 if (end->rtp_port != addr.sin_port &&
989 end->rtcp_port != addr.sin_port) {
990 LOGP(DLMGCP, LOGL_ERROR,
991 "Data from wrong transcoder dest %d source port %d on 0x%x\n",
992 dest, ntohs(addr.sin_port), ENDPOINT_NUMBER(_endp));
993 return -1;
994 }
995
996 /* throw away the dummy message */
997 if (rc == 1 && buf[0] == MGCP_DUMMY_LOAD) {
998 LOGP(DLMGCP, LOGL_NOTICE, "Filtered dummy from transcoder dest %d on 0x%x\n",
999 dest, ENDPOINT_NUMBER(_endp));
1000 return 0;
1001 }
1002
1003 end->packets += 1;
1004 return mgcp_send(_endp, dest, proto == MGCP_PROTO_RTP, &addr, buf, rc);
1005}
1006
1007static int rtp_data_trans_net(struct osmo_fd *fd, unsigned int what)
1008{
1009 struct mgcp_endpoint *endp;
1010 endp = (struct mgcp_endpoint *) fd->data;
1011
1012 return rtp_data_transcoder(&endp->trans_net, endp, MGCP_DEST_NET, fd);
1013}
1014
1015static int rtp_data_trans_bts(struct osmo_fd *fd, unsigned int what)
1016{
1017 struct mgcp_endpoint *endp;
1018 endp = (struct mgcp_endpoint *) fd->data;
1019
1020 return rtp_data_transcoder(&endp->trans_bts, endp, MGCP_DEST_BTS, fd);
1021}
1022
1023int mgcp_create_bind(const char *source_addr, struct osmo_fd *fd, int port)
1024{
1025 struct sockaddr_in addr;
1026 int on = 1;
1027
1028 fd->fd = socket(AF_INET, SOCK_DGRAM, 0);
1029 if (fd->fd < 0) {
1030 LOGP(DLMGCP, LOGL_ERROR, "Failed to create UDP port.\n");
1031 return -1;
1032 }
1033
1034 setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
1035 memset(&addr, 0, sizeof(addr));
1036 addr.sin_family = AF_INET;
1037 addr.sin_port = htons(port);
1038 inet_aton(source_addr, &addr.sin_addr);
1039
1040 if (bind(fd->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1041 close(fd->fd);
1042 fd->fd = -1;
1043 return -1;
1044 }
1045
1046 return 0;
1047}
1048
1049int mgcp_set_ip_tos(int fd, int tos)
1050{
1051 int ret;
1052 ret = setsockopt(fd, IPPROTO_IP, IP_TOS,
1053 &tos, sizeof(tos));
1054 return ret != 0;
1055}
1056
1057static int bind_rtp(struct mgcp_config *cfg, const char *source_addr,
1058 struct mgcp_rtp_end *rtp_end, int endpno)
1059{
1060 if (mgcp_create_bind(source_addr, &rtp_end->rtp,
1061 rtp_end->local_port) != 0) {
1062 LOGP(DLMGCP, LOGL_ERROR, "Failed to create RTP port: %s:%d on 0x%x\n",
1063 source_addr, rtp_end->local_port, endpno);
1064 goto cleanup0;
1065 }
1066
1067 if (mgcp_create_bind(source_addr, &rtp_end->rtcp,
1068 rtp_end->local_port + 1) != 0) {
1069 LOGP(DLMGCP, LOGL_ERROR, "Failed to create RTCP port: %s:%d on 0x%x\n",
1070 source_addr, rtp_end->local_port + 1, endpno);
1071 goto cleanup1;
1072 }
1073
1074 mgcp_set_ip_tos(rtp_end->rtp.fd, cfg->endp_dscp);
1075 mgcp_set_ip_tos(rtp_end->rtcp.fd, cfg->endp_dscp);
1076
1077 rtp_end->rtp.when = BSC_FD_READ;
1078 if (osmo_fd_register(&rtp_end->rtp) != 0) {
1079 LOGP(DLMGCP, LOGL_ERROR, "Failed to register RTP port %d on 0x%x\n",
1080 rtp_end->local_port, endpno);
1081 goto cleanup2;
1082 }
1083
1084 rtp_end->rtcp.when = BSC_FD_READ;
1085 if (osmo_fd_register(&rtp_end->rtcp) != 0) {
1086 LOGP(DLMGCP, LOGL_ERROR, "Failed to register RTCP port %d on 0x%x\n",
1087 rtp_end->local_port + 1, endpno);
1088 goto cleanup3;
1089 }
1090
1091 return 0;
1092
1093cleanup3:
1094 osmo_fd_unregister(&rtp_end->rtp);
1095cleanup2:
1096 close(rtp_end->rtcp.fd);
1097 rtp_end->rtcp.fd = -1;
1098cleanup1:
1099 close(rtp_end->rtp.fd);
1100 rtp_end->rtp.fd = -1;
1101cleanup0:
1102 return -1;
1103}
1104
1105static int int_bind(const char *port,
1106 struct mgcp_rtp_end *end, int (*cb)(struct osmo_fd *, unsigned),
1107 struct mgcp_endpoint *_endp,
1108 const char *source_addr, int rtp_port)
1109{
1110 if (end->rtp.fd != -1 || end->rtcp.fd != -1) {
1111 LOGP(DLMGCP, LOGL_ERROR, "Previous %s was still bound on %d\n",
1112 port, ENDPOINT_NUMBER(_endp));
1113 mgcp_free_rtp_port(end);
1114 }
1115
1116 end->local_port = rtp_port;
1117 end->rtp.cb = cb;
1118 end->rtp.data = _endp;
1119 end->rtcp.data = _endp;
1120 end->rtcp.cb = cb;
1121 return bind_rtp(_endp->cfg, source_addr, end, ENDPOINT_NUMBER(_endp));
1122}
1123
1124int mgcp_bind_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
1125{
1126 return int_bind("bts-port", &endp->bts_end,
1127 rtp_data_bts, endp,
1128 mgcp_bts_src_addr(endp), rtp_port);
1129}
1130
1131int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
1132{
1133 return int_bind("net-port", &endp->net_end,
1134 rtp_data_net, endp,
1135 mgcp_net_src_addr(endp), rtp_port);
1136}
1137
1138int mgcp_bind_trans_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
1139{
1140 return int_bind("trans-net", &endp->trans_net,
1141 rtp_data_trans_net, endp,
1142 endp->cfg->source_addr, rtp_port);
1143}
1144
1145int mgcp_bind_trans_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
1146{
1147 return int_bind("trans-bts", &endp->trans_bts,
1148 rtp_data_trans_bts, endp,
1149 endp->cfg->source_addr, rtp_port);
1150}
1151
1152int mgcp_free_rtp_port(struct mgcp_rtp_end *end)
1153{
1154 if (end->rtp.fd != -1) {
1155 close(end->rtp.fd);
1156 end->rtp.fd = -1;
1157 osmo_fd_unregister(&end->rtp);
1158 }
1159
1160 if (end->rtcp.fd != -1) {
1161 close(end->rtcp.fd);
1162 end->rtcp.fd = -1;
1163 osmo_fd_unregister(&end->rtcp);
1164 }
1165
1166 return 0;
1167}
1168
1169
1170void mgcp_state_calc_loss(struct mgcp_rtp_state *state,
1171 struct mgcp_rtp_end *end, uint32_t *expected,
1172 int *loss)
1173{
1174 *expected = state->stats_cycles + state->stats_max_seq;
1175 *expected = *expected - state->stats_base_seq + 1;
1176
1177 if (!state->stats_initialized) {
1178 *expected = 0;
1179 *loss = 0;
1180 return;
1181 }
1182
1183 /*
1184 * Make sure the sign is correct and use the biggest
1185 * positive/negative number that fits.
1186 */
1187 *loss = *expected - end->packets;
1188 if (*expected < end->packets) {
1189 if (*loss > 0)
1190 *loss = INT_MIN;
1191 } else {
1192 if (*loss < 0)
1193 *loss = INT_MAX;
1194 }
1195}
1196
1197uint32_t mgcp_state_calc_jitter(struct mgcp_rtp_state *state)
1198{
1199 if (!state->stats_initialized)
1200 return 0;
1201 return state->stats_jitter >> 4;
1202}