Mercurial > hg > audiostuff
view intercom/rtp.cpp @ 4:26cd8f1ef0b1
import spandsp-0.0.6pre17
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 15:50:58 +0200 |
parents | 13be24d74cd2 |
children |
line wrap: on
line source
/* rtp.cpp * * Copyright (C) DFS Deutsche Flugsicherung (2004, 2005). * All Rights Reserved. * Author: Andre Adrian * * subset of Real Time Protocol Version 2 (RFC3550) * handling of extension and padding is missing * * Version 0.3 */ #include <stdio.h> /* printf() */ #include <stdlib.h> #include <sys/types.h> /* u_long */ #include <sys/time.h> /* gettimeofday() */ #include <unistd.h> /* get..() */ #include <time.h> /* clock() */ #include <sys/utsname.h> /* uname() */ #include <netinet/in.h> #include <assert.h> #include "intercomd.h" #include "rtp.h" /* * Return random unsigned 32-bit quantity. Use 'type' argument if * you need to generate several different values in close succession. * (partly from RFC 3550 A.6 Generating a Random 32-bit Identifier) */ unsigned long random32(int type) { struct { int type; struct timeval tv; clock_t cpu; pid_t pid; u_long hid; uid_t uid; gid_t gid; struct utsname name; } s; gettimeofday(&s.tv, 0); uname(&s.name); s.type = type; s.cpu = clock(); s.pid = getpid(); s.hid = gethostid(); s.uid = getuid(); s.gid = getgid(); /* also: system uptime */ unsigned long *us = (unsigned long *) &s; /* use xor to make a (bad) random */ /* Note: remainder of long div of 32bit prim is better */ unsigned long random = 0; unsigned int i; for (i = 0; i < sizeof(s) / sizeof(long); ++i) { random ^= *us++; } return random; } /* random32 */ RTP::RTP() { version = 2; padding = 0; extension = 0; csrc_count = 0; marker = 0; payload_type = PT_PCMU; ssrc = 0; sequence = 0; timestamp = 0; } void RTP::init(int payload_type_, unsigned long ssrc_) { version = 2; padding = 0; extension = 0; csrc_count = 0; marker = 0; payload_type = payload_type_; ssrc = ssrc_; /* My interpretation of RFC3550 A.6: one seed is good enough */ sequence = random32(payload_type_); timestamp = sequence; } void RTP::next(int frameduration) { ++sequence; timestamp += frameduration; } void RTP::reset_csrc() { csrc_count = 0; } int RTP::add_csrc(unsigned long csrc_) { return_if (csrc_count >= 15, ERROR); csrc[csrc_count++] = csrc_; // printf("add_csrc = %08x\n", csrc_); return OKAY; } int RTP::find_csrc(unsigned long ssrc_) { unsigned int i; if (0 == csrc_count) return NO; // printf("find_csrc = %08x ", ssrc_); for (i = 0; i < csrc_count; ++i) { // printf("%08x ", csrc[i]); if (csrc[i] == ssrc_) { // printf("hit\n"); return YES; } } return NO; } int RTP::check() { // RFC3550 A.1 RTP Data Header Validity Checks // RTP version field must equal 2. if (version != 2) return -1; // The payload type must be known switch (payload_type) { case PT_PCMU: case PT_GSM: case PT_PCMA: case PT_G729: case PT_iLBC: case PT_EFR: case PT_G726: case PT_SPX: /* do nothing */ break; default: return -1; } // The X bit must be zero if the profile does not specify that the // header extension mechanism may be used. Otherwise, the extension // length field must be less than the total packet size minus the // fixed header length and padding. if (extension) return -1; // hack! // The length of the packet must be consistent with CC and payload // type (if payloads have a known length). // equal to SR or RR. // if (csrc_count != 0) // return -1; // hack! // If the P bit is set, then the last octet of the packet must // contain a valid octet count, in particular, less than the total // packet length minus the header size. if (padding) return -1; // hack! return 0; } char *RTP_network_copy(char *to, RTP * from) { unsigned long *ulfrom = (unsigned long *) from; unsigned long *ulto = (unsigned long *) to; int i; for (i = 0; i < 3 + from->get_cc(); ++i) { *ulto++ = htonl(*ulfrom++); } return (char *) ulto; } char *RTP_host_copy(RTP * to, char *from) { unsigned long *ulfrom = (unsigned long *) from; unsigned long *ulto = (unsigned long *) to; int i; for (i = 0; i < 3; ++i) { *ulto++ = ntohl(*ulfrom++); } for (i = 0; i < to->get_cc(); ++i) { *ulto++ = ntohl(*ulfrom++); } return (char *) ulfrom; }