aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-08-03 14:35:50 +0000
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-08-03 23:57:16 +0800
commit6aa882b515f5d86c8c64e254b087cafbaae881ce (patch)
tree6b1cb6130305a9c50defa355b89b8b1c68989d3e /openbsc/src
parent3186892771fe8174e42c7e3cddc7baf4c9abb0cd (diff)
mgcp: Allow switching the audio streams, patch the header
Patch the sequence number, the SSRC and the timestamp to allow to mix various voice streams, e.g. toggling the loop during the call.
Diffstat (limited to 'openbsc/src')
-rw-r--r--openbsc/src/mgcp/mgcp_network.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/openbsc/src/mgcp/mgcp_network.c b/openbsc/src/mgcp/mgcp_network.c
index d2dbeebe4..b5e2cddf8 100644
--- a/openbsc/src/mgcp/mgcp_network.c
+++ b/openbsc/src/mgcp/mgcp_network.c
@@ -97,6 +97,7 @@ int mgcp_send_dummy(struct mgcp_endpoint *endp)
static void patch_and_count(struct mgcp_rtp_state *state, int payload, char *data, int len)
{
uint16_t seq;
+ uint32_t timestamp;
struct rtp_hdr *rtp_hdr;
if (len < sizeof(*rtp_hdr))
@@ -104,15 +105,36 @@ static void patch_and_count(struct mgcp_rtp_state *state, int payload, char *dat
rtp_hdr = (struct rtp_hdr *) data;
seq = ntohs(rtp_hdr->sequence);
+ timestamp = ntohl(rtp_hdr->timestamp);
if (!state->initialized) {
- state->seq_no = seq;
+ state->seq_no = seq - 1;
+ state->ssrc = state->orig_ssrc = rtp_hdr->ssrc;
state->initialized = 1;
- } else if (state->seq_no + 1u != seq)
- state->lost_no = abs(seq - (state->seq_no + 1));
+ state->last_timestamp = timestamp;
+ } else if (state->ssrc != rtp_hdr->ssrc) {
+ state->ssrc = rtp_hdr->ssrc;
+ state->seq_offset = (state->seq_no + 1) - seq;
+ state->timestamp_offset = state->last_timestamp - timestamp;
+ LOGP(DMGCP, LOGL_NOTICE, "The SSRC changed... SSRC: %u offset: %d\n",
+ state->ssrc, state->seq_offset);
+ }
+
+ /* apply the offset and store it back to the packet */
+ seq += state->seq_offset;
+ rtp_hdr->sequence = htons(seq);
+ rtp_hdr->ssrc = state->orig_ssrc;
+ timestamp += state->timestamp_offset;
+ rtp_hdr->timestamp = htonl(timestamp);
+
+ /* seq changed, now compare if we have lost something */
+ if (state->seq_no + 1u != seq)
+ state->lost_no = abs(seq - (state->seq_no + 1));
state->seq_no = seq;
+ state->last_timestamp = timestamp;
+
if (payload < 0)
return;