OpenOCD
transport_usb.c
Go to the documentation of this file.
1 /*
2  * This file is part of the libjaylink project.
3  *
4  * Copyright (C) 2014-2016 Marc Schink <jaylink-dev@marcschink.de>
5  *
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.
10  *
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.
15  *
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/>.
18  */
19 
20 #include <stdlib.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 #include <string.h>
24 
25 #include "libjaylink.h"
26 #include "libjaylink-internal.h"
27 
35 #define USB_TIMEOUT 1000
36 
41 #define NUM_TIMEOUTS 2
42 
44 #define CHUNK_SIZE 2048
45 
47 {
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 
58  ctx = devh->dev->ctx;
59  devh->interface_number = 0;
60 
61  /*
62  * Retrieve active configuration descriptor to determine the endpoints
63  * for the interface number of the device.
64  */
65  ret = libusb_get_active_config_descriptor(devh->dev->usb_dev, &config);
66 
67  if (ret != LIBUSB_SUCCESS) {
68  log_err(ctx, "Failed to get configuration descriptor: %s.",
69  libusb_error_name(ret));
70  return JAYLINK_ERR;
71  }
72 
73  found_interface = false;
74 
75  for (uint8_t i = 0; i < config->bNumInterfaces; i++) {
76  interface = &config->interface[i];
77  desc = &interface->altsetting[0];
78 
79  if (desc->bInterfaceClass != LIBUSB_CLASS_VENDOR_SPEC)
80  continue;
81 
82  if (desc->bInterfaceSubClass != LIBUSB_CLASS_VENDOR_SPEC)
83  continue;
84 
85  if (desc->bNumEndpoints < 2)
86  continue;
87 
88  found_interface = true;
89  devh->interface_number = i;
90  break;
91  }
92 
93  if (!found_interface) {
94  log_err(ctx, "No suitable interface found.");
95  libusb_free_config_descriptor(config);
96  return JAYLINK_ERR;
97  }
98 
99  found_endpoint_in = false;
100  found_endpoint_out = false;
101 
102  for (uint8_t i = 0; i < desc->bNumEndpoints; i++) {
103  epdesc = &desc->endpoint[i];
104 
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;
111  }
112  }
113 
114  libusb_free_config_descriptor(config);
115 
116  if (!found_endpoint_in) {
117  log_err(ctx, "Interface IN endpoint not found.");
118  return JAYLINK_ERR;
119  }
120 
121  if (!found_endpoint_out) {
122  log_err(ctx, "Interface OUT endpoint not found.");
123  return JAYLINK_ERR;
124  }
125 
126  log_dbg(ctx, "Using endpoint %02x (IN) and %02x (OUT).",
127  devh->endpoint_in, devh->endpoint_out);
128 
129  /* Buffer size must be a multiple of CHUNK_SIZE bytes. */
130  devh->buffer_size = CHUNK_SIZE;
131  devh->buffer = malloc(devh->buffer_size);
132 
133  if (!devh->buffer) {
134  log_err(ctx, "Transport buffer malloc failed.");
135  return JAYLINK_ERR_MALLOC;
136  }
137 
138  devh->read_length = 0;
139  devh->bytes_available = 0;
140  devh->read_pos = 0;
141 
142  devh->write_length = 0;
143  devh->write_pos = 0;
144 
145  return JAYLINK_OK;
146 }
147 
149 {
150  free(devh->buffer);
151 }
152 
154 {
155  int ret;
156  struct jaylink_device *dev;
157  struct jaylink_context *ctx;
158  struct libusb_device_handle *usb_devh;
159 
160  dev = devh->dev;
161  ctx = dev->ctx;
162 
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));
166 
167  ret = initialize_handle(devh);
168 
169  if (ret != JAYLINK_OK) {
170  log_err(ctx, "Initialize device handle failed.");
171  return ret;
172  }
173 
174  ret = libusb_open(dev->usb_dev, &usb_devh);
175 
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;
181  }
182 
183  ret = libusb_claim_interface(usb_devh, devh->interface_number);
184 
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;
191  }
192 
193  log_dbg(ctx, "Device opened successfully.");
194 
195  devh->usb_devh = usb_devh;
196 
197  return JAYLINK_OK;
198 }
199 
201 {
202  int ret;
203  struct jaylink_device *dev;
204  struct jaylink_context *ctx;
205 
206  dev = devh->dev;
207  ctx = dev->ctx;
208 
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));
212 
213  ret = libusb_release_interface(devh->usb_devh, devh->interface_number);
214 
215  libusb_close(devh->usb_devh);
216  cleanup_handle(devh);
217 
218  if (ret != LIBUSB_SUCCESS) {
219  log_err(ctx, "Failed to release interface: %s.",
220  libusb_error_name(ret));
221  return JAYLINK_ERR;
222  }
223 
224  log_dbg(ctx, "Device closed successfully.");
225 
226  return JAYLINK_OK;
227 }
228 
230  size_t length, bool has_command)
231 {
232  struct jaylink_context *ctx;
233 
234  (void)has_command;
235 
236  if (!length)
237  return JAYLINK_ERR_ARG;
238 
239  ctx = devh->dev->ctx;
240 
241  log_dbgio(ctx, "Starting write operation (length = %zu bytes).", length);
242 
243  if (devh->write_pos > 0)
244  log_warn(ctx, "Last write operation left %zu bytes in the "
245  "buffer.", devh->write_pos);
246 
247  if (devh->write_length > 0)
248  log_warn(ctx, "Last write operation was not performed.");
249 
250  devh->write_length = length;
251  devh->write_pos = 0;
252 
253  return JAYLINK_OK;
254 }
255 
257  size_t length)
258 {
259  struct jaylink_context *ctx;
260 
261  if (!length)
262  return JAYLINK_ERR_ARG;
263 
264  ctx = devh->dev->ctx;
265 
266  log_dbgio(ctx, "Starting read operation (length = %zu bytes).",
267  length);
268 
269  if (devh->bytes_available > 0)
270  log_dbg(ctx, "Last read operation left %zu bytes in the "
271  "buffer.", devh->bytes_available);
272 
273  if (devh->read_length > 0)
274  log_warn(ctx, "Last read operation left %zu bytes.",
275  devh->read_length);
276 
277  devh->read_length = length;
278 
279  return JAYLINK_OK;
280 }
281 
283  struct jaylink_device_handle *devh, size_t write_length,
284  size_t read_length, bool has_command)
285 {
286  struct jaylink_context *ctx;
287 
288  (void)has_command;
289 
290  if (!read_length || !write_length)
291  return JAYLINK_ERR_ARG;
292 
293  ctx = devh->dev->ctx;
294 
295  log_dbgio(ctx, "Starting write / read operation (length = "
296  "%zu / %zu bytes).", write_length, read_length);
297 
298  if (devh->write_pos > 0)
299  log_warn(ctx, "Last write operation left %zu bytes in the "
300  "buffer.", devh->write_pos);
301 
302  if (devh->write_length > 0)
303  log_warn(ctx, "Last write operation was not performed.");
304 
305  if (devh->bytes_available > 0)
306  log_warn(ctx, "Last read operation left %zu bytes in the "
307  "buffer.", devh->bytes_available);
308 
309  if (devh->read_length > 0)
310  log_warn(ctx, "Last read operation left %zu bytes.",
311  devh->read_length);
312 
313  devh->write_length = write_length;
314  devh->write_pos = 0;
315 
316  devh->read_length = read_length;
317  devh->bytes_available = 0;
318  devh->read_pos = 0;
319 
320  return JAYLINK_OK;
321 }
322 
323 static int usb_recv(struct jaylink_device_handle *devh, uint8_t *buffer,
324  size_t *length)
325 {
326  int ret;
327  struct jaylink_context *ctx;
328  unsigned int tries;
329  int transferred;
330 
331  ctx = devh->dev->ctx;
332 
333  tries = NUM_TIMEOUTS;
334  transferred = 0;
335 
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);
341 
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;
351  }
352 
353  log_dbgio(ctx, "Received %i bytes from device.", transferred);
354  }
355 
356  /* Ignore a possible timeout if at least one byte was received. */
357  if (transferred > 0) {
358  *length = transferred;
359  return JAYLINK_OK;
360  }
361 
362  log_err(ctx, "Receiving data from device timed out.");
363 
364  return JAYLINK_ERR_TIMEOUT;
365 }
366 
367 static bool adjust_buffer(struct jaylink_device_handle *devh, size_t size)
368 {
369  struct jaylink_context *ctx;
370  size_t num_chunks;
371  uint8_t *buffer;
372 
373  ctx = devh->dev->ctx;
374 
375  /* Adjust buffer size to a multiple of CHUNK_SIZE bytes. */
376  num_chunks = size / CHUNK_SIZE;
377 
378  if (size % CHUNK_SIZE > 0)
379  num_chunks++;
380 
381  size = num_chunks * CHUNK_SIZE;
382  buffer = realloc(devh->buffer, size);
383 
384  if (!buffer) {
385  log_err(ctx, "Failed to adjust buffer size to %zu bytes.",
386  size);
387  return false;
388  }
389 
390  devh->buffer = buffer;
391  devh->buffer_size = size;
392 
393  log_dbg(ctx, "Adjusted buffer size to %zu bytes.", size);
394 
395  return true;
396 }
397 
398 static int usb_send(struct jaylink_device_handle *devh, const uint8_t *buffer,
399  size_t length)
400 {
401  int ret;
402  struct jaylink_context *ctx;
403  unsigned int tries;
404  int transferred;
405 
406  ctx = devh->dev->ctx;
407  tries = NUM_TIMEOUTS;
408 
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);
414 
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;
425  }
426 
427  buffer += transferred;
428  length -= transferred;
429 
430  log_dbgio(ctx, "Sent %i bytes to device.", transferred);
431  }
432 
433  if (!length)
434  return JAYLINK_OK;
435 
436  log_err(ctx, "Sending data to device timed out.");
437 
438  return JAYLINK_ERR_TIMEOUT;
439 }
440 
442  const uint8_t *buffer, size_t length)
443 {
444  int ret;
445  struct jaylink_context *ctx;
446  size_t num_chunks;
447  size_t fill_bytes;
448  size_t tmp;
449 
450  ctx = devh->dev->ctx;
451 
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;
457  }
458 
459  /*
460  * Store data in the buffer if the expected number of bytes for the
461  * write operation is not reached.
462  */
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;
467  }
468 
469  memcpy(devh->buffer + devh->write_pos, buffer, length);
470 
471  devh->write_length -= length;
472  devh->write_pos += length;
473 
474  log_dbgio(ctx, "Wrote %zu bytes into buffer.", length);
475  return JAYLINK_OK;
476  }
477 
478  /*
479  * Expected number of bytes for this write operation is reached and
480  * therefore the write operation will be performed.
481  */
482  devh->write_length = 0;
483 
484  /* Send data directly to the device if the buffer is empty. */
485  if (!devh->write_pos)
486  return usb_send(devh, buffer, length);
487 
488  /*
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.
494  */
495  num_chunks = devh->write_pos / CHUNK_SIZE;
496 
497  if (devh->write_pos % CHUNK_SIZE)
498  num_chunks++;
499 
500  fill_bytes = (num_chunks * CHUNK_SIZE) - devh->write_pos;
501  tmp = MIN(length, fill_bytes);
502 
503  if (tmp > 0) {
504  memcpy(devh->buffer + devh->write_pos, buffer, tmp);
505 
506  length -= tmp;
507  buffer += tmp;
508 
509  log_dbgio(ctx, "Buffer filled up with %zu bytes.", tmp);
510  }
511 
512  /* Send buffered data to the device. */
513  ret = usb_send(devh, devh->buffer, devh->write_pos + tmp);
514  devh->write_pos = 0;
515 
516  if (ret != JAYLINK_OK)
517  return ret;
518 
519  if (!length)
520  return JAYLINK_OK;
521 
522  /* Send remaining data to the device. */
523  return usb_send(devh, buffer, length);
524 }
525 
527  uint8_t *buffer, size_t length)
528 {
529  int ret;
530  struct jaylink_context *ctx;
531  size_t bytes_received;
532  size_t tmp;
533 
534  ctx = devh->dev->ctx;
535 
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;
541  }
542 
543  if (length <= devh->bytes_available) {
544  memcpy(buffer, devh->buffer + devh->read_pos, length);
545 
546  devh->read_length -= length;
547  devh->bytes_available -= length;
548  devh->read_pos += length;
549 
550  log_dbgio(ctx, "Read %zu bytes from buffer.", length);
551  return JAYLINK_OK;
552  }
553 
554  if (devh->bytes_available) {
555  memcpy(buffer, devh->buffer + devh->read_pos,
556  devh->bytes_available);
557 
558  buffer += devh->bytes_available;
559  length -= devh->bytes_available;
560  devh->read_length -= devh->bytes_available;
561 
562  log_dbgio(ctx, "Read %zu bytes from buffer to flush it.",
563  devh->bytes_available);
564 
565  devh->bytes_available = 0;
566  devh->read_pos = 0;
567  }
568 
569  while (length > 0) {
570  /*
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.
579  */
580  if (length < CHUNK_SIZE) {
581  ret = usb_recv(devh, devh->buffer, &bytes_received);
582 
583  if (ret != JAYLINK_OK)
584  return ret;
585 
586  tmp = MIN(bytes_received, length);
587  memcpy(buffer, devh->buffer, tmp);
588 
589  /*
590  * Setup the buffer for the remaining data if more data
591  * was received from the device than was requested.
592  */
593  if (bytes_received > length) {
594  devh->bytes_available = bytes_received - tmp;
595  devh->read_pos = tmp;
596  }
597 
598  buffer += tmp;
599  length -= tmp;
600  devh->read_length -= tmp;
601 
602  log_dbgio(ctx, "Read %zu bytes from buffer.", tmp);
603  } else {
604  ret = usb_recv(devh, buffer, &bytes_received);
605 
606  if (ret != JAYLINK_OK)
607  return ret;
608 
609  buffer += bytes_received;
610  length -= bytes_received;
611  devh->read_length -= bytes_received;
612 
613  log_dbgio(ctx, "Read %zu bytes from device.",
614  bytes_received);
615  }
616  }
617 
618  return JAYLINK_OK;
619 }
JAYLINK_PRIV int transport_usb_read(struct jaylink_device_handle *devh, uint8_t *buffer, size_t length)
JAYLINK_PRIV int transport_usb_open(struct jaylink_device_handle *devh)
static int usb_recv(struct jaylink_device_handle *devh, uint8_t *buffer, size_t *length)
static bool adjust_buffer(struct jaylink_device_handle *devh, size_t size)
static void cleanup_handle(struct jaylink_device_handle *devh)
static int usb_send(struct jaylink_device_handle *devh, const uint8_t *buffer, size_t length)
JAYLINK_PRIV int transport_usb_write(struct jaylink_device_handle *devh, const uint8_t *buffer, size_t length)
#define MIN(a, b)
Definition: replacements.h:32
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:37
JAYLINK_PRIV int transport_usb_start_write_read(struct jaylink_device_handle *devh, size_t write_length, size_t read_length, bool has_command)
#define CHUNK_SIZE
Chunk size in bytes in which data is transferred.
Definition: transport_usb.c:44
JAYLINK_PRIV int transport_usb_start_read(struct jaylink_device_handle *devh, size_t length)
JAYLINK_PRIV int transport_usb_start_write(struct jaylink_device_handle *devh, size_t length, bool has_command)
JAYLINK_PRIV int transport_usb_close(struct jaylink_device_handle *devh)
static int initialize_handle(struct jaylink_device_handle *devh)
Definition: transport_usb.c:46
#define NUM_TIMEOUTS
Number of consecutive timeouts before an USB transfer will be treated as timed out.
Definition: transport_usb.c:41
#define USB_TIMEOUT
Timeout of an USB transfer in milliseconds.
Definition: transport_usb.c:35