1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "NETEQTEST_DummyRTPpacket.h"
12
13 #include <assert.h>
14 #include <stdio.h>
15 #include <string.h>
16
17 #ifdef WIN32
18 #include <winsock2.h>
19 #else
20 #include <netinet/in.h> // for htons, htonl, etc
21 #endif
22
readFromFile(FILE * fp)23 int NETEQTEST_DummyRTPpacket::readFromFile(FILE *fp)
24 {
25 if (!fp)
26 {
27 return -1;
28 }
29
30 uint16_t length, plen;
31 uint32_t offset;
32 int packetLen = 0;
33
34 bool readNextPacket = true;
35 while (readNextPacket) {
36 readNextPacket = false;
37 if (fread(&length, 2, 1, fp) == 0)
38 {
39 reset();
40 return -2;
41 }
42 length = ntohs(length);
43
44 if (fread(&plen, 2, 1, fp) == 0)
45 {
46 reset();
47 return -1;
48 }
49 packetLen = ntohs(plen);
50
51 if (fread(&offset, 4, 1, fp) == 0)
52 {
53 reset();
54 return -1;
55 }
56 // Store in local variable until we have passed the reset below.
57 uint32_t receiveTime = ntohl(offset);
58
59 // Use length here because a plen of 0 specifies rtcp.
60 length = (uint16_t) (length - _kRDHeaderLen);
61
62 // check buffer size
63 if (_datagram && _memSize < length + 1)
64 {
65 reset();
66 }
67
68 if (!_datagram)
69 {
70 // Add one extra byte, to be able to fake a dummy payload of 1 byte.
71 _datagram = new uint8_t[length + 1];
72 _memSize = length + 1;
73 }
74 memset(_datagram, 0, length + 1);
75
76 if (length == 0)
77 {
78 _datagramLen = 0;
79 _rtpParsed = false;
80 return packetLen;
81 }
82
83 // Read basic header
84 if (fread((unsigned short *) _datagram, 1, _kBasicHeaderLen, fp)
85 != (size_t)_kBasicHeaderLen)
86 {
87 reset();
88 return -1;
89 }
90 _receiveTime = receiveTime;
91 _datagramLen = _kBasicHeaderLen;
92
93 // Parse the basic header
94 webrtc::WebRtcRTPHeader tempRTPinfo;
95 int P, X, CC;
96 parseBasicHeader(&tempRTPinfo, &P, &X, &CC);
97
98 // Check if we have to extend the header
99 if (X != 0 || CC != 0)
100 {
101 int newLen = _kBasicHeaderLen + CC * 4 + X * 4;
102 assert(_memSize >= newLen);
103
104 // Read extension from file
105 size_t readLen = newLen - _kBasicHeaderLen;
106 if (fread(&_datagram[_kBasicHeaderLen], 1, readLen, fp) != readLen)
107 {
108 reset();
109 return -1;
110 }
111 _datagramLen = newLen;
112
113 if (X != 0)
114 {
115 int totHdrLen = calcHeaderLength(X, CC);
116 assert(_memSize >= totHdrLen);
117
118 // Read extension from file
119 size_t readLen = totHdrLen - newLen;
120 if (fread(&_datagram[newLen], 1, readLen, fp) != readLen)
121 {
122 reset();
123 return -1;
124 }
125 _datagramLen = totHdrLen;
126 }
127 }
128 _datagramLen = length;
129
130 if (!_blockList.empty() && _blockList.count(payloadType()) > 0)
131 {
132 readNextPacket = true;
133 }
134 }
135
136 _rtpParsed = false;
137 assert(_memSize > _datagramLen);
138 _payloadLen = 1; // Set the length to 1 byte.
139 return packetLen;
140
141 }
142
writeToFile(FILE * fp)143 int NETEQTEST_DummyRTPpacket::writeToFile(FILE *fp)
144 {
145 if (!fp)
146 {
147 return -1;
148 }
149
150 uint16_t length, plen;
151 uint32_t offset;
152
153 // length including RTPplay header
154 length = htons(_datagramLen + _kRDHeaderLen);
155 if (fwrite(&length, 2, 1, fp) != 1)
156 {
157 return -1;
158 }
159
160 // payload length
161 plen = htons(_datagramLen);
162 if (fwrite(&plen, 2, 1, fp) != 1)
163 {
164 return -1;
165 }
166
167 // offset (=receive time)
168 offset = htonl(_receiveTime);
169 if (fwrite(&offset, 4, 1, fp) != 1)
170 {
171 return -1;
172 }
173
174 // Figure out the length of the RTP header.
175 int headerLen;
176 if (_datagramLen == 0)
177 {
178 // No payload at all; we are done writing to file.
179 headerLen = 0;
180 }
181 else
182 {
183 parseHeader();
184 headerLen = _payloadPtr - _datagram;
185 assert(headerLen >= 0);
186 }
187
188 // write RTP header
189 if (fwrite((unsigned short *) _datagram, 1, headerLen, fp) !=
190 static_cast<size_t>(headerLen))
191 {
192 return -1;
193 }
194
195 return (headerLen + _kRDHeaderLen); // total number of bytes written
196
197 }
198
parseHeader()199 void NETEQTEST_DummyRTPpacket::parseHeader() {
200 NETEQTEST_RTPpacket::parseHeader();
201 // Change _payloadLen to 1 byte. The memory should always be big enough.
202 assert(_memSize > _datagramLen);
203 _payloadLen = 1;
204 }
205