API: Initial api structure for creating datachannel and sctp information.

This commit is contained in:
backkem
2018-08-02 12:12:14 +02:00
committed by Sean DuBois
parent ceed0bb590
commit c85cded582
4 changed files with 202 additions and 0 deletions

View File

@@ -91,5 +91,33 @@ func (e *SyntaxError) Error() string {
return fmt.Sprintf("syntax error: %v", e.Err)
}
// Types of TypeError
var (
ErrInvalidValue = errors.New("invalid value")
)
// TypeError indicates an issue with a supplied value
type TypeError struct {
Err error
}
func (e *SyntaxError) Error() string {
return fmt.Sprintf("type error: %v", e.Err)
}
// Types of OperationError
var (
ErrMaxDataChannels = errors.New("maximum number of datachannels reached")
)
// OperationError indicates an issue with execution
type OperationError struct {
Err error
}
func (e *SyntaxError) Error() string {
return fmt.Sprintf("operation error: %v", e.Err)
}
// ErrUnknownType indicates a Unknown info
var ErrUnknownType = errors.New("Unknown")

View File

@@ -19,6 +19,95 @@ type RTCDataChannel struct {
rtcPeerConnection *RTCPeerConnection
}
// RTCPriorityType determines the priority of a data channel.
type RTCPriorityType int
const (
// RTCPriorityTypeVeryLow corresponds to "below normal"
RTCPriorityTypeVeryLow RTCPriorityType = iota + 1
// RTCPriorityTypeLow corresponds to "normal"
RTCPriorityTypeLow
// RTCPriorityTypeMedium corresponds to "high"
RTCPriorityTypeMedium
// RTCPriorityTypeHigh corresponds to "extra high"
RTCPriorityTypeHigh
)
func (p RTCPriorityType) String() string {
switch p {
case RTCPriorityTypeVeryLow:
return "very-low"
case RTCPriorityTypeLow:
return "low"
case RTCPriorityTypeMedium:
return "medium"
case RTCPriorityTypeHigh:
return "high"
default:
return "Unknown"
}
}
type RTCDataChannelInit struct {
Ordered bool
MaxPacketLifeTime *uint16
MaxRetransmits *uint16
Protocol string
Negotiated bool
Id uint16
Priority RTCPriorityType
}
// CreateDataChannel creates a new RTCDataChannel object with the given label and optitional options.
func (r *RTCPeerConnection) CreateDataChannel(label string, options *RTCDataChannelInit) (*RTCDataChannel, error) {
if r.IsClosed {
return nil, &InvalidStateError{Err: ErrConnectionClosed}
}
if len(label) > 65535 {
return nil, &TypeError{Err: ErrInvalidValue}
}
// Defaults
ordered := true
priority := RTCPriorityTypeLow
negotiated := false
if options != nil {
ordered := options.Ordered
priority := options.Priority
negotiated := options.Negotiated
}
id := 0
if negotiated {
id := options.Id
} else {
// TODO: generate id
}
if id > 65534 {
return nil, &TypeError{Err: ErrInvalidValue}
}
if r.sctp.State == RTCSctpTransportStateConnected &&
id >= r.sctp.MaxChannels {
return nil, &OperationError{Err: ErrMaxDataChannels}
}
// TODO: Actually allocate datachannel
res := &RTCDataChannel{
Label: label,
ID: id,
rtcPeerConnection: r,
}
return res, nil
}
// Send sends the passed message to the DataChannel peer
func (r *RTCDataChannel) Send(p datachannel.Payload) error {
if err := r.rtcPeerConnection.networkManager.SendDataChannelMessage(p, r.ID); err != nil {

View File

@@ -94,6 +94,9 @@ type RTCPeerConnection struct {
rtpTransceivers []*RTCRtpTransceiver
Ontrack func(*RTCTrack)
// SCTP
sctp *RTCSctpTransport
// DataChannels
dataChannels map[uint16]*RTCDataChannel
Ondatachannel func(*RTCDataChannel)
@@ -108,6 +111,7 @@ func New(config RTCConfiguration) (*RTCPeerConnection, error) {
signalingState: RTCSignalingStateStable,
connectionState: RTCPeerConnectionStateNew,
mediaEngine: DefaultMediaEngine,
sctp: newRTCSctpTransport(),
dataChannels: make(map[uint16]*RTCDataChannel),
}
var err error

81
rtcsctptransport.go Normal file
View File

@@ -0,0 +1,81 @@
package webrtc
import "math"
// RTCSctpTransportState indicates the state of the SCTP transport.
type RTCSctpTransportState int
const (
// RTCSctpTransportStateConnecting indicates the RTCSctpTransport is in the process of negotiating an association.
RTCSctpTransportStateConnecting RTCSctpTransportState = iota + 1
// RTCSctpTransportStateConnected indicates the negotiation of an association is completed.
RTCSctpTransportStateConnected
// RTCSctpTransportStateClosed indicates a SHUTDOWN or ABORT chunk is received or when the SCTP association has been closed intentionally.
RTCSctpTransportStateClosed
)
func (s RTCSctpTransportState) String() string {
switch s {
case RTCSctpTransportStateConnecting:
return "connecting"
case RTCSctpTransportStateConnected:
return "connected"
case RTCSctpTransportStateClosed:
return "closed"
default:
return "Unknown"
}
}
// RTCSctpTransport provides details about the SCTP transport.
type RTCSctpTransport struct {
State RTCSctpTransportState // TODO: Set RTCSctpTransportState
// transport *RTCDtlsTransport // TODO: DTLS introspection API
MaxMessageSize float64
MaxChannels uint16
// onstatechange func()
}
func newRTCSctpTransport() *RTCSctpTransport {
res := &RTCSctpTransport{
State: RTCSctpTransportStateConnecting,
}
res.updateMessageSize()
res.updateMaxChannels()
return res
}
func (r *RTCSctpTransport) updateMessageSize() {
var remoteMaxMessageSize float64 = 65536 // TODO: get from SDP
var canSendSize float64 = 65536 // TODO: Get from SCTP implementation
r.MaxMessageSize = r.calcMessageSize(remoteMaxMessageSize, canSendSize)
}
func (r *RTCSctpTransport) calcMessageSize(remoteMaxMessageSize, canSendSize float64) float64 {
switch {
case remoteMaxMessageSize == 0 &&
canSendSize == 0:
return math.Inf(1)
case remoteMaxMessageSize == 0:
return canSendSize
case canSendSize == 0:
return remoteMaxMessageSize
case canSendSize > remoteMaxMessageSize:
return remoteMaxMessageSize
default:
return canSendSize
}
}
func (r *RTCSctpTransport) updateMaxChannels() {
r.maxChannels = 65536 // TODO: Get from implementation
}