Add a public API to send RTCP packets

Relates to #63
This commit is contained in:
Sean DuBois
2018-09-22 14:43:27 -07:00
parent 0c0b1dddd1
commit 210db45d44
5 changed files with 66 additions and 7 deletions

View File

@@ -159,6 +159,22 @@ func (m *Manager) SendRTP(packet *rtp.Packet) {
}
}
// SendRTCP finds a connected port and sends the passed RTCP packet
func (m *Manager) SendRTCP(pkt []byte) {
m.portsLock.Lock()
defer m.portsLock.Unlock()
local, remote := m.IceAgent.SelectedPair()
if local == nil || remote == nil {
return
}
for _, p := range m.ports {
if p.listeningAddr.Equal(local) {
p.sendRTCP(pkt, remote)
}
}
}
// SendDataChannelMessage sends a DataChannel message to a connected peer
func (m *Manager) SendDataChannelMessage(payload datachannel.Payload, streamIdentifier uint16) error {
var data []byte

View File

@@ -11,7 +11,8 @@ func (p *port) sendRTP(packet *rtp.Packet, dst net.Addr) {
p.m.srtpOutboundContextLock.Lock()
defer p.m.srtpOutboundContextLock.Unlock()
if p.m.srtpOutboundContext == nil {
fmt.Printf("Tried to send RTP packet but no SRTP Context to handle it \n")
// TODO log-level
// fmt.Printf("Tried to send RTP packet but no SRTP Context to handle it \n")
return
}
@@ -40,3 +41,22 @@ func (p *port) sendSCTP(buf []byte, dst fmt.Stringer) {
fmt.Println(err)
}
}
func (p *port) sendRTCP(buf []byte, dst net.Addr) {
p.m.srtpOutboundContextLock.Lock()
defer p.m.srtpOutboundContextLock.Unlock()
if p.m.srtpOutboundContext == nil {
fmt.Printf("Tried to send RTCP packet but no SRTP Context to handle it \n")
return
}
encrypted, err := p.m.srtpOutboundContext.EncryptRTCP(buf)
if err != nil {
fmt.Println(err)
return
}
if _, err := p.conn.WriteTo(encrypted, nil, dst); err != nil {
fmt.Printf("Failed to send packet: %s \n", err.Error())
}
}

View File

@@ -9,11 +9,13 @@ type PacketType uint8
// RTCP packet types registered with IANA. See: https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-4
const (
TypeSenderReport PacketType = 200 // RFC 3550, 6.4.1
TypeReceiverReport PacketType = 201 // RFC 3550, 6.4.2
TypeSourceDescription PacketType = 202 // RFC 3550, 6.5
TypeGoodbye PacketType = 203 // RFC 3550, 6.6
TypeApplicationDefined PacketType = 204 // RFC 3550, 6.7 (unimplemented)
TypeSenderReport PacketType = 200 // RFC 3550, 6.4.1
TypeReceiverReport PacketType = 201 // RFC 3550, 6.4.2
TypeSourceDescription PacketType = 202 // RFC 3550, 6.5
TypeGoodbye PacketType = 203 // RFC 3550, 6.6
TypeApplicationDefined PacketType = 204 // RFC 3550, 6.7 (unimplemented)
TypePayloadSpecificFeedback PacketType = 206 // RFC 4585, 6.3
)
func (p PacketType) String() string {
@@ -28,6 +30,8 @@ func (p PacketType) String() string {
return "BYE"
case TypeApplicationDefined:
return "APP"
case TypePayloadSpecificFeedback:
return "PSFB"
default:
return string(p)
}
@@ -41,7 +45,7 @@ type Header struct {
// some additional padding octets at the end which are not part of
// the control information but are included in the length field.
Padding bool
// The number of reception reports or sources contained in this packet (depending on the Type)
// The number of reception reports, sources contained or FMT in this packet (depending on the Type)
Count uint8
// The RTCP packet type for this packet
Type PacketType

7
pkg/rtcp/packet.go Normal file
View File

@@ -0,0 +1,7 @@
package rtcp
// Packet represents an RTCP packet, a protocol used for out-of-band statistics and control information for an RTP session
type Packet interface {
Marshal() ([]byte, error)
Unmarshal(rawPacket []byte) error
}

View File

@@ -18,6 +18,7 @@ import (
"github.com/pions/webrtc/pkg/ice"
"github.com/pions/webrtc/pkg/media"
"github.com/pions/webrtc/pkg/rtcerr"
"github.com/pions/webrtc/pkg/rtcp"
"github.com/pions/webrtc/pkg/rtp"
"github.com/pkg/errors"
)
@@ -719,6 +720,17 @@ func (pc *RTCPeerConnection) SetIdentityProvider(provider string) error {
return errors.Errorf("TODO SetIdentityProvider")
}
// SendRTCP sends a user provided RTCP packet to the connected peer
// If no peer is connected the packet is discarded
func (pc *RTCPeerConnection) SendRTCP(pkt rtcp.Packet) error {
raw, err := pkt.Marshal()
if err != nil {
return err
}
pc.networkManager.SendRTCP(raw)
return nil
}
// Close ends the RTCPeerConnection
func (pc *RTCPeerConnection) Close() error {
pc.networkManager.Close()