Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 1 | /* |
hjelmn@cs.unm.edu | 1eff220 | 2014-01-08 23:50:34 +0000 | [diff] [blame] | 2 | * Synchronous I/O functions for libusb |
Pete Batard | a544e59 | 2012-05-23 18:25:01 +0100 | [diff] [blame] | 3 | * Copyright © 2007-2008 Daniel Drake <dsd@gentoo.org> |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 4 | * |
| 5 | * This library is free software; you can redistribute it and/or |
| 6 | * modify it under the terms of the GNU Lesser General Public |
| 7 | * License as published by the Free Software Foundation; either |
| 8 | * version 2.1 of the License, or (at your option) any later version. |
| 9 | * |
| 10 | * This library is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | * Lesser General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU Lesser General Public |
| 16 | * License along with this library; if not, write to the Free Software |
| 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 18 | */ |
| 19 | |
Chris Dickens | d8a2950 | 2014-09-03 11:50:47 -0700 | [diff] [blame] | 20 | #include <config.h> |
| 21 | |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 22 | #include <errno.h> |
| 23 | #include <stdint.h> |
| 24 | #include <stdlib.h> |
| 25 | #include <string.h> |
| 26 | |
| 27 | #include "libusbi.h" |
| 28 | |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 29 | /** |
Chris Dickens | 7ee92df | 2016-02-24 01:07:20 -0800 | [diff] [blame] | 30 | * @defgroup libusb_syncio Synchronous device I/O |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 31 | * |
hjelmn@cs.unm.edu | 1eff220 | 2014-01-08 23:50:34 +0000 | [diff] [blame] | 32 | * This page documents libusb's synchronous (blocking) API for USB device I/O. |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 33 | * This interface is easy to use but has some limitations. More advanced users |
Chris Dickens | 7ee92df | 2016-02-24 01:07:20 -0800 | [diff] [blame] | 34 | * may wish to consider using the \ref libusb_asyncio "asynchronous I/O API" instead. |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 35 | */ |
| 36 | |
Hans de Goede | 5b48dd2 | 2013-06-20 13:08:58 +0200 | [diff] [blame] | 37 | static void LIBUSB_CALL sync_transfer_cb(struct libusb_transfer *transfer) |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 38 | { |
| 39 | int *completed = transfer->user_data; |
| 40 | *completed = 1; |
| 41 | usbi_dbg("actual_length=%d", transfer->actual_length); |
| 42 | /* caller interprets result and frees transfer */ |
| 43 | } |
| 44 | |
Hans de Goede | 5b48dd2 | 2013-06-20 13:08:58 +0200 | [diff] [blame] | 45 | static void sync_transfer_wait_for_completion(struct libusb_transfer *transfer) |
| 46 | { |
| 47 | int r, *completed = transfer->user_data; |
| 48 | struct libusb_context *ctx = HANDLE_CTX(transfer->dev_handle); |
| 49 | |
| 50 | while (!*completed) { |
| 51 | r = libusb_handle_events_completed(ctx, completed); |
| 52 | if (r < 0) { |
| 53 | if (r == LIBUSB_ERROR_INTERRUPTED) |
| 54 | continue; |
| 55 | usbi_err(ctx, "libusb_handle_events failed: %s, cancelling transfer and retrying", |
| 56 | libusb_error_name(r)); |
| 57 | libusb_cancel_transfer(transfer); |
| 58 | continue; |
| 59 | } |
| 60 | } |
| 61 | } |
| 62 | |
Chris Dickens | 7ee92df | 2016-02-24 01:07:20 -0800 | [diff] [blame] | 63 | /** \ingroup libusb_syncio |
Daniel Drake | ba5d9a4 | 2008-05-11 15:36:24 +0100 | [diff] [blame] | 64 | * Perform a USB control transfer. |
| 65 | * |
| 66 | * The direction of the transfer is inferred from the bmRequestType field of |
| 67 | * the setup packet. |
| 68 | * |
| 69 | * The wValue, wIndex and wLength fields values should be given in host-endian |
| 70 | * byte order. |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 71 | * |
| 72 | * \param dev_handle a handle for the device to communicate with |
Daniel Drake | 0499e9f | 2008-03-20 21:10:01 +0000 | [diff] [blame] | 73 | * \param bmRequestType the request type field for the setup packet |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 74 | * \param bRequest the request field for the setup packet |
| 75 | * \param wValue the value field for the setup packet |
| 76 | * \param wIndex the index field for the setup packet |
| 77 | * \param data a suitably-sized data buffer for either input or output |
Daniel Drake | 0499e9f | 2008-03-20 21:10:01 +0000 | [diff] [blame] | 78 | * (depending on direction bits within bmRequestType) |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 79 | * \param wLength the length field for the setup packet. The data buffer should |
| 80 | * be at least this size. |
| 81 | * \param timeout timeout (in millseconds) that this function should wait |
Daniel Drake | 98f1b30 | 2009-09-14 08:01:24 +0100 | [diff] [blame] | 82 | * before giving up due to no response being received. For an unlimited |
| 83 | * timeout, use value 0. |
Daniel Drake | 885c2a5 | 2008-05-05 21:34:31 +0100 | [diff] [blame] | 84 | * \returns on success, the number of bytes actually transferred |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 85 | * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out |
Daniel Drake | a304eca | 2008-05-05 16:22:33 +0100 | [diff] [blame] | 86 | * \returns LIBUSB_ERROR_PIPE if the control request was not supported by the |
| 87 | * device |
Daniel Drake | fec7c84 | 2008-05-11 20:31:58 +0100 | [diff] [blame] | 88 | * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected |
Chris Dickens | 960a6e7 | 2015-09-10 02:39:20 -0700 | [diff] [blame] | 89 | * \returns LIBUSB_ERROR_BUSY if called from event handling context |
Chris Dickens | b99391d | 2016-02-24 01:50:40 -0800 | [diff] [blame] | 90 | * \returns LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than |
| 91 | * the operating system and/or hardware can support |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 92 | * \returns another LIBUSB_ERROR code on other failures |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 93 | */ |
Pete Batard | 29f9f9e | 2010-08-13 11:59:49 +0100 | [diff] [blame] | 94 | int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle, |
Daniel Drake | 0499e9f | 2008-03-20 21:10:01 +0000 | [diff] [blame] | 95 | uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 96 | unsigned char *data, uint16_t wLength, unsigned int timeout) |
| 97 | { |
Chris Dickens | 960a6e7 | 2015-09-10 02:39:20 -0700 | [diff] [blame] | 98 | struct libusb_transfer *transfer; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 99 | unsigned char *buffer; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 100 | int completed = 0; |
| 101 | int r; |
| 102 | |
Chris Dickens | 960a6e7 | 2015-09-10 02:39:20 -0700 | [diff] [blame] | 103 | if (usbi_handling_events(HANDLE_CTX(dev_handle))) |
| 104 | return LIBUSB_ERROR_BUSY; |
| 105 | |
| 106 | transfer = libusb_alloc_transfer(0); |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 107 | if (!transfer) |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 108 | return LIBUSB_ERROR_NO_MEM; |
Pete Batard | a636df4 | 2010-05-12 21:46:31 -0300 | [diff] [blame] | 109 | |
Pete Batard | 63f569b | 2012-06-28 22:49:47 +0100 | [diff] [blame] | 110 | buffer = (unsigned char*) malloc(LIBUSB_CONTROL_SETUP_SIZE + wLength); |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 111 | if (!buffer) { |
| 112 | libusb_free_transfer(transfer); |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 113 | return LIBUSB_ERROR_NO_MEM; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 114 | } |
| 115 | |
Daniel Drake | 0499e9f | 2008-03-20 21:10:01 +0000 | [diff] [blame] | 116 | libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 117 | wLength); |
Daniel Drake | 0499e9f | 2008-03-20 21:10:01 +0000 | [diff] [blame] | 118 | if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 119 | memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength); |
| 120 | |
Daniel Drake | aae05f6 | 2008-03-10 11:32:15 +0000 | [diff] [blame] | 121 | libusb_fill_control_transfer(transfer, dev_handle, buffer, |
Hans de Goede | 5b48dd2 | 2013-06-20 13:08:58 +0200 | [diff] [blame] | 122 | sync_transfer_cb, &completed, timeout); |
Daniel Drake | bef33bb | 2008-05-19 15:43:27 +0100 | [diff] [blame] | 123 | transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 124 | r = libusb_submit_transfer(transfer); |
| 125 | if (r < 0) { |
| 126 | libusb_free_transfer(transfer); |
| 127 | return r; |
| 128 | } |
| 129 | |
Hans de Goede | 5b48dd2 | 2013-06-20 13:08:58 +0200 | [diff] [blame] | 130 | sync_transfer_wait_for_completion(transfer); |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 131 | |
Daniel Drake | 0499e9f | 2008-03-20 21:10:01 +0000 | [diff] [blame] | 132 | if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 133 | memcpy(data, libusb_control_transfer_get_data(transfer), |
| 134 | transfer->actual_length); |
| 135 | |
| 136 | switch (transfer->status) { |
| 137 | case LIBUSB_TRANSFER_COMPLETED: |
| 138 | r = transfer->actual_length; |
| 139 | break; |
| 140 | case LIBUSB_TRANSFER_TIMED_OUT: |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 141 | r = LIBUSB_ERROR_TIMEOUT; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 142 | break; |
Daniel Drake | a304eca | 2008-05-05 16:22:33 +0100 | [diff] [blame] | 143 | case LIBUSB_TRANSFER_STALL: |
| 144 | r = LIBUSB_ERROR_PIPE; |
| 145 | break; |
Daniel Drake | fec7c84 | 2008-05-11 20:31:58 +0100 | [diff] [blame] | 146 | case LIBUSB_TRANSFER_NO_DEVICE: |
| 147 | r = LIBUSB_ERROR_NO_DEVICE; |
| 148 | break; |
Ludovic Rousseau | 1cc5b4a | 2011-09-16 18:07:56 +0200 | [diff] [blame] | 149 | case LIBUSB_TRANSFER_OVERFLOW: |
| 150 | r = LIBUSB_ERROR_OVERFLOW; |
| 151 | break; |
Ludovic Rousseau | 30ccbd7 | 2012-05-08 15:53:56 +0200 | [diff] [blame] | 152 | case LIBUSB_TRANSFER_ERROR: |
| 153 | case LIBUSB_TRANSFER_CANCELLED: |
| 154 | r = LIBUSB_ERROR_IO; |
| 155 | break; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 156 | default: |
Daniel Drake | 1df713d | 2008-06-24 23:01:51 -0500 | [diff] [blame] | 157 | usbi_warn(HANDLE_CTX(dev_handle), |
| 158 | "unrecognised status code %d", transfer->status); |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 159 | r = LIBUSB_ERROR_OTHER; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 160 | } |
| 161 | |
| 162 | libusb_free_transfer(transfer); |
| 163 | return r; |
| 164 | } |
| 165 | |
Daniel Drake | ebad1c7 | 2008-03-09 16:12:08 +0000 | [diff] [blame] | 166 | static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle, |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 167 | unsigned char endpoint, unsigned char *buffer, int length, |
Daniel Drake | d3ab4e3 | 2008-04-27 23:50:01 +0100 | [diff] [blame] | 168 | int *transferred, unsigned int timeout, unsigned char type) |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 169 | { |
Chris Dickens | 960a6e7 | 2015-09-10 02:39:20 -0700 | [diff] [blame] | 170 | struct libusb_transfer *transfer; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 171 | int completed = 0; |
| 172 | int r; |
| 173 | |
Chris Dickens | 960a6e7 | 2015-09-10 02:39:20 -0700 | [diff] [blame] | 174 | if (usbi_handling_events(HANDLE_CTX(dev_handle))) |
| 175 | return LIBUSB_ERROR_BUSY; |
| 176 | |
| 177 | transfer = libusb_alloc_transfer(0); |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 178 | if (!transfer) |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 179 | return LIBUSB_ERROR_NO_MEM; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 180 | |
| 181 | libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length, |
Hans de Goede | 5b48dd2 | 2013-06-20 13:08:58 +0200 | [diff] [blame] | 182 | sync_transfer_cb, &completed, timeout); |
Daniel Drake | d3ab4e3 | 2008-04-27 23:50:01 +0100 | [diff] [blame] | 183 | transfer->type = type; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 184 | |
| 185 | r = libusb_submit_transfer(transfer); |
| 186 | if (r < 0) { |
| 187 | libusb_free_transfer(transfer); |
| 188 | return r; |
| 189 | } |
| 190 | |
Hans de Goede | 5b48dd2 | 2013-06-20 13:08:58 +0200 | [diff] [blame] | 191 | sync_transfer_wait_for_completion(transfer); |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 192 | |
Chris Dickens | 60e875d | 2016-02-23 23:45:51 -0800 | [diff] [blame] | 193 | if (transferred) |
| 194 | *transferred = transfer->actual_length; |
| 195 | |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 196 | switch (transfer->status) { |
| 197 | case LIBUSB_TRANSFER_COMPLETED: |
| 198 | r = 0; |
| 199 | break; |
| 200 | case LIBUSB_TRANSFER_TIMED_OUT: |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 201 | r = LIBUSB_ERROR_TIMEOUT; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 202 | break; |
Daniel Drake | a304eca | 2008-05-05 16:22:33 +0100 | [diff] [blame] | 203 | case LIBUSB_TRANSFER_STALL: |
| 204 | r = LIBUSB_ERROR_PIPE; |
| 205 | break; |
Daniel Drake | d5f8289 | 2008-06-20 23:04:53 -0500 | [diff] [blame] | 206 | case LIBUSB_TRANSFER_OVERFLOW: |
| 207 | r = LIBUSB_ERROR_OVERFLOW; |
| 208 | break; |
Daniel Drake | fec7c84 | 2008-05-11 20:31:58 +0100 | [diff] [blame] | 209 | case LIBUSB_TRANSFER_NO_DEVICE: |
| 210 | r = LIBUSB_ERROR_NO_DEVICE; |
| 211 | break; |
Ludovic Rousseau | 30ccbd7 | 2012-05-08 15:53:56 +0200 | [diff] [blame] | 212 | case LIBUSB_TRANSFER_ERROR: |
| 213 | case LIBUSB_TRANSFER_CANCELLED: |
| 214 | r = LIBUSB_ERROR_IO; |
| 215 | break; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 216 | default: |
Daniel Drake | 1df713d | 2008-06-24 23:01:51 -0500 | [diff] [blame] | 217 | usbi_warn(HANDLE_CTX(dev_handle), |
| 218 | "unrecognised status code %d", transfer->status); |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 219 | r = LIBUSB_ERROR_OTHER; |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 220 | } |
| 221 | |
| 222 | libusb_free_transfer(transfer); |
| 223 | return r; |
| 224 | } |
| 225 | |
Chris Dickens | 7ee92df | 2016-02-24 01:07:20 -0800 | [diff] [blame] | 226 | /** \ingroup libusb_syncio |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 227 | * Perform a USB bulk transfer. The direction of the transfer is inferred from |
| 228 | * the direction bits of the endpoint address. |
| 229 | * |
Daniel Drake | 3bdafaa | 2008-04-27 19:53:51 +0100 | [diff] [blame] | 230 | * For bulk reads, the <tt>length</tt> field indicates the maximum length of |
| 231 | * data you are expecting to receive. If less data arrives than expected, |
| 232 | * this function will return that data, so be sure to check the |
| 233 | * <tt>transferred</tt> output parameter. |
| 234 | * |
| 235 | * You should also check the <tt>transferred</tt> parameter for bulk writes. |
| 236 | * Not all of the data may have been written. |
| 237 | * |
| 238 | * Also check <tt>transferred</tt> when dealing with a timeout error code. |
hjelmn@cs.unm.edu | 1eff220 | 2014-01-08 23:50:34 +0000 | [diff] [blame] | 239 | * libusb may have to split your transfer into a number of chunks to satisfy |
Daniel Drake | 3bdafaa | 2008-04-27 19:53:51 +0100 | [diff] [blame] | 240 | * underlying O/S requirements, meaning that the timeout may expire after |
hjelmn@cs.unm.edu | 1eff220 | 2014-01-08 23:50:34 +0000 | [diff] [blame] | 241 | * the first few chunks have completed. libusb is careful not to lose any data |
Daniel Drake | 3bdafaa | 2008-04-27 19:53:51 +0100 | [diff] [blame] | 242 | * that may have been transferred; do not assume that timeout conditions |
| 243 | * indicate a complete lack of I/O. |
| 244 | * |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 245 | * \param dev_handle a handle for the device to communicate with |
| 246 | * \param endpoint the address of a valid endpoint to communicate with |
| 247 | * \param data a suitably-sized data buffer for either input or output |
| 248 | * (depending on endpoint) |
| 249 | * \param length for bulk writes, the number of bytes from data to be sent. for |
| 250 | * bulk reads, the maximum number of bytes to receive into the data buffer. |
| 251 | * \param transferred output location for the number of bytes actually |
Chris Dickens | 60e875d | 2016-02-23 23:45:51 -0800 | [diff] [blame] | 252 | * transferred. Since version 1.0.21 (\ref LIBUSB_API_VERSION >= 0x01000105), |
| 253 | * it is legal to pass a NULL pointer if you do not wish to receive this |
| 254 | * information. |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 255 | * \param timeout timeout (in millseconds) that this function should wait |
Daniel Drake | 98f1b30 | 2009-09-14 08:01:24 +0100 | [diff] [blame] | 256 | * before giving up due to no response being received. For an unlimited |
| 257 | * timeout, use value 0. |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 258 | * |
| 259 | * \returns 0 on success (and populates <tt>transferred</tt>) |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 260 | * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out (and populates |
Daniel Drake | 3bdafaa | 2008-04-27 19:53:51 +0100 | [diff] [blame] | 261 | * <tt>transferred</tt>) |
Daniel Drake | a304eca | 2008-05-05 16:22:33 +0100 | [diff] [blame] | 262 | * \returns LIBUSB_ERROR_PIPE if the endpoint halted |
Daniel Drake | d5f8289 | 2008-06-20 23:04:53 -0500 | [diff] [blame] | 263 | * \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see |
Chris Dickens | 7ee92df | 2016-02-24 01:07:20 -0800 | [diff] [blame] | 264 | * \ref libusb_packetoverflow |
Daniel Drake | fec7c84 | 2008-05-11 20:31:58 +0100 | [diff] [blame] | 265 | * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected |
Chris Dickens | 960a6e7 | 2015-09-10 02:39:20 -0700 | [diff] [blame] | 266 | * \returns LIBUSB_ERROR_BUSY if called from event handling context |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 267 | * \returns another LIBUSB_ERROR code on other failures |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 268 | */ |
Pete Batard | 29f9f9e | 2010-08-13 11:59:49 +0100 | [diff] [blame] | 269 | int API_EXPORTED libusb_bulk_transfer(struct libusb_device_handle *dev_handle, |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 270 | unsigned char endpoint, unsigned char *data, int length, int *transferred, |
| 271 | unsigned int timeout) |
| 272 | { |
| 273 | return do_sync_bulk_transfer(dev_handle, endpoint, data, length, |
Daniel Drake | d3ab4e3 | 2008-04-27 23:50:01 +0100 | [diff] [blame] | 274 | transferred, timeout, LIBUSB_TRANSFER_TYPE_BULK); |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 275 | } |
| 276 | |
Chris Dickens | 7ee92df | 2016-02-24 01:07:20 -0800 | [diff] [blame] | 277 | /** \ingroup libusb_syncio |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 278 | * Perform a USB interrupt transfer. The direction of the transfer is inferred |
| 279 | * from the direction bits of the endpoint address. |
| 280 | * |
Daniel Drake | 3bdafaa | 2008-04-27 19:53:51 +0100 | [diff] [blame] | 281 | * For interrupt reads, the <tt>length</tt> field indicates the maximum length |
| 282 | * of data you are expecting to receive. If less data arrives than expected, |
| 283 | * this function will return that data, so be sure to check the |
| 284 | * <tt>transferred</tt> output parameter. |
| 285 | * |
| 286 | * You should also check the <tt>transferred</tt> parameter for interrupt |
| 287 | * writes. Not all of the data may have been written. |
| 288 | * |
| 289 | * Also check <tt>transferred</tt> when dealing with a timeout error code. |
hjelmn@cs.unm.edu | 1eff220 | 2014-01-08 23:50:34 +0000 | [diff] [blame] | 290 | * libusb may have to split your transfer into a number of chunks to satisfy |
Daniel Drake | 3bdafaa | 2008-04-27 19:53:51 +0100 | [diff] [blame] | 291 | * underlying O/S requirements, meaning that the timeout may expire after |
hjelmn@cs.unm.edu | 1eff220 | 2014-01-08 23:50:34 +0000 | [diff] [blame] | 292 | * the first few chunks have completed. libusb is careful not to lose any data |
Daniel Drake | 3bdafaa | 2008-04-27 19:53:51 +0100 | [diff] [blame] | 293 | * that may have been transferred; do not assume that timeout conditions |
| 294 | * indicate a complete lack of I/O. |
| 295 | * |
| 296 | * The default endpoint bInterval value is used as the polling interval. |
| 297 | * |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 298 | * \param dev_handle a handle for the device to communicate with |
| 299 | * \param endpoint the address of a valid endpoint to communicate with |
| 300 | * \param data a suitably-sized data buffer for either input or output |
| 301 | * (depending on endpoint) |
| 302 | * \param length for bulk writes, the number of bytes from data to be sent. for |
| 303 | * bulk reads, the maximum number of bytes to receive into the data buffer. |
| 304 | * \param transferred output location for the number of bytes actually |
Chris Dickens | 60e875d | 2016-02-23 23:45:51 -0800 | [diff] [blame] | 305 | * transferred. Since version 1.0.21 (\ref LIBUSB_API_VERSION >= 0x01000105), |
| 306 | * it is legal to pass a NULL pointer if you do not wish to receive this |
| 307 | * information. |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 308 | * \param timeout timeout (in millseconds) that this function should wait |
Daniel Drake | 98f1b30 | 2009-09-14 08:01:24 +0100 | [diff] [blame] | 309 | * before giving up due to no response being received. For an unlimited |
| 310 | * timeout, use value 0. |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 311 | * |
| 312 | * \returns 0 on success (and populates <tt>transferred</tt>) |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 313 | * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out |
Daniel Drake | a304eca | 2008-05-05 16:22:33 +0100 | [diff] [blame] | 314 | * \returns LIBUSB_ERROR_PIPE if the endpoint halted |
Daniel Drake | d5f8289 | 2008-06-20 23:04:53 -0500 | [diff] [blame] | 315 | * \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see |
Chris Dickens | 7ee92df | 2016-02-24 01:07:20 -0800 | [diff] [blame] | 316 | * \ref libusb_packetoverflow |
Daniel Drake | fec7c84 | 2008-05-11 20:31:58 +0100 | [diff] [blame] | 317 | * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected |
Chris Dickens | 960a6e7 | 2015-09-10 02:39:20 -0700 | [diff] [blame] | 318 | * \returns LIBUSB_ERROR_BUSY if called from event handling context |
Daniel Drake | bdce367 | 2008-05-04 14:22:16 +0100 | [diff] [blame] | 319 | * \returns another LIBUSB_ERROR code on other error |
Daniel Drake | ead09cd | 2008-03-15 16:35:12 +0000 | [diff] [blame] | 320 | */ |
Pete Batard | 29f9f9e | 2010-08-13 11:59:49 +0100 | [diff] [blame] | 321 | int API_EXPORTED libusb_interrupt_transfer( |
Daniel Drake | ebad1c7 | 2008-03-09 16:12:08 +0000 | [diff] [blame] | 322 | struct libusb_device_handle *dev_handle, unsigned char endpoint, |
| 323 | unsigned char *data, int length, int *transferred, unsigned int timeout) |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 324 | { |
| 325 | return do_sync_bulk_transfer(dev_handle, endpoint, data, length, |
Daniel Drake | d3ab4e3 | 2008-04-27 23:50:01 +0100 | [diff] [blame] | 326 | transferred, timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT); |
Daniel Drake | 1ac0a7d | 2008-03-09 01:01:57 +0000 | [diff] [blame] | 327 | } |