CGR Localization
 All Classes Namespaces Files Functions Variables Macros Pages
usb_libusb10.c
1 /*
2  * This file is part of the OpenKinect Project. http://www.openkinect.org
3  *
4  * Copyright (c) 2010 individual OpenKinect contributors. See the CONTRIB file
5  * for details.
6  *
7  * This code is licensed to you under the terms of the Apache License, version
8  * 2.0, or, at your option, the terms of the GNU General Public License,
9  * version 2.0. See the APACHE20 and GPL2 files for the text of the licenses,
10  * or the following URLs:
11  * http://www.apache.org/licenses/LICENSE-2.0
12  * http://www.gnu.org/licenses/gpl-2.0.txt
13  *
14  * If you redistribute this file in source form, modified or unmodified, you
15  * may:
16  * 1) Leave this header intact and distribute it under the same terms,
17  * accompanying it with the APACHE20 and GPL20 files, or
18  * 2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or
19  * 3) Delete the GPL v2 clause and accompany it with the APACHE20 file
20  * In all cases you must keep the copyright notice intact and include a copy
21  * of the CONTRIB file.
22  *
23  * Binary distributions must follow the binary distribution requirements of
24  * either License.
25  */
26 
27 #include <stdio.h>
28 #include <stdbool.h>
29 #include <stdlib.h>
30 #include <libusb.h>
31 #include "freenect_internal.h"
32 
33 int fnusb_init(fnusb_ctx *ctx, freenect_usb_context *usb_ctx)
34 {
35  int res;
36  if (!usb_ctx) {
37  res = libusb_init(&ctx->ctx);
38  if (res >= 0) {
39  ctx->should_free_ctx = 1;
40  return 0;
41  } else {
42  ctx->should_free_ctx = 0;
43  ctx->ctx = NULL;
44  return res;
45  }
46  } else {
47  ctx->ctx = usb_ctx;
48  ctx->should_free_ctx = 0;
49  return 0;
50  }
51 }
52 
53 int fnusb_shutdown(fnusb_ctx *ctx)
54 {
55  //int res;
56  if (ctx->should_free_ctx) {
57  libusb_exit(ctx->ctx);
58  ctx->ctx = NULL;
59  }
60  return 0;
61 }
62 
63 int fnusb_process_events(fnusb_ctx *ctx)
64 {
65  return libusb_handle_events(ctx->ctx);
66 }
67 
68 int fnusb_open_subdevices(freenect_device *dev, int index)
69 {
70  dev->usb_cam.parent = dev;
71 
72  // Search for 0x45e (Microsoft Corp.) and 0x02ae
73  //dev->usb_cam.dev = libusb_open_device_with_vid_pid(dev->parent->usb.ctx, 0x45e, 0x2ae);
74 
75  libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
76  ssize_t cnt = libusb_get_device_list (dev->parent->usb.ctx, &devs); //get the list of devices
77  if (cnt < 0)
78  return (-1);
79 
80  bool start_cam = false, start_motor = false;
81 
82  int i = 0, nr_cam = 0, nr_mot = 0;
83  struct libusb_device_descriptor desc;
84  for (i = 0; i < cnt; ++i)
85  {
86  int r = libusb_get_device_descriptor (devs[i], &desc);
87  if (r < 0)
88  continue;
89 
90  // Search for the camera
91  if (desc.idVendor == MS_MAGIC_VENDOR && desc.idProduct == MS_MAGIC_CAMERA_PRODUCT && !start_cam)
92  {
93  // If the index given by the user matches our camera index
94  if (nr_cam == index)
95  {
96  if (libusb_open (devs[i], &dev->usb_cam.dev) != 0)
97  return (-1);
98  // Claim the camera
99  if (!dev->usb_cam.dev)
100  return (-1);
101  int err = libusb_claim_interface (dev->usb_cam.dev, 0);
102  if(err!=0){
103  printf("Error claiming camera device: ");
104  if(err==LIBUSB_ERROR_NOT_FOUND){
105  printf("LIBUSB_ERROR_NOT_FOUND\n");
106  }else if(err==LIBUSB_ERROR_BUSY){
107  printf("LIBUSB_ERROR_BUSY\n");
108  }else if(err==LIBUSB_ERROR_NO_DEVICE){
109  printf("LIBUSB_ERROR_NO_DEVICE\n");
110  }else{
111  printf("Unknown error\n");
112  }
113  exit(1);
114  }
115 
116  start_cam = true;
117  }
118  else
119  nr_cam++;
120  }
121 
122  // Search for the motor
123  if (desc.idVendor == MS_MAGIC_VENDOR && desc.idProduct == MS_MAGIC_MOTOR_PRODUCT && !start_motor)
124  {
125  // If the index given by the user matches our camera index
126  if (nr_mot == index)
127  {
128  //libusb_open_device_with_vid_pid (dev->parent->usb.ctx, MS_MAGIC_VENDOR, MS_MAGIC_MOTOR_PRODUCT);
129  if (libusb_open (devs[i], &dev->usb_motor.dev) != 0)
130  return (-1);
131  // Claim the motor
132  if (!dev->usb_motor.dev)
133  return (-1);
134  int err = libusb_claim_interface (dev->usb_motor.dev, 0);
135  if(err!=0){
136  printf("Error claiming motor device: ");
137  if(err==LIBUSB_ERROR_NOT_FOUND){
138  printf("LIBUSB_ERROR_NOT_FOUND\n");
139  }else if(err==LIBUSB_ERROR_BUSY){
140  printf("LIBUSB_ERROR_BUSY\n");
141  }else if(err==LIBUSB_ERROR_NO_DEVICE){
142  printf("LIBUSB_ERROR_NO_DEVICE\n");
143  }else{
144  printf("Unknown error\n");
145  }
146  exit(1);
147  }
148  start_motor = true;
149  }
150  else
151  nr_mot++;
152  }
153  }
154 
155  libusb_free_device_list (devs, 1); // free the list, unref the devices in it
156 
157  if (start_cam && start_motor)
158  return (0);
159  else
160  return (-1);
161 }
162 
163 static void iso_callback(struct libusb_transfer *xfer)
164 {
165  int i;
166  fnusb_isoc_stream *strm = xfer->user_data;
167 
168  if(xfer->status == LIBUSB_TRANSFER_COMPLETED) {
169  uint8_t *buf = (void*)xfer->buffer;
170  for (i=0; i<strm->pkts; i++) {
171  strm->cb(strm->parent->parent, buf, xfer->iso_packet_desc[i].actual_length);
172  buf += strm->len;
173  }
174  libusb_submit_transfer(xfer);
175  } else {
176  printf("Xfer error: %d\n", xfer->status);
177  }
178 }
179 
180 int fnusb_start_iso(fnusb_dev *dev, fnusb_isoc_stream *strm, fnusb_iso_cb cb, int ep, int xfers, int pkts, int len)
181 {
182  int ret, i;
183 
184  strm->parent = dev;
185  strm->cb = cb;
186  strm->num_xfers = xfers;
187  strm->pkts = pkts;
188  strm->len = len;
189  strm->buffer = malloc(xfers * pkts * len);
190  strm->xfers = malloc(sizeof(struct libusb_transfer*) * xfers);
191 
192  uint8_t *bufp = strm->buffer;
193 
194  for (i=0; i<xfers; i++) {
195  //printf("Creating EP %02x transfer #%d\n", ep, i);
196  strm->xfers[i] = libusb_alloc_transfer(pkts);
197 
198  libusb_fill_iso_transfer(strm->xfers[i], dev->dev, ep, bufp, pkts * len, pkts, iso_callback, strm, 0);
199 
200  libusb_set_iso_packet_lengths(strm->xfers[i], len);
201 
202  ret = libusb_submit_transfer(strm->xfers[i]);
203  if(ret==LIBUSB_ERROR_NO_DEVICE)
204  printf("Failed to submit xfer %d: LIBUSB_ERROR_NO_DEVICE\n",i);
205  else if(ret==LIBUSB_ERROR_BUSY)
206  printf("Failed to submit xfer %d: LIBUSB_ERROR_BUSY\n",i);
207  else if (ret < 0)
208  printf("Failed to submit xfer %d: %d\n", i, ret);
209 
210  bufp += pkts*len;
211  }
212 
213  return 0;
214 
215 }
216 
217 int fnusb_control(fnusb_dev *dev, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t *data, uint16_t wLength)
218 {
219  return libusb_control_transfer(dev->dev, bmRequestType, bRequest, wValue, wIndex, data, wLength, 0);
220 }