/* NAME parse.go DESCRIPTION parse.go contains functionality for parsing RTCP packets. AUTHORS Saxon A. Nelson-Milton LICENSE This is Copyright (C) 2019 the Australian Ocean Lab (AusOcean) It is free software: you can redistribute it and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License in gpl.txt. If not, see http://www.gnu.org/licenses. */ package rtcp import ( "encoding/binary" "errors" ) // NTPTimestamp describes an NTP timestamp. // // NTP timestamps are represented as a 64-bit unsigned fixed- // point number, in seconds relative to 0h on 1 January 1900. The integer // part is in the first 32 bits and the fraction part in the last 32 bits. // This format allows convenient multiple-precision arithmetic and // conversion to Time Protocol representation (seconds), but does // complicate the conversion to ICMP Timestamp message representation // (milliseconds). The precision of this representation is about 200 // picoseconds, which should be adequate for even the most exotic // requirements. type NTPTimestamp struct { Seconds uint32 Fraction uint32 } // Timestamp gets the timestamp from a receiver report and returns it as the most // significant word, and the least significant word. If the given bytes do not // represent a valid receiver report, an error is returned. func Timestamp(buf []byte) (NTPTimestamp, error) { if len(buf) < 4 { return NTPTimestamp{}, errors.New("bad RTCP packet, not of sufficient length") } if (buf[0]&0xc0)>>6 != rtcpVer { return NTPTimestamp{}, errors.New("incompatible RTCP version") } if buf[1] != typeSenderReport { return NTPTimestamp{}, errors.New("RTCP packet is not of sender report type") } return NTPTimestamp{ Seconds: binary.BigEndian.Uint32(buf[8:]), Fraction: binary.BigEndian.Uint32(buf[12:]), }, nil }