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 }

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.