usb 1.7.2-prebuild
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/prebuild.yml +62 -0
- package/.gitmodules +3 -0
- package/LICENSE +7 -0
- package/Readme.md +339 -0
- package/binding.gyp +90 -0
- package/libusb/.gitattributes +11 -0
- package/libusb/.private/README.txt +5 -0
- package/libusb/.private/bd.cmd +89 -0
- package/libusb/.private/bm.sh +54 -0
- package/libusb/.private/bwince.cmd +57 -0
- package/libusb/.private/post-rewrite.sh +28 -0
- package/libusb/.private/pre-commit.sh +42 -0
- package/libusb/.private/wbs.txt +61 -0
- package/libusb/.private/wbs_wince.txt +42 -0
- package/libusb/AUTHORS +78 -0
- package/libusb/COPYING +504 -0
- package/libusb/ChangeLog +211 -0
- package/libusb/INSTALL +234 -0
- package/libusb/INSTALL_WIN.txt +73 -0
- package/libusb/Makefile.am +28 -0
- package/libusb/NEWS +2 -0
- package/libusb/PORTING +94 -0
- package/libusb/README +28 -0
- package/libusb/README.git +41 -0
- package/libusb/TODO +2 -0
- package/libusb/Xcode/common.xcconfig +49 -0
- package/libusb/Xcode/debug.xcconfig +29 -0
- package/libusb/Xcode/libusb.xcconfig +21 -0
- package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +1 -0
- package/libusb/Xcode/libusb_debug.xcconfig +21 -0
- package/libusb/Xcode/libusb_release.xcconfig +21 -0
- package/libusb/Xcode/release.xcconfig +30 -0
- package/libusb/android/README +114 -0
- package/libusb/android/jni/Android.mk +23 -0
- package/libusb/android/jni/Application.mk +24 -0
- package/libusb/android/jni/examples.mk +134 -0
- package/libusb/android/jni/libusb.mk +54 -0
- package/libusb/android/jni/tests.mk +56 -0
- package/libusb/autogen.sh +8 -0
- package/libusb/bootstrap.sh +19 -0
- package/libusb/configure.ac +304 -0
- package/libusb/doc/Makefile.am +9 -0
- package/libusb/doc/doxygen.cfg.in +1288 -0
- package/libusb/doc/libusb.png +0 -0
- package/libusb/examples/Makefile.am +19 -0
- package/libusb/examples/dpfp.c +506 -0
- package/libusb/examples/dpfp_threaded.c +544 -0
- package/libusb/examples/ezusb.c +831 -0
- package/libusb/examples/ezusb.h +120 -0
- package/libusb/examples/fxload.c +287 -0
- package/libusb/examples/getopt/getopt.c +1060 -0
- package/libusb/examples/getopt/getopt.h +180 -0
- package/libusb/examples/getopt/getopt1.c +188 -0
- package/libusb/examples/hotplugtest.c +104 -0
- package/libusb/examples/listdevs.c +71 -0
- package/libusb/examples/sam3u_benchmark.c +193 -0
- package/libusb/examples/xusb.c +1129 -0
- package/libusb/libusb/Makefile.am +75 -0
- package/libusb/libusb/core.c +2342 -0
- package/libusb/libusb/descriptor.c +1199 -0
- package/libusb/libusb/hotplug.c +327 -0
- package/libusb/libusb/hotplug.h +82 -0
- package/libusb/libusb/io.c +2631 -0
- package/libusb/libusb/libusb-1.0.def +166 -0
- package/libusb/libusb/libusb-1.0.rc +61 -0
- package/libusb/libusb/libusb.h +1998 -0
- package/libusb/libusb/libusbi.h +1040 -0
- package/libusb/libusb/os/darwin_usb.c +2009 -0
- package/libusb/libusb/os/darwin_usb.h +162 -0
- package/libusb/libusb/os/linux_netlink.c +369 -0
- package/libusb/libusb/os/linux_udev.c +307 -0
- package/libusb/libusb/os/linux_usbfs.c +2695 -0
- package/libusb/libusb/os/linux_usbfs.h +192 -0
- package/libusb/libusb/os/netbsd_usb.c +738 -0
- package/libusb/libusb/os/openbsd_usb.c +832 -0
- package/libusb/libusb/os/poll_posix.c +51 -0
- package/libusb/libusb/os/poll_posix.h +11 -0
- package/libusb/libusb/os/poll_windows.c +796 -0
- package/libusb/libusb/os/poll_windows.h +131 -0
- package/libusb/libusb/os/threads_posix.c +82 -0
- package/libusb/libusb/os/threads_posix.h +50 -0
- package/libusb/libusb/os/threads_windows.c +212 -0
- package/libusb/libusb/os/threads_windows.h +87 -0
- package/libusb/libusb/os/wince_usb.c +1032 -0
- package/libusb/libusb/os/wince_usb.h +131 -0
- package/libusb/libusb/os/windows_common.h +108 -0
- package/libusb/libusb/os/windows_usb.c +5347 -0
- package/libusb/libusb/os/windows_usb.h +971 -0
- package/libusb/libusb/strerror.c +199 -0
- package/libusb/libusb/sync.c +307 -0
- package/libusb/libusb/version.h +18 -0
- package/libusb/libusb/version_nano.h +1 -0
- package/libusb/libusb-1.0.pc.in +11 -0
- package/libusb/msvc/config.h +50 -0
- package/libusb/msvc/ddk_build.cmd +175 -0
- package/libusb/msvc/errno.h +102 -0
- package/libusb/msvc/fxload_2010.vcxproj +170 -0
- package/libusb/msvc/fxload_2010.vcxproj.filters +25 -0
- package/libusb/msvc/fxload_2012.vcxproj +174 -0
- package/libusb/msvc/fxload_2012.vcxproj.filters +25 -0
- package/libusb/msvc/fxload_2013.vcxproj +174 -0
- package/libusb/msvc/fxload_sources +23 -0
- package/libusb/msvc/getopt_2005.vcproj +288 -0
- package/libusb/msvc/getopt_2010.vcxproj +131 -0
- package/libusb/msvc/getopt_2010.vcxproj.filters +26 -0
- package/libusb/msvc/getopt_2012.vcxproj +136 -0
- package/libusb/msvc/getopt_2012.vcxproj.filters +26 -0
- package/libusb/msvc/getopt_2013.vcxproj +136 -0
- package/libusb/msvc/getopt_sources +20 -0
- package/libusb/msvc/hotplugtest_2010.vcxproj +163 -0
- package/libusb/msvc/hotplugtest_2010.vcxproj.filters +14 -0
- package/libusb/msvc/hotplugtest_2012.vcxproj +167 -0
- package/libusb/msvc/hotplugtest_2012.vcxproj.filters +14 -0
- package/libusb/msvc/hotplugtest_2013.vcxproj +167 -0
- package/libusb/msvc/hotplugtest_sources +20 -0
- package/libusb/msvc/inttypes.h +295 -0
- package/libusb/msvc/libusb.dsw +71 -0
- package/libusb/msvc/libusb_2005.sln +95 -0
- package/libusb/msvc/libusb_2010.sln +94 -0
- package/libusb/msvc/libusb_2012.sln +94 -0
- package/libusb/msvc/libusb_2013.sln +100 -0
- package/libusb/msvc/libusb_2015.sln +100 -0
- package/libusb/msvc/libusb_dll.dsp +194 -0
- package/libusb/msvc/libusb_dll_2005.vcproj +436 -0
- package/libusb/msvc/libusb_dll_2010.vcxproj +170 -0
- package/libusb/msvc/libusb_dll_2010.vcxproj.filters +81 -0
- package/libusb/msvc/libusb_dll_2012.vcxproj +175 -0
- package/libusb/msvc/libusb_dll_2012.vcxproj.filters +84 -0
- package/libusb/msvc/libusb_dll_2013.vcxproj +175 -0
- package/libusb/msvc/libusb_dll_wince.vcproj +1243 -0
- package/libusb/msvc/libusb_sources +38 -0
- package/libusb/msvc/libusb_static.dsp +174 -0
- package/libusb/msvc/libusb_static_2005.vcproj +362 -0
- package/libusb/msvc/libusb_static_2010.vcxproj +156 -0
- package/libusb/msvc/libusb_static_2010.vcxproj.filters +74 -0
- package/libusb/msvc/libusb_static_2012.vcxproj +160 -0
- package/libusb/msvc/libusb_static_2012.vcxproj.filters +74 -0
- package/libusb/msvc/libusb_static_2013.vcxproj +160 -0
- package/libusb/msvc/libusb_static_wince.vcproj +1185 -0
- package/libusb/msvc/libusb_wince.sln +246 -0
- package/libusb/msvc/listdevs.dsp +103 -0
- package/libusb/msvc/listdevs_2005.vcproj +360 -0
- package/libusb/msvc/listdevs_2010.vcxproj +165 -0
- package/libusb/msvc/listdevs_2010.vcxproj.filters +14 -0
- package/libusb/msvc/listdevs_2012.vcxproj +169 -0
- package/libusb/msvc/listdevs_2012.vcxproj.filters +14 -0
- package/libusb/msvc/listdevs_2013.vcxproj +169 -0
- package/libusb/msvc/listdevs_sources +19 -0
- package/libusb/msvc/listdevs_wince.vcproj +1120 -0
- package/libusb/msvc/missing.c +80 -0
- package/libusb/msvc/missing.h +32 -0
- package/libusb/msvc/stdint.h +256 -0
- package/libusb/msvc/stress_2005.vcproj +390 -0
- package/libusb/msvc/stress_2010.vcxproj +167 -0
- package/libusb/msvc/stress_2010.vcxproj.filters +25 -0
- package/libusb/msvc/stress_2012.vcxproj +171 -0
- package/libusb/msvc/stress_2012.vcxproj.filters +25 -0
- package/libusb/msvc/stress_2013.vcxproj +171 -0
- package/libusb/msvc/stress_wince.vcproj +1128 -0
- package/libusb/msvc/xusb.dsp +102 -0
- package/libusb/msvc/xusb_2005.vcproj +344 -0
- package/libusb/msvc/xusb_2010.vcxproj +163 -0
- package/libusb/msvc/xusb_2010.vcxproj.filters +14 -0
- package/libusb/msvc/xusb_2012.vcxproj +167 -0
- package/libusb/msvc/xusb_2012.vcxproj.filters +14 -0
- package/libusb/msvc/xusb_2013.vcxproj +167 -0
- package/libusb/msvc/xusb_sources +20 -0
- package/libusb/msvc/xusb_wince.vcproj +1120 -0
- package/libusb/tests/Makefile.am +6 -0
- package/libusb/tests/libusb_testlib.h +107 -0
- package/libusb/tests/stress.c +160 -0
- package/libusb/tests/testlib.c +281 -0
- package/libusb.gypi +136 -0
- package/libusb_config/config.h +1 -0
- package/package.json +69 -0
- package/src/device.cc +412 -0
- package/src/helpers.h +64 -0
- package/src/node_usb.cc +319 -0
- package/src/node_usb.h +120 -0
- package/src/transfer.cc +148 -0
- package/src/uv_async_queue.h +33 -0
- package/test/usb.coffee +191 -0
- package/usb.js +524 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* darwin backend for libusb 1.0
|
|
3
|
+
* Copyright © 2008-2013 Nathan Hjelm <hjelmn@users.sourceforge.net>
|
|
4
|
+
*
|
|
5
|
+
* This library is free software; you can redistribute it and/or
|
|
6
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
* License as published by the Free Software Foundation; either
|
|
8
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This library is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13
|
+
* Lesser General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
16
|
+
* License along with this library; if not, write to the Free Software
|
|
17
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
#if !defined(LIBUSB_DARWIN_H)
|
|
21
|
+
#define LIBUSB_DARWIN_H
|
|
22
|
+
|
|
23
|
+
#include "libusbi.h"
|
|
24
|
+
|
|
25
|
+
#include <IOKit/IOTypes.h>
|
|
26
|
+
#include <IOKit/IOCFBundle.h>
|
|
27
|
+
#include <IOKit/usb/IOUSBLib.h>
|
|
28
|
+
#include <IOKit/IOCFPlugIn.h>
|
|
29
|
+
|
|
30
|
+
/* IOUSBInterfaceInferface */
|
|
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)
|
|
44
|
+
|
|
45
|
+
#define usb_interface_t IOUSBInterfaceInterface300
|
|
46
|
+
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID300
|
|
47
|
+
#define InterfaceVersion 300
|
|
48
|
+
|
|
49
|
+
#elif defined (kIOUSBInterfaceInterfaceID245)
|
|
50
|
+
|
|
51
|
+
#define usb_interface_t IOUSBInterfaceInterface245
|
|
52
|
+
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID245
|
|
53
|
+
#define InterfaceVersion 245
|
|
54
|
+
|
|
55
|
+
#elif defined (kIOUSBInterfaceInterfaceID220)
|
|
56
|
+
|
|
57
|
+
#define usb_interface_t IOUSBInterfaceInterface220
|
|
58
|
+
#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220
|
|
59
|
+
#define InterfaceVersion 220
|
|
60
|
+
|
|
61
|
+
#else
|
|
62
|
+
|
|
63
|
+
#error "IOUSBFamily is too old. Please upgrade your OS"
|
|
64
|
+
|
|
65
|
+
#endif
|
|
66
|
+
|
|
67
|
+
/* IOUSBDeviceInterface */
|
|
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
|
+
|
|
76
|
+
#define usb_device_t IOUSBDeviceInterface320
|
|
77
|
+
#define DeviceInterfaceID kIOUSBDeviceInterfaceID320
|
|
78
|
+
#define DeviceVersion 320
|
|
79
|
+
|
|
80
|
+
#elif defined (kIOUSBDeviceInterfaceID300)
|
|
81
|
+
|
|
82
|
+
#define usb_device_t IOUSBDeviceInterface300
|
|
83
|
+
#define DeviceInterfaceID kIOUSBDeviceInterfaceID300
|
|
84
|
+
#define DeviceVersion 300
|
|
85
|
+
|
|
86
|
+
#elif defined (kIOUSBDeviceInterfaceID245)
|
|
87
|
+
|
|
88
|
+
#define usb_device_t IOUSBDeviceInterface245
|
|
89
|
+
#define DeviceInterfaceID kIOUSBDeviceInterfaceID245
|
|
90
|
+
#define DeviceVersion 245
|
|
91
|
+
|
|
92
|
+
#elif defined (kIOUSBDeviceInterfaceID220)
|
|
93
|
+
#define usb_device_t IOUSBDeviceInterface197
|
|
94
|
+
#define DeviceInterfaceID kIOUSBDeviceInterfaceID197
|
|
95
|
+
#define DeviceVersion 197
|
|
96
|
+
|
|
97
|
+
#else
|
|
98
|
+
|
|
99
|
+
#error "IOUSBFamily is too old. Please upgrade your OS"
|
|
100
|
+
|
|
101
|
+
#endif
|
|
102
|
+
|
|
103
|
+
#if !defined(IO_OBJECT_NULL)
|
|
104
|
+
#define IO_OBJECT_NULL ((io_object_t) 0)
|
|
105
|
+
#endif
|
|
106
|
+
|
|
107
|
+
typedef IOCFPlugInInterface *io_cf_plugin_ref_t;
|
|
108
|
+
typedef IONotificationPortRef io_notification_port_t;
|
|
109
|
+
|
|
110
|
+
/* private structures */
|
|
111
|
+
struct darwin_cached_device {
|
|
112
|
+
struct list_head list;
|
|
113
|
+
IOUSBDeviceDescriptor dev_descriptor;
|
|
114
|
+
UInt32 location;
|
|
115
|
+
UInt64 parent_session;
|
|
116
|
+
UInt64 session;
|
|
117
|
+
UInt16 address;
|
|
118
|
+
char sys_path[21];
|
|
119
|
+
usb_device_t **device;
|
|
120
|
+
int open_count;
|
|
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;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
struct darwin_device_handle_priv {
|
|
131
|
+
int is_open;
|
|
132
|
+
CFRunLoopSourceRef cfSource;
|
|
133
|
+
int fds[2];
|
|
134
|
+
|
|
135
|
+
struct darwin_interface {
|
|
136
|
+
usb_interface_t **interface;
|
|
137
|
+
uint8_t num_endpoints;
|
|
138
|
+
CFRunLoopSourceRef cfSource;
|
|
139
|
+
uint64_t frames[256];
|
|
140
|
+
uint8_t endpoint_addrs[USB_MAXENDPOINTS];
|
|
141
|
+
} interfaces[USB_MAXINTERFACES];
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
struct darwin_transfer_priv {
|
|
145
|
+
/* Isoc */
|
|
146
|
+
IOUSBIsocFrame *isoc_framelist;
|
|
147
|
+
int num_iso_packets;
|
|
148
|
+
|
|
149
|
+
/* Control */
|
|
150
|
+
IOUSBDevRequestTO req;
|
|
151
|
+
|
|
152
|
+
/* Bulk */
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
/* structure for signaling io completion */
|
|
156
|
+
struct darwin_msg_async_io_complete {
|
|
157
|
+
struct usbi_transfer *itransfer;
|
|
158
|
+
IOReturn result;
|
|
159
|
+
UInt32 size;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
#endif
|
|
@@ -0,0 +1,369 @@
|
|
|
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. try "DEVICE" */
|
|
228
|
+
tmp = netlink_message_parse(buffer, len, "DEVICE");
|
|
229
|
+
if (NULL == tmp) {
|
|
230
|
+
/* not usb. ignore */
|
|
231
|
+
return -1;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* Parse a device path such as /dev/bus/usb/003/004 */
|
|
235
|
+
char *pLastSlash = (char*)strrchr(tmp,'/');
|
|
236
|
+
if(NULL == pLastSlash) {
|
|
237
|
+
return -1;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
*devaddr = strtoul(pLastSlash + 1, NULL, 10);
|
|
241
|
+
if (errno) {
|
|
242
|
+
errno = 0;
|
|
243
|
+
return -1;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
*busnum = strtoul(pLastSlash - 3, NULL, 10);
|
|
247
|
+
if (errno) {
|
|
248
|
+
errno = 0;
|
|
249
|
+
return -1;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return 0;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
*busnum = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff);
|
|
256
|
+
if (errno) {
|
|
257
|
+
errno = 0;
|
|
258
|
+
return -1;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
tmp = netlink_message_parse(buffer, len, "DEVNUM");
|
|
262
|
+
if (NULL == tmp) {
|
|
263
|
+
return -1;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
*devaddr = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff);
|
|
267
|
+
if (errno) {
|
|
268
|
+
errno = 0;
|
|
269
|
+
return -1;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
tmp = netlink_message_parse(buffer, len, "DEVPATH");
|
|
273
|
+
if (NULL == tmp) {
|
|
274
|
+
return -1;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
for (i = strlen(tmp) - 1 ; i ; --i) {
|
|
278
|
+
if ('/' ==tmp[i]) {
|
|
279
|
+
*sys_name = tmp + i + 1;
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/* found a usb device */
|
|
285
|
+
return 0;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
static int linux_netlink_read_message(void)
|
|
289
|
+
{
|
|
290
|
+
unsigned char buffer[1024];
|
|
291
|
+
struct iovec iov = {.iov_base = buffer, .iov_len = sizeof(buffer)};
|
|
292
|
+
struct msghdr meh = { .msg_iov=&iov, .msg_iovlen=1,
|
|
293
|
+
.msg_name=&snl, .msg_namelen=sizeof(snl) };
|
|
294
|
+
const char *sys_name = NULL;
|
|
295
|
+
uint8_t busnum, devaddr;
|
|
296
|
+
int detached, r;
|
|
297
|
+
size_t len;
|
|
298
|
+
|
|
299
|
+
/* read netlink message */
|
|
300
|
+
memset(buffer, 0, sizeof(buffer));
|
|
301
|
+
len = recvmsg(linux_netlink_socket, &meh, 0);
|
|
302
|
+
if (len < 32) {
|
|
303
|
+
if (errno != EAGAIN)
|
|
304
|
+
usbi_dbg("error recieving message from netlink");
|
|
305
|
+
return -1;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/* TODO -- authenticate this message is from the kernel or udevd */
|
|
309
|
+
|
|
310
|
+
r = linux_netlink_parse(buffer, len, &detached, &sys_name,
|
|
311
|
+
&busnum, &devaddr);
|
|
312
|
+
if (r)
|
|
313
|
+
return r;
|
|
314
|
+
|
|
315
|
+
usbi_dbg("netlink hotplug found device busnum: %hhu, devaddr: %hhu, sys_name: %s, removed: %s",
|
|
316
|
+
busnum, devaddr, sys_name, detached ? "yes" : "no");
|
|
317
|
+
|
|
318
|
+
/* signal device is available (or not) to all contexts */
|
|
319
|
+
if (detached)
|
|
320
|
+
linux_device_disconnected(busnum, devaddr, sys_name);
|
|
321
|
+
else
|
|
322
|
+
linux_hotplug_enumerate(busnum, devaddr, sys_name);
|
|
323
|
+
|
|
324
|
+
return 0;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
static void *linux_netlink_event_thread_main(void *arg)
|
|
328
|
+
{
|
|
329
|
+
char dummy;
|
|
330
|
+
int r;
|
|
331
|
+
struct pollfd fds[] = {
|
|
332
|
+
{ .fd = netlink_control_pipe[0],
|
|
333
|
+
.events = POLLIN },
|
|
334
|
+
{ .fd = linux_netlink_socket,
|
|
335
|
+
.events = POLLIN },
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
/* silence compiler warning */
|
|
339
|
+
(void) arg;
|
|
340
|
+
|
|
341
|
+
while (poll(fds, 2, -1) >= 0) {
|
|
342
|
+
if (fds[0].revents & POLLIN) {
|
|
343
|
+
/* activity on control pipe, read the byte and exit */
|
|
344
|
+
r = usbi_read(netlink_control_pipe[0], &dummy, sizeof(dummy));
|
|
345
|
+
if (r <= 0) {
|
|
346
|
+
usbi_warn(NULL, "netlink control pipe read failed");
|
|
347
|
+
}
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
if (fds[1].revents & POLLIN) {
|
|
351
|
+
usbi_mutex_static_lock(&linux_hotplug_lock);
|
|
352
|
+
linux_netlink_read_message();
|
|
353
|
+
usbi_mutex_static_unlock(&linux_hotplug_lock);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return NULL;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
void linux_netlink_hotplug_poll(void)
|
|
361
|
+
{
|
|
362
|
+
int r;
|
|
363
|
+
|
|
364
|
+
usbi_mutex_static_lock(&linux_hotplug_lock);
|
|
365
|
+
do {
|
|
366
|
+
r = linux_netlink_read_message();
|
|
367
|
+
} while (r == 0);
|
|
368
|
+
usbi_mutex_static_unlock(&linux_hotplug_lock);
|
|
369
|
+
}
|