linux/tools/usb/ffs-aio-example/simple/host_app/test.c
<<
>>
Prefs
   1/*
   2 * This is free and unencumbered software released into the public domain.
   3 *
   4 * Anyone is free to copy, modify, publish, use, compile, sell, or
   5 * distribute this software, either in source code form or as a compiled
   6 * binary, for any purpose, commercial or non-commercial, and by any
   7 * means.
   8 *
   9 * In jurisdictions that recognize copyright laws, the author or authors
  10 * of this software dedicate any and all copyright interest in the
  11 * software to the public domain. We make this dedication for the benefit
  12 * of the public at large and to the detriment of our heirs and
  13 * successors. We intend this dedication to be an overt act of
  14 * relinquishment in perpetuity of all present and future rights to this
  15 * software under copyright law.
  16 *
  17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23 * OTHER DEALINGS IN THE SOFTWARE.
  24 *
  25 * For more information, please refer to <http://unlicense.org/>
  26 */
  27
  28#include <libusb.h>
  29#include <stdio.h>
  30#include <string.h>
  31#include <unistd.h>
  32
  33#define VENDOR  0x1d6b
  34#define PRODUCT 0x0105
  35
  36#define BUF_LEN         8192
  37
  38/*
  39 * struct test_state - describes test program state
  40 * @list: list of devices returned by libusb_get_device_list function
  41 * @found: pointer to struct describing tested device
  42 * @ctx: context, set to NULL
  43 * @handle: handle of tested device
  44 * @attached: indicates that device was attached to kernel, and has to be
  45 *            reattached at the end of test program
  46 */
  47
  48struct test_state {
  49        libusb_device *found;
  50        libusb_context *ctx;
  51        libusb_device_handle *handle;
  52        int attached;
  53};
  54
  55/*
  56 * test_init - initialize test program
  57 */
  58
  59int test_init(struct test_state *state)
  60{
  61        int i, ret;
  62        ssize_t cnt;
  63        libusb_device **list;
  64
  65        state->found = NULL;
  66        state->ctx = NULL;
  67        state->handle = NULL;
  68        state->attached = 0;
  69
  70        ret = libusb_init(&state->ctx);
  71        if (ret) {
  72                printf("cannot init libusb: %s\n", libusb_error_name(ret));
  73                return 1;
  74        }
  75
  76        cnt = libusb_get_device_list(state->ctx, &list);
  77        if (cnt <= 0) {
  78                printf("no devices found\n");
  79                goto error1;
  80        }
  81
  82        for (i = 0; i < cnt; ++i) {
  83                libusb_device *dev = list[i];
  84                struct libusb_device_descriptor desc;
  85                ret = libusb_get_device_descriptor(dev, &desc);
  86                if (ret) {
  87                        printf("unable to get device descriptor: %s\n",
  88                               libusb_error_name(ret));
  89                        goto error2;
  90                }
  91                if (desc.idVendor == VENDOR && desc.idProduct == PRODUCT) {
  92                        state->found = dev;
  93                        break;
  94                }
  95        }
  96
  97        if (!state->found) {
  98                printf("no devices found\n");
  99                goto error2;
 100        }
 101
 102        ret = libusb_open(state->found, &state->handle);
 103        if (ret) {
 104                printf("cannot open device: %s\n", libusb_error_name(ret));
 105                goto error2;
 106        }
 107
 108        if (libusb_claim_interface(state->handle, 0)) {
 109                ret = libusb_detach_kernel_driver(state->handle, 0);
 110                if (ret) {
 111                        printf("unable to detach kernel driver: %s\n",
 112                               libusb_error_name(ret));
 113                        goto error3;
 114                }
 115                state->attached = 1;
 116                ret = libusb_claim_interface(state->handle, 0);
 117                if (ret) {
 118                        printf("cannot claim interface: %s\n",
 119                               libusb_error_name(ret));
 120                        goto error4;
 121                }
 122        }
 123
 124        return 0;
 125
 126error4:
 127        if (state->attached == 1)
 128                libusb_attach_kernel_driver(state->handle, 0);
 129
 130error3:
 131        libusb_close(state->handle);
 132
 133error2:
 134        libusb_free_device_list(list, 1);
 135
 136error1:
 137        libusb_exit(state->ctx);
 138        return 1;
 139}
 140
 141/*
 142 * test_exit - cleanup test program
 143 */
 144
 145void test_exit(struct test_state *state)
 146{
 147        libusb_release_interface(state->handle, 0);
 148        if (state->attached == 1)
 149                libusb_attach_kernel_driver(state->handle, 0);
 150        libusb_close(state->handle);
 151        libusb_exit(state->ctx);
 152}
 153
 154int main(void)
 155{
 156        struct test_state state;
 157        struct libusb_config_descriptor *conf;
 158        struct libusb_interface_descriptor const *iface;
 159        unsigned char in_addr, out_addr;
 160
 161        if (test_init(&state))
 162                return 1;
 163
 164        libusb_get_config_descriptor(state.found, 0, &conf);
 165        iface = &conf->interface[0].altsetting[0];
 166        in_addr = iface->endpoint[0].bEndpointAddress;
 167        out_addr = iface->endpoint[1].bEndpointAddress;
 168
 169        while (1) {
 170                static unsigned char buffer[BUF_LEN];
 171                int bytes;
 172                libusb_bulk_transfer(state.handle, in_addr, buffer, BUF_LEN,
 173                                     &bytes, 500);
 174                libusb_bulk_transfer(state.handle, out_addr, buffer, BUF_LEN,
 175                                     &bytes, 500);
 176        }
 177        test_exit(&state);
 178}
 179