2025-11-30 19:57:34 +01:00
|
|
|
package os2l
|
2025-11-30 18:57:20 +01:00
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2025-11-30 19:57:34 +01:00
|
|
|
"dmxconnect/hardware"
|
2025-11-30 18:57:20 +01:00
|
|
|
"fmt"
|
|
|
|
|
"math/rand"
|
|
|
|
|
"strings"
|
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
|
"github.com/wailsapp/wails/v2/pkg/runtime"
|
|
|
|
|
)
|
|
|
|
|
|
2025-11-30 19:57:34 +01:00
|
|
|
// Provider represents how the protocol is defined
|
|
|
|
|
type Provider struct {
|
2025-11-30 18:57:20 +01:00
|
|
|
wg sync.WaitGroup
|
|
|
|
|
mu sync.Mutex
|
|
|
|
|
|
2025-11-30 19:57:34 +01:00
|
|
|
detected map[string]*Endpoint // The list of saved endpoints
|
2025-11-30 18:57:20 +01:00
|
|
|
|
2025-11-30 19:57:34 +01:00
|
|
|
onArrival func(context.Context, hardware.Endpoint) // When a endpoint arrives
|
|
|
|
|
onRemoval func(context.Context, hardware.Endpoint) // When a endpoint goes away
|
2025-11-30 18:57:20 +01:00
|
|
|
}
|
|
|
|
|
|
2025-11-30 19:57:34 +01:00
|
|
|
// NewProvider creates a new OS2L provider
|
|
|
|
|
func NewProvider() *Provider {
|
2025-11-30 18:57:20 +01:00
|
|
|
log.Trace().Str("file", "OS2LProvider").Msg("OS2L provider created")
|
2025-11-30 19:57:34 +01:00
|
|
|
return &Provider{
|
|
|
|
|
detected: make(map[string]*Endpoint),
|
2025-11-30 18:57:20 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initialize initializes the provider
|
2025-11-30 19:57:34 +01:00
|
|
|
func (f *Provider) Initialize() error {
|
2025-11-30 18:57:20 +01:00
|
|
|
log.Trace().Str("file", "OS2LProvider").Msg("OS2L provider initialized")
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// OnArrival is the callback function when a new endpoint arrives
|
2025-11-30 19:57:34 +01:00
|
|
|
func (f *Provider) OnArrival(cb func(context.Context, hardware.Endpoint)) {
|
2025-11-30 18:57:20 +01:00
|
|
|
f.onArrival = cb
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// OnRemoval if the callback when a endpoint goes away
|
2025-11-30 19:57:34 +01:00
|
|
|
func (f *Provider) OnRemoval(cb func(context.Context, hardware.Endpoint)) {
|
2025-11-30 18:57:20 +01:00
|
|
|
f.onRemoval = cb
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create creates a new endpoint, based on the endpoint information (manually created)
|
2025-11-30 19:57:34 +01:00
|
|
|
func (f *Provider) Create(ctx context.Context, endpointInfo hardware.EndpointInfo) (hardware.EndpointInfo, error) {
|
2025-11-30 18:57:20 +01:00
|
|
|
// If the SerialNumber is empty, generate another one
|
|
|
|
|
if endpointInfo.SerialNumber == "" {
|
|
|
|
|
endpointInfo.SerialNumber = strings.ToUpper(fmt.Sprintf("%08x", rand.Intn(1<<32)))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create a new OS2L endpoint
|
|
|
|
|
endpoint, err := NewOS2LEndpoint(endpointInfo)
|
|
|
|
|
if err != nil {
|
2025-11-30 19:57:34 +01:00
|
|
|
return hardware.EndpointInfo{}, fmt.Errorf("unable to create the OS2L endpoint: %w", err)
|
2025-11-30 18:57:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set the event callback
|
|
|
|
|
endpoint.SetEventCallback(func(event any) {
|
2025-11-30 19:57:34 +01:00
|
|
|
runtime.EventsEmit(ctx, string(hardware.EndpointEventEmitted), endpointInfo.SerialNumber, event)
|
2025-11-30 18:57:20 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
f.detected[endpointInfo.SerialNumber] = endpoint
|
|
|
|
|
|
|
|
|
|
if f.onArrival != nil {
|
|
|
|
|
f.onArrival(ctx, endpoint) // Ask to register the endpoint in the project
|
|
|
|
|
}
|
|
|
|
|
return endpointInfo, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remove removes an existing endpoint (manually created)
|
2025-11-30 19:57:34 +01:00
|
|
|
func (f *Provider) Remove(ctx context.Context, endpoint hardware.Endpoint) error {
|
2025-11-30 18:57:20 +01:00
|
|
|
if f.onRemoval != nil {
|
|
|
|
|
f.onRemoval(ctx, endpoint)
|
|
|
|
|
}
|
|
|
|
|
delete(f.detected, endpoint.GetInfo().SerialNumber)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetName returns the name of the driver
|
2025-11-30 19:57:34 +01:00
|
|
|
func (f *Provider) GetName() string {
|
2025-11-30 18:57:20 +01:00
|
|
|
return "OS2L"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Start starts the provider
|
2025-11-30 19:57:34 +01:00
|
|
|
func (f *Provider) Start(ctx context.Context) error {
|
2025-11-30 18:57:20 +01:00
|
|
|
// No endpoints to scan here
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// WaitStop stops the provider
|
2025-11-30 19:57:34 +01:00
|
|
|
func (f *Provider) WaitStop() error {
|
2025-11-30 18:57:20 +01:00
|
|
|
log.Trace().Str("file", "OS2LProvider").Msg("stopping the OS2L provider...")
|
|
|
|
|
|
|
|
|
|
// Waiting internal tasks
|
|
|
|
|
f.wg.Wait()
|
|
|
|
|
|
|
|
|
|
log.Trace().Str("file", "OS2LProvider").Msg("OS2L provider stopped")
|
|
|
|
|
return nil
|
|
|
|
|
}
|