19a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org/*
29a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
39a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *
49a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  Use of this source code is governed by a BSD-style license
59a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  that can be found in the LICENSE file in the root of the source
69a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  tree. An additional intellectual property rights grant can be found
79a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  in the file PATENTS.  All contributing project authors may
89a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
99a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org */
109a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
119a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#include "NETEQTEST_DummyRTPpacket.h"
129a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
139a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#include <assert.h>
149a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#include <stdio.h>
159a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#include <string.h>
169a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
179a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#ifdef WIN32
189a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#include <winsock2.h>
199a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#else
209a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#include <netinet/in.h> // for htons, htonl, etc
219a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org#endif
229a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
239a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgint NETEQTEST_DummyRTPpacket::readFromFile(FILE *fp)
249a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org{
259a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    if (!fp)
269a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    {
279a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        return -1;
289a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
299a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
30fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org    uint16_t length, plen;
31fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org    uint32_t offset;
32284ac1404c1d2dcd3356f8af55231f79f0b73783fbarchard@google.com    int packetLen = 0;
339a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
34cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org    bool readNextPacket = true;
35cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org    while (readNextPacket) {
36cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        readNextPacket = false;
37cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        if (fread(&length, 2, 1, fp) == 0)
38cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        {
39cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            reset();
40cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            return -2;
41cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        }
42cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        length = ntohs(length);
439a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
44cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        if (fread(&plen, 2, 1, fp) == 0)
45cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        {
46cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            reset();
47cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            return -1;
48cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        }
49cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        packetLen = ntohs(plen);
509a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
51cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        if (fread(&offset, 4, 1, fp) == 0)
52cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        {
53cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            reset();
54cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            return -1;
55cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        }
56cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        // Store in local variable until we have passed the reset below.
57cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        uint32_t receiveTime = ntohl(offset);
589a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
59cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        // Use length here because a plen of 0 specifies rtcp.
60cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        length = (uint16_t) (length - _kRDHeaderLen);
619a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
62cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        // check buffer size
637993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.org        if (_datagram && _memSize < length + 1)
64cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        {
65cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            reset();
66cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        }
679a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
68cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        if (!_datagram)
69cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        {
707993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.org            // Add one extra byte, to be able to fake a dummy payload of 1 byte.
717993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.org            _datagram = new uint8_t[length + 1];
727993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.org            _memSize = length + 1;
73cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        }
747993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.org        memset(_datagram, 0, length + 1);
759a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
76cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        if (length == 0)
77cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        {
78cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            _datagramLen = 0;
79cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            _rtpParsed = false;
80cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            return packetLen;
81cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        }
829a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
83cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        // Read basic header
84cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        if (fread((unsigned short *) _datagram, 1, _kBasicHeaderLen, fp)
85cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            != (size_t)_kBasicHeaderLen)
869a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        {
879a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org            reset();
889a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org            return -1;
899a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        }
90cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        _receiveTime = receiveTime;
91cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        _datagramLen = _kBasicHeaderLen;
929a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
93cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        // Parse the basic header
94cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        webrtc::WebRtcRTPHeader tempRTPinfo;
95cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        int P, X, CC;
96cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        parseBasicHeader(&tempRTPinfo, &P, &X, &CC);
97cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org
98cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        // Check if we have to extend the header
99cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        if (X != 0 || CC != 0)
1009a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        {
101cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            int newLen = _kBasicHeaderLen + CC * 4 + X * 4;
102cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            assert(_memSize >= newLen);
1039a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1049a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org            // Read extension from file
105cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            size_t readLen = newLen - _kBasicHeaderLen;
1067993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.org            if (fread(&_datagram[_kBasicHeaderLen], 1, readLen, fp) != readLen)
1079a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org            {
1089a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                reset();
1099a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org                return -1;
1109a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org            }
111cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            _datagramLen = newLen;
112cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org
113cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            if (X != 0)
114cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            {
115cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org                int totHdrLen = calcHeaderLength(X, CC);
116cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org                assert(_memSize >= totHdrLen);
117cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org
118cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org                // Read extension from file
119cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org                size_t readLen = totHdrLen - newLen;
1207993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.org                if (fread(&_datagram[newLen], 1, readLen, fp) != readLen)
121cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org                {
122cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org                    reset();
123cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org                    return -1;
124cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org                }
125cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org                _datagramLen = totHdrLen;
126cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            }
1279a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        }
128cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        _datagramLen = length;
1299a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
130cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        if (!_blockList.empty() && _blockList.count(payloadType()) > 0)
131cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        {
132cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org            readNextPacket = true;
133cc19dce72f11c225416b88392ef017d760700160henrik.lundin@webrtc.org        }
1349a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
1359a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1369a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    _rtpParsed = false;
1377993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.org    assert(_memSize > _datagramLen);
1387993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.org    _payloadLen = 1;  // Set the length to 1 byte.
1399a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    return packetLen;
1409a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1419a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
1429a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1439a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.orgint NETEQTEST_DummyRTPpacket::writeToFile(FILE *fp)
1449a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org{
1459a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    if (!fp)
1469a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    {
1479a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        return -1;
1489a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
1499a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
150fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org    uint16_t length, plen;
151fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org    uint32_t offset;
1529a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1539a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    // length including RTPplay header
1549a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    length = htons(_datagramLen + _kRDHeaderLen);
1559a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    if (fwrite(&length, 2, 1, fp) != 1)
1569a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    {
1579a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        return -1;
1589a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
1599a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1609a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    // payload length
1619a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    plen = htons(_datagramLen);
1629a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    if (fwrite(&plen, 2, 1, fp) != 1)
1639a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    {
1649a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        return -1;
1659a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
1669a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1679a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    // offset (=receive time)
1689a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    offset = htonl(_receiveTime);
1699a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    if (fwrite(&offset, 4, 1, fp) != 1)
1709a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    {
1719a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        return -1;
1729a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
1739a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1749a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    // Figure out the length of the RTP header.
1759a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    int headerLen;
1769a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    if (_datagramLen == 0)
1779a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    {
1789a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        // No payload at all; we are done writing to file.
1799a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        headerLen = 0;
1809a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
1819a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    else
1829a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    {
1839a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        parseHeader();
1849a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        headerLen = _payloadPtr - _datagram;
1859a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        assert(headerLen >= 0);
1869a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
1879a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1889a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    // write RTP header
1899a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    if (fwrite((unsigned short *) _datagram, 1, headerLen, fp) !=
1909a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        static_cast<size_t>(headerLen))
1919a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    {
1929a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org        return -1;
1939a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    }
1949a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1959a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org    return (headerLen + _kRDHeaderLen); // total number of bytes written
1969a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1979a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org}
1989a400812ca0006d12e538d465ab6728a8ecd07aahenrik.lundin@webrtc.org
1997993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.orgvoid NETEQTEST_DummyRTPpacket::parseHeader() {
2007993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.org  NETEQTEST_RTPpacket::parseHeader();
2017993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.org  // Change _payloadLen to 1 byte. The memory should always be big enough.
2027993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.org  assert(_memSize > _datagramLen);
2037993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.org  _payloadLen = 1;
2047993c941b8c74d2edb214eeed21890f0107af014henrik.lundin@webrtc.org}
205