Fix issue 1) not recognizes some usb device, 2) reconnect when ffmpeg encoder error
[rtmpclient.git] / app / src / main / jni / libusb-1.0.22 / libusb / os / linux_udev.c
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) 2012-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
25 #include <assert.h>
26 #include <ctype.h>
27 #include <dirent.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <poll.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/ioctl.h>
35 #include <sys/stat.h>
36 #include <sys/types.h>
37 #include <sys/utsname.h>
38 #include <sys/socket.h>
39 #include <unistd.h>
40 #include <libudev.h>
41
42 #include "libusbi.h"
43 #include "linux_usbfs.h"
44
45 /* udev context */
46 static struct udev *udev_ctx = NULL;
47 static int udev_monitor_fd = -1;
48 static int udev_control_pipe[2] = {-1, -1};
49 static struct udev_monitor *udev_monitor = NULL;
50 static pthread_t linux_event_thread;
51
52 static void udev_hotplug_event(struct udev_device* udev_dev);
53 static void *linux_udev_event_thread_main(void *arg);
54
55 int linux_udev_start_event_monitor(void)
56 {
57         int r;
58
59         assert(udev_ctx == NULL);
60         udev_ctx = udev_new();
61         if (!udev_ctx) {
62                 usbi_err(NULL, "could not create udev context");
63                 goto err;
64         }
65
66         udev_monitor = udev_monitor_new_from_netlink(udev_ctx, "udev");
67         if (!udev_monitor) {
68                 usbi_err(NULL, "could not initialize udev monitor");
69                 goto err_free_ctx;
70         }
71
72         r = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device");
73         if (r) {
74                 usbi_err(NULL, "could not initialize udev monitor filter for \"usb\" subsystem");
75                 goto err_free_monitor;
76         }
77
78         if (udev_monitor_enable_receiving(udev_monitor)) {
79                 usbi_err(NULL, "failed to enable the udev monitor");
80                 goto err_free_monitor;
81         }
82
83         udev_monitor_fd = udev_monitor_get_fd(udev_monitor);
84
85 #if defined(FD_CLOEXEC)
86         /* Make sure the udev file descriptor is marked as CLOEXEC */
87         r = fcntl(udev_monitor_fd, F_GETFD);
88         if (r == -1) {
89                 usbi_err(NULL, "geting udev monitor fd flags (%d)", errno);
90                 goto err_free_monitor;
91         }
92         if (!(r & FD_CLOEXEC)) {
93                 if (fcntl(udev_monitor_fd, F_SETFD, r | FD_CLOEXEC) == -1) {
94                         usbi_err(NULL, "setting udev monitor fd flags (%d)", errno);
95                         goto err_free_monitor;
96                 }
97         }
98 #endif
99
100         /* Some older versions of udev are not non-blocking by default,
101          * so make sure this is set */
102         r = fcntl(udev_monitor_fd, F_GETFL);
103         if (r == -1) {
104                 usbi_err(NULL, "getting udev monitor fd status flags (%d)", errno);
105                 goto err_free_monitor;
106         }
107         if (!(r & O_NONBLOCK)) {
108                 if (fcntl(udev_monitor_fd, F_SETFL, r | O_NONBLOCK) == -1) {
109                         usbi_err(NULL, "setting udev monitor fd status flags (%d)", errno);
110                         goto err_free_monitor;
111                 }
112         }
113
114         r = usbi_pipe(udev_control_pipe);
115         if (r) {
116                 usbi_err(NULL, "could not create udev control pipe");
117                 goto err_free_monitor;
118         }
119
120         r = pthread_create(&linux_event_thread, NULL, linux_udev_event_thread_main, NULL);
121         if (r) {
122                 usbi_err(NULL, "creating hotplug event thread (%d)", r);
123                 goto err_close_pipe;
124         }
125
126         return LIBUSB_SUCCESS;
127
128 err_close_pipe:
129         close(udev_control_pipe[0]);
130         close(udev_control_pipe[1]);
131 err_free_monitor:
132         udev_monitor_unref(udev_monitor);
133         udev_monitor = NULL;
134         udev_monitor_fd = -1;
135 err_free_ctx:
136         udev_unref(udev_ctx);
137 err:
138         udev_ctx = NULL;
139         return LIBUSB_ERROR_OTHER;
140 }
141
142 int linux_udev_stop_event_monitor(void)
143 {
144         char dummy = 1;
145         int r;
146
147         assert(udev_ctx != NULL);
148         assert(udev_monitor != NULL);
149         assert(udev_monitor_fd != -1);
150
151         /* Write some dummy data to the control pipe and
152          * wait for the thread to exit */
153         r = write(udev_control_pipe[1], &dummy, sizeof(dummy));
154         if (r <= 0) {
155                 usbi_warn(NULL, "udev control pipe signal failed");
156         }
157         pthread_join(linux_event_thread, NULL);
158
159         /* Release the udev monitor */
160         udev_monitor_unref(udev_monitor);
161         udev_monitor = NULL;
162         udev_monitor_fd = -1;
163
164         /* Clean up the udev context */
165         udev_unref(udev_ctx);
166         udev_ctx = NULL;
167
168         /* close and reset control pipe */
169         close(udev_control_pipe[0]);
170         close(udev_control_pipe[1]);
171         udev_control_pipe[0] = -1;
172         udev_control_pipe[1] = -1;
173
174         return LIBUSB_SUCCESS;
175 }
176
177 static void *linux_udev_event_thread_main(void *arg)
178 {
179         char dummy;
180         int r;
181         ssize_t nb;
182         struct udev_device* udev_dev;
183         struct pollfd fds[] = {
184                 {.fd = udev_control_pipe[0],
185                  .events = POLLIN},
186                 {.fd = udev_monitor_fd,
187                  .events = POLLIN},
188         };
189
190         usbi_dbg("udev event thread entering.");
191
192         while ((r = poll(fds, 2, -1)) >= 0 || errno == EINTR) {
193                 if (r < 0) {
194                         /* temporary failure */
195                         continue;
196                 }
197                 if (fds[0].revents & POLLIN) {
198                         /* activity on control pipe, read the byte and exit */
199                         nb = read(udev_control_pipe[0], &dummy, sizeof(dummy));
200                         if (nb <= 0) {
201                                 usbi_warn(NULL, "udev control pipe read failed");
202                         }
203                         break;
204                 }
205                 if (fds[1].revents & POLLIN) {
206                         usbi_mutex_static_lock(&linux_hotplug_lock);
207                         udev_dev = udev_monitor_receive_device(udev_monitor);
208                         if (udev_dev)
209                                 udev_hotplug_event(udev_dev);
210                         usbi_mutex_static_unlock(&linux_hotplug_lock);
211                 }
212         }
213
214         usbi_dbg("udev event thread exiting");
215
216         return NULL;
217 }
218
219 static int udev_device_info(struct libusb_context *ctx, int detached,
220                             struct udev_device *udev_dev, uint8_t *busnum,
221                             uint8_t *devaddr, const char **sys_name) {
222         const char *dev_node;
223
224         dev_node = udev_device_get_devnode(udev_dev);
225         if (!dev_node) {
226                 return LIBUSB_ERROR_OTHER;
227         }
228
229         *sys_name = udev_device_get_sysname(udev_dev);
230         if (!*sys_name) {
231                 return LIBUSB_ERROR_OTHER;
232         }
233
234         return linux_get_device_address(ctx, detached, busnum, devaddr,
235                                         dev_node, *sys_name);
236 }
237
238 static void udev_hotplug_event(struct udev_device* udev_dev)
239 {
240         const char* udev_action;
241         const char* sys_name = NULL;
242         uint8_t busnum = 0, devaddr = 0;
243         int detached;
244         int r;
245
246         do {
247                 udev_action = udev_device_get_action(udev_dev);
248                 if (!udev_action) {
249                         break;
250                 }
251
252                 detached = !strncmp(udev_action, "remove", 6);
253
254                 r = udev_device_info(NULL, detached, udev_dev, &busnum, &devaddr, &sys_name);
255                 if (LIBUSB_SUCCESS != r) {
256                         break;
257                 }
258
259                 usbi_dbg("udev hotplug event. action: %s.", udev_action);
260
261                 if (strncmp(udev_action, "add", 3) == 0) {
262                         linux_hotplug_enumerate(busnum, devaddr, sys_name);
263                 } else if (detached) {
264                         linux_device_disconnected(busnum, devaddr);
265                 } else {
266                         usbi_err(NULL, "ignoring udev action %s", udev_action);
267                 }
268         } while (0);
269
270         udev_device_unref(udev_dev);
271 }
272
273 int linux_udev_scan_devices(struct libusb_context *ctx)
274 {
275         struct udev_enumerate *enumerator;
276         struct udev_list_entry *devices, *entry;
277         struct udev_device *udev_dev;
278         const char *sys_name;
279         int r;
280
281         assert(udev_ctx != NULL);
282
283         enumerator = udev_enumerate_new(udev_ctx);
284         if (NULL == enumerator) {
285                 usbi_err(ctx, "error creating udev enumerator");
286                 return LIBUSB_ERROR_OTHER;
287         }
288
289         udev_enumerate_add_match_subsystem(enumerator, "usb");
290         udev_enumerate_add_match_property(enumerator, "DEVTYPE", "usb_device");
291         udev_enumerate_scan_devices(enumerator);
292         devices = udev_enumerate_get_list_entry(enumerator);
293
294         entry = NULL;
295         udev_list_entry_foreach(entry, devices) {
296                 const char *path = udev_list_entry_get_name(entry);
297                 uint8_t busnum = 0, devaddr = 0;
298
299                 udev_dev = udev_device_new_from_syspath(udev_ctx, path);
300
301                 r = udev_device_info(ctx, 0, udev_dev, &busnum, &devaddr, &sys_name);
302                 if (r) {
303                         udev_device_unref(udev_dev);
304                         continue;
305                 }
306
307                 linux_enumerate_device(ctx, busnum, devaddr, sys_name);
308                 udev_device_unref(udev_dev);
309         }
310
311         udev_enumerate_unref(enumerator);
312
313         return LIBUSB_SUCCESS;
314 }
315
316 void linux_udev_hotplug_poll(void)
317 {
318         struct udev_device* udev_dev;
319
320         usbi_mutex_static_lock(&linux_hotplug_lock);
321         do {
322                 udev_dev = udev_monitor_receive_device(udev_monitor);
323                 if (udev_dev) {
324                         usbi_dbg("Handling hotplug event from hotplug_poll");
325                         udev_hotplug_event(udev_dev);
326                 }
327         } while (udev_dev);
328         usbi_mutex_static_unlock(&linux_hotplug_lock);
329 }