blob: 8ccfb426993f048291075205e8172f38f28d4207 [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
587int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp,
588 struct sockaddr_in *addr, char *buf, int rc)
589{
590 struct mgcp_trunk_config *tcfg = endp->tcfg;
591 struct mgcp_rtp_end *rtp_end;
592 struct mgcp_rtp_state *rtp_state;
593 int tap_idx;
594
595 LOGP(DLMGCP, LOGL_DEBUG,
596 "endpoint %x dest %s tcfg->audio_loop %d endp->conn_mode %d (== loopback: %d)\n",
597 ENDPOINT_NUMBER(endp),
598 dest == MGCP_DEST_NET? "net" : "bts",
599 tcfg->audio_loop,
600 endp->conn_mode,
601 endp->conn_mode == MGCP_CONN_LOOPBACK);
602
603 /* For loop toggle the destination and then dispatch. */
604 if (tcfg->audio_loop)
605 dest = !dest;
606
607 /* Loop based on the conn_mode, maybe undoing the above */
608 if (endp->conn_mode == MGCP_CONN_LOOPBACK)
609 dest = !dest;
610
611 if (dest == MGCP_DEST_NET) {
612 rtp_end = &endp->net_end;
613 rtp_state = &endp->bts_state;
614 tap_idx = MGCP_TAP_NET_OUT;
615 } else {
616 rtp_end = &endp->bts_end;
617 rtp_state = &endp->net_state;
618 tap_idx = MGCP_TAP_BTS_OUT;
619 }
620 LOGP(DLMGCP, LOGL_DEBUG,
621 "endpoint %x dest %s net_end %s %d %d bts_end %s %d %d rtp_end %s %d %d\n",
622 ENDPOINT_NUMBER(endp),
623 dest == MGCP_DEST_NET? "net" : "bts",
624
625 inet_ntoa(endp->net_end.addr),
626 ntohs(endp->net_end.rtp_port),
627 ntohs(endp->net_end.rtcp_port),
628
629 inet_ntoa(endp->bts_end.addr),
630 ntohs(endp->bts_end.rtp_port),
631 ntohs(endp->bts_end.rtcp_port),
632
633 inet_ntoa(rtp_end->addr),
634 ntohs(rtp_end->rtp_port),
635 ntohs(rtp_end->rtcp_port)
636 );
637
638 if (!rtp_end->output_enabled) {
639 rtp_end->dropped_packets += 1;
640 LOGP(DLMGCP, LOGL_DEBUG,
641 "endpoint %x output disabled, drop to %s %s %d %d\n",
642 ENDPOINT_NUMBER(endp),
643 dest == MGCP_DEST_NET? "net" : "bts",
644 inet_ntoa(rtp_end->addr),
645 ntohs(rtp_end->rtp_port),
646 ntohs(rtp_end->rtcp_port)
647 );
648 } else if (is_rtp) {
649 int cont;
650 int nbytes = 0;
651 int len = rc;
652 do {
653 cont = endp->cfg->rtp_processing_cb(endp, rtp_end,
654 buf, &len, RTP_BUF_SIZE);
655 if (cont < 0)
656 break;
657
658 mgcp_patch_and_count(endp, rtp_state, rtp_end, addr, buf, len);
659 LOGP(DLMGCP, LOGL_DEBUG,
660 "endpoint %x process/send to %s %s %d %d\n",
661 ENDPOINT_NUMBER(endp),
662 (dest == MGCP_DEST_NET)? "net" : "bts",
663 inet_ntoa(rtp_end->addr),
664 ntohs(rtp_end->rtp_port),
665 ntohs(rtp_end->rtcp_port)
666 );
667 forward_data(rtp_end->rtp.fd, &endp->taps[tap_idx],
668 buf, len);
669
670 /* FIXME: HACK HACK HACK. See OS#2459.
671 * The ip.access nano3G needs the first RTP payload's first two bytes to read hex
672 * 'e400', or it will reject the RAB assignment. It seems to not harm other femto
673 * cells (as long as we patch only the first RTP payload in each stream).
674 */
675 if (tap_idx == MGCP_TAP_BTS_OUT
676 && !rtp_state->patched_first_rtp_payload) {
677 uint8_t *data = (uint8_t*)&buf[12];
678 data[0] = 0xe4;
679 data[1] = 0x00;
680 rtp_state->patched_first_rtp_payload = true;
681 }
682
683 rc = mgcp_udp_send(rtp_end->rtp.fd,
684 &rtp_end->addr,
685 rtp_end->rtp_port, buf, len);
686
687 if (rc <= 0)
688 return rc;
689 nbytes += rc;
690 len = cont;
691 } while (len > 0);
692 return nbytes;
693 } else if (!tcfg->omit_rtcp) {
694 LOGP(DLMGCP, LOGL_DEBUG,
695 "endpoint %x send to %s %s %d %d\n",
696 ENDPOINT_NUMBER(endp),
697 dest == MGCP_DEST_NET? "net" : "bts",
698 inet_ntoa(rtp_end->addr),
699 ntohs(rtp_end->rtp_port),
700 ntohs(rtp_end->rtcp_port)
701 );
702
703 return mgcp_udp_send(rtp_end->rtcp.fd,
704 &rtp_end->addr,
705 rtp_end->rtcp_port, buf, rc);
706 }
707
708 return 0;
709}
710
711static int receive_from(struct mgcp_endpoint *endp, int fd, struct sockaddr_in *addr,
712 char *buf, int bufsize)
713{
714 int rc;
715 socklen_t slen = sizeof(*addr);
716
717 rc = recvfrom(fd, buf, bufsize, 0,
718 (struct sockaddr *) addr, &slen);
719 if (rc < 0) {
720 LOGP(DLMGCP, LOGL_ERROR, "Failed to receive message on: 0x%x errno: %d/%s\n",
721 ENDPOINT_NUMBER(endp), errno, strerror(errno));
722 return -1;
723 }
724
725 /* do not forward aynthing... maybe there is a packet from the bts */
726 if (!endp->allocated)
727 return -1;
728
729 #warning "Slight spec violation. With connection mode recvonly we should attempt to forward."
730
731 return rc;
732}
733
734static int rtp_data_net(struct osmo_fd *fd, unsigned int what)
735{
736 char buf[RTP_BUF_SIZE];
737 struct sockaddr_in addr;
738 struct mgcp_endpoint *endp;
739 int rc, proto;
740
741 endp = (struct mgcp_endpoint *) fd->data;
742
743 rc = receive_from(endp, fd->fd, &addr, buf, sizeof(buf));
744 if (rc <= 0)
745 return -1;
746
747 LOGP(DLMGCP, LOGL_DEBUG,
748 "endpoint %x",
749 ENDPOINT_NUMBER(endp));
750 LOGPC(DLMGCP, LOGL_DEBUG,
751 " from net %s %d",
752 inet_ntoa(addr.sin_addr),
753 ntohs(addr.sin_port));
754 LOGPC(DLMGCP, LOGL_DEBUG,
755 " net_end %s %d %d",
756 inet_ntoa(endp->net_end.addr),
757 ntohs(endp->net_end.rtp_port),
758 ntohs(endp->net_end.rtcp_port));
759 LOGPC(DLMGCP, LOGL_DEBUG,
760 " bts_end %s %d %d\n",
761 inet_ntoa(endp->bts_end.addr),
762 ntohs(endp->bts_end.rtp_port),
763 ntohs(endp->bts_end.rtcp_port)
764 );
765
766 if (memcmp(&addr.sin_addr, &endp->net_end.addr, sizeof(addr.sin_addr)) != 0) {
767 LOGP(DLMGCP, LOGL_ERROR,
768 "rtp_data_net: Endpoint 0x%x data from wrong address %s vs. ",
769 ENDPOINT_NUMBER(endp), inet_ntoa(addr.sin_addr));
770 LOGPC(DLMGCP, LOGL_ERROR,
771 "%s\n", inet_ntoa(endp->net_end.addr));
772 return -1;
773 }
774
775 switch(endp->type) {
776 case MGCP_RTP_DEFAULT:
777 case MGCP_RTP_TRANSCODED:
778 if (endp->net_end.rtp_port != addr.sin_port &&
779 endp->net_end.rtcp_port != addr.sin_port) {
780 LOGP(DLMGCP, LOGL_ERROR,
781 "rtp_data_net: Data from wrong source port %d on 0x%x\n",
782 ntohs(addr.sin_port), ENDPOINT_NUMBER(endp));
783 return -1;
784 }
785 break;
786 case MGCP_OSMUX_BSC:
787 case MGCP_OSMUX_BSC_NAT:
788 break;
789 }
790
791 LOGP(DLMGCP, LOGL_DEBUG,
792 "rtp_data_net: Endpoint %x data from %s %d\n",
793 ENDPOINT_NUMBER(endp),
794 inet_ntoa(addr.sin_addr),
795 ntohs(addr.sin_port));
796
797 /* throw away the dummy message */
798 if (rc == 1 && buf[0] == MGCP_DUMMY_LOAD) {
799 LOGP(DLMGCP, LOGL_NOTICE, "Filtered dummy from network on 0x%x\n",
800 ENDPOINT_NUMBER(endp));
801 return 0;
802 }
803
804 proto = fd == &endp->net_end.rtp ? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;
805 endp->net_end.packets += 1;
806 endp->net_end.octets += rc;
807
808 forward_data(fd->fd, &endp->taps[MGCP_TAP_NET_IN], buf, rc);
809
810 switch (endp->type) {
811 case MGCP_RTP_DEFAULT:
812 return mgcp_send(endp, MGCP_DEST_BTS, proto == MGCP_PROTO_RTP,
813 &addr, buf, rc);
814 case MGCP_RTP_TRANSCODED:
815 return mgcp_send_transcoder(&endp->trans_net, endp->cfg,
816 proto == MGCP_PROTO_RTP, buf, rc);
817 case MGCP_OSMUX_BSC_NAT:
818 return osmux_xfrm_to_osmux(MGCP_DEST_BTS, buf, rc, endp);
819 case MGCP_OSMUX_BSC: /* Should not happen */
820 break;
821 }
822
823 LOGP(DLMGCP, LOGL_ERROR, "Bad MGCP type %u on endpoint %u\n",
824 endp->type, ENDPOINT_NUMBER(endp));
825 return 0;
826}
827
828static void discover_bts(struct mgcp_endpoint *endp, int proto, struct sockaddr_in *addr)
829{
830 struct mgcp_config *cfg = endp->cfg;
831
832 if (proto == MGCP_PROTO_RTP && endp->bts_end.rtp_port == 0) {
833 if (!cfg->bts_ip ||
834 memcmp(&addr->sin_addr,
835 &cfg->bts_in, sizeof(cfg->bts_in)) == 0 ||
836 memcmp(&addr->sin_addr,
837 &endp->bts_end.addr, sizeof(endp->bts_end.addr)) == 0) {
838
839 endp->bts_end.rtp_port = addr->sin_port;
840 endp->bts_end.addr = addr->sin_addr;
841
842 LOGP(DLMGCP, LOGL_NOTICE,
843 "Found BTS for endpoint: 0x%x on port: %d/%d of %s\n",
844 ENDPOINT_NUMBER(endp), ntohs(endp->bts_end.rtp_port),
845 ntohs(endp->bts_end.rtcp_port), inet_ntoa(addr->sin_addr));
846 }
847 } else if (proto == MGCP_PROTO_RTCP && endp->bts_end.rtcp_port == 0) {
848 if (memcmp(&endp->bts_end.addr, &addr->sin_addr,
849 sizeof(endp->bts_end.addr)) == 0) {
850 endp->bts_end.rtcp_port = addr->sin_port;
851 }
852 }
853}
854
855static int rtp_data_bts(struct osmo_fd *fd, unsigned int what)
856{
857 char buf[RTP_BUF_SIZE];
858 struct sockaddr_in addr;
859 struct mgcp_endpoint *endp;
860 int rc, proto;
861
862 endp = (struct mgcp_endpoint *) fd->data;
863
864 rc = receive_from(endp, fd->fd, &addr, buf, sizeof(buf));
865 if (rc <= 0)
866 return -1;
867
868 proto = fd == &endp->bts_end.rtp ? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;
869
870 /* We have no idea who called us, maybe it is the BTS. */
871 /* it was the BTS... */
872 discover_bts(endp, proto, &addr);
873
874 if (memcmp(&endp->bts_end.addr, &addr.sin_addr, sizeof(addr.sin_addr)) != 0) {
875 LOGP(DLMGCP, LOGL_ERROR,
876 "rtp_data_bts: Data from wrong bts %s on 0x%x\n",
877 inet_ntoa(addr.sin_addr), ENDPOINT_NUMBER(endp));
878 return -1;
879 }
880
881 if (endp->bts_end.rtp_port != addr.sin_port &&
882 endp->bts_end.rtcp_port != addr.sin_port) {
883 LOGP(DLMGCP, LOGL_ERROR,
884 "rtp_data_bts: ata from wrong bts source port %d on 0x%x\n",
885 ntohs(addr.sin_port), ENDPOINT_NUMBER(endp));
886 return -1;
887 }
888
889 LOGP(DLMGCP, LOGL_DEBUG,
890 "rtp_data_bts: Endpoint %x data from %s %d\n",
891 ENDPOINT_NUMBER(endp),
892 inet_ntoa(addr.sin_addr),
893 ntohs(addr.sin_port));
894
895 /* throw away the dummy message */
896 if (rc == 1 && buf[0] == MGCP_DUMMY_LOAD) {
897 LOGP(DLMGCP, LOGL_NOTICE, "Filtered dummy from bts on 0x%x\n",
898 ENDPOINT_NUMBER(endp));
899 return 0;
900 }
901
902 /* do this before the loop handling */
903 endp->bts_end.packets += 1;
904 endp->bts_end.octets += rc;
905
906 forward_data(fd->fd, &endp->taps[MGCP_TAP_BTS_IN], buf, rc);
907
908 switch (endp->type) {
909 case MGCP_RTP_DEFAULT:
910 LOGP(DLMGCP, LOGL_DEBUG,
911 "rtp_data_bts: Endpoint %x MGCP_RTP_DEFAULT\n",
912 ENDPOINT_NUMBER(endp));
913 return mgcp_send(endp, MGCP_DEST_NET, proto == MGCP_PROTO_RTP,
914 &addr, buf, rc);
915 case MGCP_RTP_TRANSCODED:
916 return mgcp_send_transcoder(&endp->trans_bts, endp->cfg,
917 proto == MGCP_PROTO_RTP, buf, rc);
918 case MGCP_OSMUX_BSC:
919 /* OSMUX translation: BTS -> BSC */
920 return osmux_xfrm_to_osmux(MGCP_DEST_NET, buf, rc, endp);
921 case MGCP_OSMUX_BSC_NAT:
922 break; /* Should not happen */
923 }
924
925 LOGP(DLMGCP, LOGL_ERROR, "Bad MGCP type %u on endpoint %u\n",
926 endp->type, ENDPOINT_NUMBER(endp));
927 return 0;
928}
929
930static int rtp_data_transcoder(struct mgcp_rtp_end *end, struct mgcp_endpoint *_endp,
931 int dest, struct osmo_fd *fd)
932{
933 char buf[RTP_BUF_SIZE];
934 struct sockaddr_in addr;
935 struct mgcp_config *cfg;
936 int rc, proto;
937
938 cfg = _endp->cfg;
939 rc = receive_from(_endp, fd->fd, &addr, buf, sizeof(buf));
940 if (rc <= 0)
941 return -1;
942
943 proto = fd == &end->rtp ? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;
944
945 if (memcmp(&addr.sin_addr, &cfg->transcoder_in, sizeof(addr.sin_addr)) != 0) {
946 LOGP(DLMGCP, LOGL_ERROR,
947 "Data not coming from transcoder dest: %d %s on 0x%x\n",
948 dest, inet_ntoa(addr.sin_addr), ENDPOINT_NUMBER(_endp));
949 return -1;
950 }
951
952 if (end->rtp_port != addr.sin_port &&
953 end->rtcp_port != addr.sin_port) {
954 LOGP(DLMGCP, LOGL_ERROR,
955 "Data from wrong transcoder dest %d source port %d on 0x%x\n",
956 dest, ntohs(addr.sin_port), ENDPOINT_NUMBER(_endp));
957 return -1;
958 }
959
960 /* throw away the dummy message */
961 if (rc == 1 && buf[0] == MGCP_DUMMY_LOAD) {
962 LOGP(DLMGCP, LOGL_NOTICE, "Filtered dummy from transcoder dest %d on 0x%x\n",
963 dest, ENDPOINT_NUMBER(_endp));
964 return 0;
965 }
966
967 end->packets += 1;
968 return mgcp_send(_endp, dest, proto == MGCP_PROTO_RTP, &addr, buf, rc);
969}
970
971static int rtp_data_trans_net(struct osmo_fd *fd, unsigned int what)
972{
973 struct mgcp_endpoint *endp;
974 endp = (struct mgcp_endpoint *) fd->data;
975
976 return rtp_data_transcoder(&endp->trans_net, endp, MGCP_DEST_NET, fd);
977}
978
979static int rtp_data_trans_bts(struct osmo_fd *fd, unsigned int what)
980{
981 struct mgcp_endpoint *endp;
982 endp = (struct mgcp_endpoint *) fd->data;
983
984 return rtp_data_transcoder(&endp->trans_bts, endp, MGCP_DEST_BTS, fd);
985}
986
987int mgcp_create_bind(const char *source_addr, struct osmo_fd *fd, int port)
988{
989 struct sockaddr_in addr;
990 int on = 1;
991
992 fd->fd = socket(AF_INET, SOCK_DGRAM, 0);
993 if (fd->fd < 0) {
994 LOGP(DLMGCP, LOGL_ERROR, "Failed to create UDP port.\n");
995 return -1;
996 }
997
998 setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
999 memset(&addr, 0, sizeof(addr));
1000 addr.sin_family = AF_INET;
1001 addr.sin_port = htons(port);
1002 inet_aton(source_addr, &addr.sin_addr);
1003
1004 if (bind(fd->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1005 close(fd->fd);
1006 fd->fd = -1;
1007 return -1;
1008 }
1009
1010 return 0;
1011}
1012
1013int mgcp_set_ip_tos(int fd, int tos)
1014{
1015 int ret;
1016 ret = setsockopt(fd, IPPROTO_IP, IP_TOS,
1017 &tos, sizeof(tos));
1018 return ret != 0;
1019}
1020
1021static int bind_rtp(struct mgcp_config *cfg, const char *source_addr,
1022 struct mgcp_rtp_end *rtp_end, int endpno)
1023{
1024 if (mgcp_create_bind(source_addr, &rtp_end->rtp,
1025 rtp_end->local_port) != 0) {
1026 LOGP(DLMGCP, LOGL_ERROR, "Failed to create RTP port: %s:%d on 0x%x\n",
1027 source_addr, rtp_end->local_port, endpno);
1028 goto cleanup0;
1029 }
1030
1031 if (mgcp_create_bind(source_addr, &rtp_end->rtcp,
1032 rtp_end->local_port + 1) != 0) {
1033 LOGP(DLMGCP, LOGL_ERROR, "Failed to create RTCP port: %s:%d on 0x%x\n",
1034 source_addr, rtp_end->local_port + 1, endpno);
1035 goto cleanup1;
1036 }
1037
1038 mgcp_set_ip_tos(rtp_end->rtp.fd, cfg->endp_dscp);
1039 mgcp_set_ip_tos(rtp_end->rtcp.fd, cfg->endp_dscp);
1040
1041 rtp_end->rtp.when = BSC_FD_READ;
1042 if (osmo_fd_register(&rtp_end->rtp) != 0) {
1043 LOGP(DLMGCP, LOGL_ERROR, "Failed to register RTP port %d on 0x%x\n",
1044 rtp_end->local_port, endpno);
1045 goto cleanup2;
1046 }
1047
1048 rtp_end->rtcp.when = BSC_FD_READ;
1049 if (osmo_fd_register(&rtp_end->rtcp) != 0) {
1050 LOGP(DLMGCP, LOGL_ERROR, "Failed to register RTCP port %d on 0x%x\n",
1051 rtp_end->local_port + 1, endpno);
1052 goto cleanup3;
1053 }
1054
1055 return 0;
1056
1057cleanup3:
1058 osmo_fd_unregister(&rtp_end->rtp);
1059cleanup2:
1060 close(rtp_end->rtcp.fd);
1061 rtp_end->rtcp.fd = -1;
1062cleanup1:
1063 close(rtp_end->rtp.fd);
1064 rtp_end->rtp.fd = -1;
1065cleanup0:
1066 return -1;
1067}
1068
1069static int int_bind(const char *port,
1070 struct mgcp_rtp_end *end, int (*cb)(struct osmo_fd *, unsigned),
1071 struct mgcp_endpoint *_endp,
1072 const char *source_addr, int rtp_port)
1073{
1074 if (end->rtp.fd != -1 || end->rtcp.fd != -1) {
1075 LOGP(DLMGCP, LOGL_ERROR, "Previous %s was still bound on %d\n",
1076 port, ENDPOINT_NUMBER(_endp));
1077 mgcp_free_rtp_port(end);
1078 }
1079
1080 end->local_port = rtp_port;
1081 end->rtp.cb = cb;
1082 end->rtp.data = _endp;
1083 end->rtcp.data = _endp;
1084 end->rtcp.cb = cb;
1085 return bind_rtp(_endp->cfg, source_addr, end, ENDPOINT_NUMBER(_endp));
1086}
1087
1088int mgcp_bind_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
1089{
1090 return int_bind("bts-port", &endp->bts_end,
1091 rtp_data_bts, endp,
1092 mgcp_bts_src_addr(endp), rtp_port);
1093}
1094
1095int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
1096{
1097 return int_bind("net-port", &endp->net_end,
1098 rtp_data_net, endp,
1099 mgcp_net_src_addr(endp), rtp_port);
1100}
1101
1102int mgcp_bind_trans_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
1103{
1104 return int_bind("trans-net", &endp->trans_net,
1105 rtp_data_trans_net, endp,
1106 endp->cfg->source_addr, rtp_port);
1107}
1108
1109int mgcp_bind_trans_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
1110{
1111 return int_bind("trans-bts", &endp->trans_bts,
1112 rtp_data_trans_bts, endp,
1113 endp->cfg->source_addr, rtp_port);
1114}
1115
1116int mgcp_free_rtp_port(struct mgcp_rtp_end *end)
1117{
1118 if (end->rtp.fd != -1) {
1119 close(end->rtp.fd);
1120 end->rtp.fd = -1;
1121 osmo_fd_unregister(&end->rtp);
1122 }
1123
1124 if (end->rtcp.fd != -1) {
1125 close(end->rtcp.fd);
1126 end->rtcp.fd = -1;
1127 osmo_fd_unregister(&end->rtcp);
1128 }
1129
1130 return 0;
1131}
1132
1133
1134void mgcp_state_calc_loss(struct mgcp_rtp_state *state,
1135 struct mgcp_rtp_end *end, uint32_t *expected,
1136 int *loss)
1137{
1138 *expected = state->stats_cycles + state->stats_max_seq;
1139 *expected = *expected - state->stats_base_seq + 1;
1140
1141 if (!state->stats_initialized) {
1142 *expected = 0;
1143 *loss = 0;
1144 return;
1145 }
1146
1147 /*
1148 * Make sure the sign is correct and use the biggest
1149 * positive/negative number that fits.
1150 */
1151 *loss = *expected - end->packets;
1152 if (*expected < end->packets) {
1153 if (*loss > 0)
1154 *loss = INT_MIN;
1155 } else {
1156 if (*loss < 0)
1157 *loss = INT_MAX;
1158 }
1159}
1160
1161uint32_t mgcp_state_calc_jitter(struct mgcp_rtp_state *state)
1162{
1163 if (!state->stats_initialized)
1164 return 0;
1165 return state->stats_jitter >> 4;
1166}