aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2011-07-21 16:48:07 +0200
committerHarald Welte <laforge@gnumonks.org>2011-07-21 16:48:07 +0200
commit8583c318113ca2d21f1a30ce4f388d74b527728b (patch)
tree20f9ed66cce75390f05b72c8159f069064e25aa4 /src
parent6b62748da6e2dc3e981869a2f788c990fd4d7342 (diff)
remove old RTP code from osmocom-bb/jolly/bts branch
Instead, I will base on the existing RTP code in openbsc
Diffstat (limited to 'src')
-rw-r--r--src/common/Makefile.am1
-rw-r--r--src/common/rtp.c516
2 files changed, 0 insertions, 517 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index c8530c40..495dd05a 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -5,4 +5,3 @@ LDADD = $(LIBOSMOCORE_LIBS)
noinst_LIBRARIES = libbts.a
libbts_a_SOURCES = gsm_data_shared.c sysinfo.c logging.c abis.c oml.c bts.c \
rsl.c vty.c paging.c measurement.c
-#support.c rtp.c
diff --git a/src/common/rtp.c b/src/common/rtp.c
deleted file mode 100644
index 99be75b0..00000000
--- a/src/common/rtp.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/* RTP code for BTS side */
-
-/* (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <errno.h>
-#include <sys/types.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <time.h>
-#include <string.h>
-
-#include <osmocom/core/msgb.h>
-
-#include <osmo-bts/logging.h>
-//#include <osmocom/bb/common/osmocom_data.h>
-#include <osmo-bts/support.h>
-#include <osmo-bts/abis.h>
-#include <osmo-bts/rtp.h>
-#include <osmo-bts/bts.h>
-#include <osmo-bts/rsl.h>
-#include <osmo-bts/oml.h>
-
-#define RTP_PORTBASE 30000
-static unsigned short next_udp_port = RTP_PORTBASE;
-
-enum {
- UDP_PRIV_RTP,
- UDP_PRIV_RTCP,
-};
-
-#define RTP_ALLOC_SIZE 1500
-
-/* according to RFC 1889 */
-struct rtcp_hdr {
- u_int8_t byte0;
- u_int8_t type;
- u_int16_t length;
-} __attribute__((packed));
-
-#define RTCP_TYPE_SDES 202
-
-#define RTCP_IE_CNAME 1
-
-/* according to RFC 3550 */
-struct rtp_hdr {
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- u_int8_t csrc_count:4,
- extension:1,
- padding:1,
- version:2;
- u_int8_t payload_type:7,
- marker:1;
-#elif __BYTE_ORDER == __BIG_ENDIAN
- u_int8_t version:2,
- padding:1,
- extension:1,
- csrc_count:4;
- u_int8_t marker:1,
- payload_type:7;
-#endif
- u_int16_t sequence;
- u_int32_t timestamp;
- u_int32_t ssrc;
-
- uint8_t data[0];
-} __attribute__((packed));
-
-struct rtp_x_hdr {
- u_int16_t by_profile;
- u_int16_t length;
-} __attribute__((packed));
-
-#define RTP_VERSION 2
-
-int rtp_tx_rtp(struct osmobts_rtp *rtp, struct msgb *msg)
-{
- struct gsm_data_frame *frame = (struct gsm_data_frame *) msg->data;
- int payload_len = msg->len - sizeof(*frame);
- uint8_t *payload = frame->data;
- struct msgb *nmsg = NULL;
- int duration = 0;
- struct rtp_hdr *nrtph;
-
- if (rtp->rtp_udp.bfd.fd <= 0) {
- LOGP(DRTP, LOGL_INFO, "Socket already closed, dropping\n");
- msgb_free(msg);
- return -EIO;
- }
-
- switch(rtp->payload_type) {
- case RTP_PT_GSM_FULL:
- nmsg = msgb_alloc(sizeof(struct rtp_hdr) + payload_len, "RTP-GSM-FULL");
- duration = 160;
- break;
- case RTP_PT_GSM_EFR:
- nmsg = msgb_alloc(sizeof(struct rtp_hdr) + payload_len, "RTP-GSM-FULL");
- duration = 160;
- break;
- }
- if (!msg) {
- msgb_free(msg);
- return -ENOMEM;
- }
-
- nrtph = (struct rtp_hdr *) msgb_put(nmsg, sizeof(*nrtph) + payload_len);
- nrtph->version = RTP_VERSION;
- nrtph->padding = 0;
- nrtph->extension = 0;
- nrtph->csrc_count = 0;
- nrtph->marker = 0;
- nrtph->payload_type = rtp->payload_type;
- nrtph->sequence = rtp->sequence++;
- nrtph->timestamp = rtp->timestamp;
- rtp->timestamp += duration;
- nrtph->ssrc = rtp->ssrc;
- memcpy(nrtph->data, payload, payload_len);
- msgb_enqueue(&rtp->rtp_udp.tx_queue, nmsg);
- rtp->rtp_udp.bfd.when |= BSC_FD_WRITE;
-
- msgb_free(msg);
-
- return 0;
-}
-
-/* received TCH frame */
-static int rtp_rx_rtp(struct osmobts_rtp *rtp, struct msgb *msg)
-{
- struct rtp_hdr *rtph = (struct rtp_hdr *) msg->data;
- struct rtp_x_hdr *rtpxh;
- uint8_t *payload;
- int payload_len, x_len;
- struct msgb *nmsg = NULL;
- struct gsm_data_frame *frame;
- time_t now;
-
- if (msg->len < 12) {
- LOGP(DRTP, LOGL_NOTICE, "RTP packet too short\n");
- return -EINVAL;
- }
- if (rtph->version != RTP_VERSION) {
- LOGP(DRTP, LOGL_NOTICE, "RTP version missmatch.\n");
- return -EINVAL;
- }
- payload = msg->data + sizeof(struct rtp_hdr) + (rtph->csrc_count << 2);
- payload_len = msg->len - sizeof(struct rtp_hdr) - (rtph->csrc_count << 2);
- if (payload_len < 0) {
- LOGP(DRTP, LOGL_NOTICE, "RTP payload too short.\n");
- return -EINVAL;
- }
- if (rtph->extension) {
- if (payload_len < sizeof(struct rtp_x_hdr)) {
- LOGP(DRTP, LOGL_NOTICE, "RTP frame for extension too short.\n");
- return -EINVAL;
- }
- rtpxh = (struct rtp_x_hdr *)payload;
- x_len = ntohs(rtpxh->length) * 4 + sizeof(struct rtp_x_hdr);
- payload += x_len;
- payload_len -= x_len;
- if (payload_len < 0) {
- LOGP(DRTP, LOGL_NOTICE, "RTP extension exceeds frame length.\n");
- return -EINVAL;
- }
- }
- if (rtph->padding) {
- if (payload_len == 0) {
- LOGP(DRTP, LOGL_NOTICE, "RTP frame too short for padding.\n");
- return -EINVAL;
- }
- payload_len -= payload[payload_len - 1];
- if (payload_len < 0) {
- LOGP(DRTP, LOGL_NOTICE, "RTP frame has padding greater than payload.\n");
- return -EINVAL;
- }
- }
- switch (rtph->payload_type) {
- case RTP_PT_GSM_FULL:
- if (payload_len != 33) {
- LOGP(DRTP, LOGL_NOTICE, "RTP full rate frame has invald payload length.\n");
- }
- nmsg = msgb_alloc(sizeof(*frame) + payload_len, "GSM-FULL");
- break;
- if (payload_len != 31) {
- LOGP(DRTP, LOGL_NOTICE, "RTP enhanced full rate frame has invald payload length.\n");
- }
- nmsg = msgb_alloc(sizeof(*frame) + payload_len, "GSM-EFR");
- break;
- }
- if (!nmsg)
- return -ENOMEM;
- frame = (struct gsm_data_frame *) msgb_put(nmsg, sizeof(*frame) + payload_len);
- frame->payload_type = rtph->payload_type;
- frame->timestamp = ntohl(rtph->timestamp);
- memcpy(frame->data, payload, payload_len);
-
- /* check jitterbuffer and adjust delay */
- time(&now);
- if (rtp->dejitter_check <= now) {
- struct msgb *fmsg;
-
- LOGP(DRTP, LOGL_INFO, "RTP dejitter: minimum fill: %d packets (dropping)\n", rtp->dejitter_min);
- while (rtp->dejitter_min && (fmsg = msgb_dequeue(&rtp->dejitter_queue))) {
- msgb_free(fmsg);
- rtp->dejitter_num--;
- rtp->dejitter_min--;
- }
- rtp->dejitter_check = now + 5;
- rtp->dejitter_min = 9999;
- }
- if (rtp->dejitter_num < rtp->dejitter_min)
- rtp->dejitter_min = rtp->dejitter_num;
-
- /* write to dejitter queue */
- msgb_enqueue(&rtp->dejitter_queue, nmsg);
- rtp->dejitter_num++;
-
- if (rtp->voice_req)
- return 0;
-
- // FIXME: send voice frame to l1ctl
- rtp->voice_req = 1;
- rtp->dejitter_num--;
- if (rtp->last_frame)
- msgb_free(rtp->last_frame);
- rtp->last_frame = nmsg;
-
- return 0;
-}
-
-/* on confirm, send next packet */
-int rtp_voice_conf(struct osmobts_rtp *rtp)
-{
- struct msgb *msg;
-
-
- msg = msgb_dequeue(&rtp->dejitter_queue);
- if (!msg) {
- msg = rtp->last_frame;
- if (!msg) {
- rtp->voice_req = 0;
- return 0;
- }
- } else {
- rtp->dejitter_num--;
- if (rtp->last_frame)
- msgb_free(rtp->last_frame);
- rtp->last_frame = msg;
- }
-
- // FIXME: send voice frame to l1ctl
-
- return 0;
-}
-
-static int udp_bfd_cb(struct bsc_fd *bfd, unsigned int flags)
-{
- struct osmobts_udp *udp = bfd->data;
- struct msgb *msg = NULL;
- int rc;
-
- switch (bfd->priv_nr) {
- case UDP_PRIV_RTP:
- msg = msgb_alloc(RTP_ALLOC_SIZE, "RTP");
- break;
- case UDP_PRIV_RTCP:
- msg = msgb_alloc(RTP_ALLOC_SIZE, "RTCP");
- break;
- }
- if (!msg)
- return -ENOMEM;
-
- rc = read(bfd->fd, msg->data, RTP_ALLOC_SIZE);
- if (rc <= 0) {
- bfd->when &= ~BSC_FD_READ;
- return rc;
- }
- msgb_put(msg, rc);
-
- switch (bfd->priv_nr) {
- case UDP_PRIV_RTP:
- if ((flags & BSC_FD_READ))
- rc = rtp_rx_rtp(udp->rtp, msg);
- if ((flags & BSC_FD_WRITE)) {
- struct msgb *msg = msgb_dequeue(&udp->tx_queue);
-
- if (!msg) {
- bfd->when &= ~BSC_FD_WRITE;
- rc = 0;
- break;
- }
- rc = write(bfd->fd, msg->data, msg->len);
- }
- break;
- case UDP_PRIV_RTCP:
- // FIXME: implement RTCP
- rc = 0;
- break;
- }
- msgb_free(msg);
-
- return rc;
-}
-
-/* subfunction: create an UDP socket */
-static int udp_create_socket(struct osmobts_rtp *rtp, struct osmobts_udp *udp, int priv_nr)
-{
- int rc;
-
- if (udp->bfd.fd <= 0)
- return -EBUSY;
-
- rc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (rc < 0)
- return rc;
- udp->bfd.fd = rc;
- udp->bfd.data = udp;
- udp->bfd.priv_nr = priv_nr;
- udp->bfd.cb = udp_bfd_cb;
- udp->bfd.when = BSC_FD_READ;
-
- udp->rtp = rtp;
- rc = bsc_register_fd(&udp->bfd);
- if (rc < 0) {
- close(udp->bfd.fd);
- udp->bfd.fd = 0;
- }
- INIT_LLIST_HEAD(&udp->tx_queue);
-
- return udp->bfd.fd;
-}
-
-/* subfunction: close an UDP socket */
-static void udp_close_socket(struct osmobts_udp *udp)
-{
- struct msgb *msg;
-
- if (udp->bfd.fd <= 0)
- return;
-
- while ((msg = msgb_dequeue(&udp->tx_queue)))
- msgb_free(msg);
-
- bsc_unregister_fd(&udp->bfd);
- close(udp->bfd.fd);
- udp->bfd.fd = 0;
-}
-
-/* create RTP/RTCP sockets */
-int rtp_create_socket(struct osmobts_lchan *lchan, struct osmobts_rtp *rtp)
-{
- int rc;
-
- LOGP(DRTP, LOGL_INFO, "Creating RTP/RTCP sockets\n");
-
- rc = udp_create_socket(rtp, &rtp->rtp_udp, UDP_PRIV_RTP);
- if (rc < 0) {
- LOGP(DRTP, LOGL_ERROR, "Failed to create RTP socket\n");
- return rc;
- }
- rc = udp_create_socket(rtp, &rtp->rtcp_udp, UDP_PRIV_RTCP);
- if (rc < 0) {
- LOGP(DRTP, LOGL_ERROR, "Failed to create RTCP socket\n");
- udp_close_socket(&rtp->rtp_udp);
- return rc;
- }
- rtp->socket_created = 1;
- rtp->lchan = lchan;
- rtp->ssrc = rand();
- rtp->sequence = random();
- rtp->timestamp = random();
- INIT_LLIST_HEAD(&rtp->dejitter_queue);
- rtp->dejitter_num = 0;
- rtp->dejitter_check = 0;
-
- return 0;
-}
-
-/* close RTP/RTCP sockets */
-int rtp_close_socket(struct osmobts_rtp *rtp)
-{
- struct msgb *msg;
-
- LOGP(DRTP, LOGL_INFO, "Closing RTP/RTCP sockets\n");
-
- while ((msg = msgb_dequeue(&rtp->dejitter_queue)))
- msgb_free(msg);
- if (rtp->last_frame) {
- msgb_free(rtp->last_frame);
- rtp->last_frame = NULL;
- }
-
- udp_close_socket(&rtp->rtp_udp);
- udp_close_socket(&rtp->rtcp_udp);
- rtp->socket_created = 0;
-
- return 0;
-}
-
-/* subfunction: bind an UDP socket */
-static int udp_bind_socket(struct osmobts_udp *udp)
-{
- socklen_t alen = sizeof(udp->sin_local);
- int rc;
-
- if (udp->bfd.fd <= 0)
- return -EINVAL;
-
- udp->sin_local.sin_family = AF_INET;
- udp->sin_local.sin_addr.s_addr = INADDR_ANY;
- udp->sin_local.sin_port = htons(next_udp_port++ & 0xffff);
-
- rc = bind(udp->bfd.fd, (struct sockaddr *)&udp->sin_local, sizeof(udp->sin_local));
- if (rc < 0)
- return rc;
-
- rc = getsockname(udp->bfd.fd, (struct sockaddr *)&udp->sin_local, &alen);
-
- return 0;
-}
-
-/* binds the local RTP/RTCP sockets */
-int rtp_bind_socket(struct osmobts_rtp *rtp)
-{
- int rc;
- int i;
-
- LOGP(DRTP, LOGL_INFO, "Binding RTP/RTCP sockets\n");
-
- if (!rtp->socket_created)
- return -EINVAL;
-
- for (i = 0; i < 1000; i++) {
- /* try RTP socket */
- rc = udp_bind_socket(&rtp->rtp_udp);
- if (rc < 0)
- continue;
- /* now try RTCP socket */
- rc = udp_bind_socket(&rtp->rtp_udp);
- if (rc == 0) {
- LOGP(DRTP, LOGL_INFO, "Sockets bount to: port(RTP)=%d port(RTCP)=%d\n", ntohs(rtp->rtp_udp.sin_local.sin_port), ntohs(rtp->rtcp_udp.sin_local.sin_port));
- return 0;
- }
- /* if fails, create a new RTP socket and start over */
- udp_close_socket(&rtp->rtp_udp);
- rc = udp_create_socket(rtp, &rtp->rtp_udp, UDP_PRIV_RTP);
- if (rc < 0)
- return rc;
- }
-
- return -EIO;
-}
-
-
-/* subfunction: connect an UDP socket */
-static int udp_connect_socket(struct osmobts_udp *udp, uint32_t ip, uint16_t port)
-{
- socklen_t alen = sizeof(udp->sin_local);
- int rc;
-
- if (udp->bfd.fd <= 0)
- return -EINVAL;
-
- udp->sin_remote.sin_family = AF_INET;
- udp->sin_remote.sin_addr.s_addr = htonl(ip);
- udp->sin_remote.sin_port = htons(port);
-
- rc = connect(udp->bfd.fd, (struct sockaddr *)&udp->sin_remote, sizeof(udp->sin_remote));
- if (rc < 0)
- return rc;
-
- rc = getsockname(udp->bfd.fd, (struct sockaddr *)&udp->sin_local, &alen);
-
- return 0;
-}
-
-/* connects the local RTP/RTCP sockets */
-int rtp_connect_socket(struct osmobts_rtp *rtp, uint32_t ip, uint16_t port)
-{
- int rc;
-
- LOGP(DRTP, LOGL_INFO, "Binding RTP/RTCP sockets\n");
-
- rc = udp_connect_socket(&rtp->rtp_udp, ip, port);
- if (rc < 0) {
- LOGP(DRTP, LOGL_ERROR, "Failed to connect RTP socket: ip=%08x, port=%d\n", ip, port);
- return rc;
- }
-
- rc = udp_connect_socket(&rtp->rtcp_udp, ip, port + 1);
- if (rc < 0) {
- LOGP(DRTP, LOGL_ERROR, "Failed to connect RTCP socket: ip=%08x, port=%d\n", ip, port);
- return rc;
- }
-
- LOGP(DRTP, LOGL_INFO, "Sockets connected to: ip=%d port(RTP)=%d port(RTCP)=%d\n", ip, port, port + 1);
-
- return 0;
-}
-