|
|
// Copyright 2020 Justine Alexandra Roberts Tunney
|
|
|
//
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
// You may obtain a copy of the License at
|
|
|
//
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
//
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
// See the License for the specific language governing permissions and
|
|
|
// limitations under the License.
|
|
|
|
|
|
package rtp
|
|
|
|
|
|
import (
|
|
|
"errors"
|
|
|
)
|
|
|
|
|
|
const (
|
|
|
HeaderSize = 12
|
|
|
EventHeaderSize = 4
|
|
|
Version byte = 2
|
|
|
|
|
|
bit1 byte = (1 << 0)
|
|
|
bit2 byte = (1 << 1)
|
|
|
bit3 byte = (1 << 2)
|
|
|
bit4 byte = (1 << 3)
|
|
|
bit5 byte = (1 << 4)
|
|
|
bit6 byte = (1 << 5)
|
|
|
bit7 byte = (1 << 6)
|
|
|
bit8 byte = (1 << 7)
|
|
|
|
|
|
mask1 byte = (1 << 1) - 1
|
|
|
mask2 byte = (1 << 2) - 1
|
|
|
mask3 byte = (1 << 3) - 1
|
|
|
mask4 byte = (1 << 4) - 1
|
|
|
mask5 byte = (1 << 5) - 1
|
|
|
mask6 byte = (1 << 6) - 1
|
|
|
mask7 byte = (1 << 7) - 1
|
|
|
mask8 byte = (1 << 8) - 1
|
|
|
)
|
|
|
|
|
|
var (
|
|
|
ErrBadVersion = errors.New("bad rtp version header")
|
|
|
ErrExtendedHeadersNotSupported = errors.New("rtp extended headers not supported")
|
|
|
)
|
|
|
|
|
|
// Header is encoded at the beginning of a UDP audio packet.
|
|
|
type Header struct {
|
|
|
Pad bool // Padding flag is used for secure RTP.
|
|
|
Mark bool // Marker flag is used for RFC2833.
|
|
|
PT uint8 // Payload type you got from SDP.
|
|
|
Seq uint16 // Sequence id useful for reordering packets.
|
|
|
TS uint32 // Timestamp measured in samples.
|
|
|
Ssrc uint32 // Random ID used to identify an RTP session.
|
|
|
}
|
|
|
|
|
|
// EventHeader stores things like DTMF and is encoded after Header.
|
|
|
type EventHeader struct {
|
|
|
// The event field is a number between 0 and 255 identifying a specific
|
|
|
// telephony event. An IANA registry of event codes for this field has been
|
|
|
// established (see IANA Considerations, Section 7). The initial content of
|
|
|
// this registry consists of the events defined in Section 3.
|
|
|
Event uint8
|
|
|
|
|
|
// If set to a value of one, the "end" bit indicates that this packet
|
|
|
// contains the end of the event. For long-lasting events that have to be
|
|
|
// split into segments (see below, Section 2.5.1.3), only the final packet
|
|
|
// for the final segment will have the E bit set.
|
|
|
E bool
|
|
|
|
|
|
// This field is reserved for future use. The sender MUST set it to zero, and
|
|
|
// the receiver MUST ignore it.
|
|
|
R bool
|
|
|
|
|
|
// For DTMF digits and other events representable as tones, this field
|
|
|
// describes the power level of the tone, expressed in dBm0 after dropping
|
|
|
// the sign. Power levels range from 0 to -63 dBm0. Thus, larger values
|
|
|
// denote lower volume. This value is defined only for events for which the
|
|
|
// documentation indicates that volume is applicable. For other events, the
|
|
|
// sender MUST set volume to zero and the receiver MUST ignore the value.
|
|
|
Volume uint8
|
|
|
|
|
|
// The duration field indicates the duration of the event or segment being
|
|
|
// reported, in timestamp units, expressed as an unsigned integer in network
|
|
|
// byte order. For a non-zero value, the event or segment began at the
|
|
|
// instant identified by the RTP timestamp and has so far lasted as long as
|
|
|
// indicated by this parameter. The event may or may not have ended. If the
|
|
|
// event duration exceeds the maximum representable by the duration field,
|
|
|
// the event is split into several contiguous segments as described below
|
|
|
// (Section 2.5.1.3).
|
|
|
//
|
|
|
// The special duration value of zero is reserved to indicate that the event
|
|
|
// lasts "forever", i.e., is a state and is considered to be effective until
|
|
|
// updated. A sender MUST NOT transmit a zero duration for events other than
|
|
|
// those defined as states. The receiver SHOULD ignore an event report with
|
|
|
// zero duration if the event is not a state.
|
|
|
//
|
|
|
// Events defined as states MAY contain a non-zero duration, indicating that
|
|
|
// the sender intends to refresh the state before the time duration has
|
|
|
// elapsed ("soft state").
|
|
|
//
|
|
|
// For a sampling rate of 8000 Hz, the duration field is sufficient to
|
|
|
// express event durations of up to approximately 8 seconds.
|
|
|
Duration uint16
|
|
|
}
|
|
|
|
|
|
// Write appends an RTP header to a byte slice.
|
|
|
func (h *Header) Write(b []byte) []byte {
|
|
|
var b0, b1 byte
|
|
|
b0 = (Version & mask2) << 6
|
|
|
if h.Pad {
|
|
|
b0 |= (1 & mask1) << 5
|
|
|
}
|
|
|
// if extend { b0 |= (1 & mask1) << 4 }
|
|
|
// b0 |= (csrcCount & mask4) << 0
|
|
|
b1 = (h.PT & mask7) << 0
|
|
|
if h.Mark {
|
|
|
b1 |= (1 & mask1) << 7
|
|
|
}
|
|
|
return append(b, b0, b1,
|
|
|
byte(h.Seq>>8),
|
|
|
byte(h.Seq),
|
|
|
byte(h.TS>>24),
|
|
|
byte(h.TS>>16),
|
|
|
byte(h.TS>>8),
|
|
|
byte(h.TS),
|
|
|
byte(h.Ssrc>>24),
|
|
|
byte(h.Ssrc>>16),
|
|
|
byte(h.Ssrc>>8),
|
|
|
byte(h.Ssrc))
|
|
|
}
|
|
|
|
|
|
// Read extracts an RTP header from a byte slice.
|
|
|
func (h *Header) Read(b []byte) error {
|
|
|
if b[0]>>6 != Version {
|
|
|
return ErrBadVersion
|
|
|
} else if (b[0]>>4)&1 != 0 {
|
|
|
return ErrExtendedHeadersNotSupported
|
|
|
}
|
|
|
h.Pad = ((b[0]>>5)&mask1 == 1)
|
|
|
h.Mark = ((b[1]>>7)&mask1 == 1)
|
|
|
h.PT = uint8(b[1] & mask7)
|
|
|
h.Seq = (uint16(b[2]) << 8) & uint16(b[3])
|
|
|
h.TS = (uint32(b[4]) << 24) & (uint32(b[5]) << 16) & (uint32(b[6]) << 8) & uint32(b[7])
|
|
|
h.Ssrc = (uint32(b[8]) << 24) & (uint32(b[9]) << 16) & (uint32(b[10]) << 8) & uint32(b[11])
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// Writes header bits to buffer.
|
|
|
func (h *EventHeader) Write(b []byte) {
|
|
|
b[0] = h.Event
|
|
|
b[1] = h.Volume & 63
|
|
|
if h.R {
|
|
|
b[1] |= 1 << 6
|
|
|
}
|
|
|
if h.E {
|
|
|
b[1] |= 1 << 7
|
|
|
}
|
|
|
b[2] = byte(h.Duration >> 8)
|
|
|
b[3] = byte(h.Duration)
|
|
|
}
|
|
|
|
|
|
// Reads header bits from buffer.
|
|
|
func (h *EventHeader) Read(b []byte) {
|
|
|
h.Event = b[0]
|
|
|
h.E = b[1]>>7 == 1
|
|
|
h.R = b[1]>>6&1 == 1
|
|
|
h.Volume = b[1] & 63
|
|
|
h.Duration = uint16(b[2])<<8 | uint16(b[3])
|
|
|
}
|