Add build support for Cygwin
[libjaylink.git] / libjaylink / transport.c
blob0a4a8dd844cac52fb86673d6f864f9e705494385
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 <stddef.h>
22 #include <stdint.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 int found_interface;
55 int found_endpoint_in;
56 int 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_SUCCESS) {
69 log_err(ctx, "Failed to get configuration descriptor: %s.",
70 libusb_error_name(ret));
71 return JAYLINK_ERR;
74 found_interface = 0;
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)
81 continue;
83 if (desc->bInterfaceSubClass != LIBUSB_CLASS_VENDOR_SPEC)
84 continue;
86 if (desc->bNumEndpoints < 2)
87 continue;
89 found_interface = 1;
90 devh->interface_number = i;
91 break;
94 if (!found_interface) {
95 log_err(ctx, "No suitable interface found.");
96 libusb_free_config_descriptor(config);
97 return JAYLINK_ERR;
100 found_endpoint_in = 0;
101 found_endpoint_out = 0;
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 = 1;
109 } else {
110 devh->endpoint_out = epdesc->bEndpointAddress;
111 found_endpoint_out = 1;
115 libusb_free_config_descriptor(config);
117 if (!found_endpoint_in) {
118 log_err(ctx, "Interface IN endpoint not found.");
119 return JAYLINK_ERR;
122 if (!found_endpoint_out) {
123 log_err(ctx, "Interface OUT endpoint not found.");
124 return JAYLINK_ERR;
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);
134 if (!devh->buffer) {
135 log_err(ctx, "Transport buffer malloc failed.");
136 return JAYLINK_ERR_MALLOC;
139 devh->read_length = 0;
140 devh->bytes_available = 0;
141 devh->read_pos = 0;
143 devh->write_length = 0;
144 devh->write_pos = 0;
146 return JAYLINK_OK;
149 static void cleanup_handle(struct jaylink_device_handle *devh)
151 free(devh->buffer);
155 * Open a device.
157 * This function must be called before any other function of the transport
158 * abstraction layer for the given device handle is called.
160 * @param devh Device handle.
162 * @retval JAYLINK_OK Success.
163 * @retval JAYLINK_ERR Other error conditions.
165 JAYLINK_PRIV int transport_open(struct jaylink_device_handle *devh)
167 int ret;
168 struct jaylink_device *dev;
169 struct jaylink_context *ctx;
170 struct libusb_device_handle *usb_devh;
172 dev = devh->dev;
173 ctx = dev->ctx;
175 log_dbg(ctx, "Trying to open device (bus:address = %03u:%03u).",
176 libusb_get_bus_number(dev->usb_dev),
177 libusb_get_device_address(dev->usb_dev));
179 ret = initialize_handle(devh);
181 if (ret != JAYLINK_OK) {
182 log_err(ctx, "Initialize device handle failed.");
183 return ret;
186 ret = libusb_open(dev->usb_dev, &usb_devh);
188 if (ret != LIBUSB_SUCCESS) {
189 log_err(ctx, "Failed to open device: %s.",
190 libusb_error_name(ret));
191 cleanup_handle(devh);
192 return JAYLINK_ERR;
195 ret = libusb_claim_interface(usb_devh, devh->interface_number);
197 if (ret != LIBUSB_SUCCESS) {
198 log_err(ctx, "Failed to claim interface: %s.",
199 libusb_error_name(ret));
200 cleanup_handle(devh);
201 libusb_close(usb_devh);
202 return JAYLINK_ERR;
205 log_dbg(ctx, "Device opened successfully.");
207 devh->usb_devh = usb_devh;
209 return JAYLINK_OK;
213 * Close a device.
215 * After this function has been called no other function of the transport
216 * abstraction layer for the given device handle must be called.
218 * @param devh Device handle.
220 * @retval JAYLINK_OK Success.
221 * @retval JAYLINK_ERR Other error conditions.
223 JAYLINK_PRIV int transport_close(struct jaylink_device_handle *devh)
225 int ret;
226 struct jaylink_device *dev;
227 struct jaylink_context *ctx;
229 dev = devh->dev;
230 ctx = dev->ctx;
232 log_dbg(ctx, "Closing device (bus:address = %03u:%03u).",
233 libusb_get_bus_number(dev->usb_dev),
234 libusb_get_device_address(dev->usb_dev));
236 ret = libusb_release_interface(devh->usb_devh, devh->interface_number);
238 libusb_close(devh->usb_devh);
239 cleanup_handle(devh);
241 if (ret != LIBUSB_SUCCESS) {
242 log_err(ctx, "Failed to release interface: %s.",
243 libusb_error_name(ret));
244 return JAYLINK_ERR;
247 return JAYLINK_OK;
251 * Start a write operation for a device.
253 * The data of a write operation must be written with at least one call of
254 * transport_write(). It is required that all data of a write operation is
255 * written before an other write and/or read operation is started.
257 * @param devh Device handle.
258 * @param length Number of bytes of the write operation.
259 * @param has_command Determines whether the data of the write operation
260 * contains the protocol command.
262 * @retval JAYLINK_OK Success.
263 * @retval JAYLINK_ERR_ARG Invalid arguments.
265 JAYLINK_PRIV int transport_start_write(struct jaylink_device_handle *devh,
266 size_t length, int has_command)
268 struct jaylink_context *ctx;
270 (void)has_command;
272 if (!length)
273 return JAYLINK_ERR_ARG;
275 ctx = devh->dev->ctx;
277 log_dbg(ctx, "Starting write operation (length = %u bytes).", length);
279 if (devh->write_pos > 0)
280 log_warn(ctx, "Last write operation left %u bytes in the "
281 "buffer.", devh->write_pos);
283 if (devh->write_length > 0)
284 log_warn(ctx, "Last write operation was not performed.");
286 devh->write_length = length;
287 devh->write_pos = 0;
289 return JAYLINK_OK;
293 * Start a read operation for a device.
295 * The data of a read operation must be read with at least one call of
296 * transport_read(). It is required that all data of a read operation is read
297 * before an other write and/or read operation is started.
299 * @param devh Device handle.
300 * @param length Number of bytes of the read operation.
302 * @retval JAYLINK_OK Success.
303 * @retval JAYLINK_ERR_ARG Invalid arguments.
305 JAYLINK_PRIV int transport_start_read(struct jaylink_device_handle *devh,
306 size_t length)
308 struct jaylink_context *ctx;
310 if (!length)
311 return JAYLINK_ERR_ARG;
313 ctx = devh->dev->ctx;
315 log_dbg(ctx, "Starting read operation (length = %u bytes).", length);
317 if (devh->bytes_available > 0)
318 log_dbg(ctx, "Last read operation left %u bytes in the "
319 "buffer.", devh->bytes_available);
321 if (devh->read_length > 0)
322 log_warn(ctx, "Last read operation left %u bytes.",
323 devh->read_length);
325 devh->read_length = length;
327 return JAYLINK_OK;
331 * Start a write and read operation for a device.
333 * This function starts a write and read operation as the consecutive call of
334 * transport_start_write() and transport_start_read() but has a different
335 * meaning from the protocol perspective and can therefore not be replaced by
336 * these functions and vice versa.
338 * @note The write operation must be completed first before the read operation
339 * must be processed.
341 * @param devh Device handle.
342 * @param write_length Number of bytes of the write operation.
343 * @param read_length Number of bytes of the read operation.
344 * @param has_command Determines whether the data of the write operation
345 * contains the protocol command.
347 * @retval JAYLINK_OK Success.
348 * @retval JAYLINK_ERR_ARG Invalid arguments.
350 JAYLINK_PRIV int transport_start_write_read(struct jaylink_device_handle *devh,
351 size_t write_length, size_t read_length, int has_command)
353 struct jaylink_context *ctx;
355 (void)has_command;
357 if (!read_length || !write_length)
358 return JAYLINK_ERR_ARG;
360 ctx = devh->dev->ctx;
362 log_dbg(ctx, "Starting write / read operation (length = "
363 "%u / %u bytes).", write_length, read_length);
365 if (devh->write_pos > 0)
366 log_warn(ctx, "Last write operation left %u bytes in the "
367 "buffer.", devh->write_pos);
369 if (devh->write_length > 0)
370 log_warn(ctx, "Last write operation was not performed.");
372 if (devh->bytes_available > 0)
373 log_warn(ctx, "Last read operation left %u bytes in the "
374 "buffer.", devh->bytes_available);
376 if (devh->read_length > 0)
377 log_warn(ctx, "Last read operation left %u bytes.",
378 devh->read_length);
380 devh->write_length = write_length;
381 devh->write_pos = 0;
383 devh->read_length = read_length;
384 devh->bytes_available = 0;
385 devh->read_pos = 0;
387 return JAYLINK_OK;
390 static int usb_recv(struct jaylink_device_handle *devh, uint8_t *buffer,
391 size_t *length)
393 int ret;
394 struct jaylink_context *ctx;
395 unsigned int tries;
396 int transferred;
398 ctx = devh->dev->ctx;
399 tries = NUM_TIMEOUTS;
400 transferred = 0;
402 while (tries > 0 && !transferred) {
403 /* Always request CHUNK_SIZE bytes from the device. */
404 ret = libusb_bulk_transfer(devh->usb_devh, devh->endpoint_in,
405 (unsigned char *)buffer, CHUNK_SIZE, &transferred,
406 USB_TIMEOUT);
408 if (ret == LIBUSB_ERROR_TIMEOUT) {
409 log_warn(ctx, "Failed to receive data from "
410 "device: %s.", libusb_error_name(ret));
411 tries--;
412 continue;
413 } else if (ret != LIBUSB_SUCCESS) {
414 log_err(ctx, "Failed to receive data from "
415 "device: %s.", libusb_error_name(ret));
416 return JAYLINK_ERR;
419 log_dbg(ctx, "Received %u bytes from device.", transferred);
422 /* Ignore a possible timeout if at least one byte was received. */
423 if (transferred > 0) {
424 *length = transferred;
425 return JAYLINK_OK;
428 log_err(ctx, "Receiving data from device timed out.");
430 return JAYLINK_ERR_TIMEOUT;
433 static int usb_send(struct jaylink_device_handle *devh, const uint8_t *buffer,
434 size_t length)
436 int ret;
437 struct jaylink_context *ctx;
438 unsigned int tries;
439 int transferred;
441 ctx = devh->dev->ctx;
442 tries = NUM_TIMEOUTS;
444 while (tries > 0 && length > 0) {
445 /* Send data in chunks of CHUNK_SIZE bytes to the device. */
446 ret = libusb_bulk_transfer(devh->usb_devh, devh->endpoint_out,
447 (unsigned char *)buffer, MIN(CHUNK_SIZE, length),
448 &transferred, USB_TIMEOUT);
450 if (ret == LIBUSB_SUCCESS) {
451 tries = NUM_TIMEOUTS;
452 } else if (ret == LIBUSB_ERROR_TIMEOUT) {
453 log_warn(ctx, "Failed to send data to device: %s.",
454 libusb_error_name(ret));
455 tries--;
456 } else {
457 log_err(ctx, "Failed to send data to device: %s.",
458 libusb_error_name(ret));
459 return JAYLINK_ERR;
462 buffer += transferred;
463 length -= transferred;
465 log_dbg(ctx, "Sent %u bytes to device.", transferred);
468 if (!length)
469 return JAYLINK_OK;
471 log_err(ctx, "Sending data to device timed out.");
473 return JAYLINK_ERR_TIMEOUT;
476 static int adjust_buffer(struct jaylink_device_handle *devh, size_t size)
478 struct jaylink_context *ctx;
479 size_t num_chunks;
480 uint8_t *buffer;
482 ctx = devh->dev->ctx;
484 /* Adjust buffer size to a multiple of CHUNK_SIZE bytes. */
485 num_chunks = size / CHUNK_SIZE;
487 if (size % CHUNK_SIZE > 0)
488 num_chunks++;
490 size = num_chunks * CHUNK_SIZE;
491 buffer = realloc(devh->buffer, size);
493 if (!buffer) {
494 log_err(ctx, "Failed to adjust buffer size to %zu bytes.",
495 size);
496 return 0;
499 devh->buffer = buffer;
500 devh->buffer_size = size;
502 log_dbg(ctx, "Adjusted buffer size to %zu bytes.", size);
504 return 1;
508 * Write data to a device.
510 * Before this function is used transport_start_write() or
511 * transport_start_write_read() must be called to start a write operation. The
512 * total number of written bytes must not exceed the number of bytes of the
513 * write operation.
515 * @note A write operation will be performed and the data will be sent to the
516 * device when the number of written bytes reaches the number of bytes of
517 * the write operation. Before that the data will be written into a
518 * buffer.
520 * @param devh Device handle.
521 * @param buffer Buffer to write data from.
522 * @param length Number of bytes to write.
524 * @retval JAYLINK_OK Success.
525 * @retval JAYLINK_ERR_ARG Invalid arguments.
526 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
527 * @retval JAYLINK_ERR Other error conditions.
529 JAYLINK_PRIV int transport_write(struct jaylink_device_handle *devh,
530 const uint8_t *buffer, size_t length)
532 int ret;
533 struct jaylink_context *ctx;
534 size_t num_chunks;
535 size_t fill_bytes;
536 size_t tmp;
538 ctx = devh->dev->ctx;
540 if (length > devh->write_length) {
541 log_err(ctx, "Requested to write %u bytes but only %u bytes "
542 "are expected for the write operation.", length,
543 devh->write_length);
544 return JAYLINK_ERR_ARG;
548 * Store data in the buffer if the expected number of bytes for the
549 * write operation is not reached.
551 if (length < devh->write_length) {
552 if (devh->write_pos + length > devh->buffer_size) {
553 if (!adjust_buffer(devh, devh->write_pos + length))
554 return JAYLINK_ERR_MALLOC;
557 memcpy(devh->buffer + devh->write_pos, buffer, length);
559 devh->write_length -= length;
560 devh->write_pos += length;
562 log_dbg(ctx, "Wrote %u bytes into buffer.", length);
563 return JAYLINK_OK;
567 * Expected number of bytes for this write operation is reached and
568 * therefore the write operation will be performed.
570 devh->write_length = 0;
572 /* Send data directly to the device if the buffer is empty. */
573 if (!devh->write_pos)
574 return usb_send(devh, buffer, length);
577 * Calculate the number of bytes to fill up the buffer to reach a
578 * multiple of CHUNK_SIZE bytes. This ensures that the data from the
579 * buffer will be sent to the device in chunks of CHUNK_SIZE bytes.
580 * Note that this is why the buffer size must be a multiple of
581 * CHUNK_SIZE bytes.
583 num_chunks = devh->write_pos / CHUNK_SIZE;
585 if (devh->write_pos % CHUNK_SIZE)
586 num_chunks++;
588 fill_bytes = (num_chunks * CHUNK_SIZE) - devh->write_pos;
589 tmp = MIN(length, fill_bytes);
591 if (tmp > 0) {
592 memcpy(devh->buffer + devh->write_pos, buffer, tmp);
594 length -= tmp;
595 buffer += tmp;
597 log_dbg(ctx, "Buffer filled up with %u bytes.", tmp);
600 /* Send buffered data to the device. */
601 ret = usb_send(devh, devh->buffer, devh->write_pos + tmp);
602 devh->write_pos = 0;
604 if (ret != JAYLINK_OK)
605 return ret;
607 if (!length)
608 return JAYLINK_OK;
610 /* Send remaining data to the device. */
611 return usb_send(devh, buffer, length);
615 * Read data from a device.
617 * Before this function is used transport_start_read() or
618 * transport_start_write_read() must be called to start a read operation. The
619 * total number of read bytes must not exceed the number of bytes of the read
620 * operation.
622 * @param devh Device handle.
623 * @param buffer Buffer to read data into on success. Its content is undefined
624 * on failure.
625 * @param length Number of bytes to read.
627 * @retval JAYLINK_OK Success.
628 * @retval JAYLINK_ERR_ARG Invalid arguments.
629 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
630 * @retval JAYLINK_ERR Other error conditions.
632 JAYLINK_PRIV int transport_read(struct jaylink_device_handle *devh,
633 uint8_t *buffer, size_t length)
635 int ret;
636 struct jaylink_context *ctx;
637 size_t bytes_received;
638 size_t tmp;
640 ctx = devh->dev->ctx;
642 if (length > devh->read_length) {
643 log_err(ctx, "Requested to read %u bytes but only %u bytes "
644 "are expected for the read operation.", length,
645 devh->read_length);
646 return JAYLINK_ERR_ARG;
649 if (length <= devh->bytes_available) {
650 memcpy(buffer, devh->buffer + devh->read_pos, length);
652 devh->read_length -= length;
653 devh->bytes_available -= length;
654 devh->read_pos += length;
656 log_dbg(ctx, "Read %u bytes from buffer.", length);
657 return JAYLINK_OK;
660 if (devh->bytes_available) {
661 memcpy(buffer, devh->buffer + devh->read_pos,
662 devh->bytes_available);
664 buffer += devh->bytes_available;
665 length -= devh->bytes_available;
666 devh->read_length -= devh->bytes_available;
668 log_dbg(ctx, "Read %u bytes from buffer to flush it.",
669 devh->bytes_available);
671 devh->bytes_available = 0;
672 devh->read_pos = 0;
675 while (length > 0) {
677 * If less than CHUNK_SIZE bytes are requested from the device,
678 * store the received data into the internal buffer instead of
679 * directly into the user provided buffer. This is necessary to
680 * prevent a possible buffer overflow because the number of
681 * requested bytes from the device is always CHUNK_SIZE and
682 * therefore up to CHUNK_SIZE bytes may be received.
683 * Note that this is why the internal buffer size must be at
684 * least CHUNK_SIZE bytes.
686 if (length < CHUNK_SIZE) {
687 ret = usb_recv(devh, devh->buffer, &bytes_received);
689 if (ret != JAYLINK_OK)
690 return ret;
692 tmp = MIN(bytes_received, length);
693 memcpy(buffer, devh->buffer, tmp);
696 * Setup the buffer for the remaining data if more data
697 * was received from the device than was requested.
699 if (bytes_received > length) {
700 devh->bytes_available = bytes_received - tmp;
701 devh->read_pos = tmp;
704 buffer += tmp;
705 length -= tmp;
706 devh->read_length -= tmp;
708 log_dbg(ctx, "Read %u bytes from buffer.", tmp);
709 } else {
710 ret = usb_recv(devh, buffer, &bytes_received);
712 if (ret != JAYLINK_OK)
713 return ret;
715 buffer += bytes_received;
716 length -= bytes_received;
717 devh->read_length -= bytes_received;
719 log_dbg(ctx, "Read %u bytes from device.",
720 bytes_received);
724 return JAYLINK_OK;