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
;
59 devh
->interface_number
= 0;
62 * Retrieve active configuration descriptor to determine the endpoints
63 * for the interface number of the device.
65 ret
= libusb_get_active_config_descriptor(devh
->dev
->usb_dev
, &config
);
67 if (ret
!= LIBUSB_SUCCESS
) {
68 log_err(ctx
, "Failed to get configuration descriptor: %s",
69 libusb_error_name(ret
));
73 found_interface
= false;
75 for (uint8_t i
= 0; i
< config
->bNumInterfaces
; i
++) {
76 interface
= &config
->interface
[i
];
77 desc
= &interface
->altsetting
[0];
79 if (desc
->bInterfaceClass
!= LIBUSB_CLASS_VENDOR_SPEC
)
82 if (desc
->bInterfaceSubClass
!= LIBUSB_CLASS_VENDOR_SPEC
)
85 if (desc
->bNumEndpoints
< 2)
88 found_interface
= true;
89 devh
->interface_number
= i
;
93 if (!found_interface
) {
94 log_err(ctx
, "No suitable interface found");
95 libusb_free_config_descriptor(config
);
99 found_endpoint_in
= false;
100 found_endpoint_out
= false;
102 for (uint8_t i
= 0; i
< desc
->bNumEndpoints
; i
++) {
103 epdesc
= &desc
->endpoint
[i
];
105 if (epdesc
->bEndpointAddress
& LIBUSB_ENDPOINT_IN
) {
106 devh
->endpoint_in
= epdesc
->bEndpointAddress
;
107 found_endpoint_in
= true;
109 devh
->endpoint_out
= epdesc
->bEndpointAddress
;
110 found_endpoint_out
= true;
114 libusb_free_config_descriptor(config
);
116 if (!found_endpoint_in
) {
117 log_err(ctx
, "Interface IN endpoint not found");
121 if (!found_endpoint_out
) {
122 log_err(ctx
, "Interface OUT endpoint not found");
126 log_dbg(ctx
, "Using endpoint %02x (IN) and %02x (OUT)",
127 devh
->endpoint_in
, devh
->endpoint_out
);
129 /* Buffer size must be a multiple of CHUNK_SIZE bytes. */
130 devh
->buffer_size
= CHUNK_SIZE
;
131 devh
->buffer
= malloc(devh
->buffer_size
);
134 log_err(ctx
, "Transport buffer malloc failed");
135 return JAYLINK_ERR_MALLOC
;
138 devh
->read_length
= 0;
139 devh
->bytes_available
= 0;
142 devh
->write_length
= 0;
148 static void cleanup_handle(struct jaylink_device_handle
*devh
)
153 JAYLINK_PRIV
int transport_usb_open(struct jaylink_device_handle
*devh
)
156 struct jaylink_device
*dev
;
157 struct jaylink_context
*ctx
;
158 struct libusb_device_handle
*usb_devh
;
163 log_dbg(ctx
, "Trying to open device (bus:address = %03u:%03u)",
164 libusb_get_bus_number(dev
->usb_dev
),
165 libusb_get_device_address(dev
->usb_dev
));
167 ret
= initialize_handle(devh
);
169 if (ret
!= JAYLINK_OK
) {
170 log_err(ctx
, "Initialize device handle failed");
174 ret
= libusb_open(dev
->usb_dev
, &usb_devh
);
176 if (ret
!= LIBUSB_SUCCESS
) {
177 log_err(ctx
, "Failed to open device: %s",
178 libusb_error_name(ret
));
179 cleanup_handle(devh
);
183 ret
= libusb_claim_interface(usb_devh
, devh
->interface_number
);
185 if (ret
!= LIBUSB_SUCCESS
) {
186 log_err(ctx
, "Failed to claim interface: %s",
187 libusb_error_name(ret
));
188 cleanup_handle(devh
);
189 libusb_close(usb_devh
);
193 log_dbg(ctx
, "Device opened successfully");
195 devh
->usb_devh
= usb_devh
;
200 JAYLINK_PRIV
int transport_usb_close(struct jaylink_device_handle
*devh
)
203 struct jaylink_device
*dev
;
204 struct jaylink_context
*ctx
;
209 log_dbg(ctx
, "Closing device (bus:address = %03u:%03u)",
210 libusb_get_bus_number(dev
->usb_dev
),
211 libusb_get_device_address(dev
->usb_dev
));
213 ret
= libusb_release_interface(devh
->usb_devh
, devh
->interface_number
);
215 libusb_close(devh
->usb_devh
);
216 cleanup_handle(devh
);
218 if (ret
!= LIBUSB_SUCCESS
) {
219 log_err(ctx
, "Failed to release interface: %s",
220 libusb_error_name(ret
));
224 log_dbg(ctx
, "Device closed successfully");
229 JAYLINK_PRIV
int transport_usb_start_write(struct jaylink_device_handle
*devh
,
230 size_t length
, bool has_command
)
232 struct jaylink_context
*ctx
;
237 return JAYLINK_ERR_ARG
;
239 ctx
= devh
->dev
->ctx
;
241 log_dbgio(ctx
, "Starting write operation (length = %zu bytes)", length
);
243 if (devh
->write_pos
> 0)
244 log_warn(ctx
, "Last write operation left %zu bytes in the "
245 "buffer", devh
->write_pos
);
247 if (devh
->write_length
> 0)
248 log_warn(ctx
, "Last write operation was not performed");
250 devh
->write_length
= length
;
256 JAYLINK_PRIV
int transport_usb_start_read(struct jaylink_device_handle
*devh
,
259 struct jaylink_context
*ctx
;
262 return JAYLINK_ERR_ARG
;
264 ctx
= devh
->dev
->ctx
;
266 log_dbgio(ctx
, "Starting read operation (length = %zu bytes)",
269 if (devh
->bytes_available
> 0)
270 log_dbg(ctx
, "Last read operation left %zu bytes in the "
271 "buffer", devh
->bytes_available
);
273 if (devh
->read_length
> 0)
274 log_warn(ctx
, "Last read operation left %zu bytes",
277 devh
->read_length
= length
;
282 JAYLINK_PRIV
int transport_usb_start_write_read(
283 struct jaylink_device_handle
*devh
, size_t write_length
,
284 size_t read_length
, bool has_command
)
286 struct jaylink_context
*ctx
;
290 if (!read_length
|| !write_length
)
291 return JAYLINK_ERR_ARG
;
293 ctx
= devh
->dev
->ctx
;
295 log_dbgio(ctx
, "Starting write / read operation (length = "
296 "%zu / %zu bytes)", write_length
, read_length
);
298 if (devh
->write_pos
> 0)
299 log_warn(ctx
, "Last write operation left %zu bytes in the "
300 "buffer", devh
->write_pos
);
302 if (devh
->write_length
> 0)
303 log_warn(ctx
, "Last write operation was not performed");
305 if (devh
->bytes_available
> 0)
306 log_warn(ctx
, "Last read operation left %zu bytes in the "
307 "buffer", devh
->bytes_available
);
309 if (devh
->read_length
> 0)
310 log_warn(ctx
, "Last read operation left %zu bytes",
313 devh
->write_length
= write_length
;
316 devh
->read_length
= read_length
;
317 devh
->bytes_available
= 0;
323 static int usb_recv(struct jaylink_device_handle
*devh
, uint8_t *buffer
,
327 struct jaylink_context
*ctx
;
331 ctx
= devh
->dev
->ctx
;
333 tries
= NUM_TIMEOUTS
;
336 while (tries
> 0 && !transferred
) {
337 /* Always request CHUNK_SIZE bytes from the device. */
338 ret
= libusb_bulk_transfer(devh
->usb_devh
, devh
->endpoint_in
,
339 (unsigned char *)buffer
, CHUNK_SIZE
, &transferred
,
342 if (ret
== LIBUSB_ERROR_TIMEOUT
) {
343 log_warn(ctx
, "Failed to receive data from "
344 "device: %s", libusb_error_name(ret
));
347 } else if (ret
!= LIBUSB_SUCCESS
) {
348 log_err(ctx
, "Failed to receive data from "
349 "device: %s", libusb_error_name(ret
));
353 log_dbgio(ctx
, "Received %i bytes from device", transferred
);
356 /* Ignore a possible timeout if at least one byte was received. */
357 if (transferred
> 0) {
358 *length
= transferred
;
362 log_err(ctx
, "Receiving data from device timed out");
364 return JAYLINK_ERR_TIMEOUT
;
367 static bool adjust_buffer(struct jaylink_device_handle
*devh
, size_t size
)
369 struct jaylink_context
*ctx
;
373 ctx
= devh
->dev
->ctx
;
375 /* Adjust buffer size to a multiple of CHUNK_SIZE bytes. */
376 num_chunks
= size
/ CHUNK_SIZE
;
378 if (size
% CHUNK_SIZE
> 0)
381 size
= num_chunks
* CHUNK_SIZE
;
382 buffer
= realloc(devh
->buffer
, size
);
385 log_err(ctx
, "Failed to adjust buffer size to %zu bytes",
390 devh
->buffer
= buffer
;
391 devh
->buffer_size
= size
;
393 log_dbg(ctx
, "Adjusted buffer size to %zu bytes", size
);
398 static int usb_send(struct jaylink_device_handle
*devh
, const uint8_t *buffer
,
402 struct jaylink_context
*ctx
;
406 ctx
= devh
->dev
->ctx
;
407 tries
= NUM_TIMEOUTS
;
409 while (tries
> 0 && length
> 0) {
410 /* Send data in chunks of CHUNK_SIZE bytes to the device. */
411 ret
= libusb_bulk_transfer(devh
->usb_devh
, devh
->endpoint_out
,
412 (unsigned char *)buffer
, MIN(CHUNK_SIZE
, length
),
413 &transferred
, USB_TIMEOUT
);
415 if (ret
== LIBUSB_SUCCESS
) {
416 tries
= NUM_TIMEOUTS
;
417 } else if (ret
== LIBUSB_ERROR_TIMEOUT
) {
418 log_warn(ctx
, "Failed to send data to device: %s",
419 libusb_error_name(ret
));
422 log_err(ctx
, "Failed to send data to device: %s",
423 libusb_error_name(ret
));
427 buffer
+= transferred
;
428 length
-= transferred
;
430 log_dbgio(ctx
, "Sent %i bytes to device", transferred
);
436 log_err(ctx
, "Sending data to device timed out");
438 return JAYLINK_ERR_TIMEOUT
;
441 JAYLINK_PRIV
int transport_usb_write(struct jaylink_device_handle
*devh
,
442 const uint8_t *buffer
, size_t length
)
445 struct jaylink_context
*ctx
;
450 ctx
= devh
->dev
->ctx
;
452 if (length
> devh
->write_length
) {
453 log_err(ctx
, "Requested to write %zu bytes but only %zu bytes "
454 "are expected for the write operation", length
,
456 return JAYLINK_ERR_ARG
;
460 * Store data in the buffer if the expected number of bytes for the
461 * write operation is not reached.
463 if (length
< devh
->write_length
) {
464 if (devh
->write_pos
+ length
> devh
->buffer_size
) {
465 if (!adjust_buffer(devh
, devh
->write_pos
+ length
))
466 return JAYLINK_ERR_MALLOC
;
469 memcpy(devh
->buffer
+ devh
->write_pos
, buffer
, length
);
471 devh
->write_length
-= length
;
472 devh
->write_pos
+= length
;
474 log_dbgio(ctx
, "Wrote %zu bytes into buffer", length
);
479 * Expected number of bytes for this write operation is reached and
480 * therefore the write operation will be performed.
482 devh
->write_length
= 0;
484 /* Send data directly to the device if the buffer is empty. */
485 if (!devh
->write_pos
)
486 return usb_send(devh
, buffer
, length
);
489 * Calculate the number of bytes to fill up the buffer to reach a
490 * multiple of CHUNK_SIZE bytes. This ensures that the data from the
491 * buffer will be sent to the device in chunks of CHUNK_SIZE bytes.
492 * Note that this is why the buffer size must be a multiple of
495 num_chunks
= devh
->write_pos
/ CHUNK_SIZE
;
497 if (devh
->write_pos
% CHUNK_SIZE
)
500 fill_bytes
= (num_chunks
* CHUNK_SIZE
) - devh
->write_pos
;
501 tmp
= MIN(length
, fill_bytes
);
504 memcpy(devh
->buffer
+ devh
->write_pos
, buffer
, tmp
);
509 log_dbgio(ctx
, "Buffer filled up with %zu bytes", tmp
);
512 /* Send buffered data to the device. */
513 ret
= usb_send(devh
, devh
->buffer
, devh
->write_pos
+ tmp
);
516 if (ret
!= JAYLINK_OK
)
522 /* Send remaining data to the device. */
523 return usb_send(devh
, buffer
, length
);
526 JAYLINK_PRIV
int transport_usb_read(struct jaylink_device_handle
*devh
,
527 uint8_t *buffer
, size_t length
)
530 struct jaylink_context
*ctx
;
531 size_t bytes_received
;
534 ctx
= devh
->dev
->ctx
;
536 if (length
> devh
->read_length
) {
537 log_err(ctx
, "Requested to read %zu bytes but only %zu bytes "
538 "are expected for the read operation", length
,
540 return JAYLINK_ERR_ARG
;
543 if (length
<= devh
->bytes_available
) {
544 memcpy(buffer
, devh
->buffer
+ devh
->read_pos
, length
);
546 devh
->read_length
-= length
;
547 devh
->bytes_available
-= length
;
548 devh
->read_pos
+= length
;
550 log_dbgio(ctx
, "Read %zu bytes from buffer", length
);
554 if (devh
->bytes_available
) {
555 memcpy(buffer
, devh
->buffer
+ devh
->read_pos
,
556 devh
->bytes_available
);
558 buffer
+= devh
->bytes_available
;
559 length
-= devh
->bytes_available
;
560 devh
->read_length
-= devh
->bytes_available
;
562 log_dbgio(ctx
, "Read %zu bytes from buffer to flush it",
563 devh
->bytes_available
);
565 devh
->bytes_available
= 0;
571 * If less than CHUNK_SIZE bytes are requested from the device,
572 * store the received data into the internal buffer instead of
573 * directly into the user provided buffer. This is necessary to
574 * prevent a possible buffer overflow because the number of
575 * requested bytes from the device is always CHUNK_SIZE and
576 * therefore up to CHUNK_SIZE bytes may be received.
577 * Note that this is why the internal buffer size must be at
578 * least CHUNK_SIZE bytes.
580 if (length
< CHUNK_SIZE
) {
581 ret
= usb_recv(devh
, devh
->buffer
, &bytes_received
);
583 if (ret
!= JAYLINK_OK
)
586 tmp
= MIN(bytes_received
, length
);
587 memcpy(buffer
, devh
->buffer
, tmp
);
590 * Setup the buffer for the remaining data if more data
591 * was received from the device than was requested.
593 if (bytes_received
> length
) {
594 devh
->bytes_available
= bytes_received
- tmp
;
595 devh
->read_pos
= tmp
;
600 devh
->read_length
-= tmp
;
602 log_dbgio(ctx
, "Read %zu bytes from buffer", tmp
);
604 ret
= usb_recv(devh
, buffer
, &bytes_received
);
606 if (ret
!= JAYLINK_OK
)
609 buffer
+= bytes_received
;
610 length
-= bytes_received
;
611 devh
->read_length
-= bytes_received
;
613 log_dbgio(ctx
, "Read %zu bytes from device",