## USB transfer helpers

USB transfer helpers — Helpers for libgusb to ease transfer handling

## Functions

void | (*FpiUsbTransferCallback) ()
FpiUsbTransfer * | fpi_usb_transfer_new ()
FpiUsbTransfer * | fpi_usb_transfer_ref ()
void | fpi_usb_transfer_unref ()
void | fpi_usb_transfer_set_short_error ()
void | fpi_usb_transfer_fill_bulk ()
void | fpi_usb_transfer_fill_bulk_full ()
void | fpi_usb_transfer_fill_control ()
void | fpi_usb_transfer_fill_interrupt ()
void | fpi_usb_transfer_fill_interrupt_full ()
void | fpi_usb_transfer_submit ()
gboolean | fpi_usb_transfer_submit_sync ()

## Types and Values

#define | FPI_USB_ENDPOINT_IN
#define | FPI_USB_ENDPOINT_OUT
enum | FpiTransferType
| FpiUsbTransfer

## Description

FpiUsbTransfer is a structure to simplify the USB transfer handling. The main goal is to ease memory management and provide more parameters to callbacks that are useful for libfprint drivers.

Drivers should use this API only rather than accessing the GUsbDevice directly in most cases.

## Functions

### FpiUsbTransferCallback ()

    void
    (*FpiUsbTransferCallback) (FpiUsbTransfer *transfer,
                               FpDevice *dev,
                               gpointer user_data,
                               GError *error);

### fpi_usb_transfer_new ()

    FpiUsbTransfer *
    fpi_usb_transfer_new (FpDevice *device);

Creates a new FpiUsbTransfer.

#### Parameters

device | The FpDevice the transfer is for |

#### Returns

A newly created FpiUsbTransfer.

[transfer full]

### fpi_usb_transfer_ref ()

    FpiUsbTransfer *
    fpi_usb_transfer_ref (FpiUsbTransfer *self);

Increments the reference count of `self` by one.

#### Parameters

self | A FpiUsbTransfer |

#### Returns

`self` .

[transfer full]

### fpi_usb_transfer_unref ()

    void
    fpi_usb_transfer_unref (FpiUsbTransfer *self);

Decrements the reference count of `self` by one, freeing the structure when the reference count reaches zero.

#### Parameters

self | A FpiUsbTransfer |

### fpi_usb_transfer_set_short_error ()

    void
    fpi_usb_transfer_set_short_error (FpiUsbTransfer *transfer,
                                      gboolean short_is_error);

### fpi_usb_transfer_fill_bulk ()

    void
    fpi_usb_transfer_fill_bulk (FpiUsbTransfer *transfer,
                                guint8 endpoint,
                                gsize length);

Prepare a bulk transfer. A buffer will be created for you, use `fpi_usb_transfer_fill_bulk_full()` if you want to send a static buffer or receive a pre-defined buffer.

#### Parameters

transfer | The FpiUsbTransfer |
endpoint | The endpoint to send the transfer to |
length | The buffer size to allocate |

### fpi_usb_transfer_fill_bulk_full ()

    void
    fpi_usb_transfer_fill_bulk_full (FpiUsbTransfer *transfer,
                                     guint8 endpoint,
                                     guint8 *buffer,
                                     gsize length,
                                     GDestroyNotify free_func);

Prepare a bulk transfer.

#### Parameters

transfer | The FpiUsbTransfer |
endpoint | The endpoint to send the transfer to |
buffer | The data to send. |
length | The size of `buffer` |
free_func | Destroy notify for `buffer` . | [destroy buffer]

### fpi_usb_transfer_fill_control ()

    void
    fpi_usb_transfer_fill_control (FpiUsbTransfer *transfer,
                                   GUsbDeviceDirection direction,
                                   GUsbDeviceRequestType request_type,
                                   GUsbDeviceRecipient recipient,
                                   guint8 request,
                                   guint16 value,
                                   guint16 idx,
                                   gsize length);

Prepare a control transfer. The function will create a new buffer, you can initialize the buffer after calling this function.

