mirror of
https://github.com/pion/webrtc.git
synced 2025-10-05 15:16:52 +08:00
API: Initial api structure for creating datachannel and sctp information.
This commit is contained in:
28
errors.go
28
errors.go
@@ -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")
|
||||
|
@@ -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 {
|
||||
|
@@ -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
81
rtcsctptransport.go
Normal 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
|
||||
}
|
Reference in New Issue
Block a user