libusb 0.3.4 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Gemfile +1 -0
- data/History.md +10 -0
- data/README.md +19 -6
- data/Rakefile +1 -1
- data/ext/extconf.rb +17 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/AUTHORS +18 -6
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/COPYING +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ChangeLog +58 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/INSTALL +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.am +6 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.in +248 -174
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/NEWS +2 -2
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/PORTING +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/README +2 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/TODO +0 -0
- data/ext/libusbx-1.0.17/Xcode/common.xcconfig +40 -0
- data/ext/libusbx-1.0.17/Xcode/config.h +28 -0
- data/ext/libusbx-1.0.17/Xcode/debug.xcconfig +29 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx.xcodeproj/project.pbxproj +864 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx_debug.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx_release.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/release.xcconfig +29 -0
- data/ext/libusbx-1.0.17/aclocal.m4 +1112 -0
- data/ext/libusbx-1.0.17/android/README +114 -0
- data/ext/libusbx-1.0.17/android/config.h +90 -0
- data/ext/libusbx-1.0.17/android/jni/Android.mk +23 -0
- data/ext/libusbx-1.0.17/android/jni/Application.mk +19 -0
- data/ext/libusbx-1.0.17/android/jni/examples.mk +134 -0
- data/ext/libusbx-1.0.17/android/jni/libusb.mk +54 -0
- data/ext/libusbx-1.0.17/android/jni/tests.mk +56 -0
- data/ext/libusbx-1.0.17/compile +347 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.guess +164 -130
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.h.in +37 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.sub +174 -89
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure +723 -302
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure.ac +71 -20
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/depcomp +345 -185
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.am +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.in +95 -32
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/doxygen.cfg.in +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.am +5 -4
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.in +208 -104
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp.c +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp_threaded.c +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.c +188 -8
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.h +18 -5
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/fxload.c +90 -64
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.c +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.h +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt1.c +0 -0
- data/ext/libusbx-1.0.17/examples/hotplugtest.c +97 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/listdevs.c +12 -4
- data/ext/libusbx-1.0.17/examples/sam3u_benchmark.c +193 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/xusb.c +106 -49
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/install-sh +21 -14
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb-1.0.pc.in +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/Makefile.am +29 -10
- data/ext/libusbx-1.0.17/libusb/Makefile.in +914 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/core.c +378 -87
- data/ext/libusbx-1.0.17/libusb/descriptor.c +1199 -0
- data/ext/libusbx-1.0.17/libusb/hotplug.c +322 -0
- data/ext/libusbx-1.0.17/libusb/hotplug.h +82 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/io.c +182 -62
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.def +32 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.rc +2 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb.h +481 -32
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusbi.h +135 -38
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.c +591 -496
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.h +39 -46
- data/ext/libusbx-1.0.17/libusb/os/linux_netlink.c +345 -0
- data/ext/libusbx-1.0.17/libusb/os/linux_udev.c +306 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.c +653 -617
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.h +32 -0
- data/ext/{libusbx-1.0.14/libusb/os/openbsd_usb.c → libusbx-1.0.17/libusb/os/netbsd_usb.c} +70 -63
- data/ext/libusbx-1.0.17/libusb/os/openbsd_usb.c +823 -0
- data/ext/libusbx-1.0.17/libusb/os/poll_posix.c +51 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_posix.h +2 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.c +85 -106
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.h +14 -3
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.c +3 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.h +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.c +6 -5
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.h +0 -0
- data/ext/libusbx-1.0.17/libusb/os/wince_usb.c +1026 -0
- data/ext/libusbx-1.0.17/libusb/os/wince_usb.h +131 -0
- data/ext/libusbx-1.0.17/libusb/os/windows_common.h +108 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.c +92 -57
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.h +2 -63
- data/ext/libusbx-1.0.17/libusb/strerror.c +184 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/sync.c +24 -38
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/version.h +1 -1
- data/ext/libusbx-1.0.17/libusb/version_nano.h +1 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ltmain.sh +60 -41
- data/ext/{libusbx-1.0.14/aclocal.m4 → libusbx-1.0.17/m4/libtool.m4} +229 -1723
- data/ext/libusbx-1.0.17/m4/ltoptions.m4 +384 -0
- data/ext/libusbx-1.0.17/m4/ltsugar.m4 +123 -0
- data/ext/libusbx-1.0.17/m4/ltversion.m4 +23 -0
- data/ext/libusbx-1.0.17/m4/lt~obsolete.m4 +98 -0
- data/ext/libusbx-1.0.17/missing +215 -0
- data/ext/libusbx-1.0.17/tests/Makefile.am +6 -0
- data/ext/libusbx-1.0.17/tests/Makefile.in +583 -0
- data/ext/libusbx-1.0.17/tests/libusbx_testlib.h +107 -0
- data/ext/libusbx-1.0.17/tests/stress.c +160 -0
- data/ext/libusbx-1.0.17/tests/testlib.c +276 -0
- data/lib/libusb.rb +4 -0
- data/lib/libusb/call.rb +43 -1
- data/lib/libusb/constants.rb +5 -0
- data/lib/libusb/context.rb +100 -0
- data/lib/libusb/dev_handle.rb +27 -0
- data/lib/libusb/device.rb +10 -4
- data/lib/libusb/version_gem.rb +1 -1
- data/test/test_libusb_capability.rb +2 -2
- data/test/test_libusb_compat.rb +2 -2
- data/test/test_libusb_compat_mass_storage.rb +2 -2
- data/test/test_libusb_descriptors.rb +4 -2
- data/test/test_libusb_event_machine.rb +2 -2
- data/test/test_libusb_gc.rb +2 -2
- data/test/test_libusb_hotplug.rb +115 -0
- data/test/test_libusb_iso_transfer.rb +3 -3
- data/test/test_libusb_mass_storage.rb +6 -16
- data/test/test_libusb_mass_storage2.rb +26 -3
- data/test/test_libusb_structs.rb +2 -2
- data/test/test_libusb_threads.rb +2 -2
- data/test/test_libusb_version.rb +2 -2
- metadata +127 -68
- metadata.gz.sig +0 -0
- data/ext/libusbx-1.0.14/THANKS +0 -7
- data/ext/libusbx-1.0.14/compile +0 -143
- data/ext/libusbx-1.0.14/libusb/Makefile.in +0 -721
- data/ext/libusbx-1.0.14/libusb/descriptor.c +0 -731
- data/ext/libusbx-1.0.14/libusb/version_nano.h +0 -1
- data/ext/libusbx-1.0.14/missing +0 -376
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* darwin backend for libusbx 1.0
|
3
|
-
* Copyright © 2008-
|
3
|
+
* Copyright © 2008-2013 Nathan Hjelm <hjelmn@users.sourceforge.net>
|
4
4
|
*
|
5
5
|
* This library is free software; you can redistribute it and/or
|
6
6
|
* modify it under the terms of the GNU Lesser General Public
|
@@ -28,7 +28,19 @@
|
|
28
28
|
#include <IOKit/IOCFPlugIn.h>
|
29
29
|
|
30
30
|
/* IOUSBInterfaceInferface */
|
31
|
-
#if defined (
|
31
|
+
#if defined (kIOUSBInterfaceInterfaceID550)
|
32
|
+
|
33
|
+
#define usb_interface_t IOUSBInterfaceInterface550
|
34
|
+
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID550
|
35
|
+
#define InterfaceVersion 550
|
36
|
+
|
37
|
+
#elif defined (kIOUSBInterfaceInterfaceID500)
|
38
|
+
|
39
|
+
#define usb_interface_t IOUSBInterfaceInterface500
|
40
|
+
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID500
|
41
|
+
#define InterfaceVersion 500
|
42
|
+
|
43
|
+
#elif defined (kIOUSBInterfaceInterfaceID300)
|
32
44
|
|
33
45
|
#define usb_interface_t IOUSBInterfaceInterface300
|
34
46
|
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID300
|
@@ -46,24 +58,6 @@
|
|
46
58
|
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220
|
47
59
|
#define InterfaceVersion 220
|
48
60
|
|
49
|
-
#elif defined (kIOUSBInterfaceInterfaceID197)
|
50
|
-
|
51
|
-
#define usb_interface_t IOUSBInterfaceInterface197
|
52
|
-
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID197
|
53
|
-
#define InterfaceVersion 197
|
54
|
-
|
55
|
-
#elif defined (kIOUSBInterfaceInterfaceID190)
|
56
|
-
|
57
|
-
#define usb_interface_t IOUSBInterfaceInterface190
|
58
|
-
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID190
|
59
|
-
#define InterfaceVersion 190
|
60
|
-
|
61
|
-
#elif defined (kIOUSBInterfaceInterfaceID182)
|
62
|
-
|
63
|
-
#define usb_interface_t IOUSBInterfaceInterface182
|
64
|
-
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID182
|
65
|
-
#define InterfaceVersion 182
|
66
|
-
|
67
61
|
#else
|
68
62
|
|
69
63
|
#error "IOUSBFamily is too old. Please upgrade your OS"
|
@@ -71,7 +65,13 @@
|
|
71
65
|
#endif
|
72
66
|
|
73
67
|
/* IOUSBDeviceInterface */
|
74
|
-
#if defined (
|
68
|
+
#if defined (kIOUSBDeviceInterfaceID500)
|
69
|
+
|
70
|
+
#define usb_device_t IOUSBDeviceInterface500
|
71
|
+
#define DeviceInterfaceID kIOUSBDeviceInterfaceID500
|
72
|
+
#define DeviceVersion 500
|
73
|
+
|
74
|
+
#elif defined (kIOUSBDeviceInterfaceID320)
|
75
75
|
|
76
76
|
#define usb_device_t IOUSBDeviceInterface320
|
77
77
|
#define DeviceInterfaceID kIOUSBDeviceInterfaceID320
|
@@ -89,24 +89,11 @@
|
|
89
89
|
#define DeviceInterfaceID kIOUSBDeviceInterfaceID245
|
90
90
|
#define DeviceVersion 245
|
91
91
|
|
92
|
-
#elif defined (
|
93
|
-
|
92
|
+
#elif defined (kIOUSBDeviceInterfaceID220)
|
94
93
|
#define usb_device_t IOUSBDeviceInterface197
|
95
94
|
#define DeviceInterfaceID kIOUSBDeviceInterfaceID197
|
96
95
|
#define DeviceVersion 197
|
97
96
|
|
98
|
-
#elif defined (kIOUSBDeviceInterfaceID187)
|
99
|
-
|
100
|
-
#define usb_device_t IOUSBDeviceInterface187
|
101
|
-
#define DeviceInterfaceID kIOUSBDeviceInterfaceID187
|
102
|
-
#define DeviceVersion 187
|
103
|
-
|
104
|
-
#elif defined (kIOUSBDeviceInterfaceID182)
|
105
|
-
|
106
|
-
#define usb_device_t IOUSBDeviceInterface182
|
107
|
-
#define DeviceInterfaceID kIOUSBDeviceInterfaceID182
|
108
|
-
#define DeviceVersion 182
|
109
|
-
|
110
97
|
#else
|
111
98
|
|
112
99
|
#error "IOUSBFamily is too old. Please upgrade your OS"
|
@@ -121,13 +108,23 @@ typedef IOCFPlugInInterface *io_cf_plugin_ref_t;
|
|
121
108
|
typedef IONotificationPortRef io_notification_port_t;
|
122
109
|
|
123
110
|
/* private structures */
|
124
|
-
struct
|
111
|
+
struct darwin_cached_device {
|
112
|
+
struct list_head list;
|
125
113
|
IOUSBDeviceDescriptor dev_descriptor;
|
126
114
|
UInt32 location;
|
115
|
+
UInt64 parent_session;
|
116
|
+
UInt64 session;
|
117
|
+
UInt16 address;
|
127
118
|
char sys_path[21];
|
128
119
|
usb_device_t **device;
|
129
120
|
int open_count;
|
130
|
-
UInt8 first_config, active_config;
|
121
|
+
UInt8 first_config, active_config, port;
|
122
|
+
int can_enumerate;
|
123
|
+
int refcount;
|
124
|
+
};
|
125
|
+
|
126
|
+
struct darwin_device_priv {
|
127
|
+
struct darwin_cached_device *dev;
|
131
128
|
};
|
132
129
|
|
133
130
|
struct darwin_device_handle_priv {
|
@@ -150,20 +147,16 @@ struct darwin_transfer_priv {
|
|
150
147
|
int num_iso_packets;
|
151
148
|
|
152
149
|
/* Control */
|
153
|
-
#if !defined (LIBUSB_NO_TIMEOUT_DEVICE)
|
154
150
|
IOUSBDevRequestTO req;
|
155
|
-
#else
|
156
|
-
IOUSBDevRequest req;
|
157
|
-
#endif
|
158
151
|
|
159
152
|
/* Bulk */
|
160
153
|
};
|
161
154
|
|
162
|
-
|
163
|
-
|
164
|
-
|
155
|
+
/* structure for signaling io completion */
|
156
|
+
struct darwin_msg_async_io_complete {
|
157
|
+
struct usbi_transfer *itransfer;
|
158
|
+
IOReturn result;
|
159
|
+
UInt32 size;
|
165
160
|
};
|
166
161
|
|
167
|
-
|
168
|
-
|
169
162
|
#endif
|
@@ -0,0 +1,345 @@
|
|
1
|
+
/* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */
|
2
|
+
/*
|
3
|
+
* Linux usbfs backend for libusb
|
4
|
+
* Copyright (C) 2007-2009 Daniel Drake <dsd@gentoo.org>
|
5
|
+
* Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
|
6
|
+
* Copyright (c) 2013 Nathan Hjelm <hjelmn@mac.com>
|
7
|
+
*
|
8
|
+
* This library is free software; you can redistribute it and/or
|
9
|
+
* modify it under the terms of the GNU Lesser General Public
|
10
|
+
* License as published by the Free Software Foundation; either
|
11
|
+
* version 2.1 of the License, or (at your option) any later version.
|
12
|
+
*
|
13
|
+
* This library is distributed in the hope that it will be useful,
|
14
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
16
|
+
* Lesser General Public License for more details.
|
17
|
+
*
|
18
|
+
* You should have received a copy of the GNU Lesser General Public
|
19
|
+
* License along with this library; if not, write to the Free Software
|
20
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
21
|
+
*/
|
22
|
+
|
23
|
+
#include "config.h"
|
24
|
+
#include "libusb.h"
|
25
|
+
#include "libusbi.h"
|
26
|
+
#include "linux_usbfs.h"
|
27
|
+
|
28
|
+
#include <ctype.h>
|
29
|
+
#include <dirent.h>
|
30
|
+
#include <errno.h>
|
31
|
+
#include <fcntl.h>
|
32
|
+
#include <poll.h>
|
33
|
+
#include <stdio.h>
|
34
|
+
#include <stdlib.h>
|
35
|
+
#include <string.h>
|
36
|
+
#include <sys/types.h>
|
37
|
+
|
38
|
+
#ifdef HAVE_ASM_TYPES_H
|
39
|
+
#include <asm/types.h>
|
40
|
+
#endif
|
41
|
+
|
42
|
+
#ifdef HAVE_SYS_SOCKET_H
|
43
|
+
#include <sys/socket.h>
|
44
|
+
#endif
|
45
|
+
|
46
|
+
#include <arpa/inet.h>
|
47
|
+
|
48
|
+
#ifdef HAVE_LINUX_NETLINK_H
|
49
|
+
#include <linux/netlink.h>
|
50
|
+
#endif
|
51
|
+
|
52
|
+
#ifdef HAVE_LINUX_FILTER_H
|
53
|
+
#include <linux/filter.h>
|
54
|
+
#endif
|
55
|
+
|
56
|
+
#define KERNEL 1
|
57
|
+
|
58
|
+
static int linux_netlink_socket = -1;
|
59
|
+
static int netlink_control_pipe[2] = { -1, -1 };
|
60
|
+
static pthread_t libusb_linux_event_thread;
|
61
|
+
|
62
|
+
static void *linux_netlink_event_thread_main(void *arg);
|
63
|
+
|
64
|
+
struct sockaddr_nl snl = { .nl_family=AF_NETLINK, .nl_groups=KERNEL };
|
65
|
+
|
66
|
+
static int set_fd_cloexec_nb (int fd)
|
67
|
+
{
|
68
|
+
int flags;
|
69
|
+
|
70
|
+
#if defined(FD_CLOEXEC)
|
71
|
+
flags = fcntl (linux_netlink_socket, F_GETFD);
|
72
|
+
if (0 > flags) {
|
73
|
+
return -1;
|
74
|
+
}
|
75
|
+
|
76
|
+
if (!(flags & FD_CLOEXEC)) {
|
77
|
+
fcntl (linux_netlink_socket, F_SETFD, flags | FD_CLOEXEC);
|
78
|
+
}
|
79
|
+
#endif
|
80
|
+
|
81
|
+
flags = fcntl (linux_netlink_socket, F_GETFL);
|
82
|
+
if (0 > flags) {
|
83
|
+
return -1;
|
84
|
+
}
|
85
|
+
|
86
|
+
if (!(flags & O_NONBLOCK)) {
|
87
|
+
fcntl (linux_netlink_socket, F_SETFL, flags | O_NONBLOCK);
|
88
|
+
}
|
89
|
+
|
90
|
+
return 0;
|
91
|
+
}
|
92
|
+
|
93
|
+
int linux_netlink_start_event_monitor(void)
|
94
|
+
{
|
95
|
+
int socktype = SOCK_RAW;
|
96
|
+
int ret;
|
97
|
+
|
98
|
+
snl.nl_groups = KERNEL;
|
99
|
+
|
100
|
+
#if defined(SOCK_CLOEXEC)
|
101
|
+
socktype |= SOCK_CLOEXEC;
|
102
|
+
#endif
|
103
|
+
#if defined(SOCK_NONBLOCK)
|
104
|
+
socktype |= SOCK_NONBLOCK;
|
105
|
+
#endif
|
106
|
+
|
107
|
+
linux_netlink_socket = socket(PF_NETLINK, socktype, NETLINK_KOBJECT_UEVENT);
|
108
|
+
if (-1 == linux_netlink_socket && EINVAL == errno) {
|
109
|
+
linux_netlink_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
|
110
|
+
}
|
111
|
+
|
112
|
+
if (-1 == linux_netlink_socket) {
|
113
|
+
return LIBUSB_ERROR_OTHER;
|
114
|
+
}
|
115
|
+
|
116
|
+
ret = set_fd_cloexec_nb (linux_netlink_socket);
|
117
|
+
if (0 != ret) {
|
118
|
+
close (linux_netlink_socket);
|
119
|
+
linux_netlink_socket = -1;
|
120
|
+
return LIBUSB_ERROR_OTHER;
|
121
|
+
}
|
122
|
+
|
123
|
+
ret = bind(linux_netlink_socket, (struct sockaddr *) &snl, sizeof(snl));
|
124
|
+
if (0 != ret) {
|
125
|
+
close(linux_netlink_socket);
|
126
|
+
return LIBUSB_ERROR_OTHER;
|
127
|
+
}
|
128
|
+
|
129
|
+
/* TODO -- add authentication */
|
130
|
+
/* setsockopt(linux_netlink_socket, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); */
|
131
|
+
|
132
|
+
ret = usbi_pipe(netlink_control_pipe);
|
133
|
+
if (ret) {
|
134
|
+
usbi_err(NULL, "could not create netlink control pipe");
|
135
|
+
close(linux_netlink_socket);
|
136
|
+
return LIBUSB_ERROR_OTHER;
|
137
|
+
}
|
138
|
+
|
139
|
+
ret = pthread_create(&libusb_linux_event_thread, NULL, linux_netlink_event_thread_main, NULL);
|
140
|
+
if (0 != ret) {
|
141
|
+
close(netlink_control_pipe[0]);
|
142
|
+
close(netlink_control_pipe[1]);
|
143
|
+
close(linux_netlink_socket);
|
144
|
+
return LIBUSB_ERROR_OTHER;
|
145
|
+
}
|
146
|
+
|
147
|
+
return LIBUSB_SUCCESS;
|
148
|
+
}
|
149
|
+
|
150
|
+
int linux_netlink_stop_event_monitor(void)
|
151
|
+
{
|
152
|
+
int r;
|
153
|
+
char dummy = 1;
|
154
|
+
|
155
|
+
if (-1 == linux_netlink_socket) {
|
156
|
+
/* already closed. nothing to do */
|
157
|
+
return LIBUSB_SUCCESS;
|
158
|
+
}
|
159
|
+
|
160
|
+
/* Write some dummy data to the control pipe and
|
161
|
+
* wait for the thread to exit */
|
162
|
+
r = usbi_write(netlink_control_pipe[1], &dummy, sizeof(dummy));
|
163
|
+
if (r <= 0) {
|
164
|
+
usbi_warn(NULL, "netlink control pipe signal failed");
|
165
|
+
}
|
166
|
+
pthread_join(libusb_linux_event_thread, NULL);
|
167
|
+
|
168
|
+
close(linux_netlink_socket);
|
169
|
+
linux_netlink_socket = -1;
|
170
|
+
|
171
|
+
/* close and reset control pipe */
|
172
|
+
close(netlink_control_pipe[0]);
|
173
|
+
close(netlink_control_pipe[1]);
|
174
|
+
netlink_control_pipe[0] = -1;
|
175
|
+
netlink_control_pipe[1] = -1;
|
176
|
+
|
177
|
+
return LIBUSB_SUCCESS;
|
178
|
+
}
|
179
|
+
|
180
|
+
static const char *netlink_message_parse (const char *buffer, size_t len, const char *key)
|
181
|
+
{
|
182
|
+
size_t keylen = strlen(key);
|
183
|
+
size_t offset;
|
184
|
+
|
185
|
+
for (offset = 0 ; offset < len && '\0' != buffer[offset] ; offset += strlen(buffer + offset) + 1) {
|
186
|
+
if (0 == strncmp(buffer + offset, key, keylen) &&
|
187
|
+
'=' == buffer[offset + keylen]) {
|
188
|
+
return buffer + offset + keylen + 1;
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
return NULL;
|
193
|
+
}
|
194
|
+
|
195
|
+
/* parse parts of netlink message common to both libudev and the kernel */
|
196
|
+
static int linux_netlink_parse(char *buffer, size_t len, int *detached, const char **sys_name,
|
197
|
+
uint8_t *busnum, uint8_t *devaddr) {
|
198
|
+
const char *tmp;
|
199
|
+
int i;
|
200
|
+
|
201
|
+
errno = 0;
|
202
|
+
|
203
|
+
*sys_name = NULL;
|
204
|
+
*detached = 0;
|
205
|
+
*busnum = 0;
|
206
|
+
*devaddr = 0;
|
207
|
+
|
208
|
+
tmp = netlink_message_parse((const char *) buffer, len, "ACTION");
|
209
|
+
if (tmp == NULL)
|
210
|
+
return -1;
|
211
|
+
if (0 == strcmp(tmp, "remove")) {
|
212
|
+
*detached = 1;
|
213
|
+
} else if (0 != strcmp(tmp, "add")) {
|
214
|
+
usbi_dbg("unknown device action %s", tmp);
|
215
|
+
return -1;
|
216
|
+
}
|
217
|
+
|
218
|
+
/* check that this is a usb message */
|
219
|
+
tmp = netlink_message_parse(buffer, len, "SUBSYSTEM");
|
220
|
+
if (NULL == tmp || 0 != strcmp(tmp, "usb")) {
|
221
|
+
/* not usb. ignore */
|
222
|
+
return -1;
|
223
|
+
}
|
224
|
+
|
225
|
+
tmp = netlink_message_parse(buffer, len, "BUSNUM");
|
226
|
+
if (NULL == tmp) {
|
227
|
+
/* no bus number (likely a usb interface). ignore*/
|
228
|
+
return -1;
|
229
|
+
}
|
230
|
+
|
231
|
+
*busnum = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff);
|
232
|
+
if (errno) {
|
233
|
+
errno = 0;
|
234
|
+
return -1;
|
235
|
+
}
|
236
|
+
|
237
|
+
tmp = netlink_message_parse(buffer, len, "DEVNUM");
|
238
|
+
if (NULL == tmp) {
|
239
|
+
return -1;
|
240
|
+
}
|
241
|
+
|
242
|
+
*devaddr = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff);
|
243
|
+
if (errno) {
|
244
|
+
errno = 0;
|
245
|
+
return -1;
|
246
|
+
}
|
247
|
+
|
248
|
+
tmp = netlink_message_parse(buffer, len, "DEVPATH");
|
249
|
+
if (NULL == tmp) {
|
250
|
+
return -1;
|
251
|
+
}
|
252
|
+
|
253
|
+
for (i = strlen(tmp) - 1 ; i ; --i) {
|
254
|
+
if ('/' ==tmp[i]) {
|
255
|
+
*sys_name = tmp + i + 1;
|
256
|
+
break;
|
257
|
+
}
|
258
|
+
}
|
259
|
+
|
260
|
+
/* found a usb device */
|
261
|
+
return 0;
|
262
|
+
}
|
263
|
+
|
264
|
+
static int linux_netlink_read_message(void)
|
265
|
+
{
|
266
|
+
unsigned char buffer[1024];
|
267
|
+
struct iovec iov = {.iov_base = buffer, .iov_len = sizeof(buffer)};
|
268
|
+
struct msghdr meh = { .msg_iov=&iov, .msg_iovlen=1,
|
269
|
+
.msg_name=&snl, .msg_namelen=sizeof(snl) };
|
270
|
+
const char *sys_name = NULL;
|
271
|
+
uint8_t busnum, devaddr;
|
272
|
+
int detached, r;
|
273
|
+
size_t len;
|
274
|
+
|
275
|
+
/* read netlink message */
|
276
|
+
memset(buffer, 0, sizeof(buffer));
|
277
|
+
len = recvmsg(linux_netlink_socket, &meh, 0);
|
278
|
+
if (len < 32) {
|
279
|
+
if (errno != EAGAIN)
|
280
|
+
usbi_dbg("error recieving message from netlink");
|
281
|
+
return -1;
|
282
|
+
}
|
283
|
+
|
284
|
+
/* TODO -- authenticate this message is from the kernel or udevd */
|
285
|
+
|
286
|
+
r = linux_netlink_parse(buffer, len, &detached, &sys_name,
|
287
|
+
&busnum, &devaddr);
|
288
|
+
if (r)
|
289
|
+
return r;
|
290
|
+
|
291
|
+
usbi_dbg("netlink hotplug found device busnum: %hhu, devaddr: %hhu, sys_name: %s, removed: %s",
|
292
|
+
busnum, devaddr, sys_name, detached ? "yes" : "no");
|
293
|
+
|
294
|
+
/* signal device is available (or not) to all contexts */
|
295
|
+
if (detached)
|
296
|
+
linux_device_disconnected(busnum, devaddr, sys_name);
|
297
|
+
else
|
298
|
+
linux_hotplug_enumerate(busnum, devaddr, sys_name);
|
299
|
+
|
300
|
+
return 0;
|
301
|
+
}
|
302
|
+
|
303
|
+
static void *linux_netlink_event_thread_main(void *arg)
|
304
|
+
{
|
305
|
+
char dummy;
|
306
|
+
int r;
|
307
|
+
struct pollfd fds[] = {
|
308
|
+
{ .fd = netlink_control_pipe[0],
|
309
|
+
.events = POLLIN },
|
310
|
+
{ .fd = linux_netlink_socket,
|
311
|
+
.events = POLLIN },
|
312
|
+
};
|
313
|
+
|
314
|
+
/* silence compiler warning */
|
315
|
+
(void) arg;
|
316
|
+
|
317
|
+
while (poll(fds, 2, -1) >= 0) {
|
318
|
+
if (fds[0].revents & POLLIN) {
|
319
|
+
/* activity on control pipe, read the byte and exit */
|
320
|
+
r = usbi_read(netlink_control_pipe[0], &dummy, sizeof(dummy));
|
321
|
+
if (r <= 0) {
|
322
|
+
usbi_warn(NULL, "netlink control pipe read failed");
|
323
|
+
}
|
324
|
+
break;
|
325
|
+
}
|
326
|
+
if (fds[1].revents & POLLIN) {
|
327
|
+
usbi_mutex_static_lock(&linux_hotplug_lock);
|
328
|
+
linux_netlink_read_message();
|
329
|
+
usbi_mutex_static_unlock(&linux_hotplug_lock);
|
330
|
+
}
|
331
|
+
}
|
332
|
+
|
333
|
+
return NULL;
|
334
|
+
}
|
335
|
+
|
336
|
+
void linux_netlink_hotplug_poll(void)
|
337
|
+
{
|
338
|
+
int r;
|
339
|
+
|
340
|
+
usbi_mutex_static_lock(&linux_hotplug_lock);
|
341
|
+
do {
|
342
|
+
r = linux_netlink_read_message();
|
343
|
+
} while (r == 0);
|
344
|
+
usbi_mutex_static_unlock(&linux_hotplug_lock);
|
345
|
+
}
|