diff --git a/cmd/olcrtc/main.go b/cmd/olcrtc/main.go index 402a8a7..6306a0d 100644 --- a/cmd/olcrtc/main.go +++ b/cmd/olcrtc/main.go @@ -19,6 +19,7 @@ import ( type config struct { mode string transport string + carrier string roomID string provider string socksPort int @@ -83,8 +84,9 @@ func parseFlags() config { flag.StringVar(&cfg.mode, "mode", "", "Mode: srv or cnc") flag.StringVar(&cfg.transport, "transport", "datachannel", "Transport: datachannel") + flag.StringVar(&cfg.carrier, "carrier", "", "Carrier: telemost, jazz, wb_stream") flag.StringVar(&cfg.roomID, "id", "", "Room ID") - flag.StringVar(&cfg.provider, "provider", "", "Provider: telemost or jazz (required)") + flag.StringVar(&cfg.provider, "provider", "", "Deprecated alias for -carrier") flag.IntVar(&cfg.socksPort, "socks-port", 1080, "SOCKS5 port (client only)") flag.StringVar(&cfg.socksHost, "socks-host", "127.0.0.1", "SOCKS5 listen host (client only)") flag.StringVar(&cfg.keyHex, "key", "", "Shared encryption key (hex)") @@ -131,7 +133,7 @@ func toSessionConfig(cfg config) session.Config { return session.Config{ Mode: cfg.mode, Transport: cfg.transport, - Provider: cfg.provider, + Carrier: firstNonEmpty(cfg.carrier, cfg.provider), RoomID: cfg.roomID, KeyHex: cfg.keyHex, SOCKSHost: cfg.socksHost, @@ -142,6 +144,15 @@ func toSessionConfig(cfg config) session.Config { } } +func firstNonEmpty(values ...string) string { + for _, value := range values { + if value != "" { + return value + } + } + return "" +} + func waitForShutdown(errCh <-chan error) error { done := make(chan error, 1) go func() { diff --git a/internal/app/session/session.go b/internal/app/session/session.go index f183956..5685d98 100644 --- a/internal/app/session/session.go +++ b/internal/app/session/session.go @@ -6,8 +6,8 @@ import ( "errors" "fmt" + "github.com/openlibrecommunity/olcrtc/internal/carrier" "github.com/openlibrecommunity/olcrtc/internal/client" - "github.com/openlibrecommunity/olcrtc/internal/provider" "github.com/openlibrecommunity/olcrtc/internal/provider/jazz" "github.com/openlibrecommunity/olcrtc/internal/provider/telemost" "github.com/openlibrecommunity/olcrtc/internal/provider/wbstream" @@ -21,10 +21,10 @@ var ( ErrRoomIDRequired = errors.New("room ID required") // ErrModeRequired indicates that mode is not one of the supported values. ErrModeRequired = errors.New("specify -mode srv or -mode cnc") - // ErrProviderRequired indicates that no provider was selected. - ErrProviderRequired = errors.New("provider required (use -provider telemost or -provider jazz)") - // ErrUnsupportedProvider indicates that provider is not registered. - ErrUnsupportedProvider = errors.New("unsupported provider") + // ErrCarrierRequired indicates that no carrier was selected. + ErrCarrierRequired = errors.New("carrier required (use -carrier telemost or -carrier jazz)") + // ErrUnsupportedCarrier indicates that carrier is not registered. + ErrUnsupportedCarrier = errors.New("unsupported carrier") // ErrUnsupportedTransport indicates that transport is not registered. ErrUnsupportedTransport = errors.New("unsupported transport") ) @@ -33,7 +33,7 @@ var ( type Config struct { Mode string Transport string - Provider string + Carrier string RoomID string KeyHex string SOCKSHost string @@ -45,20 +45,20 @@ type Config struct { // RegisterDefaults registers built-in providers and transports. func RegisterDefaults() { - provider.Register("jazz", jazz.New) - provider.Register("telemost", telemost.New) - provider.Register("wb_stream", wbstream.New) + carrier.Register("jazz", jazz.New) + carrier.Register("telemost", telemost.New) + carrier.Register("wb_stream", wbstream.New) transport.Register("datachannel", datachannel.New) } // Validate verifies that the runtime config refers to registered components. func Validate(cfg Config) error { - availableProviders := provider.Available() - validProvider := false - for _, p := range availableProviders { - if cfg.Provider == p { - validProvider = true + availableCarriers := carrier.Available() + validCarrier := false + for _, c := range availableCarriers { + if cfg.Carrier == c { + validCarrier = true break } } @@ -73,13 +73,13 @@ func Validate(cfg Config) error { } switch { - case cfg.Provider == "": - return ErrProviderRequired - case !validProvider: - return fmt.Errorf("%w: %s (available: %v)", ErrUnsupportedProvider, cfg.Provider, availableProviders) + case cfg.Carrier == "": + return ErrCarrierRequired + case !validCarrier: + return fmt.Errorf("%w: %s (available: %v)", ErrUnsupportedCarrier, cfg.Carrier, availableCarriers) case !validTransport: return fmt.Errorf("%w: %s (available: %v)", ErrUnsupportedTransport, cfg.Transport, availableTransports) - case cfg.RoomID == "" && cfg.Provider != "jazz": + case cfg.RoomID == "" && cfg.Carrier != "jazz": return ErrRoomIDRequired case cfg.Mode != "srv" && cfg.Mode != "cnc": return ErrModeRequired @@ -90,14 +90,14 @@ func Validate(cfg Config) error { // Run starts the configured mode. func Run(ctx context.Context, cfg Config) error { - roomURL := buildRoomURL(cfg.Provider, cfg.RoomID) + roomURL := buildRoomURL(cfg.Carrier, cfg.RoomID) switch cfg.Mode { case "srv": return server.Run( ctx, cfg.Transport, - cfg.Provider, + cfg.Carrier, roomURL, cfg.KeyHex, cfg.DNSServer, @@ -108,7 +108,7 @@ func Run(ctx context.Context, cfg Config) error { return client.Run( ctx, cfg.Transport, - cfg.Provider, + cfg.Carrier, roomURL, cfg.KeyHex, fmt.Sprintf("%s:%d", cfg.SOCKSHost, cfg.SOCKSPort), @@ -121,8 +121,8 @@ func Run(ctx context.Context, cfg Config) error { } } -func buildRoomURL(providerName, roomID string) string { - switch providerName { +func buildRoomURL(carrierName, roomID string) string { + switch carrierName { case "telemost": return "https://telemost.yandex.ru/j/" + roomID case "jazz": diff --git a/internal/carrier/carrier.go b/internal/carrier/carrier.go new file mode 100644 index 0000000..0e0cf9d --- /dev/null +++ b/internal/carrier/carrier.go @@ -0,0 +1,32 @@ +// Package carrier exposes carrier-oriented registration and construction APIs. +package carrier + +import ( + "context" + + "github.com/openlibrecommunity/olcrtc/internal/provider" +) + +// Carrier is the current carrier implementation contract. +type Carrier = provider.Provider + +// Config holds carrier configuration. +type Config = provider.Config + +// Factory creates a new carrier instance. +type Factory = provider.Factory + +// Register adds a carrier factory to the registry. +func Register(name string, factory Factory) { + provider.Register(name, factory) +} + +// New creates a carrier instance by name. +func New(ctx context.Context, name string, cfg Config) (Carrier, error) { + return provider.New(ctx, name, cfg) +} + +// Available returns a list of registered carriers. +func Available() []string { + return provider.Available() +} diff --git a/internal/transport/datachannel/transport.go b/internal/transport/datachannel/transport.go index dfd1b2d..f57e6ca 100644 --- a/internal/transport/datachannel/transport.go +++ b/internal/transport/datachannel/transport.go @@ -5,18 +5,18 @@ import ( "context" "fmt" - "github.com/openlibrecommunity/olcrtc/internal/provider" + "github.com/openlibrecommunity/olcrtc/internal/carrier" "github.com/openlibrecommunity/olcrtc/internal/transport" "github.com/pion/webrtc/v4" ) type providerTransport struct { - provider provider.Provider + carrier carrier.Carrier } // New creates a datachannel transport backed by a carrier-specific provider. func New(ctx context.Context, cfg transport.Config) (transport.Transport, error) { - p, err := provider.New(ctx, cfg.Carrier, provider.Config{ + c, err := carrier.New(ctx, cfg.Carrier, carrier.Config{ RoomURL: cfg.RoomURL, Name: cfg.Name, OnData: cfg.OnData, @@ -28,27 +28,27 @@ func New(ctx context.Context, cfg transport.Config) (transport.Transport, error) return nil, fmt.Errorf("create provider transport: %w", err) } - return &providerTransport{provider: p}, nil + return &providerTransport{carrier: c}, nil } // Connect starts the transport connection. func (p *providerTransport) Connect(ctx context.Context) error { - return p.provider.Connect(ctx) + return p.carrier.Connect(ctx) } // Send transmits data through the transport. func (p *providerTransport) Send(data []byte) error { - return p.provider.Send(data) + return p.carrier.Send(data) } // Close terminates the transport. func (p *providerTransport) Close() error { - return p.provider.Close() + return p.carrier.Close() } // SetReconnectCallback registers reconnect handling. func (p *providerTransport) SetReconnectCallback(cb func()) { - p.provider.SetReconnectCallback(func(_ *webrtc.DataChannel) { + p.carrier.SetReconnectCallback(func(_ *webrtc.DataChannel) { if cb != nil { cb() } @@ -57,20 +57,20 @@ func (p *providerTransport) SetReconnectCallback(cb func()) { // SetShouldReconnect configures reconnect policy. func (p *providerTransport) SetShouldReconnect(fn func() bool) { - p.provider.SetShouldReconnect(fn) + p.carrier.SetShouldReconnect(fn) } // SetEndedCallback registers end-of-session handling. func (p *providerTransport) SetEndedCallback(cb func(string)) { - p.provider.SetEndedCallback(cb) + p.carrier.SetEndedCallback(cb) } // WatchConnection monitors connection lifecycle. func (p *providerTransport) WatchConnection(ctx context.Context) { - p.provider.WatchConnection(ctx) + p.carrier.WatchConnection(ctx) } // CanSend reports whether transport is ready for sending. func (p *providerTransport) CanSend() bool { - return p.provider.CanSend() + return p.carrier.CanSend() }