2 * This file is part of the libjaylink project.
4 * Copyright (C) 2014-2015 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"
29 * libusb.h includes windows.h and therefore must be included after anything
30 * that includes winsock2.h.
37 * Transport abstraction layer.
40 /** Timeout of an USB transfer in milliseconds. */
41 #define USB_TIMEOUT 1000
44 * Number of consecutive timeouts before an USB transfer will be treated as
47 #define NUM_TIMEOUTS 2
49 /** Chunk size in bytes in which data is transferred. */
50 #define CHUNK_SIZE 2048
52 static int initialize_handle(struct jaylink_device_handle
*devh
)
55 struct jaylink_context
*ctx
;
56 struct libusb_config_descriptor
*config
;
57 const struct libusb_interface
*interface
;
58 const struct libusb_interface_descriptor
*desc
;
59 const struct libusb_endpoint_descriptor
*ep_desc
;
61 bool found_endpoint_in
;
62 bool found_endpoint_out
;
66 devh
->interface_number
= 0;
69 * Retrieve active configuration descriptor to determine the endpoints
70 * for the interface number of the device.
72 ret
= libusb_get_active_config_descriptor(devh
->dev
->usb_dev
, &config
);
74 if (ret
== LIBUSB_ERROR_IO
) {
75 log_err(ctx
, "Failed to get configuration descriptor: "
76 "input/output error.");
77 return JAYLINK_ERR_IO
;
78 } else if (ret
!= LIBUSB_SUCCESS
) {
79 log_err(ctx
, "Failed to get configuration descriptor: %s.",
80 libusb_error_name(ret
));
84 found_interface
= false;
86 for (i
= 0; i
< config
->bNumInterfaces
; i
++) {
87 interface
= &config
->interface
[i
];
88 desc
= &interface
->altsetting
[0];
90 if (desc
->bInterfaceClass
!= LIBUSB_CLASS_VENDOR_SPEC
)
93 if (desc
->bInterfaceSubClass
!= LIBUSB_CLASS_VENDOR_SPEC
)
96 if (desc
->bNumEndpoints
< 2)
99 found_interface
= true;
100 devh
->interface_number
= i
;
104 if (!found_interface
) {
105 log_err(ctx
, "No suitable interface found.");
106 libusb_free_config_descriptor(config
);
110 found_endpoint_in
= false;
111 found_endpoint_out
= false;
113 for (i
= 0; i
< desc
->bNumEndpoints
; i
++) {
114 ep_desc
= &desc
->endpoint
[i
];
116 if (ep_desc
->bEndpointAddress
& LIBUSB_ENDPOINT_IN
) {
117 devh
->endpoint_in
= ep_desc
->bEndpointAddress
;
118 found_endpoint_in
= true;
120 devh
->endpoint_out
= ep_desc
->bEndpointAddress
;
121 found_endpoint_out
= true;
125 libusb_free_config_descriptor(config
);
127 if (!found_endpoint_in
) {
128 log_err(ctx
, "Interface IN endpoint not found.");
132 if (!found_endpoint_out
) {
133 log_err(ctx
, "Interface OUT endpoint not found.");
137 log_dbg(ctx
, "Using endpoint %02x (IN) and %02x (OUT).",
138 devh
->endpoint_in
, devh
->endpoint_out
);
140 /* Buffer size must be a multiple of CHUNK_SIZE bytes. */
141 devh
->buffer_size
= CHUNK_SIZE
;
142 devh
->buffer
= malloc(devh
->buffer_size
);
145 log_err(ctx
, "Transport buffer malloc failed.");
146 return JAYLINK_ERR_MALLOC
;
149 devh
->read_length
= 0;
150 devh
->bytes_available
= 0;
153 devh
->write_length
= 0;
159 static void cleanup_handle(struct jaylink_device_handle
*devh
)
167 * This function must be called before any other function of the transport
168 * abstraction layer for the given device handle is called.
170 * @param[in,out] devh Device handle.
172 * @retval JAYLINK_OK Success.
173 * @retval JAYLINK_ERR_IO Input/output error.
174 * @retval JAYLINK_ERR Other error conditions.
176 JAYLINK_PRIV
int transport_open(struct jaylink_device_handle
*devh
)
179 struct jaylink_device
*dev
;
180 struct jaylink_context
*ctx
;
181 struct libusb_device_handle
*usb_devh
;
186 log_dbg(ctx
, "Trying to open device (bus:address = %03u:%03u).",
187 libusb_get_bus_number(dev
->usb_dev
),
188 libusb_get_device_address(dev
->usb_dev
));
190 ret
= initialize_handle(devh
);
192 if (ret
!= JAYLINK_OK
) {
193 log_err(ctx
, "Failed to initialize device handle.");
197 ret
= libusb_open(dev
->usb_dev
, &usb_devh
);
199 if (ret
== LIBUSB_ERROR_IO
) {
200 log_err(ctx
, "Failed to open device: input/output error.");
201 cleanup_handle(devh
);
202 return JAYLINK_ERR_IO
;
203 } else if (ret
!= LIBUSB_SUCCESS
) {
204 log_err(ctx
, "Failed to open device: %s.",
205 libusb_error_name(ret
));
206 cleanup_handle(devh
);
210 ret
= libusb_claim_interface(usb_devh
, devh
->interface_number
);
212 if (ret
== LIBUSB_ERROR_IO
) {
213 log_err(ctx
, "Failed to claim interface: input/output error.");
214 return JAYLINK_ERR_IO
;
215 } else if (ret
!= LIBUSB_SUCCESS
) {
216 log_err(ctx
, "Failed to claim interface: %s.",
217 libusb_error_name(ret
));
218 cleanup_handle(devh
);
219 libusb_close(usb_devh
);
223 log_dbg(ctx
, "Device opened successfully.");
225 devh
->usb_devh
= usb_devh
;
233 * After this function has been called no other function of the transport
234 * abstraction layer for the given device handle must be called.
236 * @param[in,out] devh Device handle.
238 * @retval JAYLINK_OK Success.
239 * @retval JAYLINK_ERR Other error conditions.
241 JAYLINK_PRIV
int transport_close(struct jaylink_device_handle
*devh
)
244 struct jaylink_device
*dev
;
245 struct jaylink_context
*ctx
;
250 log_dbg(ctx
, "Closing device (bus:address = %03u:%03u).",
251 libusb_get_bus_number(dev
->usb_dev
),
252 libusb_get_device_address(dev
->usb_dev
));
254 ret
= libusb_release_interface(devh
->usb_devh
, devh
->interface_number
);
256 libusb_close(devh
->usb_devh
);
257 cleanup_handle(devh
);
259 if (ret
!= LIBUSB_SUCCESS
) {
260 log_err(ctx
, "Failed to release interface: %s.",
261 libusb_error_name(ret
));
265 log_dbg(ctx
, "Device closed successfully.");
271 * Start a write operation for a device.
273 * The data of a write operation must be written with at least one call of
274 * transport_write(). It is required that all data of a write operation is
275 * written before an other write and/or read operation is started.
277 * @param[in,out] devh Device handle.
278 * @param[in] length Number of bytes of the write operation.
279 * @param[in] has_command Determines whether the data of the write operation
280 * contains the protocol command.
282 * @retval JAYLINK_OK Success.
283 * @retval JAYLINK_ERR_ARG Invalid arguments.
285 JAYLINK_PRIV
int transport_start_write(struct jaylink_device_handle
*devh
,
286 size_t length
, bool has_command
)
288 struct jaylink_context
*ctx
;
293 return JAYLINK_ERR_ARG
;
295 ctx
= devh
->dev
->ctx
;
297 log_dbg(ctx
, "Starting write operation (length = %zu bytes).", 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 devh
->write_length
= length
;
313 * Start a read operation for a device.
315 * The data of a read operation must be read with at least one call of
316 * transport_read(). It is required that all data of a read operation is read
317 * before an other write and/or read operation is started.
319 * @param[in,out] devh Device handle.
320 * @param[in] length Number of bytes of the read operation.
322 * @retval JAYLINK_OK Success.
323 * @retval JAYLINK_ERR_ARG Invalid arguments.
325 JAYLINK_PRIV
int transport_start_read(struct jaylink_device_handle
*devh
,
328 struct jaylink_context
*ctx
;
331 return JAYLINK_ERR_ARG
;
333 ctx
= devh
->dev
->ctx
;
335 log_dbg(ctx
, "Starting read operation (length = %zu bytes).", length
);
337 if (devh
->bytes_available
> 0)
338 log_dbg(ctx
, "Last read operation left %zu bytes in the "
339 "buffer.", devh
->bytes_available
);
341 if (devh
->read_length
> 0)
342 log_warn(ctx
, "Last read operation left %zu bytes.",
345 devh
->read_length
= length
;
351 * Start a write and read operation for a device.
353 * This function starts a write and read operation as the consecutive call of
354 * transport_start_write() and transport_start_read() but has a different
355 * meaning from the protocol perspective and can therefore not be replaced by
356 * these functions and vice versa.
358 * @note The write operation must be completed first before the read operation
361 * @param[in,out] devh Device handle.
362 * @param[in] write_length Number of bytes of the write operation.
363 * @param[in] read_length Number of bytes of the read operation.
364 * @param[in] has_command Determines whether the data of the write operation
365 * contains the protocol command.
367 * @retval JAYLINK_OK Success.
368 * @retval JAYLINK_ERR_ARG Invalid arguments.
370 JAYLINK_PRIV
int transport_start_write_read(struct jaylink_device_handle
*devh
,
371 size_t write_length
, size_t read_length
, bool has_command
)
373 struct jaylink_context
*ctx
;
377 if (!read_length
|| !write_length
)
378 return JAYLINK_ERR_ARG
;
380 ctx
= devh
->dev
->ctx
;
382 log_dbg(ctx
, "Starting write / read operation (length = "
383 "%zu / %zu bytes).", write_length
, read_length
);
385 if (devh
->write_pos
> 0)
386 log_warn(ctx
, "Last write operation left %zu bytes in the "
387 "buffer.", devh
->write_pos
);
389 if (devh
->write_length
> 0)
390 log_warn(ctx
, "Last write operation was not performed.");
392 if (devh
->bytes_available
> 0)
393 log_warn(ctx
, "Last read operation left %zu bytes in the "
394 "buffer.", devh
->bytes_available
);
396 if (devh
->read_length
> 0)
397 log_warn(ctx
, "Last read operation left %zu bytes.",
400 devh
->write_length
= write_length
;
403 devh
->read_length
= read_length
;
404 devh
->bytes_available
= 0;
410 static bool adjust_buffer(struct jaylink_device_handle
*devh
, size_t size
)
412 struct jaylink_context
*ctx
;
416 ctx
= devh
->dev
->ctx
;
418 /* Adjust buffer size to a multiple of CHUNK_SIZE bytes. */
419 num_chunks
= size
/ CHUNK_SIZE
;
421 if (size
% CHUNK_SIZE
> 0)
424 size
= num_chunks
* CHUNK_SIZE
;
425 buffer
= realloc(devh
->buffer
, size
);
428 log_err(ctx
, "Failed to adjust buffer size to %zu bytes.",
433 devh
->buffer
= buffer
;
434 devh
->buffer_size
= size
;
436 log_dbg(ctx
, "Adjusted buffer size to %zu bytes.", size
);
441 static int usb_send(struct jaylink_device_handle
*devh
, const uint8_t *buffer
,
445 struct jaylink_context
*ctx
;
449 ctx
= devh
->dev
->ctx
;
450 tries
= NUM_TIMEOUTS
;
452 while (tries
> 0 && length
> 0) {
453 /* Send data in chunks of CHUNK_SIZE bytes to the device. */
454 ret
= libusb_bulk_transfer(devh
->usb_devh
, devh
->endpoint_out
,
455 (unsigned char *)buffer
, MIN(CHUNK_SIZE
, length
),
456 &transferred
, USB_TIMEOUT
);
458 if (ret
== LIBUSB_SUCCESS
) {
459 tries
= NUM_TIMEOUTS
;
460 } else if (ret
== LIBUSB_ERROR_TIMEOUT
) {
461 log_warn(ctx
, "Sending data to device timed out, "
464 } else if (ret
== LIBUSB_ERROR_IO
) {
465 log_err(ctx
, "Failed to send data to device: "
466 "input/output error.");
467 return JAYLINK_ERR_IO
;
469 log_err(ctx
, "Failed to send data to device: %s.",
470 libusb_error_name(ret
));
474 buffer
+= transferred
;
475 length
-= transferred
;
477 log_dbg(ctx
, "Sent %i bytes to device.", transferred
);
483 log_err(ctx
, "Sending data to device timed out.");
485 return JAYLINK_ERR_TIMEOUT
;
489 * Write data to a device.
491 * Before this function is used transport_start_write() or
492 * transport_start_write_read() must be called to start a write operation. The
493 * total number of written bytes must not exceed the number of bytes of the
496 * @note A write operation will be performed and the data will be sent to the
497 * device when the number of written bytes reaches the number of bytes of
498 * the write operation. Before that the data will be written into a
501 * @param[in,out] devh Device handle.
502 * @param[in] buffer Buffer to write data from.
503 * @param[in] length Number of bytes to write.
505 * @retval JAYLINK_OK Success.
506 * @retval JAYLINK_ERR_ARG Invalid arguments.
507 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
508 * @retval JAYLINK_ERR_IO Input/output error.
509 * @retval JAYLINK_ERR Other error conditions.
511 JAYLINK_PRIV
int transport_write(struct jaylink_device_handle
*devh
,
512 const uint8_t *buffer
, size_t length
)
515 struct jaylink_context
*ctx
;
520 ctx
= devh
->dev
->ctx
;
522 if (length
> devh
->write_length
) {
523 log_err(ctx
, "Requested to write %zu bytes but only %zu bytes "
524 "are expected for the write operation.", length
,
526 return JAYLINK_ERR_ARG
;
530 * Store data in the buffer if the expected number of bytes for the
531 * write operation is not reached.
533 if (length
< devh
->write_length
) {
534 if (devh
->write_pos
+ length
> devh
->buffer_size
) {
535 if (!adjust_buffer(devh
, devh
->write_pos
+ length
))
536 return JAYLINK_ERR_MALLOC
;
539 memcpy(devh
->buffer
+ devh
->write_pos
, buffer
, length
);
541 devh
->write_length
-= length
;
542 devh
->write_pos
+= length
;
544 log_dbg(ctx
, "Wrote %zu bytes into buffer.", length
);
549 * Expected number of bytes for this write operation is reached and
550 * therefore the write operation will be performed.
552 devh
->write_length
= 0;
554 /* Send data directly to the device if the buffer is empty. */
555 if (!devh
->write_pos
)
556 return usb_send(devh
, buffer
, length
);
559 * Calculate the number of bytes to fill up the buffer to reach a
560 * multiple of CHUNK_SIZE bytes. This ensures that the data from the
561 * buffer will be sent to the device in chunks of CHUNK_SIZE bytes.
562 * Note that this is why the buffer size must be a multiple of
565 num_chunks
= devh
->write_pos
/ CHUNK_SIZE
;
567 if (devh
->write_pos
% CHUNK_SIZE
)
570 fill_bytes
= (num_chunks
* CHUNK_SIZE
) - devh
->write_pos
;
571 tmp
= MIN(length
, fill_bytes
);
574 memcpy(devh
->buffer
+ devh
->write_pos
, buffer
, tmp
);
579 log_dbg(ctx
, "Buffer filled up with %zu bytes.", tmp
);
582 /* Send buffered data to the device. */
583 ret
= usb_send(devh
, devh
->buffer
, devh
->write_pos
+ tmp
);
586 if (ret
!= JAYLINK_OK
)
592 /* Send remaining data to the device. */
593 return usb_send(devh
, buffer
, length
);
596 static int usb_recv(struct jaylink_device_handle
*devh
, uint8_t *buffer
,
600 struct jaylink_context
*ctx
;
604 ctx
= devh
->dev
->ctx
;
605 tries
= NUM_TIMEOUTS
;
608 while (tries
> 0 && !transferred
) {
609 /* Always request CHUNK_SIZE bytes from the device. */
610 ret
= libusb_bulk_transfer(devh
->usb_devh
, devh
->endpoint_in
,
611 (unsigned char *)buffer
, CHUNK_SIZE
, &transferred
,
614 if (ret
== LIBUSB_ERROR_TIMEOUT
) {
615 log_warn(ctx
, "Receiving data from device timed out, "
619 } else if (ret
== LIBUSB_ERROR_IO
) {
620 log_err(ctx
, "Failed to receive data from device: "
621 "input/output error.");
622 return JAYLINK_ERR_IO
;
623 } else if (ret
!= LIBUSB_SUCCESS
) {
624 log_err(ctx
, "Failed to receive data from device: %s.",
625 libusb_error_name(ret
));
629 log_dbg(ctx
, "Received %i bytes from device.", transferred
);
632 /* Ignore a possible timeout if at least one byte was received. */
633 if (transferred
> 0) {
634 *length
= transferred
;
638 log_err(ctx
, "Receiving data from device timed out.");
640 return JAYLINK_ERR_TIMEOUT
;
644 * Read data from a device.
646 * Before this function is used transport_start_read() or
647 * transport_start_write_read() must be called to start a read operation. The
648 * total number of read bytes must not exceed the number of bytes of the read
651 * @param[in,out] devh Device handle.
652 * @param[out] buffer Buffer to read data into on success. Its content is
653 * undefined on failure.
654 * @param[in] length Number of bytes to read.
656 * @retval JAYLINK_OK Success.
657 * @retval JAYLINK_ERR_ARG Invalid arguments.
658 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
659 * @retval JAYLINK_ERR_IO Input/output error.
660 * @retval JAYLINK_ERR Other error conditions.
662 JAYLINK_PRIV
int transport_read(struct jaylink_device_handle
*devh
,
663 uint8_t *buffer
, size_t length
)
666 struct jaylink_context
*ctx
;
667 size_t bytes_received
;
670 ctx
= devh
->dev
->ctx
;
672 if (length
> devh
->read_length
) {
673 log_err(ctx
, "Requested to read %zu bytes but only %zu bytes "
674 "are expected for the read operation.", length
,
676 return JAYLINK_ERR_ARG
;
679 if (length
<= devh
->bytes_available
) {
680 memcpy(buffer
, devh
->buffer
+ devh
->read_pos
, length
);
682 devh
->read_length
-= length
;
683 devh
->bytes_available
-= length
;
684 devh
->read_pos
+= length
;
686 log_dbg(ctx
, "Read %zu bytes from buffer.", length
);
690 if (devh
->bytes_available
> 0) {
691 memcpy(buffer
, devh
->buffer
+ devh
->read_pos
,
692 devh
->bytes_available
);
694 buffer
+= devh
->bytes_available
;
695 length
-= devh
->bytes_available
;
696 devh
->read_length
-= devh
->bytes_available
;
698 log_dbg(ctx
, "Read %zu bytes from buffer to flush it.",
699 devh
->bytes_available
);
701 devh
->bytes_available
= 0;
707 * If less than CHUNK_SIZE bytes are requested from the device,
708 * store the received data into the internal buffer instead of
709 * directly into the user provided buffer. This is necessary to
710 * prevent a possible buffer overflow because the number of
711 * requested bytes from the device is always CHUNK_SIZE and
712 * therefore up to CHUNK_SIZE bytes may be received.
713 * Note that this is why the internal buffer size must be at
714 * least CHUNK_SIZE bytes.
716 if (length
< CHUNK_SIZE
) {
717 ret
= usb_recv(devh
, devh
->buffer
, &bytes_received
);
719 if (ret
!= JAYLINK_OK
)
722 tmp
= MIN(bytes_received
, length
);
723 memcpy(buffer
, devh
->buffer
, tmp
);
726 * Setup the buffer for the remaining data if more data
727 * was received from the device than was requested.
729 if (bytes_received
> length
) {
730 devh
->bytes_available
= bytes_received
- tmp
;
731 devh
->read_pos
= tmp
;
736 devh
->read_length
-= tmp
;
738 log_dbg(ctx
, "Read %zu bytes from buffer.", tmp
);
740 ret
= usb_recv(devh
, buffer
, &bytes_received
);
742 if (ret
!= JAYLINK_OK
)
745 buffer
+= bytes_received
;
746 length
-= bytes_received
;
747 devh
->read_length
-= bytes_received
;
749 log_dbg(ctx
, "Read %zu bytes from device.",