diff options
author | Harald Welte <laforge@gnumonks.org> | 2011-07-21 16:48:07 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2011-07-21 16:48:07 +0200 |
commit | 8583c318113ca2d21f1a30ce4f388d74b527728b (patch) | |
tree | 20f9ed66cce75390f05b72c8159f069064e25aa4 /src | |
parent | 6b62748da6e2dc3e981869a2f788c990fd4d7342 (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.am | 1 | ||||
-rw-r--r-- | src/common/rtp.c | 516 |
2 files changed, 0 insertions, 517 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am index c8530c4..495dd05 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 99be75b..0000000 --- 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; -} - |