Make use of JAYLINK_LOG_LEVEL_DEBUG_IO
[libjaylink.git] / libjaylink / transport_usb.c
blobdfe9eac08b47ed7362a7d9a1f317d5abb4b89a91
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;
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 = false;
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 = true;
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 = false;
101 found_endpoint_out = false;
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 = true;
109 } else {
110 devh->endpoint_out = epdesc->bEndpointAddress;
111 found_endpoint_out = true;
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);
154 JAYLINK_PRIV int transport_usb_open(struct jaylink_device_handle *devh)
156 int ret;
157 struct jaylink_device *dev;
158 struct jaylink_context *ctx;
159 struct libusb_device_handle *usb_devh;
161 dev = devh->dev;
162 ctx = dev->ctx;
164 log_dbg(ctx, "Trying to open device (bus:address = %03u:%03u).",
165 libusb_get_bus_number(dev->usb_dev),
166 libusb_get_device_address(dev->usb_dev));
168 ret = initialize_handle(devh);
170 if (ret != JAYLINK_OK) {
171 log_err(ctx, "Initialize device handle failed.");
172 return ret;
175 ret = libusb_open(dev->usb_dev, &usb_devh);
177 if (ret != LIBUSB_SUCCESS) {
178 log_err(ctx, "Failed to open device: %s.",
179 libusb_error_name(ret));
180 cleanup_handle(devh);
181 return JAYLINK_ERR;
184 ret = libusb_claim_interface(usb_devh, devh->interface_number);
186 if (ret != LIBUSB_SUCCESS) {
187 log_err(ctx, "Failed to claim interface: %s.",
188 libusb_error_name(ret));
189 cleanup_handle(devh);
190 libusb_close(usb_devh);
191 return JAYLINK_ERR;
194 log_dbg(ctx, "Device opened successfully.");
196 devh->usb_devh = usb_devh;
198 return JAYLINK_OK;
201 JAYLINK_PRIV int transport_usb_close(struct jaylink_device_handle *devh)
203 int ret;
204 struct jaylink_device *dev;
205 struct jaylink_context *ctx;
207 dev = devh->dev;
208 ctx = dev->ctx;
210 log_dbg(ctx, "Closing device (bus:address = %03u:%03u).",
211 libusb_get_bus_number(dev->usb_dev),
212 libusb_get_device_address(dev->usb_dev));
214 ret = libusb_release_interface(devh->usb_devh, devh->interface_number);
216 libusb_close(devh->usb_devh);
217 cleanup_handle(devh);
219 if (ret != LIBUSB_SUCCESS) {
220 log_err(ctx, "Failed to release interface: %s.",
221 libusb_error_name(ret));
222 return JAYLINK_ERR;
225 log_dbg(ctx, "Device closed successfully.");
227 return JAYLINK_OK;
230 JAYLINK_PRIV int transport_usb_start_write(struct jaylink_device_handle *devh,
231 size_t length, bool has_command)
233 struct jaylink_context *ctx;
235 (void)has_command;
237 if (!length)
238 return JAYLINK_ERR_ARG;
240 ctx = devh->dev->ctx;
242 log_dbgio(ctx, "Starting write operation (length = %zu bytes).", length);
244 if (devh->write_pos > 0)
245 log_warn(ctx, "Last write operation left %zu bytes in the "
246 "buffer.", devh->write_pos);
248 if (devh->write_length > 0)
249 log_warn(ctx, "Last write operation was not performed.");
251 devh->write_length = length;
252 devh->write_pos = 0;
254 return JAYLINK_OK;
257 JAYLINK_PRIV int transport_usb_start_read(struct jaylink_device_handle *devh,
258 size_t length)
260 struct jaylink_context *ctx;
262 if (!length)
263 return JAYLINK_ERR_ARG;
265 ctx = devh->dev->ctx;
267 log_dbgio(ctx, "Starting read operation (length = %zu bytes).",
268 length);
270 if (devh->bytes_available > 0)
271 log_dbg(ctx, "Last read operation left %zu bytes in the "
272 "buffer.", devh->bytes_available);
274 if (devh->read_length > 0)
275 log_warn(ctx, "Last read operation left %zu bytes.",
276 devh->read_length);
278 devh->read_length = length;
280 return JAYLINK_OK;
283 JAYLINK_PRIV int transport_usb_start_write_read(
284 struct jaylink_device_handle *devh, size_t write_length,
285 size_t read_length, bool has_command)
287 struct jaylink_context *ctx;
289 (void)has_command;
291 if (!read_length || !write_length)
292 return JAYLINK_ERR_ARG;
294 ctx = devh->dev->ctx;
296 log_dbgio(ctx, "Starting write / read operation (length = "
297 "%zu / %zu bytes).", write_length, read_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 if (devh->bytes_available > 0)
307 log_warn(ctx, "Last read operation left %zu bytes in the "
308 "buffer.", devh->bytes_available);
310 if (devh->read_length > 0)
311 log_warn(ctx, "Last read operation left %zu bytes.",
312 devh->read_length);
314 devh->write_length = write_length;
315 devh->write_pos = 0;
317 devh->read_length = read_length;
318 devh->bytes_available = 0;
319 devh->read_pos = 0;
321 return JAYLINK_OK;
324 static int usb_recv(struct jaylink_device_handle *devh, uint8_t *buffer,
325 size_t *length)
327 int ret;
328 struct jaylink_context *ctx;
329 unsigned int tries;
330 int transferred;
332 ctx = devh->dev->ctx;
334 tries = NUM_TIMEOUTS;
335 transferred = 0;
337 while (tries > 0 && !transferred) {
338 /* Always request CHUNK_SIZE bytes from the device. */
339 ret = libusb_bulk_transfer(devh->usb_devh, devh->endpoint_in,
340 (unsigned char *)buffer, CHUNK_SIZE, &transferred,
341 USB_TIMEOUT);
343 if (ret == LIBUSB_ERROR_TIMEOUT) {
344 log_warn(ctx, "Failed to receive data from "
345 "device: %s.", libusb_error_name(ret));
346 tries--;
347 continue;
348 } else if (ret != LIBUSB_SUCCESS) {
349 log_err(ctx, "Failed to receive data from "
350 "device: %s.", libusb_error_name(ret));
351 return JAYLINK_ERR;
354 log_dbgio(ctx, "Received %i bytes from device.", transferred);
357 /* Ignore a possible timeout if at least one byte was received. */
358 if (transferred > 0) {
359 *length = transferred;
360 return JAYLINK_OK;
363 log_err(ctx, "Receiving data from device timed out.");
365 return JAYLINK_ERR_TIMEOUT;
368 static bool adjust_buffer(struct jaylink_device_handle *devh, size_t size)
370 struct jaylink_context *ctx;
371 size_t num_chunks;
372 uint8_t *buffer;
374 ctx = devh->dev->ctx;
376 /* Adjust buffer size to a multiple of CHUNK_SIZE bytes. */
377 num_chunks = size / CHUNK_SIZE;
379 if (size % CHUNK_SIZE > 0)
380 num_chunks++;
382 size = num_chunks * CHUNK_SIZE;
383 buffer = realloc(devh->buffer, size);
385 if (!buffer) {
386 log_err(ctx, "Failed to adjust buffer size to %zu bytes.",
387 size);
388 return false;
391 devh->buffer = buffer;
392 devh->buffer_size = size;
394 log_dbg(ctx, "Adjusted buffer size to %zu bytes.", size);
396 return true;
399 static int usb_send(struct jaylink_device_handle *devh, const uint8_t *buffer,
400 size_t length)
402 int ret;
403 struct jaylink_context *ctx;
404 unsigned int tries;
405 int transferred;
407 ctx = devh->dev->ctx;
408 tries = NUM_TIMEOUTS;
410 while (tries > 0 && length > 0) {
411 /* Send data in chunks of CHUNK_SIZE bytes to the device. */
412 ret = libusb_bulk_transfer(devh->usb_devh, devh->endpoint_out,
413 (unsigned char *)buffer, MIN(CHUNK_SIZE, length),
414 &transferred, USB_TIMEOUT);
416 if (ret == LIBUSB_SUCCESS) {
417 tries = NUM_TIMEOUTS;
418 } else if (ret == LIBUSB_ERROR_TIMEOUT) {
419 log_warn(ctx, "Failed to send data to device: %s.",
420 libusb_error_name(ret));
421 tries--;
422 } else {
423 log_err(ctx, "Failed to send data to device: %s.",
424 libusb_error_name(ret));
425 return JAYLINK_ERR;
428 buffer += transferred;
429 length -= transferred;
431 log_dbgio(ctx, "Sent %i bytes to device.", transferred);
434 if (!length)
435 return JAYLINK_OK;
437 log_err(ctx, "Sending data to device timed out.");
439 return JAYLINK_ERR_TIMEOUT;
442 JAYLINK_PRIV int transport_usb_write(struct jaylink_device_handle *devh,
443 const uint8_t *buffer, size_t length)
445 int ret;
446 struct jaylink_context *ctx;
447 size_t num_chunks;
448 size_t fill_bytes;
449 size_t tmp;
451 ctx = devh->dev->ctx;
453 if (length > devh->write_length) {
454 log_err(ctx, "Requested to write %zu bytes but only %zu bytes "
455 "are expected for the write operation.", length,
456 devh->write_length);
457 return JAYLINK_ERR_ARG;
461 * Store data in the buffer if the expected number of bytes for the
462 * write operation is not reached.
464 if (length < devh->write_length) {
465 if (devh->write_pos + length > devh->buffer_size) {
466 if (!adjust_buffer(devh, devh->write_pos + length))
467 return JAYLINK_ERR_MALLOC;
470 memcpy(devh->buffer + devh->write_pos, buffer, length);
472 devh->write_length -= length;
473 devh->write_pos += length;
475 log_dbgio(ctx, "Wrote %zu bytes into buffer.", length);
476 return JAYLINK_OK;
480 * Expected number of bytes for this write operation is reached and
481 * therefore the write operation will be performed.
483 devh->write_length = 0;
485 /* Send data directly to the device if the buffer is empty. */
486 if (!devh->write_pos)
487 return usb_send(devh, buffer, length);
490 * Calculate the number of bytes to fill up the buffer to reach a
491 * multiple of CHUNK_SIZE bytes. This ensures that the data from the
492 * buffer will be sent to the device in chunks of CHUNK_SIZE bytes.
493 * Note that this is why the buffer size must be a multiple of
494 * CHUNK_SIZE bytes.
496 num_chunks = devh->write_pos / CHUNK_SIZE;
498 if (devh->write_pos % CHUNK_SIZE)
499 num_chunks++;
501 fill_bytes = (num_chunks * CHUNK_SIZE) - devh->write_pos;
502 tmp = MIN(length, fill_bytes);
504 if (tmp > 0) {
505 memcpy(devh->buffer + devh->write_pos, buffer, tmp);
507 length -= tmp;
508 buffer += tmp;
510 log_dbgio(ctx, "Buffer filled up with %zu bytes.", tmp);
513 /* Send buffered data to the device. */
514 ret = usb_send(devh, devh->buffer, devh->write_pos + tmp);
515 devh->write_pos = 0;
517 if (ret != JAYLINK_OK)
518 return ret;
520 if (!length)
521 return JAYLINK_OK;
523 /* Send remaining data to the device. */
524 return usb_send(devh, buffer, length);
527 JAYLINK_PRIV int transport_usb_read(struct jaylink_device_handle *devh,
528 uint8_t *buffer, size_t length)
530 int ret;
531 struct jaylink_context *ctx;
532 size_t bytes_received;
533 size_t tmp;
535 ctx = devh->dev->ctx;
537 if (length > devh->read_length) {
538 log_err(ctx, "Requested to read %zu bytes but only %zu bytes "
539 "are expected for the read operation.", length,
540 devh->read_length);
541 return JAYLINK_ERR_ARG;
544 if (length <= devh->bytes_available) {
545 memcpy(buffer, devh->buffer + devh->read_pos, length);
547 devh->read_length -= length;
548 devh->bytes_available -= length;
549 devh->read_pos += length;
551 log_dbgio(ctx, "Read %zu bytes from buffer.", length);
552 return JAYLINK_OK;
555 if (devh->bytes_available) {
556 memcpy(buffer, devh->buffer + devh->read_pos,
557 devh->bytes_available);
559 buffer += devh->bytes_available;
560 length -= devh->bytes_available;
561 devh->read_length -= devh->bytes_available;
563 log_dbgio(ctx, "Read %zu bytes from buffer to flush it.",
564 devh->bytes_available);
566 devh->bytes_available = 0;
567 devh->read_pos = 0;
570 while (length > 0) {
572 * If less than CHUNK_SIZE bytes are requested from the device,
573 * store the received data into the internal buffer instead of
574 * directly into the user provided buffer. This is necessary to
575 * prevent a possible buffer overflow because the number of
576 * requested bytes from the device is always CHUNK_SIZE and
577 * therefore up to CHUNK_SIZE bytes may be received.
578 * Note that this is why the internal buffer size must be at
579 * least CHUNK_SIZE bytes.
581 if (length < CHUNK_SIZE) {
582 ret = usb_recv(devh, devh->buffer, &bytes_received);
584 if (ret != JAYLINK_OK)
585 return ret;
587 tmp = MIN(bytes_received, length);
588 memcpy(buffer, devh->buffer, tmp);
591 * Setup the buffer for the remaining data if more data
592 * was received from the device than was requested.
594 if (bytes_received > length) {
595 devh->bytes_available = bytes_received - tmp;
596 devh->read_pos = tmp;
599 buffer += tmp;
600 length -= tmp;
601 devh->read_length -= tmp;
603 log_dbgio(ctx, "Read %zu bytes from buffer.", tmp);
604 } else {
605 ret = usb_recv(devh, buffer, &bytes_received);
607 if (ret != JAYLINK_OK)
608 return ret;
610 buffer += bytes_received;
611 length -= bytes_received;
612 devh->read_length -= bytes_received;
614 log_dbgio(ctx, "Read %zu bytes from device.",
615 bytes_received);
619 return JAYLINK_OK;