mirror of
https://github.com/pion/webrtc.git
synced 2025-10-06 07:37:10 +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)
|
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
|
// ErrUnknownType indicates a Unknown info
|
||||||
var ErrUnknownType = errors.New("Unknown")
|
var ErrUnknownType = errors.New("Unknown")
|
||||||
|
@@ -19,6 +19,95 @@ type RTCDataChannel struct {
|
|||||||
rtcPeerConnection *RTCPeerConnection
|
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
|
// Send sends the passed message to the DataChannel peer
|
||||||
func (r *RTCDataChannel) Send(p datachannel.Payload) error {
|
func (r *RTCDataChannel) Send(p datachannel.Payload) error {
|
||||||
if err := r.rtcPeerConnection.networkManager.SendDataChannelMessage(p, r.ID); err != nil {
|
if err := r.rtcPeerConnection.networkManager.SendDataChannelMessage(p, r.ID); err != nil {
|
||||||
|
@@ -94,6 +94,9 @@ type RTCPeerConnection struct {
|
|||||||
rtpTransceivers []*RTCRtpTransceiver
|
rtpTransceivers []*RTCRtpTransceiver
|
||||||
Ontrack func(*RTCTrack)
|
Ontrack func(*RTCTrack)
|
||||||
|
|
||||||
|
// SCTP
|
||||||
|
sctp *RTCSctpTransport
|
||||||
|
|
||||||
// DataChannels
|
// DataChannels
|
||||||
dataChannels map[uint16]*RTCDataChannel
|
dataChannels map[uint16]*RTCDataChannel
|
||||||
Ondatachannel func(*RTCDataChannel)
|
Ondatachannel func(*RTCDataChannel)
|
||||||
@@ -108,6 +111,7 @@ func New(config RTCConfiguration) (*RTCPeerConnection, error) {
|
|||||||
signalingState: RTCSignalingStateStable,
|
signalingState: RTCSignalingStateStable,
|
||||||
connectionState: RTCPeerConnectionStateNew,
|
connectionState: RTCPeerConnectionStateNew,
|
||||||
mediaEngine: DefaultMediaEngine,
|
mediaEngine: DefaultMediaEngine,
|
||||||
|
sctp: newRTCSctpTransport(),
|
||||||
dataChannels: make(map[uint16]*RTCDataChannel),
|
dataChannels: make(map[uint16]*RTCDataChannel),
|
||||||
}
|
}
|
||||||
var err error
|
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