Mercurial > hg > audiostuff
comparison intercom/rtp.cpp @ 2:13be24d74cd2
import intercom-0.4.1
| author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
|---|---|
| date | Fri, 25 Jun 2010 09:57:52 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:9cadc470e3da | 2:13be24d74cd2 |
|---|---|
| 1 /* rtp.cpp | |
| 2 * | |
| 3 * Copyright (C) DFS Deutsche Flugsicherung (2004, 2005). | |
| 4 * All Rights Reserved. | |
| 5 * Author: Andre Adrian | |
| 6 * | |
| 7 * subset of Real Time Protocol Version 2 (RFC3550) | |
| 8 * handling of extension and padding is missing | |
| 9 * | |
| 10 * Version 0.3 | |
| 11 */ | |
| 12 | |
| 13 #include <stdio.h> /* printf() */ | |
| 14 #include <stdlib.h> | |
| 15 | |
| 16 #include <sys/types.h> /* u_long */ | |
| 17 #include <sys/time.h> /* gettimeofday() */ | |
| 18 #include <unistd.h> /* get..() */ | |
| 19 #include <time.h> /* clock() */ | |
| 20 #include <sys/utsname.h> /* uname() */ | |
| 21 #include <netinet/in.h> | |
| 22 #include <assert.h> | |
| 23 | |
| 24 #include "intercomd.h" | |
| 25 #include "rtp.h" | |
| 26 | |
| 27 /* | |
| 28 * Return random unsigned 32-bit quantity. Use 'type' argument if | |
| 29 * you need to generate several different values in close succession. | |
| 30 * (partly from RFC 3550 A.6 Generating a Random 32-bit Identifier) | |
| 31 */ | |
| 32 unsigned long random32(int type) | |
| 33 { | |
| 34 struct { | |
| 35 int type; | |
| 36 struct timeval tv; | |
| 37 clock_t cpu; | |
| 38 pid_t pid; | |
| 39 u_long hid; | |
| 40 uid_t uid; | |
| 41 gid_t gid; | |
| 42 struct utsname name; | |
| 43 } s; | |
| 44 | |
| 45 gettimeofday(&s.tv, 0); | |
| 46 uname(&s.name); | |
| 47 s.type = type; | |
| 48 s.cpu = clock(); | |
| 49 s.pid = getpid(); | |
| 50 s.hid = gethostid(); | |
| 51 s.uid = getuid(); | |
| 52 s.gid = getgid(); | |
| 53 /* also: system uptime */ | |
| 54 | |
| 55 unsigned long *us = (unsigned long *) &s; | |
| 56 | |
| 57 /* use xor to make a (bad) random */ | |
| 58 /* Note: remainder of long div of 32bit prim is better */ | |
| 59 unsigned long random = 0; | |
| 60 unsigned int i; | |
| 61 for (i = 0; i < sizeof(s) / sizeof(long); ++i) { | |
| 62 random ^= *us++; | |
| 63 } | |
| 64 return random; | |
| 65 } /* random32 */ | |
| 66 | |
| 67 | |
| 68 RTP::RTP() | |
| 69 { | |
| 70 version = 2; | |
| 71 padding = 0; | |
| 72 extension = 0; | |
| 73 csrc_count = 0; | |
| 74 marker = 0; | |
| 75 payload_type = PT_PCMU; | |
| 76 ssrc = 0; | |
| 77 sequence = 0; | |
| 78 timestamp = 0; | |
| 79 } | |
| 80 | |
| 81 void RTP::init(int payload_type_, unsigned long ssrc_) | |
| 82 { | |
| 83 version = 2; | |
| 84 padding = 0; | |
| 85 extension = 0; | |
| 86 csrc_count = 0; | |
| 87 marker = 0; | |
| 88 payload_type = payload_type_; | |
| 89 ssrc = ssrc_; | |
| 90 /* My interpretation of RFC3550 A.6: one seed is good enough */ | |
| 91 sequence = random32(payload_type_); | |
| 92 timestamp = sequence; | |
| 93 } | |
| 94 | |
| 95 void RTP::next(int frameduration) | |
| 96 { | |
| 97 ++sequence; | |
| 98 timestamp += frameduration; | |
| 99 } | |
| 100 | |
| 101 void RTP::reset_csrc() | |
| 102 { | |
| 103 csrc_count = 0; | |
| 104 } | |
| 105 | |
| 106 int RTP::add_csrc(unsigned long csrc_) | |
| 107 { | |
| 108 return_if (csrc_count >= 15, ERROR); | |
| 109 csrc[csrc_count++] = csrc_; | |
| 110 | |
| 111 // printf("add_csrc = %08x\n", csrc_); | |
| 112 return OKAY; | |
| 113 } | |
| 114 | |
| 115 int RTP::find_csrc(unsigned long ssrc_) | |
| 116 { | |
| 117 unsigned int i; | |
| 118 | |
| 119 if (0 == csrc_count) return NO; | |
| 120 // printf("find_csrc = %08x ", ssrc_); | |
| 121 for (i = 0; i < csrc_count; ++i) { | |
| 122 // printf("%08x ", csrc[i]); | |
| 123 if (csrc[i] == ssrc_) { | |
| 124 // printf("hit\n"); | |
| 125 return YES; | |
| 126 } | |
| 127 } | |
| 128 return NO; | |
| 129 } | |
| 130 | |
| 131 int RTP::check() | |
| 132 { | |
| 133 // RFC3550 A.1 RTP Data Header Validity Checks | |
| 134 | |
| 135 // RTP version field must equal 2. | |
| 136 if (version != 2) | |
| 137 return -1; | |
| 138 | |
| 139 // The payload type must be known | |
| 140 switch (payload_type) { | |
| 141 case PT_PCMU: | |
| 142 case PT_GSM: | |
| 143 case PT_PCMA: | |
| 144 case PT_G729: | |
| 145 case PT_iLBC: | |
| 146 case PT_EFR: | |
| 147 case PT_G726: | |
| 148 case PT_SPX: | |
| 149 /* do nothing */ | |
| 150 break; | |
| 151 default: | |
| 152 return -1; | |
| 153 } | |
| 154 | |
| 155 // The X bit must be zero if the profile does not specify that the | |
| 156 // header extension mechanism may be used. Otherwise, the extension | |
| 157 // length field must be less than the total packet size minus the | |
| 158 // fixed header length and padding. | |
| 159 if (extension) | |
| 160 return -1; // hack! | |
| 161 | |
| 162 // The length of the packet must be consistent with CC and payload | |
| 163 // type (if payloads have a known length). | |
| 164 // equal to SR or RR. | |
| 165 // if (csrc_count != 0) | |
| 166 // return -1; // hack! | |
| 167 | |
| 168 // If the P bit is set, then the last octet of the packet must | |
| 169 // contain a valid octet count, in particular, less than the total | |
| 170 // packet length minus the header size. | |
| 171 if (padding) | |
| 172 return -1; // hack! | |
| 173 return 0; | |
| 174 } | |
| 175 | |
| 176 char *RTP_network_copy(char *to, RTP * from) | |
| 177 { | |
| 178 unsigned long *ulfrom = (unsigned long *) from; | |
| 179 unsigned long *ulto = (unsigned long *) to; | |
| 180 int i; | |
| 181 for (i = 0; i < 3 + from->get_cc(); ++i) { | |
| 182 *ulto++ = htonl(*ulfrom++); | |
| 183 } | |
| 184 return (char *) ulto; | |
| 185 } | |
| 186 | |
| 187 char *RTP_host_copy(RTP * to, char *from) | |
| 188 { | |
| 189 unsigned long *ulfrom = (unsigned long *) from; | |
| 190 unsigned long *ulto = (unsigned long *) to; | |
| 191 int i; | |
| 192 for (i = 0; i < 3; ++i) { | |
| 193 *ulto++ = ntohl(*ulfrom++); | |
| 194 } | |
| 195 for (i = 0; i < to->get_cc(); ++i) { | |
| 196 *ulto++ = ntohl(*ulfrom++); | |
| 197 } | |
| 198 return (char *) ulfrom; | |
| 199 } |
