forked from pion/webrtc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rtcsignalingstate.go
179 lines (161 loc) · 5.47 KB
/
rtcsignalingstate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package webrtc
import (
"fmt"
"github.com/pions/webrtc/pkg/rtcerr"
"github.com/pkg/errors"
)
type rtcStateChangeOp int
const (
rtcStateChangeOpSetLocal rtcStateChangeOp = iota + 1
rtcStateChangeOpSetRemote
)
func (op rtcStateChangeOp) String() string {
switch op {
case rtcStateChangeOpSetLocal:
return "SetLocal"
case rtcStateChangeOpSetRemote:
return "SetRemote"
default:
return "Unknown State Change Operation"
}
}
// RTCSignalingState indicates the signaling state of the offer/answer process.
type RTCSignalingState int
const (
// RTCSignalingStateStable indicates there is no offer/answer exchange in
// progress. This is also the initial state, in which case the local and
// remote descriptions are nil.
RTCSignalingStateStable RTCSignalingState = iota + 1
// RTCSignalingStateHaveLocalOffer indicates that a local description, of
// type "offer", has been successfully applied.
RTCSignalingStateHaveLocalOffer
// RTCSignalingStateHaveRemoteOffer indicates that a remote description, of
// type "offer", has been successfully applied.
RTCSignalingStateHaveRemoteOffer
// RTCSignalingStateHaveLocalPranswer indicates that a remote description
// of type "offer" has been successfully applied and a local description
// of type "pranswer" has been successfully applied.
RTCSignalingStateHaveLocalPranswer
// RTCSignalingStateHaveRemotePranswer indicates that a local description
// of type "offer" has been successfully applied and a remote description
// of type "pranswer" has been successfully applied.
RTCSignalingStateHaveRemotePranswer
// RTCSignalingStateClosed indicates The RTCPeerConnection has been closed.
RTCSignalingStateClosed
)
// This is done this way because of a linter.
const (
rtcSignalingStateStableStr = "stable"
rtcSignalingStateHaveLocalOfferStr = "have-local-offer"
rtcSignalingStateHaveRemoteOfferStr = "have-remote-offer"
rtcSignalingStateHaveLocalPranswerStr = "have-local-pranswer"
rtcSignalingStateHaveRemotePranswerStr = "have-remote-pranswer"
rtcSignalingStateClosedStr = "closed"
)
func newRTCSignalingState(raw string) RTCSignalingState {
switch raw {
case rtcSignalingStateStableStr:
return RTCSignalingStateStable
case rtcSignalingStateHaveLocalOfferStr:
return RTCSignalingStateHaveLocalOffer
case rtcSignalingStateHaveRemoteOfferStr:
return RTCSignalingStateHaveRemoteOffer
case rtcSignalingStateHaveLocalPranswerStr:
return RTCSignalingStateHaveLocalPranswer
case rtcSignalingStateHaveRemotePranswerStr:
return RTCSignalingStateHaveRemotePranswer
case rtcSignalingStateClosedStr:
return RTCSignalingStateClosed
default:
return RTCSignalingState(Unknown)
}
}
func (t RTCSignalingState) String() string {
switch t {
case RTCSignalingStateStable:
return rtcSignalingStateStableStr
case RTCSignalingStateHaveLocalOffer:
return rtcSignalingStateHaveLocalOfferStr
case RTCSignalingStateHaveRemoteOffer:
return rtcSignalingStateHaveRemoteOfferStr
case RTCSignalingStateHaveLocalPranswer:
return rtcSignalingStateHaveLocalPranswerStr
case RTCSignalingStateHaveRemotePranswer:
return rtcSignalingStateHaveRemotePranswerStr
case RTCSignalingStateClosed:
return rtcSignalingStateClosedStr
default:
return ErrUnknownType.Error()
}
}
func checkNextSignalingState(cur, next RTCSignalingState, op rtcStateChangeOp, sdpType RTCSdpType) (RTCSignalingState, error) {
// Special case for rollbacks
if sdpType == RTCSdpTypeRollback && cur == RTCSignalingStateStable {
return cur, &rtcerr.InvalidModificationError{
Err: errors.New("Can't rollback from stable state"),
}
}
// 4.3.1 valid state transitions
switch cur {
case RTCSignalingStateStable:
switch op {
case rtcStateChangeOpSetLocal:
// stable->SetLocal(offer)->have-local-offer
if sdpType == RTCSdpTypeOffer && next == RTCSignalingStateHaveLocalOffer {
return next, nil
}
case rtcStateChangeOpSetRemote:
// stable->SetRemote(offer)->have-remote-offer
if sdpType == RTCSdpTypeOffer && next == RTCSignalingStateHaveRemoteOffer {
return next, nil
}
}
case RTCSignalingStateHaveLocalOffer:
if op == rtcStateChangeOpSetRemote {
switch sdpType {
// have-local-offer->SetRemote(answer)->stable
case RTCSdpTypeAnswer:
if next == RTCSignalingStateStable {
return next, nil
}
// have-local-offer->SetRemote(pranswer)->have-remote-pranswer
case RTCSdpTypePranswer:
if next == RTCSignalingStateHaveRemotePranswer {
return next, nil
}
}
}
case RTCSignalingStateHaveRemotePranswer:
if op == rtcStateChangeOpSetRemote && sdpType == RTCSdpTypeAnswer {
// have-remote-pranswer->SetRemote(answer)->stable
if next == RTCSignalingStateStable {
return next, nil
}
}
case RTCSignalingStateHaveRemoteOffer:
if op == rtcStateChangeOpSetLocal {
switch sdpType {
// have-remote-offer->SetLocal(answer)->stable
case RTCSdpTypeAnswer:
if next == RTCSignalingStateStable {
return next, nil
}
// have-remote-offer->SetLocal(pranswer)->have-local-pranswer
case RTCSdpTypePranswer:
if next == RTCSignalingStateHaveLocalPranswer {
return next, nil
}
}
}
case RTCSignalingStateHaveLocalPranswer:
if op == rtcStateChangeOpSetLocal && sdpType == RTCSdpTypeAnswer {
// have-local-pranswer->SetLocal(answer)->stable
if next == RTCSignalingStateStable {
return next, nil
}
}
}
return cur, &rtcerr.InvalidModificationError{
Err: fmt.Errorf("Invalid proposed signaling state transition %s->%s(%s)->%s", cur, op, sdpType, next),
}
}