aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/mgcp_internal.h4
-rw-r--r--openbsc/src/libmgcp/mgcp_network.c23
-rw-r--r--openbsc/src/libmgcp/mgcp_protocol.c12
-rw-r--r--openbsc/tests/mgcp/mgcp_test.c16
-rw-r--r--openbsc/tests/mgcp/mgcp_test.ok6
5 files changed, 49 insertions, 12 deletions
diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h
index 8b6a56be8..0b52c1c06 100644
--- a/openbsc/include/openbsc/mgcp_internal.h
+++ b/openbsc/include/openbsc/mgcp_internal.h
@@ -77,6 +77,10 @@ struct mgcp_rtp_end {
/* per endpoint data */
int payload_type;
+ uint32_t rate;
+ uint32_t frame_duration_num;
+ uint32_t frame_duration_den;
+ int frames_per_packet;
char *fmtp_extra;
/*
diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c
index 72d0a5c32..75d39c195 100644
--- a/openbsc/src/libmgcp/mgcp_network.c
+++ b/openbsc/src/libmgcp/mgcp_network.c
@@ -238,15 +238,30 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta
state->transit = arrival_time - timestamp;
state->out_stream = state->in_stream;
} else if (state->in_stream.ssrc != rtp_hdr->ssrc) {
+ int32_t tsdelta = state->out_stream.last_tsdelta;
+ if (tsdelta == 0) {
+ tsdelta = rtp_end->rate * rtp_end->frames_per_packet *
+ rtp_end->frame_duration_num /
+ rtp_end->frame_duration_den;
+ LOGP(DMGCP, LOGL_NOTICE,
+ "Computed timestamp delta %d based on "
+ "rate %d, num frames %d, frame duration %d/%d\n",
+ tsdelta, rtp_end->rate, rtp_end->frames_per_packet,
+ rtp_end->frame_duration_num,
+ rtp_end->frame_duration_den);
+ }
state->in_stream.ssrc = rtp_hdr->ssrc;
state->seq_offset = (state->out_stream.last_seq + 1) - seq;
- state->timestamp_offset = state->out_stream.last_timestamp - timestamp;
+ state->timestamp_offset =
+ (state->out_stream.last_timestamp + tsdelta) - timestamp;
state->patch = endp->allow_patch;
LOGP(DMGCP, LOGL_NOTICE,
- "The SSRC changed on 0x%x SSRC: %u offset: %d from %s:%d in %d\n",
+ "The SSRC changed on 0x%x SSRC: %u offset: %d tsdelta: %d "
+ "from %s:%d in %d\n",
ENDPOINT_NUMBER(endp), state->in_stream.ssrc,
- state->seq_offset, inet_ntoa(addr->sin_addr),
- ntohs(addr->sin_port), endp->conn_mode);
+ state->seq_offset, tsdelta,
+ inet_ntoa(addr->sin_addr), ntohs(addr->sin_port),
+ endp->conn_mode);
state->in_stream.last_tsdelta = 0;
} else {
diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c
index aec2cb0a4..70964958a 100644
--- a/openbsc/src/libmgcp/mgcp_protocol.c
+++ b/openbsc/src/libmgcp/mgcp_protocol.c
@@ -40,6 +40,12 @@
for (line = strtok_r(NULL, "\r\n", &save); line;\
line = strtok_r(NULL, "\r\n", &save))
+/* Assume audio frame length of 20ms */
+#define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20
+#define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000
+#define DEFAULT_RTP_AUDIO_FRAMES_PER_PACKET 1
+#define DEFAULT_RTP_AUDIO_DEFAULT_RATE 8000
+
static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end);
struct mgcp_parse_data {
@@ -965,6 +971,12 @@ static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end)
end->local_alloc = -1;
talloc_free(end->fmtp_extra);
end->fmtp_extra = NULL;
+
+ /* Set default values */
+ end->frame_duration_num = DEFAULT_RTP_AUDIO_FRAME_DUR_NUM;
+ end->frame_duration_den = DEFAULT_RTP_AUDIO_FRAME_DUR_DEN;
+ end->frames_per_packet = DEFAULT_RTP_AUDIO_FRAMES_PER_PACKET;
+ end->rate = DEFAULT_RTP_AUDIO_DEFAULT_RATE;
}
static void mgcp_rtp_end_init(struct mgcp_rtp_end *end)
diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c
index b2d20b45b..d36aaa8c6 100644
--- a/openbsc/tests/mgcp/mgcp_test.c
+++ b/openbsc/tests/mgcp/mgcp_test.c
@@ -417,7 +417,7 @@ static void test_packet_error_detection(void)
struct mgcp_trunk_config trunk;
struct mgcp_endpoint endp;
struct mgcp_rtp_state state;
- struct mgcp_rtp_end rtp;
+ struct mgcp_rtp_end *rtp = &endp.net_end;
struct sockaddr_in addr = {0};
char buffer[4096];
@@ -426,14 +426,20 @@ static void test_packet_error_detection(void)
memset(&trunk, 0, sizeof(trunk));
memset(&endp, 0, sizeof(endp));
memset(&state, 0, sizeof(state));
- memset(&rtp, 0, sizeof(rtp));
trunk.number_endpoints = 1;
trunk.endpoints = &endp;
+ endp.tcfg = &trunk;
+
+ /* This doesn't free endp but resets/frees all fields of the structure
+ * and invokes mgcp_rtp_end_reset() for each mgcp_rtp_end. OTOH, it
+ * expects valid pointer fields (either NULL or talloc'ed), so the
+ * memset is still needed. It also requires that endp.tcfg and
+ * trunk.endpoints are set up properly. */
+ mgcp_free_endp(&endp);
- rtp.payload_type = 98;
+ rtp->payload_type = 98;
endp.allow_patch = 1;
- endp.tcfg = &trunk;
for (i = 0; i < ARRAY_SIZE(test_rtp_packets1); ++i) {
struct rtp_packet_info *info = test_rtp_packets1 + i;
@@ -442,7 +448,7 @@ static void test_packet_error_detection(void)
OSMO_ASSERT(info->len >= 0);
memmove(buffer, info->data, info->len);
- mgcp_patch_and_count(&endp, &state, &rtp, &addr,
+ mgcp_patch_and_count(&endp, &state, rtp, &addr,
buffer, info->len);
printf("TS: %d, dTS: %d, TS Errs: in %d, out %d\n",
diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok
index 8c3fa266b..5666424bd 100644
--- a/openbsc/tests/mgcp/mgcp_test.ok
+++ b/openbsc/tests/mgcp/mgcp_test.ok
@@ -41,7 +41,7 @@ TS: 1280, dTS: 160, TS Errs: in 3, out 3
TS: 1400, dTS: 120, TS Errs: in 4, out 4
TS: 1560, dTS: 160, TS Errs: in 5, out 5
TS: 1720, dTS: 160, TS Errs: in 5, out 5
-TS: 1720, dTS: 160, TS Errs: in 5, out 6
-TS: 1880, dTS: 160, TS Errs: in 5, out 6
-TS: 2040, dTS: 160, TS Errs: in 5, out 6
+TS: 1880, dTS: 160, TS Errs: in 5, out 5
+TS: 2040, dTS: 160, TS Errs: in 5, out 5
+TS: 2200, dTS: 160, TS Errs: in 5, out 5
Done