66 lines
1.7 KiB
Go
66 lines
1.7 KiB
Go
package asterisk
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/CyCoreSystems/ari/v5"
|
|
)
|
|
|
|
// awaitDialUp only runs after Dial was submitted. Create enters Stasis before
|
|
// any SIP request is sent, so StasisStart alone can never prove an answer.
|
|
func awaitDialUp(ctx context.Context, sub ari.Subscription, channelID string) error {
|
|
if ctx == nil || sub == nil || channelID == "" {
|
|
return errors.New("native answer wait has no channel subscription")
|
|
}
|
|
stasis, up := false, false
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return ctx.Err()
|
|
case event, ok := <-sub.Events():
|
|
if !ok {
|
|
return errors.New("native answer subscription closed before confirmed answer")
|
|
}
|
|
if event == nil {
|
|
continue
|
|
}
|
|
switch e := event.(type) {
|
|
case *ari.StasisStart:
|
|
if e.Channel.ID == channelID {
|
|
stasis = true
|
|
}
|
|
case *ari.ChannelStateChange:
|
|
if e.Channel.ID == channelID && e.Channel.State == "Up" {
|
|
up = true
|
|
}
|
|
case *ari.ChannelDestroyed:
|
|
if e.Channel.ID == channelID {
|
|
return fmt.Errorf("native outbound channel destroyed before verified answer: cause=%d", e.Cause)
|
|
}
|
|
case *ari.ChannelHangupRequest:
|
|
if e.Channel.ID == channelID {
|
|
return fmt.Errorf("native outbound channel requested hangup before verified answer: cause=%d", e.Cause)
|
|
}
|
|
case *ari.StasisEnd:
|
|
if e.Channel.ID == channelID {
|
|
return errors.New("native outbound channel left Stasis before verified answer")
|
|
}
|
|
}
|
|
if stasis && up {
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func eventBelongsToChannel(event ari.Event, channelID string) bool {
|
|
for _, key := range event.Keys() {
|
|
if key != nil && key.Kind == "channel" && key.ID == channelID {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|