Coverage Report

Created: 2023-06-07 06:32

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