#### Parameters

transfer | The FpiUsbTransfer |
direction | The direction of the control transfer |
request_type | The request type |
recipient | The recipient |
request | The control transfer request |
value | The control transfer value |
idx | The control transfer index |
length | The size of the transfer |

### fpi_usb_transfer_fill_interrupt ()

    void
    fpi_usb_transfer_fill_interrupt (FpiUsbTransfer *transfer,
                                     guint8 endpoint,
                                     gsize length);

Prepare an interrupt transfer. The function will create a new buffer, you can initialize the buffer after calling this function.

#### Parameters

transfer | The FpiUsbTransfer |
endpoint | The endpoint to send the transfer to |
length | The size of the transfer |

### fpi_usb_transfer_fill_interrupt_full ()

    void
    fpi_usb_transfer_fill_interrupt_full (FpiUsbTransfer *transfer,
                                          guint8 endpoint,
                                          guint8 *buffer,
                                          gsize length,
                                          GDestroyNotify free_func);

Prepare an interrupt transfer.

#### Parameters

transfer | The FpiUsbTransfer |
endpoint | The endpoint to send the transfer to |
buffer | The data to send. |
length | The size of `buffer` |
free_func | Destroy notify for `buffer` . | [destroy buffer]

### fpi_usb_transfer_submit ()

    void
    fpi_usb_transfer_submit (FpiUsbTransfer *transfer,
                             guint timeout_ms,
                             GCancellable *cancellable,
                             FpiUsbTransferCallback callback,
                             gpointer user_data);

Submit a USB transfer with a specific timeout and callback functions.

Note that FpiUsbTransfer will be stolen when this function is called. So that all associated data will be free'ed automatically, after the callback ran unless `fpi_usb_transfer_ref()` is explicitly called.

#### Parameters

transfer | The transfer to submit, must have been filled. | [transfer full]
timeout_ms | Timeout for the transfer in ms |
cancellable | Cancellable to use, e.g. `fpi_device_get_cancellable()` |
callback | Callback on completion or error |
user_data | Data to pass to callback |

### fpi_usb_transfer_submit_sync ()

    gboolean
    fpi_usb_transfer_submit_sync (FpiUsbTransfer *transfer,
                                  guint timeout_ms,
                                  GError **error);

Synchronously submit a USB transfer with a specific timeout. Only use this function with short timeouts as the application will be blocked otherwise.

Note that you still need to `fpi_usb_transfer_unref()` the FpiUsbTransfer afterwards.

#### Parameters

transfer | The transfer to submit, must have been filled. |
timeout_ms | Timeout for the transfer in millisecnods |
error | Location to store GError to |

#### Returns

TRUE on success, otherwise FALSE and `error` will be set

## Types and Values

### FPI_USB_ENDPOINT_IN

    #define FPI_USB_ENDPOINT_IN 0x80

### FPI_USB_ENDPOINT_OUT

    #define FPI_USB_ENDPOINT_OUT 0x00

### enum FpiTransferType

Type of the transfer.

#### Members

FP_TRANSFER_NONE | Type not set |
FP_TRANSFER_CONTROL | Control transfer |
FP_TRANSFER_BULK | Bulk transfer |
FP_TRANSFER_INTERRUPT | Interrupt transfer |

### FpiUsbTransfer

    typedef struct {
      FpDevice *device;

      FpiSsm   *ssm;

      gssize    length;
      gssize    actual_length;

      guchar   *buffer;
    } FpiUsbTransfer;

Helper for handling USB transfers.

#### Members

FpDevice *`device`; | The FpDevice that the transfer belongs to. |
FpiSsm *`ssm`; | Storage slot to associate the transfer with a state machine. Used by `fpi_ssm_usb_transfer_cb()` to modify the given state machine. |
gssize `length`; | The requested length of the transfer in bytes. |
gssize `actual_length`; | The actual length of the transfer (see also `fpi_usb_transfer_set_short_error()`) |
guchar *`buffer`; | The transferred data. |