2 * This file is part of the libjaylink project.
4 * Copyright (C) 2014-2016 Marc Schink <jaylink-dev@marcschink.de>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "libjaylink.h"
26 #include "libjaylink-internal.h"
31 * Transport abstraction layer (USB).
34 /** Timeout of an USB transfer in milliseconds. */
35 #define USB_TIMEOUT 1000
38 * Number of consecutive timeouts before an USB transfer will be treated as
41 #define NUM_TIMEOUTS 2
43 /** Chunk size in bytes in which data is transferred. */
44 #define CHUNK_SIZE 2048
46 static int initialize_handle(struct jaylink_device_handle
*devh
)
49 struct jaylink_context
*ctx
;
50 struct libusb_config_descriptor
*config
;
51 const struct libusb_interface
*interface
;
52 const struct libusb_interface_descriptor
*desc
;
53 const struct libusb_endpoint_descriptor
*epdesc
;
55 bool found_endpoint_in
;
56 bool found_endpoint_out
;
60 devh
->interface_number
= 0;
63 * Retrieve active configuration descriptor to determine the endpoints
64 * for the interface number of the device.
66 ret
= libusb_get_active_config_descriptor(devh
->dev
->usb_dev
, &config
);
68 if (ret
!= LIBUSB_SUCCESS
) {
69 log_err(ctx
, "Failed to get configuration descriptor: %s.",
70 libusb_error_name(ret
));
74 found_interface
= false;
76 for (i
= 0; i
< config
->bNumInterfaces
; i
++) {
77 interface
= &config
->interface
[i
];
78 desc
= &interface
->altsetting
[0];
80 if (desc
->bInterfaceClass
!= LIBUSB_CLASS_VENDOR_SPEC
)
83 if (desc
->bInterfaceSubClass
!= LIBUSB_CLASS_VENDOR_SPEC
)
86 if (desc
->bNumEndpoints
< 2)
89 found_interface
= true;
90 devh
->interface_number
= i
;
94 if (!found_interface
) {
95 log_err(ctx
, "No suitable interface found.");
96 libusb_free_config_descriptor(config
);
100 found_endpoint_in
= false;
101 found_endpoint_out
= false;
103 for (i
= 0; i
< desc
->bNumEndpoints
; i
++) {
104 epdesc
= &desc
->endpoint
[i
];
106 if (epdesc
->bEndpointAddress
& LIBUSB_ENDPOINT_IN
) {
107 devh
->endpoint_in
= epdesc
->bEndpointAddress
;
108 found_endpoint_in
= true;
110 devh
->endpoint_out
= epdesc
->bEndpointAddress
;
111 found_endpoint_out
= true;
115 libusb_free_config_descriptor(config
);
117 if (!found_endpoint_in
) {
118 log_err(ctx
, "Interface IN endpoint not found.");
122 if (!found_endpoint_out
) {
123 log_err(ctx
, "Interface OUT endpoint not found.");
127 log_dbg(ctx
, "Using endpoint %02x (IN) and %02x (OUT).",
128 devh
->endpoint_in
, devh
->endpoint_out
);
130 /* Buffer size must be a multiple of CHUNK_SIZE bytes. */
131 devh
->buffer_size
= CHUNK_SIZE
;
132 devh
->buffer
= malloc(devh
->buffer_size
);
135 log_err(ctx
, "Transport buffer malloc failed.");
136 return JAYLINK_ERR_MALLOC
;
139 devh
->read_length
= 0;
140 devh
->bytes_available
= 0;
143 devh
->write_length
= 0;
149 static void cleanup_handle(struct jaylink_device_handle
*devh
)
154 JAYLINK_PRIV
int transport_usb_open(struct jaylink_device_handle
*devh
)
157 struct jaylink_device
*dev
;
158 struct jaylink_context
*ctx
;
159 struct libusb_device_handle
*usb_devh
;
164 log_dbg(ctx
, "Trying to open device (bus:address = %03u:%03u).",
165 libusb_get_bus_number(dev
->usb_dev
),
166 libusb_get_device_address(dev
->usb_dev
));
168 ret
= initialize_handle(devh
);
170 if (ret
!= JAYLINK_OK
) {
171 log_err(ctx
, "Initialize device handle failed.");
175 ret
= libusb_open(dev
->usb_dev
, &usb_devh
);
177 if (ret
!= LIBUSB_SUCCESS
) {
178 log_err(ctx
, "Failed to open device: %s.",
179 libusb_error_name(ret
));
180 cleanup_handle(devh
);
184 ret
= libusb_claim_interface(usb_devh
, devh
->interface_number
);
186 if (ret
!= LIBUSB_SUCCESS
) {
187 log_err(ctx
, "Failed to claim interface: %s.",
188 libusb_error_name(ret
));
189 cleanup_handle(devh
);
190 libusb_close(usb_devh
);
194 log_dbg(ctx
, "Device opened successfully.");
196 devh
->usb_devh
= usb_devh
;
201 JAYLINK_PRIV
int transport_usb_close(struct jaylink_device_handle
*devh
)
204 struct jaylink_device
*dev
;
205 struct jaylink_context
*ctx
;
210 log_dbg(ctx
, "Closing device (bus:address = %03u:%03u).",
211 libusb_get_bus_number(dev
->usb_dev
),
212 libusb_get_device_address(dev
->usb_dev
));
214 ret
= libusb_release_interface(devh
->usb_devh
, devh
->interface_number
);
216 libusb_close(devh
->usb_devh
);
217 cleanup_handle(devh
);
219 if (ret
!= LIBUSB_SUCCESS
) {
220 log_err(ctx
, "Failed to release interface: %s.",
221 libusb_error_name(ret
));
225 log_dbg(ctx
, "Device closed successfully.");
230 JAYLINK_PRIV
int transport_usb_start_write(struct jaylink_device_handle
*devh
,
231 size_t length
, bool has_command
)
233 struct jaylink_context
*ctx
;
238 return JAYLINK_ERR_ARG
;
240 ctx
= devh
->dev
->ctx
;
242 log_dbgio(ctx
, "Starting write operation (length = %zu bytes).", length
);
244 if (devh
->write_pos
> 0)
245 log_warn(ctx
, "Last write operation left %zu bytes in the "
246 "buffer.", devh
->write_pos
);
248 if (devh
->write_length
> 0)
249 log_warn(ctx
, "Last write operation was not performed.");
251 devh
->write_length
= length
;
257 JAYLINK_PRIV
int transport_usb_start_read(struct jaylink_device_handle
*devh
,
260 struct jaylink_context
*ctx
;
263 return JAYLINK_ERR_ARG
;
265 ctx
= devh
->dev
->ctx
;
267 log_dbgio(ctx
, "Starting read operation (length = %zu bytes).",
270 if (devh
->bytes_available
> 0)
271 log_dbg(ctx
, "Last read operation left %zu bytes in the "
272 "buffer.", devh
->bytes_available
);
274 if (devh
->read_length
> 0)
275 log_warn(ctx
, "Last read operation left %zu bytes.",
278 devh
->read_length
= length
;
283 JAYLINK_PRIV
int transport_usb_start_write_read(
284 struct jaylink_device_handle
*devh
, size_t write_length
,
285 size_t read_length
, bool has_command
)
287 struct jaylink_context
*ctx
;
291 if (!read_length
|| !write_length
)
292 return JAYLINK_ERR_ARG
;
294 ctx
= devh
->dev
->ctx
;
296 log_dbgio(ctx
, "Starting write / read operation (length = "
297 "%zu / %zu bytes).", write_length
, read_length
);
299 if (devh
->write_pos
> 0)
300 log_warn(ctx
, "Last write operation left %zu bytes in the "
301 "buffer.", devh
->write_pos
);
303 if (devh
->write_length
> 0)
304 log_warn(ctx
, "Last write operation was not performed.");
306 if (devh
->bytes_available
> 0)
307 log_warn(ctx
, "Last read operation left %zu bytes in the "
308 "buffer.", devh
->bytes_available
);
310 if (devh
->read_length
> 0)
311 log_warn(ctx
, "Last read operation left %zu bytes.",
314 devh
->write_length
= write_length
;
317 devh
->read_length
= read_length
;
318 devh
->bytes_available
= 0;
324 static int usb_recv(struct jaylink_device_handle
*devh
, uint8_t *buffer
,
328 struct jaylink_context
*ctx
;
332 ctx
= devh
->dev
->ctx
;
334 tries
= NUM_TIMEOUTS
;
337 while (tries
> 0 && !transferred
) {
338 /* Always request CHUNK_SIZE bytes from the device. */
339 ret
= libusb_bulk_transfer(devh
->usb_devh
, devh
->endpoint_in
,
340 (unsigned char *)buffer
, CHUNK_SIZE
, &transferred
,
343 if (ret
== LIBUSB_ERROR_TIMEOUT
) {
344 log_warn(ctx
, "Failed to receive data from "
345 "device: %s.", libusb_error_name(ret
));
348 } else if (ret
!= LIBUSB_SUCCESS
) {
349 log_err(ctx
, "Failed to receive data from "
350 "device: %s.", libusb_error_name(ret
));
354 log_dbgio(ctx
, "Received %i bytes from device.", transferred
);
357 /* Ignore a possible timeout if at least one byte was received. */
358 if (transferred
> 0) {
359 *length
= transferred
;
363 log_err(ctx
, "Receiving data from device timed out.");
365 return JAYLINK_ERR_TIMEOUT
;
368 static bool adjust_buffer(struct jaylink_device_handle
*devh
, size_t size
)
370 struct jaylink_context
*ctx
;
374 ctx
= devh
->dev
->ctx
;
376 /* Adjust buffer size to a multiple of CHUNK_SIZE bytes. */
377 num_chunks
= size
/ CHUNK_SIZE
;
379 if (size
% CHUNK_SIZE
> 0)
382 size
= num_chunks
* CHUNK_SIZE
;
383 buffer
= realloc(devh
->buffer
, size
);
386 log_err(ctx
, "Failed to adjust buffer size to %zu bytes.",
391 devh
->buffer
= buffer
;
392 devh
->buffer_size
= size
;
394 log_dbg(ctx
, "Adjusted buffer size to %zu bytes.", size
);
399 static int usb_send(struct jaylink_device_handle
*devh
, const uint8_t *buffer
,
403 struct jaylink_context
*ctx
;
407 ctx
= devh
->dev
->ctx
;
408 tries
= NUM_TIMEOUTS
;
410 while (tries
> 0 && length
> 0) {
411 /* Send data in chunks of CHUNK_SIZE bytes to the device. */
412 ret
= libusb_bulk_transfer(devh
->usb_devh
, devh
->endpoint_out
,
413 (unsigned char *)buffer
, MIN(CHUNK_SIZE
, length
),
414 &transferred
, USB_TIMEOUT
);
416 if (ret
== LIBUSB_SUCCESS
) {
417 tries
= NUM_TIMEOUTS
;
418 } else if (ret
== LIBUSB_ERROR_TIMEOUT
) {
419 log_warn(ctx
, "Failed to send data to device: %s.",
420 libusb_error_name(ret
));
423 log_err(ctx
, "Failed to send data to device: %s.",
424 libusb_error_name(ret
));
428 buffer
+= transferred
;
429 length
-= transferred
;
431 log_dbgio(ctx
, "Sent %i bytes to device.", transferred
);
437 log_err(ctx
, "Sending data to device timed out.");
439 return JAYLINK_ERR_TIMEOUT
;
442 JAYLINK_PRIV
int transport_usb_write(struct jaylink_device_handle
*devh
,
443 const uint8_t *buffer
, size_t length
)
446 struct jaylink_context
*ctx
;
451 ctx
= devh
->dev
->ctx
;
453 if (length
> devh
->write_length
) {
454 log_err(ctx
, "Requested to write %zu bytes but only %zu bytes "
455 "are expected for the write operation.", length
,
457 return JAYLINK_ERR_ARG
;
461 * Store data in the buffer if the expected number of bytes for the
462 * write operation is not reached.
464 if (length
< devh
->write_length
) {
465 if (devh
->write_pos
+ length
> devh
->buffer_size
) {
466 if (!adjust_buffer(devh
, devh
->write_pos
+ length
))
467 return JAYLINK_ERR_MALLOC
;
470 memcpy(devh
->buffer
+ devh
->write_pos
, buffer
, length
);
472 devh
->write_length
-= length
;
473 devh
->write_pos
+= length
;
475 log_dbgio(ctx
, "Wrote %zu bytes into buffer.", length
);
480 * Expected number of bytes for this write operation is reached and
481 * therefore the write operation will be performed.
483 devh
->write_length
= 0;
485 /* Send data directly to the device if the buffer is empty. */
486 if (!devh
->write_pos
)
487 return usb_send(devh
, buffer
, length
);
490 * Calculate the number of bytes to fill up the buffer to reach a
491 * multiple of CHUNK_SIZE bytes. This ensures that the data from the
492 * buffer will be sent to the device in chunks of CHUNK_SIZE bytes.
493 * Note that this is why the buffer size must be a multiple of
496 num_chunks
= devh
->write_pos
/ CHUNK_SIZE
;
498 if (devh
->write_pos
% CHUNK_SIZE
)
501 fill_bytes
= (num_chunks
* CHUNK_SIZE
) - devh
->write_pos
;
502 tmp
= MIN(length
, fill_bytes
);
505 memcpy(devh
->buffer
+ devh
->write_pos
, buffer
, tmp
);
510 log_dbgio(ctx
, "Buffer filled up with %zu bytes.", tmp
);
513 /* Send buffered data to the device. */
514 ret
= usb_send(devh
, devh
->buffer
, devh
->write_pos
+ tmp
);
517 if (ret
!= JAYLINK_OK
)
523 /* Send remaining data to the device. */
524 return usb_send(devh
, buffer
, length
);
527 JAYLINK_PRIV
int transport_usb_read(struct jaylink_device_handle
*devh
,
528 uint8_t *buffer
, size_t length
)
531 struct jaylink_context
*ctx
;
532 size_t bytes_received
;
535 ctx
= devh
->dev
->ctx
;
537 if (length
> devh
->read_length
) {
538 log_err(ctx
, "Requested to read %zu bytes but only %zu bytes "
539 "are expected for the read operation.", length
,
541 return JAYLINK_ERR_ARG
;
544 if (length
<= devh
->bytes_available
) {
545 memcpy(buffer
, devh
->buffer
+ devh
->read_pos
, length
);
547 devh
->read_length
-= length
;
548 devh
->bytes_available
-= length
;
549 devh
->read_pos
+= length
;
551 log_dbgio(ctx
, "Read %zu bytes from buffer.", length
);
555 if (devh
->bytes_available
) {
556 memcpy(buffer
, devh
->buffer
+ devh
->read_pos
,
557 devh
->bytes_available
);
559 buffer
+= devh
->bytes_available
;
560 length
-= devh
->bytes_available
;
561 devh
->read_length
-= devh
->bytes_available
;
563 log_dbgio(ctx
, "Read %zu bytes from buffer to flush it.",
564 devh
->bytes_available
);
566 devh
->bytes_available
= 0;
572 * If less than CHUNK_SIZE bytes are requested from the device,
573 * store the received data into the internal buffer instead of
574 * directly into the user provided buffer. This is necessary to
575 * prevent a possible buffer overflow because the number of
576 * requested bytes from the device is always CHUNK_SIZE and
577 * therefore up to CHUNK_SIZE bytes may be received.
578 * Note that this is why the internal buffer size must be at
579 * least CHUNK_SIZE bytes.
581 if (length
< CHUNK_SIZE
) {
582 ret
= usb_recv(devh
, devh
->buffer
, &bytes_received
);
584 if (ret
!= JAYLINK_OK
)
587 tmp
= MIN(bytes_received
, length
);
588 memcpy(buffer
, devh
->buffer
, tmp
);
591 * Setup the buffer for the remaining data if more data
592 * was received from the device than was requested.
594 if (bytes_received
> length
) {
595 devh
->bytes_available
= bytes_received
- tmp
;
596 devh
->read_pos
= tmp
;
601 devh
->read_length
-= tmp
;
603 log_dbgio(ctx
, "Read %zu bytes from buffer.", tmp
);
605 ret
= usb_recv(devh
, buffer
, &bytes_received
);
607 if (ret
!= JAYLINK_OK
)
610 buffer
+= bytes_received
;
611 length
-= bytes_received
;
612 devh
->read_length
-= bytes_received
;
614 log_dbgio(ctx
, "Read %zu bytes from device.",