Minor cosmetics and cleanups.
[libjaylink.git] / libjaylink / transport.c
blobbcbe9526f309bd1a3566b54c6bbe73fdd07d9d25
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 <string.h>
24 #include "libjaylink.h"
25 #include "libjaylink-internal.h"
27 /**
28 * @file
30 * Transport abstraction layer.
33 /** Timeout of an USB transfer in milliseconds. */
34 #define USB_TIMEOUT 1000
36 /**
37 * Number of consecutive timeouts before an USB transfer will be treated as
38 * timed out.
40 #define NUM_TIMEOUTS 2
42 /** Chunk size in bytes in which data is transferred. */
43 #define CHUNK_SIZE 2048
45 /**
46 * Buffer size in bytes.
48 * Note that both write and read operations require a buffer size of at least
49 * #CHUNK_SIZE bytes.
51 #define BUFFER_SIZE CHUNK_SIZE
53 static int initialize_handle(struct jaylink_device_handle *devh)
55 int ret;
56 struct jaylink_context *ctx;
57 struct libusb_config_descriptor *config;
58 const struct libusb_interface *interface;
59 const struct libusb_interface_descriptor *desc;
60 const struct libusb_endpoint_descriptor *epdesc;
61 int found_interface;
62 int found_endpoint_in;
63 int found_endpoint_out;
64 uint8_t i;
66 ctx = devh->dev->ctx;
67 devh->interface_number = 0;
70 * Retrieve active configuration descriptor to determine the endpoints
71 * for the interface number of the device.
73 ret = libusb_get_active_config_descriptor(devh->dev->usb_dev, &config);
75 if (ret != LIBUSB_SUCCESS) {
76 log_err(ctx, "Failed to get configuration descriptor: %s.",
77 libusb_error_name(ret));
78 return JAYLINK_ERR;
81 found_interface = 0;
83 for (i = 0; i < config->bNumInterfaces; i++) {
84 interface = &config->interface[i];
85 desc = &interface->altsetting[0];
87 if (desc->bInterfaceClass != LIBUSB_CLASS_VENDOR_SPEC)
88 continue;
90 if (desc->bInterfaceSubClass != LIBUSB_CLASS_VENDOR_SPEC)
91 continue;
93 if (desc->bNumEndpoints < 2)
94 continue;
96 found_interface = 1;
97 devh->interface_number = i;
98 break;
101 if (!found_interface) {
102 log_err(ctx, "No suitable interface found.");
103 libusb_free_config_descriptor(config);
104 return JAYLINK_ERR;
107 found_endpoint_in = 0;
108 found_endpoint_out = 0;
110 for (i = 0; i < desc->bNumEndpoints; i++) {
111 epdesc = &desc->endpoint[i];
113 if (epdesc->bEndpointAddress & LIBUSB_ENDPOINT_IN) {
114 devh->endpoint_in = epdesc->bEndpointAddress;
115 found_endpoint_in = 1;
116 } else {
117 devh->endpoint_out = epdesc->bEndpointAddress;
118 found_endpoint_out = 1;
122 libusb_free_config_descriptor(config);
124 if (!found_endpoint_in) {
125 log_err(ctx, "Interface IN endpoint not found.");
126 return JAYLINK_ERR;
129 if (!found_endpoint_out) {
130 log_err(ctx, "Interface OUT endpoint not found.");
131 return JAYLINK_ERR;
134 log_dbg(ctx, "Using endpoint %02x (IN) and %02x (OUT).",
135 devh->endpoint_in, devh->endpoint_out);
137 devh->buffer = malloc(BUFFER_SIZE);
139 if (!devh->buffer) {
140 log_err(ctx, "Transport buffer malloc failed.");
141 return JAYLINK_ERR_MALLOC;
144 devh->read_length = 0;
145 devh->bytes_available = 0;
146 devh->read_pos = 0;
148 devh->write_length = 0;
149 devh->write_pos = 0;
151 return JAYLINK_OK;
154 static void cleanup_handle(struct jaylink_device_handle *devh)
156 free(devh->buffer);
160 * Open a device.
162 * This function must be called before any other function of the transport
163 * abstraction layer for the given device handle is called.
165 * @param devh Device handle.
167 * @retval JAYLINK_OK Success.
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, "Initialize device handle failed.");
188 return ret;
191 ret = libusb_open(dev->usb_dev, &usb_devh);
193 if (ret != LIBUSB_SUCCESS) {
194 log_err(ctx, "Failed to open device: %s.",
195 libusb_error_name(ret));
196 cleanup_handle(devh);
197 return JAYLINK_ERR;
200 ret = libusb_claim_interface(usb_devh, devh->interface_number);
202 if (ret != LIBUSB_SUCCESS) {
203 log_err(ctx, "Failed to claim interface: %s.",
204 libusb_error_name(ret));
205 cleanup_handle(devh);
206 libusb_close(usb_devh);
207 return JAYLINK_ERR;
210 log_dbg(ctx, "Device opened successfully.");
212 devh->usb_devh = usb_devh;
214 return JAYLINK_OK;
218 * Close a device.
220 * After this function has been called no other function of the transport
221 * abstraction layer for the given device handle must be called.
223 * @param devh Device handle.
225 * @retval JAYLINK_OK Success.
226 * @retval JAYLINK_ERR Other error conditions.
228 JAYLINK_PRIV int transport_close(struct jaylink_device_handle *devh)
230 int ret;
231 struct jaylink_device *dev;
232 struct jaylink_context *ctx;
234 dev = devh->dev;
235 ctx = dev->ctx;
237 log_dbg(ctx, "Closing device (bus:address = %03u:%03u).",
238 libusb_get_bus_number(dev->usb_dev),
239 libusb_get_device_address(dev->usb_dev));
241 ret = libusb_release_interface(devh->usb_devh, devh->interface_number);
243 libusb_close(devh->usb_devh);
244 cleanup_handle(devh);
246 if (ret != LIBUSB_SUCCESS) {
247 log_err(ctx, "Failed to release interface: %s.",
248 libusb_error_name(ret));
249 return JAYLINK_ERR;
252 return JAYLINK_OK;
256 * Start a write operation for a device.
258 * The data of a write operation must be written with at least one call of
259 * transport_write(). It is required that all data of a write operation is
260 * written before an other write and/or read operation is started.
262 * @param devh Device handle.
263 * @param length Number of bytes of the write operation.
264 * @param has_command Determines whether the data of the write operation
265 * contains the protocol command.
267 * @retval JAYLINK_OK Success.
268 * @retval JAYLINK_ERR_ARG Invalid arguments.
270 JAYLINK_PRIV int transport_start_write(struct jaylink_device_handle *devh,
271 uint16_t length, int has_command)
273 struct jaylink_context *ctx;
275 (void)has_command;
277 if (!length)
278 return JAYLINK_ERR_ARG;
280 ctx = devh->dev->ctx;
282 log_dbg(ctx, "Starting write operation (length = %u bytes).", length);
284 if (devh->write_pos > 0)
285 log_warn(ctx, "Last write operation left %u bytes in the "
286 "buffer.", devh->write_pos);
288 if (devh->write_length > 0)
289 log_warn(ctx, "Last write operation was not performed.");
291 devh->write_length = length;
292 devh->write_pos = 0;
294 return JAYLINK_OK;
298 * Start a read operation for a device.
300 * The data of a read operation must be read with at least one call of
301 * transport_read(). It is required that all data of a read operation is read
302 * before an other write and/or read operation is started.
304 * @param devh Device handle.
305 * @param length Number of bytes of the read operation.
307 * @retval JAYLINK_OK Success.
308 * @retval JAYLINK_ERR_ARG Invalid arguments.
310 JAYLINK_PRIV int transport_start_read(struct jaylink_device_handle *devh,
311 uint16_t length)
313 struct jaylink_context *ctx;
315 if (!length)
316 return JAYLINK_ERR_ARG;
318 ctx = devh->dev->ctx;
320 log_dbg(ctx, "Starting read operation (length = %u bytes).", length);
322 if (devh->bytes_available > 0)
323 log_dbg(ctx, "Last read operation left %u bytes in the "
324 "buffer.", devh->bytes_available);
326 if (devh->read_length > 0)
327 log_warn(ctx, "Last read operation left %u bytes.",
328 devh->read_length);
330 devh->read_length = length;
332 return JAYLINK_OK;
336 * Start a write and read operation for a device.
338 * This function starts a write and read operation as the consecutive call of
339 * transport_start_write() and transport_start_read() but has a different
340 * meaning from the protocol perspective and can therefore not be replaced by
341 * these functions and vice versa.
343 * @note The write operation must be completed first before the read operation
344 * must be processed.
346 * @param devh Device handle.
347 * @param write_length Number of bytes of the write operation.
348 * @param read_length Number of bytes of the read operation.
349 * @param has_command Determines whether the data of the write operation
350 * contains the protocol command.
352 * @retval JAYLINK_OK Success.
353 * @retval JAYLINK_ERR_ARG Invalid arguments.
355 JAYLINK_PRIV int transport_start_write_read(struct jaylink_device_handle *devh,
356 uint16_t write_length, uint16_t read_length, int has_command)
358 struct jaylink_context *ctx;
360 (void)has_command;
362 if (!read_length || !write_length)
363 return JAYLINK_ERR_ARG;
365 ctx = devh->dev->ctx;
367 log_dbg(ctx, "Starting write / read operation (length = "
368 "%u / %u bytes).", write_length, read_length);
370 if (devh->write_pos > 0)
371 log_warn(ctx, "Last write operation left %u bytes in the "
372 "buffer.", devh->write_pos);
374 if (devh->write_length > 0)
375 log_warn(ctx, "Last write operation was not performed.");
377 if (devh->bytes_available > 0)
378 log_warn(ctx, "Last read operation left %u bytes in the "
379 "buffer.", devh->bytes_available);
381 if (devh->read_length > 0)
382 log_warn(ctx, "Last read operation left %u bytes.",
383 devh->read_length);
385 devh->write_length = write_length;
386 devh->write_pos = 0;
388 devh->read_length = read_length;
389 devh->bytes_available = 0;
390 devh->read_pos = 0;
392 return JAYLINK_OK;
395 static int usb_recv(struct jaylink_device_handle *devh, uint8_t *buffer,
396 uint16_t *length)
398 int ret;
399 struct jaylink_context *ctx;
400 unsigned int tries;
401 int transferred;
403 ctx = devh->dev->ctx;
404 tries = NUM_TIMEOUTS;
405 transferred = 0;
407 while (tries > 0 && !transferred) {
408 /* Always request CHUNK_SIZE bytes from the device. */
409 ret = libusb_bulk_transfer(devh->usb_devh, devh->endpoint_in,
410 (unsigned char *)buffer, CHUNK_SIZE, &transferred,
411 USB_TIMEOUT);
413 if (ret == LIBUSB_ERROR_TIMEOUT) {
414 log_warn(ctx, "Failed to receive data from "
415 "device: %s.", libusb_error_name(ret));
416 tries--;
417 continue;
418 } else if (ret != LIBUSB_SUCCESS) {
419 log_err(ctx, "Failed to receive data from "
420 "device: %s.", libusb_error_name(ret));
421 return JAYLINK_ERR;
424 log_dbg(ctx, "Received %u bytes from device.", transferred);
427 /* Ignore a possible timeout if at least one byte was received. */
428 if (transferred > 0) {
429 *length = transferred;
430 return JAYLINK_OK;
433 log_err(ctx, "Receiving data from device timed out.");
435 return JAYLINK_ERR_TIMEOUT;
438 static int usb_send(struct jaylink_device_handle *devh, const uint8_t *buffer,
439 uint16_t length)
441 int ret;
442 struct jaylink_context *ctx;
443 unsigned int tries;
444 int transferred;
446 ctx = devh->dev->ctx;
447 tries = NUM_TIMEOUTS;
449 while (tries > 0 && length > 0) {
450 /* Send data in chunks of CHUNK_SIZE bytes to the device. */
451 ret = libusb_bulk_transfer(devh->usb_devh, devh->endpoint_out,
452 (unsigned char *)buffer, MIN(CHUNK_SIZE, length),
453 &transferred, USB_TIMEOUT);
455 if (ret == LIBUSB_SUCCESS) {
456 tries = NUM_TIMEOUTS;
457 } else if (ret == LIBUSB_ERROR_TIMEOUT) {
458 log_warn(ctx, "Failed to send data to device: %s.",
459 libusb_error_name(ret));
460 tries--;
461 } else {
462 log_err(ctx, "Failed to send data to device: %s.",
463 libusb_error_name(ret));
464 return JAYLINK_ERR;
467 buffer += transferred;
468 length -= transferred;
470 log_dbg(ctx, "Sent %u bytes to device.", transferred);
473 if (!length)
474 return JAYLINK_OK;
476 log_err(ctx, "Sending data to device timed out.");
478 return JAYLINK_ERR_TIMEOUT;
482 * Write data to a device.
484 * Before this function is used transport_start_write() or
485 * transport_start_write_read() must be called to start a write operation. The
486 * total number of written bytes must not exceed the number of bytes of the
487 * write operation.
489 * @note A write operation will be performed and the data will be sent to the
490 * device when the number of written bytes reaches the number of bytes of
491 * the write operation. Before that the data will be written into a
492 * buffer.
494 * @param devh Device handle.
495 * @param buffer Buffer to write data from.
496 * @param length Number of bytes to write.
498 * @retval JAYLINK_OK Success.
499 * @retval JAYLINK_ERR_ARG Invalid arguments.
500 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
501 * @retval JAYLINK_ERR Other error conditions.
503 JAYLINK_PRIV int transport_write(struct jaylink_device_handle *devh,
504 const uint8_t *buffer, uint16_t length)
506 int ret;
507 struct jaylink_context *ctx;
508 uint8_t num_chunks;
509 uint16_t fill_bytes;
510 uint16_t tmp;
512 ctx = devh->dev->ctx;
514 if (length > devh->write_length) {
515 log_err(ctx, "Requested to write %u bytes but only %u bytes "
516 "are expected for the write operation.", length,
517 devh->write_length);
518 return JAYLINK_ERR_ARG;
522 * Store data in the buffer if the expected number of bytes for the
523 * write operation is not reached.
525 if (length < devh->write_length) {
526 if (devh->write_pos + length > BUFFER_SIZE) {
527 log_err(ctx, "Write request is too large for the "
528 "buffer.");
529 return JAYLINK_ERR_ARG;
532 memcpy(devh->buffer + devh->write_pos, buffer, length);
534 devh->write_length -= length;
535 devh->write_pos += length;
537 log_dbg(ctx, "Wrote %u bytes into buffer.", length);
538 return JAYLINK_OK;
542 * Expected number of bytes for this write operation is reached and
543 * therefore the write operation will be performed.
545 devh->write_length = 0;
547 /* Send data directly to the device if the buffer is empty. */
548 if (!devh->write_pos)
549 return usb_send(devh, buffer, length);
552 * Calculate the number of bytes to fill up the buffer to reach a
553 * multiple of CHUNK_SIZE bytes. This ensures that the data from the
554 * buffer will be sent to the device in chunks of CHUNK_SIZE bytes.
555 * Note that this is why the buffer size must be at least CHUNK_SIZE
556 * bytes.
558 num_chunks = devh->write_pos / CHUNK_SIZE;
560 if (devh->write_pos % CHUNK_SIZE)
561 num_chunks++;
563 fill_bytes = (num_chunks * CHUNK_SIZE) - devh->write_pos;
564 tmp = MIN(length, fill_bytes);
566 if (tmp > 0) {
567 memcpy(devh->buffer + devh->write_pos, buffer, tmp);
569 length -= tmp;
570 buffer += tmp;
572 log_dbg(ctx, "Buffer filled up with %u bytes.", tmp);
575 /* Send buffered data to the device. */
576 ret = usb_send(devh, devh->buffer, devh->write_pos + tmp);
577 devh->write_pos = 0;
579 if (ret != JAYLINK_OK)
580 return ret;
582 if (!length)
583 return JAYLINK_OK;
585 /* Send remaining data to the device. */
586 return usb_send(devh, buffer, length);
590 * Read data from a device.
592 * Before this function is used transport_start_read() or
593 * transport_start_write_read() must be called to start a read operation. The
594 * total number of read bytes must not exceed the number of bytes of the read
595 * operation.
597 * @param devh Device handle.
598 * @param buffer Buffer to read data into on success. Its content is undefined
599 * on failure.
600 * @param length Number of bytes to read.
602 * @retval JAYLINK_OK Success.
603 * @retval JAYLINK_ERR_ARG Invalid arguments.
604 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
605 * @retval JAYLINK_ERR Other error conditions.
607 JAYLINK_PRIV int transport_read(struct jaylink_device_handle *devh,
608 uint8_t *buffer, uint16_t length)
610 int ret;
611 struct jaylink_context *ctx;
612 uint16_t bytes_received;
613 uint16_t tmp;
615 ctx = devh->dev->ctx;
617 if (length > devh->read_length) {
618 log_err(ctx, "Requested to read %u bytes but only %u bytes "
619 "are expected for the read operation.", length,
620 devh->read_length);
621 return JAYLINK_ERR_ARG;
624 if (length <= devh->bytes_available) {
625 memcpy(buffer, devh->buffer + devh->read_pos, length);
627 devh->read_length -= length;
628 devh->bytes_available -= length;
629 devh->read_pos += length;
631 log_dbg(ctx, "Read %u bytes from buffer.", length);
632 return JAYLINK_OK;
635 if (devh->bytes_available) {
636 memcpy(buffer, devh->buffer + devh->read_pos,
637 devh->bytes_available);
639 buffer += devh->bytes_available;
640 length -= devh->bytes_available;
641 devh->read_length -= devh->bytes_available;
643 log_dbg(ctx, "Read %u bytes from buffer to flush it.",
644 devh->bytes_available);
646 devh->bytes_available = 0;
647 devh->read_pos = 0;
650 while (length > 0) {
652 * If less than CHUNK_SIZE bytes are requested from the device,
653 * store the received data in the internal buffer instead of
654 * directly into the user provided buffer. This is necessary to
655 * prevent a possible buffer overflow because the number of
656 * requested bytes from the device is always CHUNK_SIZE and
657 * therefore up to CHUNK_SIZE bytes may be received.
659 if (length < CHUNK_SIZE) {
660 ret = usb_recv(devh, devh->buffer, &bytes_received);
662 if (ret != JAYLINK_OK)
663 return ret;
665 tmp = MIN(bytes_received, length);
666 memcpy(buffer, devh->buffer, tmp);
669 * Setup the buffer for the remaining data if more data
670 * was received from the device than was requested.
672 if (bytes_received > length) {
673 devh->bytes_available = bytes_received - tmp;
674 devh->read_pos = tmp;
677 buffer += tmp;
678 length -= tmp;
679 devh->read_length -= tmp;
681 log_dbg(ctx, "Read %u bytes from buffer.", tmp);
682 } else {
683 ret = usb_recv(devh, buffer, &bytes_received);
685 if (ret != JAYLINK_OK)
686 return ret;
688 buffer += bytes_received;
689 length -= bytes_received;
690 devh->read_length -= bytes_received;
692 log_dbg(ctx, "Read %u bytes from device.",
693 bytes_received);
697 return JAYLINK_OK;