Files
olcrtc/internal/carrier/builtin/engine_adapter.go
zarazaex69 dc1fe0f19c refactor: replace -carrier with -auth/-engine/-url/-token (stage E)
Break CLI backwards compatibility as planned for refactor/universal-carrier:

- Drop -carrier flag; add -auth (auth provider name), -engine (engine
  name for -auth none), -url and -token (SFU endpoint + access token for
  direct/none auth mode).
- session.Config.Carrier → Auth + Engine + URL + Token.
- session.Gen() is now generic: auth.Get(cfg.Auth).(auth.RoomCreator)
  replaces the hard-coded switch on carrier names.
- Register a "none" carrier in builtin (registerDirect) that bypasses
  auth and connects directly to any engine with caller-supplied URL+Token.
- auth/telemost.Provider.Issue now accepts a raw room-ID hash in addition
  to a full https://telemost.yandex.ru/j/<id> URL.
- Plumb Engine/URL/Token from session.Config through server.Run,
  client.Run/RunWithReady, bringUpLink, link.Config, transport.Config, and
  carrier.Config so the "none" carrier has access to them end-to-end.
- Update all tests and mobile.go call sites.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 13:31:07 +03:00

187 lines
5.3 KiB
Go

package builtin
import (
"context"
"fmt"
"github.com/openlibrecommunity/olcrtc/internal/auth"
"github.com/openlibrecommunity/olcrtc/internal/carrier"
"github.com/openlibrecommunity/olcrtc/internal/engine"
"github.com/pion/webrtc/v4"
)
// registerDirect registers a carrier that skips auth entirely — the caller
// supplies the engine name, SFU URL, and access token directly via
// carrier.Config.Engine / carrier.Config.URL / carrier.Config.Token.
func registerDirect(carrierName string) {
carrier.Register(carrierName, func(ctx context.Context, cfg carrier.Config) (carrier.Session, error) {
engineName := cfg.Engine
if engineName == "" {
engineName = "livekit"
}
sess, err := engine.New(ctx, engineName, engine.Config{
URL: cfg.URL,
Token: cfg.Token,
Name: cfg.Name,
OnData: cfg.OnData,
DNSServer: cfg.DNSServer,
ProxyAddr: cfg.ProxyAddr,
ProxyPort: cfg.ProxyPort,
})
if err != nil {
return nil, fmt.Errorf("engine new: %w", err)
}
return &engineSession{session: sess}, nil
})
}
// registerEngineAuth registers a carrier name that resolves credentials
// through an auth provider and connects via the engine the auth provider
// reports.
func registerEngineAuth(carrierName string, authProvider auth.Provider) {
carrier.Register(carrierName, func(ctx context.Context, cfg carrier.Config) (carrier.Session, error) {
authCfg := auth.Config{
RoomURL: cfg.RoomURL,
Name: cfg.Name,
DNSServer: cfg.DNSServer,
ProxyAddr: cfg.ProxyAddr,
ProxyPort: cfg.ProxyPort,
}
creds, err := authProvider.Issue(ctx, authCfg)
if err != nil {
return nil, fmt.Errorf("auth issue: %w", err)
}
sess, err := engine.New(ctx, authProvider.Engine(), engine.Config{
URL: creds.URL,
Token: creds.Token,
Name: cfg.Name,
Extra: creds.Extra,
OnData: cfg.OnData,
DNSServer: cfg.DNSServer,
ProxyAddr: cfg.ProxyAddr,
ProxyPort: cfg.ProxyPort,
Refresh: func(ctx context.Context) (engine.Credentials, error) {
fresh, err := authProvider.Issue(ctx, authCfg)
if err != nil {
return engine.Credentials{}, fmt.Errorf("auth refresh: %w", err)
}
return engine.Credentials{URL: fresh.URL, Token: fresh.Token, Extra: fresh.Extra}, nil
},
})
if err != nil {
return nil, fmt.Errorf("engine new: %w", err)
}
return &engineSession{session: sess}, nil
})
}
type engineSession struct {
session engine.Session
}
func (s *engineSession) Capabilities() carrier.Capabilities {
caps := s.session.Capabilities()
return carrier.Capabilities{ByteStream: caps.ByteStream, VideoTrack: caps.VideoTrack}
}
func (s *engineSession) OpenByteStream() (carrier.ByteStream, error) {
if !s.session.Capabilities().ByteStream {
return nil, carrier.ErrByteStreamUnsupported
}
return &engineByteStream{session: s.session}, nil
}
func (s *engineSession) OpenVideoTrack() (carrier.VideoTrack, error) {
vt, ok := s.session.(engine.VideoTrackCapable)
if !ok {
return nil, carrier.ErrVideoTrackUnsupported
}
return &engineVideoTrack{session: s.session, vt: vt}, nil
}
type engineByteStream struct {
session engine.Session
}
func (b *engineByteStream) Connect(ctx context.Context) error {
if err := b.session.Connect(ctx); err != nil {
return fmt.Errorf("connect: %w", err)
}
return nil
}
func (b *engineByteStream) Send(data []byte) error {
if err := b.session.Send(data); err != nil {
return fmt.Errorf("send: %w", err)
}
return nil
}
func (b *engineByteStream) Close() error {
if err := b.session.Close(); err != nil {
return fmt.Errorf("close: %w", err)
}
return nil
}
func (b *engineByteStream) SetReconnectCallback(cb func()) {
b.session.SetReconnectCallback(func(_ *webrtc.DataChannel) {
if cb != nil {
cb()
}
})
}
func (b *engineByteStream) SetShouldReconnect(fn func() bool) { b.session.SetShouldReconnect(fn) }
func (b *engineByteStream) SetEndedCallback(cb func(string)) { b.session.SetEndedCallback(cb) }
func (b *engineByteStream) WatchConnection(ctx context.Context) {
b.session.WatchConnection(ctx)
}
func (b *engineByteStream) CanSend() bool { return b.session.CanSend() }
type engineVideoTrack struct {
session engine.Session
vt engine.VideoTrackCapable
}
func (v *engineVideoTrack) Connect(ctx context.Context) error {
if err := v.session.Connect(ctx); err != nil {
return fmt.Errorf("connect: %w", err)
}
return nil
}
func (v *engineVideoTrack) Close() error {
if err := v.session.Close(); err != nil {
return fmt.Errorf("close: %w", err)
}
return nil
}
func (v *engineVideoTrack) SetReconnectCallback(cb func()) {
v.session.SetReconnectCallback(func(_ *webrtc.DataChannel) {
if cb != nil {
cb()
}
})
}
func (v *engineVideoTrack) SetShouldReconnect(fn func() bool) { v.session.SetShouldReconnect(fn) }
func (v *engineVideoTrack) SetEndedCallback(cb func(string)) { v.session.SetEndedCallback(cb) }
func (v *engineVideoTrack) WatchConnection(ctx context.Context) {
v.session.WatchConnection(ctx)
}
func (v *engineVideoTrack) CanSend() bool { return v.session.CanSend() }
func (v *engineVideoTrack) AddTrack(track webrtc.TrackLocal) error {
if err := v.vt.AddVideoTrack(track); err != nil {
return fmt.Errorf("add track: %w", err)
}
return nil
}
func (v *engineVideoTrack) SetTrackHandler(cb func(*webrtc.TrackRemote, *webrtc.RTPReceiver)) {
v.vt.SetVideoTrackHandler(cb)
}