Add project website URL
[libjaylink.git] / libjaylink / transport.c
bloba82b83dc99a447b047c0467305de3a8d6ca4ef71
1 /*
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/>.
20 #include <stdlib.h>
21 #include <stdint.h>
22 #include <stdbool.h>
23 #include <string.h>
25 #include "libjaylink.h"
26 #include "libjaylink-internal.h"
28 /**
29 * @file
31 * Transport abstraction layer.
34 /** Timeout of an USB transfer in milliseconds. */
35 #define USB_TIMEOUT 1000
37 /**
38 * Number of consecutive timeouts before an USB transfer will be treated as
39 * timed out.
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)
48 int ret;
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;
54 bool found_interface;
55 bool found_endpoint_in;
56 bool found_endpoint_out;
57 uint8_t i;
59 ctx = devh->dev->ctx;
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_ERROR_IO) {
69 log_err(ctx, "Failed to get configuration descriptor: "
70 "input/output error.");
71 return JAYLINK_ERR_IO;
72 } else if (ret != LIBUSB_SUCCESS) {
73 log_err(ctx, "Failed to get configuration descriptor: %s.",
74 libusb_error_name(ret));
75 return JAYLINK_ERR;
78 found_interface = false;
80 for (i = 0; i < config->bNumInterfaces; i++) {
81 interface = &config->interface[i];
82 desc = &interface->altsetting[0];
84 if (desc->bInterfaceClass != LIBUSB_CLASS_VENDOR_SPEC)
85 continue;
87 if (desc->bInterfaceSubClass != LIBUSB_CLASS_VENDOR_SPEC)
88 continue;
90 if (desc->bNumEndpoints < 2)
91 continue;
93 found_interface = true;
94 devh->interface_number = i;
95 break;
98 if (!found_interface) {
99 log_err(ctx, "No suitable interface found.");
100 libusb_free_config_descriptor(config);
101 return JAYLINK_ERR;
104 found_endpoint_in = false;
105 found_endpoint_out = false;
107 for (i = 0; i < desc->bNumEndpoints; i++) {
108 epdesc = &desc->endpoint[i];
110 if (epdesc->bEndpointAddress & LIBUSB_ENDPOINT_IN) {
111 devh->endpoint_in = epdesc->bEndpointAddress;
112 found_endpoint_in = true;
113 } else {
114 devh->endpoint_out = epdesc->bEndpointAddress;
115 found_endpoint_out = true;
119 libusb_free_config_descriptor(config);
121 if (!found_endpoint_in) {
122 log_err(ctx, "Interface IN endpoint not found.");
123 return JAYLINK_ERR;
126 if (!found_endpoint_out) {
127 log_err(ctx, "Interface OUT endpoint not found.");
128 return JAYLINK_ERR;
131 log_dbg(ctx, "Using endpoint %02x (IN) and %02x (OUT).",
132 devh->endpoint_in, devh->endpoint_out);
134 /* Buffer size must be a multiple of CHUNK_SIZE bytes. */
135 devh->buffer_size = CHUNK_SIZE;
136 devh->buffer = malloc(devh->buffer_size);
138 if (!devh->buffer) {
139 log_err(ctx, "Transport buffer malloc failed.");
140 return JAYLINK_ERR_MALLOC;
143 devh->read_length = 0;
144 devh->bytes_available = 0;
145 devh->read_pos = 0;
147 devh->write_length = 0;
148 devh->write_pos = 0;
150 return JAYLINK_OK;
153 static void cleanup_handle(struct jaylink_device_handle *devh)
155 free(devh->buffer);
159 * Open a device.
161 * This function must be called before any other function of the transport
162 * abstraction layer for the given device handle is called.
164 * @param[in,out] devh Device handle.
166 * @retval JAYLINK_OK Success.
167 * @retval JAYLINK_ERR_IO Input/output error.
168 * @retval JAYLINK_ERR Other error conditions.
170 JAYLINK_PRIV int transport_open(struct jaylink_device_handle *devh)
172 int ret;
173 struct jaylink_device *dev;
174 struct jaylink_context *ctx;
175 struct libusb_device_handle *usb_devh;
177 dev = devh->dev;
178 ctx = dev->ctx;
180 log_dbg(ctx, "Trying to open device (bus:address = %03u:%03u).",
181 libusb_get_bus_number(dev->usb_dev),
182 libusb_get_device_address(dev->usb_dev));
184 ret = initialize_handle(devh);
186 if (ret != JAYLINK_OK) {
187 log_err(ctx, "Failed to initialize device handle.");
188 return ret;
191 ret = libusb_open(dev->usb_dev, &usb_devh);
193 if (ret == LIBUSB_ERROR_IO) {
194 log_err(ctx, "Failed to open device: input/output error.");
195 cleanup_handle(devh);
196 return JAYLINK_ERR_IO;
197 } else if (ret != LIBUSB_SUCCESS) {
198 log_err(ctx, "Failed to open device: %s.",
199 libusb_error_name(ret));
200 cleanup_handle(devh);
201 return JAYLINK_ERR;
204 ret = libusb_claim_interface(usb_devh, devh->interface_number);
206 if (ret == LIBUSB_ERROR_IO) {
207 log_err(ctx, "Failed to claim interface: input/output error.");
208 return JAYLINK_ERR_IO;
209 } else if (ret != LIBUSB_SUCCESS) {
210 log_err(ctx, "Failed to claim interface: %s.",
211 libusb_error_name(ret));
212 cleanup_handle(devh);
213 libusb_close(usb_devh);
214 return JAYLINK_ERR;
217 log_dbg(ctx, "Device opened successfully.");
219 devh->usb_devh = usb_devh;
221 return JAYLINK_OK;
225 * Close a device.
227 * After this function has been called no other function of the transport
228 * abstraction layer for the given device handle must be called.
230 * @param[in,out] devh Device handle.
232 * @retval JAYLINK_OK Success.
233 * @retval JAYLINK_ERR Other error conditions.
235 JAYLINK_PRIV int transport_close(struct jaylink_device_handle *devh)
237 int ret;
238 struct jaylink_device *dev;
239 struct jaylink_context *ctx;
241 dev = devh->dev;
242 ctx = dev->ctx;
244 log_dbg(ctx, "Closing device (bus:address = %03u:%03u).",
245 libusb_get_bus_number(dev->usb_dev),
246 libusb_get_device_address(dev->usb_dev));
248 ret = libusb_release_interface(devh->usb_devh, devh->interface_number);
250 libusb_close(devh->usb_devh);
251 cleanup_handle(devh);
253 if (ret != LIBUSB_SUCCESS) {
254 log_err(ctx, "Failed to release interface: %s.",
255 libusb_error_name(ret));
256 return JAYLINK_ERR;
259 log_dbg(ctx, "Device closed successfully.");
261 return JAYLINK_OK;
265 * Start a write operation for a device.
267 * The data of a write operation must be written with at least one call of
268 * transport_write(). It is required that all data of a write operation is
269 * written before an other write and/or read operation is started.
271 * @param[in,out] devh Device handle.
272 * @param[in] length Number of bytes of the write operation.
273 * @param[in] has_command Determines whether the data of the write operation
274 * contains the protocol command.
276 * @retval JAYLINK_OK Success.
277 * @retval JAYLINK_ERR_ARG Invalid arguments.
279 JAYLINK_PRIV int transport_start_write(struct jaylink_device_handle *devh,
280 size_t length, bool has_command)
282 struct jaylink_context *ctx;
284 (void)has_command;
286 if (!length)
287 return JAYLINK_ERR_ARG;
289 ctx = devh->dev->ctx;
291 log_dbg(ctx, "Starting write operation (length = %zu bytes).", length);
293 if (devh->write_pos > 0)
294 log_warn(ctx, "Last write operation left %zu bytes in the "
295 "buffer.", devh->write_pos);
297 if (devh->write_length > 0)
298 log_warn(ctx, "Last write operation was not performed.");
300 devh->write_length = length;
301 devh->write_pos = 0;
303 return JAYLINK_OK;
307 * Start a read operation for a device.
309 * The data of a read operation must be read with at least one call of
310 * transport_read(). It is required that all data of a read operation is read
311 * before an other write and/or read operation is started.
313 * @param[in,out] devh Device handle.
314 * @param[in] length Number of bytes of the read operation.
316 * @retval JAYLINK_OK Success.
317 * @retval JAYLINK_ERR_ARG Invalid arguments.
319 JAYLINK_PRIV int transport_start_read(struct jaylink_device_handle *devh,
320 size_t length)
322 struct jaylink_context *ctx;
324 if (!length)
325 return JAYLINK_ERR_ARG;
327 ctx = devh->dev->ctx;
329 log_dbg(ctx, "Starting read operation (length = %zu bytes).", length);
331 if (devh->bytes_available > 0)
332 log_dbg(ctx, "Last read operation left %zu bytes in the "
333 "buffer.", devh->bytes_available);
335 if (devh->read_length > 0)
336 log_warn(ctx, "Last read operation left %zu bytes.",
337 devh->read_length);
339 devh->read_length = length;
341 return JAYLINK_OK;
345 * Start a write and read operation for a device.
347 * This function starts a write and read operation as the consecutive call of
348 * transport_start_write() and transport_start_read() but has a different
349 * meaning from the protocol perspective and can therefore not be replaced by
350 * these functions and vice versa.
352 * @note The write operation must be completed first before the read operation
353 * must be processed.
355 * @param[in,out] devh Device handle.
356 * @param[in] write_length Number of bytes of the write operation.
357 * @param[in] read_length Number of bytes of the read operation.
358 * @param[in] has_command Determines whether the data of the write operation
359 * contains the protocol command.
361 * @retval JAYLINK_OK Success.
362 * @retval JAYLINK_ERR_ARG Invalid arguments.
364 JAYLINK_PRIV int transport_start_write_read(struct jaylink_device_handle *devh,
365 size_t write_length, size_t read_length, bool has_command)
367 struct jaylink_context *ctx;
369 (void)has_command;
371 if (!read_length || !write_length)
372 return JAYLINK_ERR_ARG;
374 ctx = devh->dev->ctx;
376 log_dbg(ctx, "Starting write / read operation (length = "
377 "%zu / %zu bytes).", write_length, read_length);
379 if (devh->write_pos > 0)
380 log_warn(ctx, "Last write operation left %zu bytes in the "
381 "buffer.", devh->write_pos);
383 if (devh->write_length > 0)
384 log_warn(ctx, "Last write operation was not performed.");
386 if (devh->bytes_available > 0)
387 log_warn(ctx, "Last read operation left %zu bytes in the "
388 "buffer.", devh->bytes_available);
390 if (devh->read_length > 0)
391 log_warn(ctx, "Last read operation left %zu bytes.",
392 devh->read_length);
394 devh->write_length = write_length;
395 devh->write_pos = 0;
397 devh->read_length = read_length;
398 devh->bytes_available = 0;
399 devh->read_pos = 0;
401 return JAYLINK_OK;
404 static bool adjust_buffer(struct jaylink_device_handle *devh, size_t size)
406 struct jaylink_context *ctx;
407 size_t num_chunks;
408 uint8_t *buffer;
410 ctx = devh->dev->ctx;
412 /* Adjust buffer size to a multiple of CHUNK_SIZE bytes. */
413 num_chunks = size / CHUNK_SIZE;
415 if (size % CHUNK_SIZE > 0)
416 num_chunks++;
418 size = num_chunks * CHUNK_SIZE;
419 buffer = realloc(devh->buffer, size);
421 if (!buffer) {
422 log_err(ctx, "Failed to adjust buffer size to %zu bytes.",
423 size);
424 return false;
427 devh->buffer = buffer;
428 devh->buffer_size = size;
430 log_dbg(ctx, "Adjusted buffer size to %zu bytes.", size);
432 return true;
435 static int usb_send(struct jaylink_device_handle *devh, const uint8_t *buffer,
436 size_t length)
438 int ret;
439 struct jaylink_context *ctx;
440 unsigned int tries;
441 int transferred;
443 ctx = devh->dev->ctx;
444 tries = NUM_TIMEOUTS;
446 while (tries > 0 && length > 0) {
447 /* Send data in chunks of CHUNK_SIZE bytes to the device. */
448 ret = libusb_bulk_transfer(devh->usb_devh, devh->endpoint_out,
449 (unsigned char *)buffer, MIN(CHUNK_SIZE, length),
450 &transferred, USB_TIMEOUT);
452 if (ret == LIBUSB_SUCCESS) {
453 tries = NUM_TIMEOUTS;
454 } else if (ret == LIBUSB_ERROR_TIMEOUT) {
455 log_warn(ctx, "Sending data to device timed out, "
456 "retrying.");
457 tries--;
458 } else if (ret == LIBUSB_ERROR_IO) {
459 log_err(ctx, "Failed to send data to device: "
460 "input/output error.");
461 return JAYLINK_ERR_IO;
462 } else {
463 log_err(ctx, "Failed to send data to device: %s.",
464 libusb_error_name(ret));
465 return JAYLINK_ERR;
468 buffer += transferred;
469 length -= transferred;
471 log_dbg(ctx, "Sent %i bytes to device.", transferred);
474 if (!length)
475 return JAYLINK_OK;
477 log_err(ctx, "Sending data to device timed out.");
479 return JAYLINK_ERR_TIMEOUT;
483 * Write data to a device.
485 * Before this function is used transport_start_write() or
486 * transport_start_write_read() must be called to start a write operation. The
487 * total number of written bytes must not exceed the number of bytes of the
488 * write operation.
490 * @note A write operation will be performed and the data will be sent to the
491 * device when the number of written bytes reaches the number of bytes of
492 * the write operation. Before that the data will be written into a
493 * buffer.
495 * @param[in,out] devh Device handle.
496 * @param[in] buffer Buffer to write data from.
497 * @param[in] length Number of bytes to write.
499 * @retval JAYLINK_OK Success.
500 * @retval JAYLINK_ERR_ARG Invalid arguments.
501 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
502 * @retval JAYLINK_ERR_IO Input/output error.
503 * @retval JAYLINK_ERR Other error conditions.
505 JAYLINK_PRIV int transport_write(struct jaylink_device_handle *devh,
506 const uint8_t *buffer, size_t length)
508 int ret;
509 struct jaylink_context *ctx;
510 size_t num_chunks;
511 size_t fill_bytes;
512 size_t tmp;
514 ctx = devh->dev->ctx;
516 if (length > devh->write_length) {
517 log_err(ctx, "Requested to write %zu bytes but only %zu bytes "
518 "are expected for the write operation.", length,
519 devh->write_length);
520 return JAYLINK_ERR_ARG;
524 * Store data in the buffer if the expected number of bytes for the
525 * write operation is not reached.
527 if (length < devh->write_length) {
528 if (devh->write_pos + length > devh->buffer_size) {
529 if (!adjust_buffer(devh, devh->write_pos + length))
530 return JAYLINK_ERR_MALLOC;
533 memcpy(devh->buffer + devh->write_pos, buffer, length);
535 devh->write_length -= length;
536 devh->write_pos += length;
538 log_dbg(ctx, "Wrote %zu bytes into buffer.", length);
539 return JAYLINK_OK;
543 * Expected number of bytes for this write operation is reached and
544 * therefore the write operation will be performed.
546 devh->write_length = 0;
548 /* Send data directly to the device if the buffer is empty. */
549 if (!devh->write_pos)
550 return usb_send(devh, buffer, length);
553 * Calculate the number of bytes to fill up the buffer to reach a
554 * multiple of CHUNK_SIZE bytes. This ensures that the data from the
555 * buffer will be sent to the device in chunks of CHUNK_SIZE bytes.
556 * Note that this is why the buffer size must be a multiple of
557 * CHUNK_SIZE bytes.
559 num_chunks = devh->write_pos / CHUNK_SIZE;
561 if (devh->write_pos % CHUNK_SIZE)
562 num_chunks++;
564 fill_bytes = (num_chunks * CHUNK_SIZE) - devh->write_pos;
565 tmp = MIN(length, fill_bytes);
567 if (tmp > 0) {
568 memcpy(devh->buffer + devh->write_pos, buffer, tmp);
570 length -= tmp;
571 buffer += tmp;
573 log_dbg(ctx, "Buffer filled up with %zu bytes.", tmp);
576 /* Send buffered data to the device. */
577 ret = usb_send(devh, devh->buffer, devh->write_pos + tmp);
578 devh->write_pos = 0;
580 if (ret != JAYLINK_OK)
581 return ret;
583 if (!length)
584 return JAYLINK_OK;
586 /* Send remaining data to the device. */
587 return usb_send(devh, buffer, length);
590 static int usb_recv(struct jaylink_device_handle *devh, uint8_t *buffer,
591 size_t *length)
593 int ret;
594 struct jaylink_context *ctx;
595 unsigned int tries;
596 int transferred;
598 ctx = devh->dev->ctx;
599 tries = NUM_TIMEOUTS;
600 transferred = 0;
602 while (tries > 0 && !transferred) {
603 /* Always request CHUNK_SIZE bytes from the device. */
604 ret = libusb_bulk_transfer(devh->usb_devh, devh->endpoint_in,
605 (unsigned char *)buffer, CHUNK_SIZE, &transferred,
606 USB_TIMEOUT);
608 if (ret == LIBUSB_ERROR_TIMEOUT) {
609 log_warn(ctx, "Receiving data from device timed out, "
610 "retrying.");
611 tries--;
612 continue;
613 } else if (ret == LIBUSB_ERROR_IO) {
614 log_err(ctx, "Failed to receive data from device: "
615 "input/output error.");
616 return JAYLINK_ERR_IO;
617 } else if (ret != LIBUSB_SUCCESS) {
618 log_err(ctx, "Failed to receive data from device: %s.",
619 libusb_error_name(ret));
620 return JAYLINK_ERR;
623 log_dbg(ctx, "Received %i bytes from device.", transferred);
626 /* Ignore a possible timeout if at least one byte was received. */
627 if (transferred > 0) {
628 *length = transferred;
629 return JAYLINK_OK;
632 log_err(ctx, "Receiving data from device timed out.");
634 return JAYLINK_ERR_TIMEOUT;
638 * Read data from a device.
640 * Before this function is used transport_start_read() or
641 * transport_start_write_read() must be called to start a read operation. The
642 * total number of read bytes must not exceed the number of bytes of the read
643 * operation.
645 * @param[in,out] devh Device handle.
646 * @param[out] buffer Buffer to read data into on success. Its content is
647 * undefined on failure.
648 * @param[in] length Number of bytes to read.
650 * @retval JAYLINK_OK Success.
651 * @retval JAYLINK_ERR_ARG Invalid arguments.
652 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
653 * @retval JAYLINK_ERR_IO Input/output error.
654 * @retval JAYLINK_ERR Other error conditions.
656 JAYLINK_PRIV int transport_read(struct jaylink_device_handle *devh,
657 uint8_t *buffer, size_t length)
659 int ret;
660 struct jaylink_context *ctx;
661 size_t bytes_received;
662 size_t tmp;
664 ctx = devh->dev->ctx;
666 if (length > devh->read_length) {
667 log_err(ctx, "Requested to read %zu bytes but only %zu bytes "
668 "are expected for the read operation.", length,
669 devh->read_length);
670 return JAYLINK_ERR_ARG;
673 if (length <= devh->bytes_available) {
674 memcpy(buffer, devh->buffer + devh->read_pos, length);
676 devh->read_length -= length;
677 devh->bytes_available -= length;
678 devh->read_pos += length;
680 log_dbg(ctx, "Read %zu bytes from buffer.", length);
681 return JAYLINK_OK;
684 if (devh->bytes_available > 0) {
685 memcpy(buffer, devh->buffer + devh->read_pos,
686 devh->bytes_available);
688 buffer += devh->bytes_available;
689 length -= devh->bytes_available;
690 devh->read_length -= devh->bytes_available;
692 log_dbg(ctx, "Read %zu bytes from buffer to flush it.",
693 devh->bytes_available);
695 devh->bytes_available = 0;
696 devh->read_pos = 0;
699 while (length > 0) {
701 * If less than CHUNK_SIZE bytes are requested from the device,
702 * store the received data into the internal buffer instead of
703 * directly into the user provided buffer. This is necessary to
704 * prevent a possible buffer overflow because the number of
705 * requested bytes from the device is always CHUNK_SIZE and
706 * therefore up to CHUNK_SIZE bytes may be received.
707 * Note that this is why the internal buffer size must be at
708 * least CHUNK_SIZE bytes.
710 if (length < CHUNK_SIZE) {
711 ret = usb_recv(devh, devh->buffer, &bytes_received);
713 if (ret != JAYLINK_OK)
714 return ret;
716 tmp = MIN(bytes_received, length);
717 memcpy(buffer, devh->buffer, tmp);
720 * Setup the buffer for the remaining data if more data
721 * was received from the device than was requested.
723 if (bytes_received > length) {
724 devh->bytes_available = bytes_received - tmp;
725 devh->read_pos = tmp;
728 buffer += tmp;
729 length -= tmp;
730 devh->read_length -= tmp;
732 log_dbg(ctx, "Read %zu bytes from buffer.", tmp);
733 } else {
734 ret = usb_recv(devh, buffer, &bytes_received);
736 if (ret != JAYLINK_OK)
737 return ret;
739 buffer += bytes_received;
740 length -= bytes_received;
741 devh->read_length -= bytes_received;
743 log_dbg(ctx, "Read %zu bytes from device.",
744 bytes_received);
748 return JAYLINK_OK;