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 } |