From e142ddfd7714cb067fa15216a432e758218027bf Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 7 Jul 2012 17:37:26 +0200 Subject: rtp: split osmo_rtp_parse in two functions This patch splits osmo_rtp_parse in two functions: osmo_rtp_get_hdr osmo_rtp_get_payload So we can validate corrent RTP header to access its fields. Then, obtain the payload. --- examples/rtp-udp-test-client.c | 11 ++++++----- examples/rtp-udp-test-server.c | 10 +++++----- include/osmocom/netif/rtp.h | 4 +++- src/rtp.c | 40 +++++++++++++++++++++------------------- 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/examples/rtp-udp-test-client.c b/examples/rtp-udp-test-client.c index 4163703..97ec6ff 100644 --- a/examples/rtp-udp-test-client.c +++ b/examples/rtp-udp-test-client.c @@ -39,7 +39,7 @@ static struct osmo_rtp_handle *rtp; static int read_cb(struct osmo_dgram_conn *conn) { struct msgb *msg; - int payload_type; + struct rtp_hdr *rtph; LOGP(DLINP, LOGL_DEBUG, "received message\n"); @@ -53,15 +53,16 @@ static int read_cb(struct osmo_dgram_conn *conn) LOGP(DRTP_TEST, LOGL_ERROR, "cannot receive message\n"); return -1; } - payload_type = osmo_rtp_parse(msg); - if (payload_type < 0) { + + rtph = osmo_rtp_get_hdr(msg); + if (rtph == NULL) { msgb_free(msg); LOGP(DRTP_TEST, LOGL_ERROR, "cannot parse RTP message\n"); return -1; } - LOGP(DLINP, LOGL_DEBUG, "received message with payload type: %d " - "and size: %d (%s)\n", payload_type, msg->len, msg->data); + LOGP(DLINP, LOGL_DEBUG, "received message with payload type: %d\n", + rtph->payload_type); msgb_free(msg); return 0; diff --git a/examples/rtp-udp-test-server.c b/examples/rtp-udp-test-server.c index 5efd920..2f7f291 100644 --- a/examples/rtp-udp-test-server.c +++ b/examples/rtp-udp-test-server.c @@ -38,7 +38,7 @@ int read_cb(struct osmo_dgram_conn *conn) { struct msgb *msg; char dummy_data[RTP_PT_GSM_FULL_PAYLOAD_LEN] = "payload test"; - int payload_type; + struct rtp_hdr *rtph; LOGP(DRTP_TEST, LOGL_DEBUG, "received message from datagram\n"); @@ -51,14 +51,14 @@ int read_cb(struct osmo_dgram_conn *conn) LOGP(DRTP_TEST, LOGL_ERROR, "cannot receive message\n"); return -1; } - payload_type = osmo_rtp_parse(msg); - if (payload_type < 0) { + rtph = osmo_rtp_get_hdr(msg); + if (rtph == NULL) { msgb_free(msg); LOGP(DRTP_TEST, LOGL_ERROR, "cannot parse RTP message\n"); return -1; } - LOGP(DLINP, LOGL_DEBUG, "received message with RTP payload type: %d " - "and size: %d (%s)\n", payload_type, msg->len, msg->data); + LOGP(DLINP, LOGL_DEBUG, "received message with RTP payload type: %d\n", + rtph->payload_type); /* * ... now build gsm_data_frame, set callref and msg_type based diff --git a/include/osmocom/netif/rtp.h b/include/osmocom/netif/rtp.h index e65bd15..6888cc3 100644 --- a/include/osmocom/netif/rtp.h +++ b/include/osmocom/netif/rtp.h @@ -57,7 +57,9 @@ int osmo_rtp_handle_tx_set_sequence(struct osmo_rtp_handle *h, uint16_t seq); int osmo_rtp_handle_tx_set_ssrc(struct osmo_rtp_handle *h, uint32_t ssrc); int osmo_rtp_handle_tx_set_timestamp(struct osmo_rtp_handle *h, uint32_t timestamp); -int osmo_rtp_parse(struct msgb *msg); +struct rtp_hdr *osmo_rtp_get_hdr(struct msgb *msg); +void *osmo_rtp_get_payload(struct rtp_hdr *rtph, struct msgb *msg); + struct msgb *osmo_rtp_build(struct osmo_rtp_handle *h, uint8_t payload_type, uint32_t payload_len, const void *data, uint32_t duration); /* supported RTP payload types. */ diff --git a/src/rtp.c b/src/rtp.c index 0e66502..77f3d5f 100644 --- a/src/rtp.c +++ b/src/rtp.c @@ -68,41 +68,45 @@ int osmo_rtp_handle_tx_set_timestamp(struct osmo_rtp_handle *h, uint32_t timesta return 0; } -/* decode and pull RTP header out and return payload_type. The msg->data - points to data payload after this is called. This function returns the - RTP payload type on success. */ -int osmo_rtp_parse(struct msgb *msg) +struct rtp_hdr *osmo_rtp_get_hdr(struct msgb *msg) { struct rtp_hdr *rtph = (struct rtp_hdr *)msg->data; - struct rtp_x_hdr *rtpxh; - uint8_t *payload; - int payload_len; - int x_len; - int csrc_len; if (msg->len < sizeof(struct rtp_hdr)) { DEBUGPC(DLMUX, "received RTP frame too short (len = %d)\n", msg->len); - return -EINVAL; + return NULL; } if (rtph->version != RTP_VERSION) { DEBUGPC(DLMUX, "received RTP version %d not supported.\n", rtph->version); - return -EINVAL; + return NULL; } + + return rtph; +} + +void *osmo_rtp_get_payload(struct rtp_hdr *rtph, struct msgb *msg) +{ + struct rtp_x_hdr *rtpxh; + uint8_t *payload; + int payload_len; + int x_len; + int csrc_len; + csrc_len = rtph->csrc_count << 2; payload = msg->data + sizeof(struct rtp_hdr) + csrc_len; payload_len = msg->len - sizeof(struct rtp_hdr) - csrc_len; if (payload_len < 0) { DEBUGPC(DLMUX, "received RTP frame too short (len = %d, " "csrc count = %d)\n", msg->len, rtph->csrc_count); - return -EINVAL; + return NULL; } if (rtph->extension) { if (payload_len < sizeof(struct rtp_x_hdr)) { DEBUGPC(DLMUX, "received RTP frame too short for " "extension header\n"); - return -EINVAL; + return NULL; } rtpxh = (struct rtp_x_hdr *)payload; x_len = ntohs(rtpxh->length) * 4 + sizeof(struct rtp_x_hdr); @@ -111,26 +115,24 @@ int osmo_rtp_parse(struct msgb *msg) if (payload_len < 0) { DEBUGPC(DLMUX, "received RTP frame too short, " "extension header exceeds frame length\n"); - return -EINVAL; + return NULL; } } if (rtph->padding) { if (payload_len < 0) { DEBUGPC(DLMUX, "received RTP frame too short for " "padding length\n"); - return -EINVAL; + return NULL; } payload_len -= payload[payload_len - 1]; if (payload_len < 0) { DEBUGPC(DLMUX, "received RTP frame with padding " "greater than payload\n"); - return -EINVAL; + return NULL; } } - msgb_pull(msg, msg->len - payload_len); - - return rtph->payload_type; + return (uint8_t *)msg->data + msg->len - payload_len; } struct msgb * -- cgit v1.2.3