Add rtcp.RawPacket type

This will be returned by Unmarhsal when an unknown type is seen
in the packet stream, avoiding an error and allowing the user to
write their own packet handling code for that type if desired.

Relates to #119
This commit is contained in:
Max Hawkins
2018-12-02 11:15:56 -08:00
committed by Woodrow Douglass
parent bcc7ae2061
commit 5655d151b1
3 changed files with 87 additions and 2 deletions

View File

@@ -36,10 +36,9 @@ func Unmarshal(rawPacket []byte) (Packet, Header, error) {
p = new(PictureLossIndication) p = new(PictureLossIndication)
default: default:
return nil, h, errWrongType p = new(RawPacket)
} }
err = p.Unmarshal(rawPacket) err = p.Unmarshal(rawPacket)
return p, h, err return p, h, err
} }

25
pkg/rtcp/raw_packet.go Normal file
View File

@@ -0,0 +1,25 @@
package rtcp
// RawPacket represents an unparsed RTCP packet. It's returned by Unmarshal when
// a packet with an unknown type is encountered.
type RawPacket []byte
// Marshal encodes the packet in binary.
func (r RawPacket) Marshal() ([]byte, error) {
return r, nil
}
// Unmarshal decodes the packet from binary.
func (r *RawPacket) Unmarshal(b []byte) error {
if len(b) < (headerLength) {
return errPacketTooShort
}
*r = b
var h Header
if err := h.Unmarshal(b); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,61 @@
package rtcp
import (
"reflect"
"testing"
)
func TestRawPacketRoundTrip(t *testing.T) {
for _, test := range []struct {
Name string
Packet RawPacket
WantMarshalError error
WantUnmarshalError error
}{
{
Name: "valid",
Packet: RawPacket([]byte{
// v=2, p=0, count=1, BYE, len=12
0x81, 0xcb, 0x00, 0x0c,
// ssrc=0x902f9e2e
0x90, 0x2f, 0x9e, 0x2e,
// len=3, text=FOO
0x03, 0x46, 0x4f, 0x4f,
}),
},
{
Name: "short header",
Packet: RawPacket([]byte{0x00}),
WantUnmarshalError: errPacketTooShort,
},
{
Name: "invalid header",
Packet: RawPacket([]byte{
// v=0, p=0, count=0, RR, len=4
0x00, 0xc9, 0x00, 0x04,
}),
WantUnmarshalError: errBadVersion,
},
} {
data, err := test.Packet.Marshal()
if got, want := err, test.WantMarshalError; got != want {
t.Fatalf("Marshal %q: err = %v, want %v", test.Name, got, want)
}
if err != nil {
continue
}
var decoded RawPacket
err = decoded.Unmarshal(data)
if got, want := err, test.WantUnmarshalError; got != want {
t.Fatalf("Unmarshal %q: err = %v, want %v", test.Name, got, want)
}
if err != nil {
continue
}
if got, want := decoded, test.Packet; !reflect.DeepEqual(got, want) {
t.Fatalf("%q raw round trip: got %#v, want %#v", test.Name, got, want)
}
}
}