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