Skip to content

Commit 6a482b6

Browse files
committed
Added hotplug support from libusb
1 parent 7756816 commit 6a482b6

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

main.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,44 @@ void dfuProbeDevices() {
7979
clearDfuRoot();
8080
probe_devices(ctx);
8181
}
82+
83+
volatile int has_event = 0;
84+
85+
int libusbHandleEvents() {
86+
struct timeval tv;
87+
tv.tv_sec = 0;
88+
tv.tv_usec = 500000;
89+
libusb_handle_events_timeout_completed(ctx, &tv, NULL);
90+
int res = has_event;
91+
has_event = 0;
92+
return res;
93+
}
94+
95+
int callback(libusb_context *ctx, libusb_device *device, libusb_hotplug_event event, void *user_data) {
96+
has_event = 1;
97+
return 0;
98+
}
99+
100+
libusb_hotplug_callback_handle callbackHandle;
101+
102+
const char *libusbHotplugRegisterCallback() {
103+
int err = libusb_hotplug_register_callback(
104+
ctx,
105+
LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
106+
LIBUSB_HOTPLUG_NO_FLAGS,
107+
LIBUSB_HOTPLUG_MATCH_ANY, // Vendor ID
108+
LIBUSB_HOTPLUG_MATCH_ANY, // Product ID
109+
LIBUSB_HOTPLUG_MATCH_ANY, // Device Class
110+
callback, // Actual callback function
111+
NULL, // User data
112+
&callbackHandle
113+
);
114+
if (err != 0) {
115+
return libusb_strerror(err);
116+
}
117+
return NULL;
118+
}
119+
120+
void libusbHotplugDeregisterCallback() {
121+
libusb_hotplug_deregister_callback(ctx, callbackHandle);
122+
}

main.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
package main
1919

2020
/*
21-
#cgo CPPFLAGS: -DHAVE_UNISTD_H -DHAVE_NANOSLEEP -DHAVE_ERR -I. -Idfu-util-0.11/src -I/usr/local/include/libusb-1.0
22-
#cgo CFLAGS: -DHAVE_UNISTD_H -DHAVE_NANOSLEEP -DHAVE_ERR -I. -Idfu-util-0.11/src -I/usr/local/include/libusb-1.0
21+
#cgo CPPFLAGS: -DHAVE_UNISTD_H -DHAVE_NANOSLEEP -DHAVE_ERR -I. -Idfu-util-0.11/src -I/usr/local/include/libusb-1.0 -Wall
22+
#cgo CFLAGS: -DHAVE_UNISTD_H -DHAVE_NANOSLEEP -DHAVE_ERR -I. -Idfu-util-0.11/src -I/usr/local/include/libusb-1.0 -Wall
2323
#cgo darwin LDFLAGS: -L/usr/local/lib -lusb-1.0 -framework IOKit -framework CoreFoundation -framework Security
2424
#cgo !darwin LDFLAGS: -L/usr/local/lib -lusb-1.0
2525
@@ -32,13 +32,16 @@ char *get_path(libusb_device *dev);
3232
const char *libusbOpen();
3333
void libusbClose();
3434
void dfuProbeDevices();
35+
const char *libusbHotplugRegisterCallback();
36+
void libusbHotplugDeregisterCallback();
37+
int libusbHandleEvents();
3538
*/
3639
import "C"
3740

3841
import (
42+
"errors"
3943
"fmt"
4044
"os"
41-
"time"
4245

4346
"github.com/arduino/go-properties-orderedmap"
4447
discovery "github.com/arduino/pluggable-discovery-protocol-handler/v2"
@@ -84,16 +87,24 @@ func (d *DFUDiscovery) StartSync(eventCB discovery.EventCallback, errorCB discov
8487
if cErr := C.libusbOpen(); cErr != nil {
8588
return fmt.Errorf("can't open libusb: %s", C.GoString(cErr))
8689
}
90+
if err := C.libusbHotplugRegisterCallback(); err != nil {
91+
return errors.New(C.GoString(err))
92+
}
93+
8794
closeChan := make(chan struct{})
8895
go func() {
8996
d.portsCache = map[string]*discovery.Port{}
97+
d.sendUpdates(eventCB, errorCB)
9098
for {
91-
d.sendUpdates(eventCB, errorCB)
99+
if C.libusbHandleEvents() != 0 {
100+
d.sendUpdates(eventCB, errorCB)
101+
}
92102
select {
93-
case <-time.After(5 * time.Second):
94103
case <-closeChan:
104+
C.libusbHotplugDeregisterCallback()
95105
d.portsCache = nil
96106
return
107+
default:
97108
}
98109
}
99110
}()

0 commit comments

Comments
 (0)