Skip to content

Commit 849ace5

Browse files
committed
chore: verify host mode available and enabled
1 parent 8472aa0 commit 849ace5

File tree

6 files changed

+126
-10
lines changed

6 files changed

+126
-10
lines changed

.task/checksum/build

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
67563be1715a0a013997a8f9f75637e
1+
a83c8fc345928bd53180aac00c1667df

.task/checksum/build-debug

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
a86696d76dc0e7c46e7da1efaa995964
1+
a83c8fc345928bd53180aac00c1667df

cmd/bt-hid-relay/main.go

+14
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"log"
66
"os"
77

8+
"github.com/bahaaador/bluetooth-usb-peripheral-relay/internal/device"
89
"github.com/bahaaador/bluetooth-usb-peripheral-relay/internal/logger"
910
"github.com/bahaaador/bluetooth-usb-peripheral-relay/internal/relay"
1011
)
@@ -26,6 +27,19 @@ func parseFlags() relay.Config {
2627
func main() {
2728
config := parseFlags()
2829

30+
hasHostCapability, isHostEnabled, err := device.CheckUSBHostSupport()
31+
if err != nil {
32+
log.Fatal(err)
33+
}
34+
35+
if !hasHostCapability {
36+
log.Fatal("USB Host mode is not supported")
37+
}
38+
39+
if !isHostEnabled {
40+
log.Fatal("USB Host mode is not enabled")
41+
}
42+
2943
relay := relay.NewRelay(config)
3044
if err := relay.Start(); err != nil {
3145
log.Printf("Error: %v", err)

cmd/bt-hid-relay/main_test.go

+12-4
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ func TestMain(t *testing.T) {
146146
// Test with default arguments
147147
os.Args = []string{"cmd"}
148148

149-
// Create a channel to capture potential panics
149+
// Create channels for synchronization
150+
ready := make(chan bool)
150151
done := make(chan bool)
151152

152153
go func() {
@@ -160,9 +161,16 @@ func TestMain(t *testing.T) {
160161
done <- true
161162
}()
162163

163-
// Run main
164-
go main()
165-
time.Sleep(100 * time.Millisecond) // Let main initialize
164+
// Run main in a goroutine with synchronization
165+
go func() {
166+
ready <- true
167+
main()
168+
}()
169+
170+
// Wait for main to start
171+
<-ready
172+
// Give main some time to initialize
173+
time.Sleep(100 * time.Millisecond)
166174
osExit(0)
167175
}()
168176

cmd/diagnose-io/main.go

+37-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"fmt"
66
"log"
77
"os"
8+
"os/signal"
9+
"syscall"
810

911
"github.com/bahaaador/bluetooth-usb-peripheral-relay/internal/device"
1012
"github.com/bahaaador/bluetooth-usb-peripheral-relay/internal/relay"
@@ -24,6 +26,10 @@ func main() {
2426
fmt.Println("Bluetooth Device Verification Tool")
2527
fmt.Println("=================================")
2628

29+
if err := verifyUSBHostSupport(); err != nil {
30+
log.Fatal(err)
31+
}
32+
2733
if err := verifyDevices(); err != nil {
2834
log.Fatal(err)
2935
}
@@ -33,6 +39,28 @@ func main() {
3339
}
3440
}
3541

42+
func verifyUSBHostSupport() error {
43+
fmt.Println("\nChecking USB Host Support:")
44+
hasHostCapability, isHostEnabled, err := device.CheckUSBHostSupport()
45+
if err != nil {
46+
return fmt.Errorf("failed to check USB host support: %v", err)
47+
}
48+
49+
if !hasHostCapability {
50+
return fmt.Errorf("USB Host mode is not supported")
51+
} else {
52+
fmt.Printf("%s USB Host mode: supported\n", checkMark)
53+
}
54+
55+
if !isHostEnabled {
56+
return fmt.Errorf("USB Host mode is not enabled")
57+
} else {
58+
fmt.Printf("%s USB Host mode: enabled\n", checkMark)
59+
}
60+
61+
return nil
62+
}
63+
3664
func verifyDevices() error {
3765
// Check HID gadget devices
3866
fmt.Println("\nChecking HID gadget devices:")
@@ -94,7 +122,7 @@ func echoDeviceInputs() error {
94122

95123
// Only start readers for devices that were found
96124
if mouseDevice != "" {
97-
mouseFile, err := osOpenFile(mouseDevice, os.O_WRONLY, 0666)
125+
mouseFile, err := osOpenFile(mouseDevice, os.O_RDONLY, 0666)
98126
if err != nil {
99127
return fmt.Errorf("failed to open mouse device: %v", err)
100128
}
@@ -103,16 +131,21 @@ func echoDeviceInputs() error {
103131
}
104132

105133
if keyboardDevice != "" {
106-
keyboardFile, err := osOpenFile(keyboardDevice, os.O_WRONLY, 0666)
134+
keyboardFile, err := osOpenFile(keyboardDevice, os.O_RDONLY, 0666)
107135
if err != nil {
108136
return fmt.Errorf("failed to open keyboard device: %v", err)
109137
}
110138
defer keyboardFile.Close()
111139
go readInput(keyboardFile, "Keyboard")
112140
}
113141

114-
// Keep the program running
115-
select {}
142+
// Add a channel to handle program termination
143+
done := make(chan os.Signal, 1)
144+
signal.Notify(done, os.Interrupt, syscall.SIGTERM)
145+
146+
// Wait for interrupt signal
147+
<-done
148+
return nil
116149
}
117150

118151
func readInput(file *os.File, deviceName string) {

internal/device/host_check.go

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package device
2+
3+
import (
4+
"os"
5+
"strings"
6+
)
7+
8+
// CheckUSBHostSupport verifies both USB host hardware capability and if it's enabled
9+
func CheckUSBHostSupport() (hasCapability bool, isEnabled bool, err error) {
10+
// Check hardware capability first
11+
hasCapability = false
12+
13+
// Check for USB host controller presence
14+
if _, err := os.Stat("/sys/class/usb_host"); err == nil {
15+
hasCapability = true
16+
}
17+
18+
// Check USB controllers capabilities through kernel info
19+
controllers, err := os.ReadFile("/sys/kernel/debug/usb/devices")
20+
if err == nil {
21+
content := string(controllers)
22+
// Look for host controller interfaces (EHCI, XHCI, OHCI)
23+
if strings.Contains(content, "Cls=09") || // USB Hub Class
24+
strings.Contains(content, "EHCI") ||
25+
strings.Contains(content, "XHCI") ||
26+
strings.Contains(content, "OHCI") {
27+
hasCapability = true
28+
}
29+
}
30+
31+
// If no hardware capability, return early
32+
if !hasCapability {
33+
return hasCapability, false, nil
34+
}
35+
36+
// Check if it's enabled/configured
37+
isEnabled = false
38+
39+
// Check if the device tree has USB OTG support
40+
dtOverlay, err := os.ReadFile("/boot/config.txt")
41+
if err == nil && strings.Contains(string(dtOverlay), "dtoverlay=dwc2") {
42+
isEnabled = true
43+
}
44+
45+
// Check if the necessary modules are loaded
46+
modules, err := os.ReadFile("/proc/modules")
47+
if err == nil {
48+
moduleContent := string(modules)
49+
if strings.Contains(moduleContent, "dwc2") &&
50+
strings.Contains(moduleContent, "libcomposite") {
51+
isEnabled = true
52+
}
53+
}
54+
55+
// Check for USB gadget configfs support
56+
if _, err := os.Stat("/sys/kernel/config/usb_gadget"); err == nil {
57+
isEnabled = true
58+
}
59+
60+
return hasCapability, isEnabled, nil
61+
}

0 commit comments

Comments
 (0)