package hardware import ( "context" "fmt" "math/rand" "strings" "sync" "github.com/rs/zerolog/log" "github.com/wailsapp/wails/v2/pkg/runtime" ) // OS2LFinder represents how the protocol is defined type OS2LFinder struct { wg sync.WaitGroup mu sync.Mutex detected map[string]*OS2LPeripheral // The list of saved peripherals eventBus EventBus // The hardware event bus onArrival func(context.Context, Peripheral, bool) // When a peripheral arrives onRemoval func(context.Context, Peripheral) // When a peripheral goes away } // NewOS2LFinder creates a new OS2L finder func NewOS2LFinder(eventBus EventBus) *OS2LFinder { log.Trace().Str("file", "OS2LFinder").Msg("OS2L finder created") return &OS2LFinder{ detected: make(map[string]*OS2LPeripheral), eventBus: eventBus, } } // Initialize initializes the finder func (f *OS2LFinder) Initialize() error { // Subscribe to all OS2L peripherals that are added to the project f.eventBus.SubscribeType(f.GetName(), f) log.Trace().Str("file", "OS2LFinder").Msg("OS2L finder initialized") return nil } // OnArrival is the callback function when a new peripheral arrives func (f *OS2LFinder) OnArrival(cb func(context.Context, Peripheral, bool)) { f.onArrival = cb } // OnRemoval i the callback when a peripheral goes away func (f *OS2LFinder) OnRemoval(cb func(context.Context, Peripheral)) { f.onRemoval = cb } // Create creates a new peripheral, based on the peripheral information (manually created) func (f *OS2LFinder) Create(ctx context.Context, peripheralInfo PeripheralInfo) error { // If the SerialNumber is empty, generate another one if peripheralInfo.SerialNumber == "" { peripheralInfo.SerialNumber = strings.ToUpper(fmt.Sprintf("%08x", rand.Intn(1<<32))) } // Create a new OS2L peripheral peripheral, err := NewOS2LPeripheral(peripheralInfo) if err != nil { return fmt.Errorf("unable to create the OS2L peripheral: %w", err) } // Set the event callback peripheral.SetEventCallback(func(event any) { runtime.EventsEmit(ctx, string(PeripheralEventEmitted), peripheralInfo.SerialNumber, event) }) f.detected[peripheralInfo.SerialNumber] = peripheral if f.onArrival != nil { f.onArrival(ctx, peripheral, true) // Ask to register the peripheral in the project } return err } // Remove removes an existing peripheral (manually created) func (f *OS2LFinder) Remove(ctx context.Context, peripheral Peripheral) error { if f.onRemoval != nil { f.onRemoval(ctx, peripheral) } delete(f.detected, peripheral.GetInfo().SerialNumber) return nil } // GetName returns the name of the driver func (f *OS2LFinder) GetName() string { return "OS2L" } // Start starts the finder func (f *OS2LFinder) Start(ctx context.Context) error { // No peripherals to scan here return nil } // WaitStop stops the finder func (f *OS2LFinder) WaitStop() error { log.Trace().Str("file", "OS2LFinder").Msg("stopping the OS2L finder...") // Waiting internal tasks f.wg.Wait() log.Trace().Str("file", "OS2LFinder").Msg("OS2L finder stopped") return nil }