aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/src/libmgcp/rtp_helper.c44
-rw-r--r--openbsc/tests/mgcp/mgcp_test.c6
2 files changed, 45 insertions, 5 deletions
diff --git a/openbsc/src/libmgcp/rtp_helper.c b/openbsc/src/libmgcp/rtp_helper.c
index aafbbe52d..0ad895d72 100644
--- a/openbsc/src/libmgcp/rtp_helper.c
+++ b/openbsc/src/libmgcp/rtp_helper.c
@@ -31,6 +31,9 @@ enum RTP_EXTRA_FRAME {
/** Set a marker bit on the RFC */
RTP_EXTRA_MARKER = 0x1,
+ /** Time adjustments */
+ RTP_TS_ADJUSTMENT = 0x2,
+
/** Maybe add a bit to mention no further extension bits? */
};
@@ -105,6 +108,13 @@ static void write_compressed_big(struct reduced_rtp_hdr *reduced_hdr,
uint32_t len = msgb_l2len(rtp) - sizeof(*hdr);
uint8_t *data;
+ if (hdr->marker && rtp->cb[0] != 0) {
+ uint16_t ts = rtp->cb[0];
+ msgb_v_put(msg, RTP_TS_ADJUSTMENT);
+ msgb_put_u16(msg, htons(ts));
+ reduced_hdr->payloads += 1;
+ }
+
msgb_v_put(msg, hdr->marker ? RTP_EXTRA_MARKER : 0);
data = msgb_put(msg, len);
memcpy(data, hdr->data, len);
@@ -152,8 +162,29 @@ static int read_compressed_big(struct msgb *msg,
struct msgb *out;
int alen;
+ if (len < offset + 1) {
+ LOGP(DMGCP, LOGL_ERROR, "Can not fit Type in %d\n", i);
+ goto clean_all;
+ }
+
+#warning "TODO: Cleanup, dispatch on the header type to a specific handler"
+
+ if (rhdr->data[offset] & RTP_TS_ADJUSTMENT) {
+ uint16_t ts_adj;
+ if (len < offset + 1 + 2) {
+ LOGP(DMGCP, LOGL_ERROR,
+ "Can not fit TS adjustment payload in %d\n", i);
+ goto clean_all;
+ }
+
+ ts_adj = rhdr->data[offset + 1] << 8 | rhdr->data[offset + 2];
+ state->timestamp += ntohs(ts_adj);
+ offset += 3;
+ continue;
+ }
+
if (len < offset + 1 + sizeof(struct amr_toc)) {
- LOGP(DMGCP, LOGL_ERROR, "Can not fit RTP/AMR in %d\n", i);
+ LOGP(DMGCP, LOGL_ERROR, "Can not fit AMR payload in %d\n", i);
goto clean_all;
}
@@ -313,9 +344,18 @@ int rtp_compress(struct mgcp_rtp_compr_state *state, struct msgb *msg,
continue;
}
- if (hdr->marker)
+ if (hdr->marker) {
marker = 1;
+ uint16_t ts_off = abs(state->timestamp -
+ ntohl(hdr->timestamp));
+ if (state->timestamp != 0 && ts_off > 160) {
+ LOGP(DMGCP, LOGL_NOTICE,
+ "Timestamp jumped: %d\n", ts_off);
+ rtp->cb[0] = ts_off - 160;
+ }
+ }
+
state->generated_ssrc = ntohl(hdr->ssrc);
state->timestamp = ntohl(hdr->timestamp);
state->sequence = ntohs(hdr->sequence);
diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c
index 32f2fd649..a1d53abb2 100644
--- a/openbsc/tests/mgcp/mgcp_test.c
+++ b/openbsc/tests/mgcp/mgcp_test.c
@@ -190,9 +190,9 @@ static const struct estate test_scenarious[] = {
.timestamp = 4157324008u,
},
},
- /* this is testing the bigger encoding due the marker */
+ /* this is testing the bigger encoding due the marker, and ts adjustment */
{ .data = shorter_marker, .plen = ARRAY_SIZE(shorter_marker),
- .output_size = 17 * 3 + 7 * 1 + 3 + 4 * 1,
+ .output_size = 17 * 3 + 7 * 1 + 3 + 4 * 1 + 3,
.state = {
.last_ts = UCHAR_MAX,
.generated_ssrc = 0x6f0fb1da,
@@ -266,7 +266,7 @@ static void test_compress_one(const struct estate *edata, char *t)
abort();
}
- if (memcmp(msg->l2h, got_data->data, len) != 0) {
+ if (memcmp(msg->l2h, got_data->data, got_data->len) != 0) {
fprintf(stderr, "Wrong data for %d, '%s'\n",
i, osmo_hexdump(msg->l2h, msgb_l2len(msg)));
abort();