11-hardware-definition #17

Merged
thinkode merged 13 commits from 11-hardware-definition into develop 2025-01-18 14:53:30 +00:00
7 changed files with 128 additions and 148 deletions
Showing only changes of commit ea325e23c5 - Show all commits

6
app.go
View File

@@ -28,9 +28,9 @@ type App struct {
func NewApp() *App {
// Create a new hadware manager
hardwareManager := hardware.NewHardwareManager()
hardwareManager.RegisterDriver(hardware.NewMIDIFinder(5 * time.Second))
hardwareManager.RegisterDriver(hardware.NewFTDIFinder(5 * time.Second))
// hardwareManager.RegisterDriver(hardware.NewOS2LDriver())
hardwareManager.RegisterFinder(hardware.NewMIDIFinder(5 * time.Second))
hardwareManager.RegisterFinder(hardware.NewFTDIFinder(5 * time.Second))
hardwareManager.RegisterFinder(hardware.NewOS2LFinder())
return &App{
hardwareManager: hardwareManager,
projectSave: "",

3
go.mod
View File

@@ -5,11 +5,9 @@ go 1.21
toolchain go1.21.3
require (
github.com/lxn/win v0.0.0-20210218163916-a377121e959e
github.com/mattrtaylor/go-rtmidi v0.0.0-20220428034745-af795b1c1a79
github.com/rs/zerolog v1.33.0
github.com/wailsapp/wails/v2 v2.9.1
golang.org/x/sys v0.20.0
gopkg.in/yaml.v2 v2.4.0
)
@@ -39,6 +37,7 @@ require (
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
)

3
go.sum
View File

@@ -28,8 +28,6 @@ github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/
github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8=
github.com/leaanthony/u v1.1.0 h1:2n0d2BwPVXSUq5yhe8lJPHdxevE2qK5G99PMStMZMaI=
github.com/leaanthony/u v1.1.0/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI=
github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+CtW96g0Or0Fxa9IKr4uc=
github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
@@ -81,7 +79,6 @@ golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@@ -1,69 +0,0 @@
package hardware
import (
"context"
"fmt"
"math/rand"
"strings"
"github.com/rs/zerolog/log"
)
// OS2LDriver represents how the protocol is defined
type OS2LDriver struct {
peripherals map[string]Peripheral // The list of peripherals
}
// NewOS2LDriver creates a new OS2L driver
func NewOS2LDriver() *OS2LDriver {
log.Trace().Str("file", "OS2LDriver").Msg("OS2L driver created")
return &OS2LDriver{
peripherals: make(map[string]Peripheral),
}
}
// Initialize initializes the MIDI driver
func (d *OS2LDriver) Initialize() error {
log.Trace().Str("file", "OS2LDriver").Msg("OS2L driver initialized")
return nil
}
// CreatePeripheral creates a new OS2L peripheral
func (d *OS2LDriver) CreatePeripheral(ctx context.Context) (Peripheral, error) {
// Create a random serial number for this peripheral
randomSerialNumber := strings.ToUpper(fmt.Sprintf("%08x", rand.Intn(1<<32)))
log.Trace().Str("file", "OS2LDriver").Str("serialNumber", randomSerialNumber).Msg("OS2L peripheral created")
peripheral := NewOS2LPeripheral("OS2L", randomSerialNumber)
d.peripherals[randomSerialNumber] = peripheral
log.Info().Str("file", "OS2LDriver").Str("serialNumber", randomSerialNumber).Msg("OS2L peripheral created and registered")
return peripheral, nil
}
// RemovePeripheral removes an OS2L dev
func (d *OS2LDriver) RemovePeripheral(serialNumber string) error {
delete(d.peripherals, serialNumber)
log.Info().Str("file", "OS2LDriver").Str("serialNumber", serialNumber).Msg("OS2L peripheral removed")
return nil
}
// GetName returns the name of the driver
func (d *OS2LDriver) GetName() string {
return "OS2L"
}
// GetPeripheral gets the peripheral that correspond to the specified ID
func (d *OS2LDriver) GetPeripheral(peripheralID string) (Peripheral, bool) {
// Return the specified peripheral
peripheral, found := d.peripherals[peripheralID]
if !found {
log.Error().Str("file", "OS2LDriver").Str("peripheralID", peripheralID).Msg("unable to get this peripheral in the OS2L driver")
return nil, false
}
log.Trace().Str("file", "OS2LDriver").Str("peripheralID", peripheralID).Msg("OS2L peripheral found in the driver")
return peripheral, true
}
// Scan scans the interfaces compatible with the MIDI protocol
func (d *OS2LDriver) Scan(ctx context.Context) error {
return nil
}

78
hardware/OS2LFinder.go Normal file
View File

@@ -0,0 +1,78 @@
package hardware
import (
"context"
"fmt"
"math/rand"
"strings"
"github.com/rs/zerolog/log"
)
// OS2LFinder represents how the protocol is defined
type OS2LFinder struct {
peripherals map[string]Peripheral // The list of peripherals
}
// NewOS2LFinder creates a new OS2L finder
func NewOS2LFinder() *OS2LFinder {
log.Trace().Str("file", "OS2LFinder").Msg("OS2L finder created")
return &OS2LFinder{
peripherals: make(map[string]Peripheral),
}
}
// Initialize initializes the finder
func (f *OS2LFinder) Initialize() error {
log.Trace().Str("file", "OS2LFinder").Msg("OS2L finder initialized")
return nil
}
// CreatePeripheral creates a new OS2L peripheral
func (f *OS2LFinder) CreatePeripheral(ctx context.Context) (Peripheral, error) {
// Create a random serial number for this peripheral
randomSerialNumber := strings.ToUpper(fmt.Sprintf("%08x", rand.Intn(1<<32)))
log.Trace().Str("file", "OS2LFinder").Str("serialNumber", randomSerialNumber).Msg("OS2L peripheral created")
peripheral := NewOS2LPeripheral("OS2L", randomSerialNumber)
f.peripherals[randomSerialNumber] = peripheral
log.Info().Str("file", "OS2LFinder").Str("serialNumber", randomSerialNumber).Msg("OS2L peripheral created and registered")
return peripheral, nil
}
// DeletePeripheral removes an OS2L peripheral
func (f *OS2LFinder) DeletePeripheral(serialNumber string) error {
delete(f.peripherals, serialNumber)
log.Info().Str("file", "OS2LFinder").Str("serialNumber", serialNumber).Msg("OS2L peripheral removed")
return nil
}
// GetName returns the name of the driver
func (f *OS2LFinder) GetName() string {
return "OS2L"
}
// GetPeripheral gets the peripheral that correspond to the specified ID
func (f *OS2LFinder) GetPeripheral(peripheralID string) (Peripheral, bool) {
// Return the specified peripheral
peripheral, found := f.peripherals[peripheralID]
if !found {
log.Error().Str("file", "OS2LFinder").Str("peripheralID", peripheralID).Msg("unable to get this peripheral in the OS2L finder")
return nil, false
}
log.Trace().Str("file", "OS2LFinder").Str("peripheralID", peripheralID).Msg("OS2L peripheral found in the finder")
return peripheral, true
}
// Start starts the finder
func (f *OS2LFinder) Start(ctx context.Context) error {
return nil
}
// Stop stops this finder
func (f *OS2LFinder) Stop() error {
return nil
}
// ForceScan scans the interfaces (not implemented)
func (f *OS2LFinder) ForceScan() {
}

View File

@@ -8,9 +8,7 @@ import (
"github.com/rs/zerolog/log"
"github.com/lxn/win"
"github.com/wailsapp/wails/v2/pkg/runtime"
"golang.org/x/sys/windows"
)
// PeripheralEvent is trigger by the finders when the scan is complete
@@ -21,7 +19,7 @@ const (
PeripheralArrival PeripheralEvent = "PERIPHERAL_ARRIVAL"
// PeripheralRemoval is triggered when a peripheral has been disconnected from the system
PeripheralRemoval PeripheralEvent = "PERIPHERAL_REMOVAL"
debounceDuration = 500 * time.Millisecond
// debounceDuration = 500 * time.Millisecond
)
var (
@@ -30,7 +28,7 @@ var (
// HardwareManager is the class who manages the hardware
type HardwareManager struct {
drivers map[string]PeripheralFinder // The map of peripherals finders
finders map[string]PeripheralFinder // The map of peripherals finders
peripherals []Peripheral // The current list of peripherals
peripheralsScanTrigger chan struct{} // Trigger the peripherals scans
goWait sync.WaitGroup // Wait for goroutines to terminate
@@ -40,7 +38,7 @@ type HardwareManager struct {
func NewHardwareManager() *HardwareManager {
log.Trace().Str("package", "hardware").Msg("Hardware instance created")
return &HardwareManager{
drivers: make(map[string]PeripheralFinder),
finders: make(map[string]PeripheralFinder),
peripherals: make([]Peripheral, 0),
peripheralsScanTrigger: make(chan struct{}),
}
@@ -48,7 +46,7 @@ func NewHardwareManager() *HardwareManager {
// Start starts to find new peripheral events
func (h *HardwareManager) Start(ctx context.Context) error {
for finderName, finder := range h.drivers {
for finderName, finder := range h.finders {
err := finder.Initialize()
if err != nil {
log.Err(err).Str("file", "hardware").Str("finderName", finderName).Msg("unable to initialize finder")
@@ -60,60 +58,53 @@ func (h *HardwareManager) Start(ctx context.Context) error {
return err
}
}
// n, err := detector.Register()
// if err != nil {
// log.Err(err).Str("file", "hardware").Msg("error registering the usb event")
// }
// h.detector = n
// // Run the detector
// n.Run(ctx)
// h.goWait.Add(1)
// go func() {
// defer h.goWait.Done()
// for {
// select {
// case <-ctx.Done():
// return
// case <-h.detector.EventChannel:
// // Trigger hardware scans
// log.Info().Str("file", "hardware").Msg("peripheral change event")
// case <-h.peripheralsScanTrigger:
// log.Info().Str("file", "hardware").Msg("scan triggered")
// }
// }
// }()
h.goWait.Add(1)
go func() {
defer h.goWait.Done()
for {
select {
case <-ctx.Done():
return
case <-h.peripheralsScanTrigger:
for finderName, finder := range h.finders {
log.Trace().Str("file", "hardware").Str("finderName", finderName).Msg("force a finder to scan peripherals")
finder.ForceScan()
}
}
}
}()
return nil
}
// GetDriver returns a register driver
func (h *HardwareManager) GetDriver(driverName string) (PeripheralFinder, error) {
driver, exists := h.drivers[driverName]
// GetFinder returns a register finder
func (h *HardwareManager) GetFinder(finderName string) (PeripheralFinder, error) {
finder, exists := h.finders[finderName]
if !exists {
log.Error().Str("file", "hardware").Str("driverName", driverName).Msg("unable to get the driver")
return nil, fmt.Errorf("Unable to locate the '%s' driver", driverName)
log.Error().Str("file", "hardware").Str("finderName", finderName).Msg("unable to get the finder")
return nil, fmt.Errorf("unable to locate the '%s' finder", finderName)
}
log.Debug().Str("file", "hardware").Str("driverName", driverName).Msg("got driver")
return driver, nil
log.Debug().Str("file", "hardware").Str("finderName", finderName).Msg("got finder")
return finder, nil
}
// RegisterDriver registers a new peripherals driver
func (h *HardwareManager) RegisterDriver(driver PeripheralFinder) {
h.drivers[driver.GetName()] = driver
log.Info().Str("file", "hardware").Str("driverName", driver.GetName()).Msg("driver registered")
// RegisterFinder registers a new peripherals finder
func (h *HardwareManager) RegisterFinder(finder PeripheralFinder) {
h.finders[finder.GetName()] = finder
log.Info().Str("file", "hardware").Str("finderName", finder.GetName()).Msg("finder registered")
}
// GetPeripheral gets the peripheral object from the parent driver
func (h *HardwareManager) GetPeripheral(driverName string, peripheralID string) (Peripheral, bool) {
// Get the driver
parentDriver, found := h.drivers[driverName]
// If no driver found, return false
// GetPeripheral gets the peripheral object from the parent finder
func (h *HardwareManager) GetPeripheral(finderName string, peripheralID string) (Peripheral, bool) {
// Get the finder
parentFinder, found := h.finders[finderName]
// If no finder found, return false
if !found {
log.Error().Str("file", "hardware").Str("driverName", driverName).Msg("unable to get the driver")
log.Error().Str("file", "hardware").Str("finderName", finderName).Msg("unable to get the finder")
return nil, false
}
log.Trace().Str("file", "hardware").Str("driverName", parentDriver.GetName()).Msg("driver got")
// Contact the driver to get the device
return parentDriver.GetPeripheral(peripheralID)
log.Trace().Str("file", "hardware").Str("finderName", parentFinder.GetName()).Msg("finder got")
// Contact the finder to get the peripheral
return parentFinder.GetPeripheral(peripheralID)
}
// Scan scans all the peripherals for the registered finders
@@ -122,27 +113,11 @@ func (h *HardwareManager) Scan() error {
return nil
}
func (h *HardwareManager) wndProc(hwnd windows.HWND, msg uint32, wParam, lParam uintptr) uintptr {
log.Trace().Str("file", "hardware").Uint32("msg", msg).Msg("wndProc triggered")
if msg == win.WM_DEVICECHANGE {
// Trigger the devices scan when the last DEVICE_CHANGE event is received
if debounceTimer != nil {
debounceTimer.Stop()
log.Debug().Str("file", "hardware").Msg("scan debounce timer stopped")
}
debounceTimer = time.AfterFunc(debounceDuration, func() {
log.Debug().Str("file", "hardware").Msg("peripheral changed")
h.peripheralsScanTrigger <- struct{}{}
})
}
return win.DefWindowProc(win.HWND(hwnd), msg, wParam, lParam)
}
// Stop stops the hardware manager
func (h *HardwareManager) Stop() error {
log.Trace().Str("file", "hardware").Msg("closing the hardware manager")
// Stop each finder
for finderName, finder := range h.drivers {
for finderName, finder := range h.finders {
err := finder.Stop()
if err != nil {
log.Err(err).Str("file", "hardware").Str("finderName", finderName).Msg("unable to stop the finder")

View File

@@ -35,7 +35,7 @@ func (a *App) RemovePeripheral(protocolName string, peripheralID string) error {
// AddOS2LPeripheral adds a new OS2L peripheral
func (a *App) AddOS2LPeripheral() (hardware.PeripheralInfo, error) {
// Get the OS2L driver
os2lDriver, err := a.hardwareManager.GetDriver("OS2L")
os2lDriver, err := a.hardwareManager.GetFinder("OS2L")
if err != nil {
log.Err(err).Str("file", "peripheral").Msg("unable to found the OS2L driver")
return hardware.PeripheralInfo{}, err
@@ -59,7 +59,7 @@ func (a *App) AddOS2LPeripheral() (hardware.PeripheralInfo, error) {
func (a *App) ConnectFTDI() error {
// Connect the FTDI
driver, err := a.hardwareManager.GetDriver("FTDI")
driver, err := a.hardwareManager.GetFinder("FTDI")
if err != nil {
return err
}
@@ -72,7 +72,7 @@ func (a *App) ConnectFTDI() error {
func (a *App) ActivateFTDI() error {
// Connect the FTDI
driver, err := a.hardwareManager.GetDriver("FTDI")
driver, err := a.hardwareManager.GetFinder("FTDI")
if err != nil {
return err
}
@@ -85,7 +85,7 @@ func (a *App) ActivateFTDI() error {
func (a *App) SetDeviceFTDI(channelValue byte) error {
// Connect the FTDI
driver, err := a.hardwareManager.GetDriver("FTDI")
driver, err := a.hardwareManager.GetFinder("FTDI")
if err != nil {
return err
}
@@ -98,7 +98,7 @@ func (a *App) SetDeviceFTDI(channelValue byte) error {
func (a *App) DeactivateFTDI() error {
// Connect the FTDI
driver, err := a.hardwareManager.GetDriver("FTDI")
driver, err := a.hardwareManager.GetFinder("FTDI")
if err != nil {
return err
}
@@ -111,7 +111,7 @@ func (a *App) DeactivateFTDI() error {
func (a *App) DisconnectFTDI() error {
// Connect the FTDI
driver, err := a.hardwareManager.GetDriver("FTDI")
driver, err := a.hardwareManager.GetFinder("FTDI")
if err != nil {
return err
}