Skip to content

Commit 17d310f

Browse files
committed
Added hotplug support from libusb
1 parent 1e7da91 commit 17d310f

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

main.go

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

2121
/*
22-
#cgo CPPFLAGS: -DHAVE_UNISTD_H -DHAVE_NANOSLEEP -DHAVE_ERR -I. -Idfu-util-0.11/src -I/usr/include/libusb-1.0
23-
#cgo CFLAGS: -DHAVE_UNISTD_H -DHAVE_NANOSLEEP -DHAVE_ERR -I. -Idfu-util-0.11/src -I/usr/include/libusb-1.0
22+
#cgo CPPFLAGS: -DHAVE_UNISTD_H -DHAVE_NANOSLEEP -DHAVE_ERR -I. -Idfu-util-0.11/src -I/usr/include/libusb-1.0 -Wall
23+
#cgo CFLAGS: -DHAVE_UNISTD_H -DHAVE_NANOSLEEP -DHAVE_ERR -I. -Idfu-util-0.11/src -I/usr/include/libusb-1.0 -Wall
2424
#cgo LDFLAGS: -lusb-1.0
2525
2626
#include <dfu.h>
@@ -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)