Bump package version to 0.4.0
[libjaylink.git] / libjaylink / transport_usb.c
blob382702d433d139adcda0ba3e774e01dcd8ee30f9
1 /*
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/>.
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 (USB).
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;
58 ctx = devh->dev->ctx;
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));
70 return JAYLINK_ERR;
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)
80 continue;
82 if (desc->bInterfaceSubClass != LIBUSB_CLASS_VENDOR_SPEC)
83 continue;
85 if (desc->bNumEndpoints < 2)
86 continue;
88 found_interface = true;
89 devh->interface_number = i;
90 break;
93 if (!found_interface) {
94 log_err(ctx, "No suitable interface found");
95 libusb_free_config_descriptor(config);
96 return JAYLINK_ERR;
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;
108 } else {
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");
118 return JAYLINK_ERR;
121 if (!found_endpoint_out) {
122 log_err(ctx, "Interface OUT endpoint not found");
123 return JAYLINK_ERR;
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);
133 if (!devh->buffer) {
134 log_err(ctx, "Transport buffer malloc failed");
135 return JAYLINK_ERR_MALLOC;
138 devh->read_length = 0;
139 devh->bytes_available = 0;
140 devh->read_pos = 0;
142 devh->write_length = 0;
143 devh->write_pos = 0;
145 return JAYLINK_OK;
148 static void cleanup_handle(struct jaylink_device_handle *devh)
150 free(devh->buffer);
153 JAYLINK_PRIV int transport_usb_open(struct jaylink_device_handle *devh)
155 int ret;
156 struct jaylink_device *dev;
157 struct jaylink_context *ctx;
158 struct libusb_device_handle *usb_devh;
160 dev = devh->dev;
161 ctx = dev->ctx;
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");
171 return ret;
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);
180 return JAYLINK_ERR;
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);
190 return JAYLINK_ERR;
193 log_dbg(ctx, "Device opened successfully");
195 devh->usb_devh = usb_devh;
197 return JAYLINK_OK;
200 JAYLINK_PRIV int transport_usb_close(struct jaylink_device_handle *devh)
202 int ret;
203 struct jaylink_device *dev;
204 struct jaylink_context *ctx;
206 dev = devh->dev;
207 ctx = dev->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));
221 return JAYLINK_ERR;
224 log_dbg(ctx, "Device closed successfully");
226 return JAYLINK_OK;
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;
234 (void)has_command;
236 if (!length)
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;
251 devh->write_pos = 0;
253 return JAYLINK_OK;
256 JAYLINK_PRIV int transport_usb_start_read(struct jaylink_device_handle *devh,
257 size_t length)
259 struct jaylink_context *ctx;
261 if (!length)
262 return JAYLINK_ERR_ARG;
264 ctx = devh->dev->ctx;
266 log_dbgio(ctx, "Starting read operation (length = %zu bytes)",
267 length);
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",
275 devh->read_length);
277 devh->read_length = length;
279 return JAYLINK_OK;
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;
288 (void)has_command;
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",
311 devh->read_length);
313 devh->write_length = write_length;
314 devh->write_pos = 0;
316 devh->read_length = read_length;
317 devh->bytes_available = 0;
318 devh->read_pos = 0;
320 return JAYLINK_OK;
323 static int usb_recv(struct jaylink_device_handle *devh, uint8_t *buffer,
324 size_t *length)
326 int ret;
327 struct jaylink_context *ctx;
328 unsigned int tries;
329 int transferred;
331 ctx = devh->dev->ctx;
333 tries = NUM_TIMEOUTS;
334 transferred = 0;
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,
340 USB_TIMEOUT);
342 if (ret == LIBUSB_ERROR_TIMEOUT) {
343 log_warn(ctx, "Failed to receive data from "
344 "device: %s", libusb_error_name(ret));
345 tries--;
346 continue;
347 } else if (ret != LIBUSB_SUCCESS) {
348 log_err(ctx, "Failed to receive data from "
349 "device: %s", libusb_error_name(ret));
350 return JAYLINK_ERR;
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;
359 return JAYLINK_OK;
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;
370 size_t num_chunks;
371 uint8_t *buffer;
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)
379 num_chunks++;
381 size = num_chunks * CHUNK_SIZE;
382 buffer = realloc(devh->buffer, size);
384 if (!buffer) {
385 log_err(ctx, "Failed to adjust buffer size to %zu bytes",
386 size);
387 return false;
390 devh->buffer = buffer;
391 devh->buffer_size = size;
393 log_dbg(ctx, "Adjusted buffer size to %zu bytes", size);
395 return true;
398 static int usb_send(struct jaylink_device_handle *devh, const uint8_t *buffer,
399 size_t length)
401 int ret;
402 struct jaylink_context *ctx;
403 unsigned int tries;
404 int transferred;
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));
420 tries--;
421 } else {
422 log_err(ctx, "Failed to send data to device: %s",
423 libusb_error_name(ret));
424 return JAYLINK_ERR;
427 buffer += transferred;
428 length -= transferred;
430 log_dbgio(ctx, "Sent %i bytes to device", transferred);
433 if (!length)
434 return JAYLINK_OK;
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)
444 int ret;
445 struct jaylink_context *ctx;
446 size_t num_chunks;
447 size_t fill_bytes;
448 size_t tmp;
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,
455 devh->write_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);
475 return JAYLINK_OK;
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
493 * CHUNK_SIZE bytes.
495 num_chunks = devh->write_pos / CHUNK_SIZE;
497 if (devh->write_pos % CHUNK_SIZE)
498 num_chunks++;
500 fill_bytes = (num_chunks * CHUNK_SIZE) - devh->write_pos;
501 tmp = MIN(length, fill_bytes);
503 if (tmp > 0) {
504 memcpy(devh->buffer + devh->write_pos, buffer, tmp);
506 length -= tmp;
507 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);
514 devh->write_pos = 0;
516 if (ret != JAYLINK_OK)
517 return ret;
519 if (!length)
520 return 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)
529 int ret;
530 struct jaylink_context *ctx;
531 size_t bytes_received;
532 size_t tmp;
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,
539 devh->read_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);
551 return JAYLINK_OK;
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;
566 devh->read_pos = 0;
569 while (length > 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)
584 return ret;
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;
598 buffer += tmp;
599 length -= tmp;
600 devh->read_length -= tmp;
602 log_dbgio(ctx, "Read %zu bytes from buffer", tmp);
603 } else {
604 ret = usb_recv(devh, buffer, &bytes_received);
606 if (ret != JAYLINK_OK)
607 return ret;
609 buffer += bytes_received;
610 length -= bytes_received;
611 devh->read_length -= bytes_received;
613 log_dbgio(ctx, "Read %zu bytes from device",
614 bytes_received);
618 return JAYLINK_OK;