Commit 6b861322c45063f91dd3bdd7b04ef4345c72e254

Moving files to allow rubygems building of extensions

Commit diff

.gitignore

 
1Makefile
2mkmf.log
3usb.bundle
4usb.o
1ext/Makefile
2ext/mkmf.log
3ext/usb.bundle
4ext/usb.o
5pkg
toggle raw diff

Manifest.txt

 
55README.txt
66README.win32
77Rakefile
8constants.h
9extconf.rb
8ext/constants.h
9ext/extconf.rb
10ext/usb.c
1011lib/usb.rb
1112sample/usb-power
12usb.c
toggle raw diff

constants.h

 
0/*
1 constants.h - libusb constants
2
3 Copyright (C) 2007 Tanaka Akira
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
20f(USB_CLASS_PER_INTERFACE)
21f(USB_CLASS_AUDIO)
22f(USB_CLASS_COMM)
23f(USB_CLASS_HID)
24f(USB_CLASS_PRINTER)
25#ifdef USB_CLASS_PTP
26f(USB_CLASS_PTP)
27#endif
28f(USB_CLASS_MASS_STORAGE)
29f(USB_CLASS_HUB)
30f(USB_CLASS_DATA)
31f(USB_CLASS_VENDOR_SPEC)
32f(USB_DT_DEVICE)
33f(USB_DT_CONFIG)
34f(USB_DT_STRING)
35f(USB_DT_INTERFACE)
36f(USB_DT_ENDPOINT)
37f(USB_DT_HID)
38f(USB_DT_REPORT)
39f(USB_DT_PHYSICAL)
40f(USB_DT_HUB)
41f(USB_DT_DEVICE_SIZE)
42f(USB_DT_CONFIG_SIZE)
43f(USB_DT_INTERFACE_SIZE)
44f(USB_DT_ENDPOINT_SIZE)
45f(USB_DT_ENDPOINT_AUDIO_SIZE)
46f(USB_DT_HUB_NONVAR_SIZE)
47f(USB_MAXENDPOINTS)
48f(USB_ENDPOINT_ADDRESS_MASK)
49f(USB_ENDPOINT_DIR_MASK)
50f(USB_ENDPOINT_TYPE_MASK)
51f(USB_ENDPOINT_TYPE_CONTROL)
52f(USB_ENDPOINT_TYPE_ISOCHRONOUS)
53f(USB_ENDPOINT_TYPE_BULK)
54f(USB_ENDPOINT_TYPE_INTERRUPT)
55f(USB_MAXINTERFACES)
56f(USB_MAXALTSETTING)
57f(USB_MAXCONFIG)
58f(USB_REQ_GET_STATUS)
59f(USB_REQ_CLEAR_FEATURE)
60f(USB_REQ_SET_FEATURE)
61f(USB_REQ_SET_ADDRESS)
62f(USB_REQ_GET_DESCRIPTOR)
63f(USB_REQ_SET_DESCRIPTOR)
64f(USB_REQ_GET_CONFIGURATION)
65f(USB_REQ_SET_CONFIGURATION)
66f(USB_REQ_GET_INTERFACE)
67f(USB_REQ_SET_INTERFACE)
68f(USB_REQ_SYNCH_FRAME)
69f(USB_TYPE_STANDARD)
70f(USB_TYPE_CLASS)
71f(USB_TYPE_VENDOR)
72f(USB_TYPE_RESERVED)
73f(USB_RECIP_DEVICE)
74f(USB_RECIP_INTERFACE)
75f(USB_RECIP_ENDPOINT)
76f(USB_RECIP_OTHER)
77f(USB_ENDPOINT_IN)
78f(USB_ENDPOINT_OUT)
79f(USB_ERROR_BEGIN)
80#ifdef LIBUSB_HAS_GET_DRIVER_NP
81f(LIBUSB_HAS_GET_DRIVER_NP)
82#endif
83#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
84f(LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP)
85#endif
toggle raw diff

ext/constants.h

 
1/*
2 constants.h - libusb constants
3
4 Copyright (C) 2007 Tanaka Akira
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*/
20
21f(USB_CLASS_PER_INTERFACE)
22f(USB_CLASS_AUDIO)
23f(USB_CLASS_COMM)
24f(USB_CLASS_HID)
25f(USB_CLASS_PRINTER)
26#ifdef USB_CLASS_PTP
27f(USB_CLASS_PTP)
28#endif
29f(USB_CLASS_MASS_STORAGE)
30f(USB_CLASS_HUB)
31f(USB_CLASS_DATA)
32f(USB_CLASS_VENDOR_SPEC)
33f(USB_DT_DEVICE)
34f(USB_DT_CONFIG)
35f(USB_DT_STRING)
36f(USB_DT_INTERFACE)
37f(USB_DT_ENDPOINT)
38f(USB_DT_HID)
39f(USB_DT_REPORT)
40f(USB_DT_PHYSICAL)
41f(USB_DT_HUB)
42f(USB_DT_DEVICE_SIZE)
43f(USB_DT_CONFIG_SIZE)
44f(USB_DT_INTERFACE_SIZE)
45f(USB_DT_ENDPOINT_SIZE)
46f(USB_DT_ENDPOINT_AUDIO_SIZE)
47f(USB_DT_HUB_NONVAR_SIZE)
48f(USB_MAXENDPOINTS)
49f(USB_ENDPOINT_ADDRESS_MASK)
50f(USB_ENDPOINT_DIR_MASK)
51f(USB_ENDPOINT_TYPE_MASK)
52f(USB_ENDPOINT_TYPE_CONTROL)
53f(USB_ENDPOINT_TYPE_ISOCHRONOUS)
54f(USB_ENDPOINT_TYPE_BULK)
55f(USB_ENDPOINT_TYPE_INTERRUPT)
56f(USB_MAXINTERFACES)
57f(USB_MAXALTSETTING)
58f(USB_MAXCONFIG)
59f(USB_REQ_GET_STATUS)
60f(USB_REQ_CLEAR_FEATURE)
61f(USB_REQ_SET_FEATURE)
62f(USB_REQ_SET_ADDRESS)
63f(USB_REQ_GET_DESCRIPTOR)
64f(USB_REQ_SET_DESCRIPTOR)
65f(USB_REQ_GET_CONFIGURATION)
66f(USB_REQ_SET_CONFIGURATION)
67f(USB_REQ_GET_INTERFACE)
68f(USB_REQ_SET_INTERFACE)
69f(USB_REQ_SYNCH_FRAME)
70f(USB_TYPE_STANDARD)
71f(USB_TYPE_CLASS)
72f(USB_TYPE_VENDOR)
73f(USB_TYPE_RESERVED)
74f(USB_RECIP_DEVICE)
75f(USB_RECIP_INTERFACE)
76f(USB_RECIP_ENDPOINT)
77f(USB_RECIP_OTHER)
78f(USB_ENDPOINT_IN)
79f(USB_ENDPOINT_OUT)
80f(USB_ERROR_BEGIN)
81#ifdef LIBUSB_HAS_GET_DRIVER_NP
82f(LIBUSB_HAS_GET_DRIVER_NP)
83#endif
84#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
85f(LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP)
86#endif
toggle raw diff

ext/extconf.rb

 
1# Copyright (C) 2006 Tanaka Akira. All rights reserved.
2#
3# Redistribution and use in source and binary forms, with or without
4# modification, are permitted provided that the following conditions
5# are met:
6# 1. Redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer.
8# 2. Redistributions in binary form must reproduce the above copyright
9# notice, this list of conditions and the following disclaimer in the
10# documentation and/or other materials provided with the distribution.
11#
12# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
16# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22# SUCH DAMAGE.
23
24require 'mkmf'
25
26have_library("usb", "usb_init")
27
28create_makefile('usb')
toggle raw diff

ext/usb.c

 
1/*
2 usb.c - libusb interface for Ruby.
3
4 Copyright (C) 2007 Tanaka Akira
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*/
20
21#include "ruby.h"
22#include "st.h"
23#include <usb.h>
24#include <errno.h>
25
26#ifndef RSTRING_PTR
27# define RSTRING_PTR(s) (RSTRING(s)->ptr)
28# define RSTRING_LEN(s) (RSTRING(s)->len)
29#endif
30
31static VALUE rb_cUSB;
32
33static VALUE rusb_dev_handle_new(usb_dev_handle *h);
34
35#define define_usb_struct(c_name, ruby_name) \
36 static VALUE rb_cUSB_ ## ruby_name; \
37 static st_table *c_name ## _objects; \
38 typedef struct { struct usb_ ## c_name *ptr; VALUE parent; } rusb_ ## c_name ## _t; \
39 static void rusb_ ## c_name ## _free(void *p) { \
40 if (p) free(p); \
41 } \
42 static VALUE rusb_ ## c_name ## _make(struct usb_ ## c_name *p, VALUE parent) \
43 { \
44 VALUE v; \
45 rusb_ ## c_name ## _t *d; \
46 if (p == NULL) { return Qnil; } \
47 if (st_lookup(c_name ## _objects, (st_data_t)p, (st_data_t *)&v)) \
48 return v; \
49 d = (rusb_ ## c_name ## _t *)xmalloc(sizeof(*d)); \
50 d->ptr = p; \
51 d->parent = parent; \
52 v = Data_Wrap_Struct(rb_cUSB_ ## ruby_name, 0, rusb_ ## c_name ## _free, d); \
53 st_add_direct(c_name ## _objects, (st_data_t)p, (st_data_t)v); \
54 return v; \
55 } \
56 static rusb_ ## c_name ## _t *check_usb_ ## c_name(VALUE v) \
57 { \
58 Check_Type(v, T_DATA); \
59 if (RDATA(v)->dfree != rusb_ ## c_name ## _free) { \
60 rb_raise(rb_eTypeError, "wrong argument type %s (expected USB::" #ruby_name ")", \
61 rb_class2name(CLASS_OF(v))); \
62 } \
63 return DATA_PTR(v); \
64 } \
65 static rusb_ ## c_name ## _t *get_rusb_ ## c_name(VALUE v) \
66 { \
67 rusb_ ## c_name ## _t *d = check_usb_ ## c_name(v); \
68 if (!d) { \
69 rb_raise(rb_eArgError, "revoked USB::" #ruby_name); \
70 } \
71 return d; \
72 } \
73 static struct usb_ ## c_name *get_usb_ ## c_name(VALUE v) \
74 { \
75 return get_rusb_ ## c_name(v)->ptr; \
76 } \
77 static VALUE get_usb_ ## c_name ## _parent(VALUE v) \
78 { \
79 return get_rusb_ ## c_name(v)->parent; \
80 }
81
82define_usb_struct(bus, Bus)
83define_usb_struct(device, Device)
84define_usb_struct(config_descriptor, Configuration)
85define_usb_struct(interface, Interface)
86define_usb_struct(interface_descriptor, Setting)
87define_usb_struct(endpoint_descriptor, Endpoint)
88
89static int mark_data_i(st_data_t key, st_data_t val, st_data_t arg)
90{
91 if (DATA_PTR((VALUE)val))
92 rb_gc_mark((VALUE)val);
93 return ST_CONTINUE;
94}
95
96VALUE rusb_gc_root;
97static void rusb_gc_mark(void *p) {
98 st_foreach(bus_objects, mark_data_i, 0);
99 st_foreach(device_objects, mark_data_i, 0);
100 st_foreach(config_descriptor_objects, mark_data_i, 0);
101 st_foreach(interface_objects, mark_data_i, 0);
102 st_foreach(interface_descriptor_objects, mark_data_i, 0);
103 st_foreach(endpoint_descriptor_objects, mark_data_i, 0);
104}
105
106/* -------- USB::Bus -------- */
107static int revoke_data_i(st_data_t key, st_data_t val, st_data_t arg)
108{
109 DATA_PTR((VALUE)val) = NULL;
110 return ST_DELETE;
111}
112
113/* USB.find_busses */
114static VALUE
115rusb_find_busses(VALUE cUSB)
116{
117 st_foreach(bus_objects, revoke_data_i, 0);
118 st_foreach(device_objects, revoke_data_i, 0);
119 st_foreach(config_descriptor_objects, revoke_data_i, 0);
120 st_foreach(interface_objects, revoke_data_i, 0);
121 st_foreach(interface_descriptor_objects, revoke_data_i, 0);
122 st_foreach(endpoint_descriptor_objects, revoke_data_i, 0);
123 return INT2NUM(usb_find_busses());
124}
125
126/* USB.find_devices */
127static VALUE
128rusb_find_devices(VALUE cUSB)
129{
130 return INT2NUM(usb_find_devices());
131}
132
133/* USB.first_bus */
134static VALUE
135rusb_first_bus(VALUE cUSB)
136{
137 struct usb_bus *bus = usb_get_busses();
138 return rusb_bus_make(bus, Qnil);
139}
140
141/* USB::Bus#revoked? */
142static VALUE
143rusb_bus_revoked_p(VALUE v)
144{
145 return RTEST(!check_usb_bus(v));
146}
147
148/* USB::Bus#prev */
149static VALUE rusb_bus_prev(VALUE v) { return rusb_bus_make(get_usb_bus(v)->prev, Qnil); }
150
151/* USB::Bus#next */
152static VALUE rusb_bus_next(VALUE v) { return rusb_bus_make(get_usb_bus(v)->next, Qnil); }
153
154/* USB::Bus#dirname */
155static VALUE rusb_bus_dirname(VALUE v) { return rb_str_new2(get_usb_bus(v)->dirname); }
156
157/* USB::Bus#location */
158static VALUE rusb_bus_location(VALUE v) { return UINT2NUM(get_usb_bus(v)->location); }
159
160/* USB::Bus#first_device */
161static VALUE rusb_bus_first_device(VALUE v) { return rusb_device_make(get_usb_bus(v)->devices, v); }
162
163/* -------- USB::Device -------- */
164
165/* USB::Bus#revoked? */
166static VALUE
167rusb_device_revoked_p(VALUE v)
168{
169 return RTEST(!check_usb_device(v));
170}
171
172/* USB::Device#prev */
173static VALUE rusb_device_prev(VALUE v) { rusb_device_t *device = get_rusb_device(v); return rusb_device_make(device->ptr->prev, device->parent); }
174
175/* USB::Device#next */
176static VALUE rusb_device_next(VALUE v) { rusb_device_t *device = get_rusb_device(v); return rusb_device_make(device->ptr->next, device->parent); }
177
178/* USB::Device#filename */
179static VALUE rusb_device_filename(VALUE v) { return rb_str_new2(get_usb_device(v)->filename); }
180
181/* USB::Device#bus */
182static VALUE rusb_device_bus(VALUE v) { return rusb_bus_make(get_usb_device(v)->bus, Qnil); }
183
184/* USB::Device#devnum */
185static VALUE rusb_device_devnum(VALUE v) { return INT2FIX(get_usb_device(v)->devnum); }
186
187/* USB::Device#num_children */
188static VALUE rusb_device_num_children(VALUE v) { return INT2FIX(get_usb_device(v)->num_children); }
189
190/* USB::Device#children */
191static VALUE
192rusb_device_children(VALUE vdevice)
193{
194 rusb_device_t *d = get_rusb_device(vdevice);
195 struct usb_device *device = d->ptr;
196 int i;
197 VALUE children = rb_ary_new2(device->num_children);
198 for (i = 0; i < device->num_children; i++)
199 rb_ary_store(children, i, rusb_device_make(device->children[i], d->parent));
200 return children;
201}
202
203/* USB::Device#descriptor_bLength */
204static VALUE rusb_devdesc_bLength(VALUE v) { return INT2FIX(get_usb_device(v)->descriptor.bLength); }
205
206/* USB::Device#descriptor_bDescriptorType */
207static VALUE rusb_devdesc_bDescriptorType(VALUE v) { return INT2FIX(get_usb_device(v)->descriptor.bDescriptorType); }
208
209/* USB::Device#descriptor_bcdUSB */
210static VALUE rusb_devdesc_bcdUSB(VALUE v) { return INT2FIX(get_usb_device(v)->descriptor.bcdUSB); }
211
212/* USB::Device#descriptor_bDeviceClass */
213static VALUE rusb_devdesc_bDeviceClass(VALUE v) { return INT2FIX(get_usb_device(v)->descriptor.bDeviceClass); }
214
215/* USB::Device#descriptor_bDeviceSubClass */
216static VALUE rusb_devdesc_bDeviceSubClass(VALUE v) { return INT2FIX(get_usb_device(v)->descriptor.bDeviceSubClass); }
217
218/* USB::Device#descriptor_bDeviceProtocol */
219static VALUE rusb_devdesc_bDeviceProtocol(VALUE v) { return INT2FIX(get_usb_device(v)->descriptor.bDeviceProtocol); }
220
221/* USB::Device#descriptor_bMaxPacketSize0 */
222static VALUE rusb_devdesc_bMaxPacketSize0(VALUE v) { return INT2FIX(get_usb_device(v)->descriptor.bMaxPacketSize0); }
223
224/* USB::Device#descriptor_idVendor */
225static VALUE rusb_devdesc_idVendor(VALUE v) { return INT2FIX(get_usb_device(v)->descriptor.idVendor); }
226
227/* USB::Device#descriptor_idProduct */
228static VALUE rusb_devdesc_idProduct(VALUE v) { return INT2FIX(get_usb_device(v)->descriptor.idProduct); }
229
230/* USB::Device#descriptor_bcdDevice */
231static VALUE rusb_devdesc_bcdDevice(VALUE v) { return INT2FIX(get_usb_device(v)->descriptor.bcdDevice); }
232
233/* USB::Device#descriptor_iManufacturer */
234static VALUE rusb_devdesc_iManufacturer(VALUE v) { return INT2FIX(get_usb_device(v)->descriptor.iManufacturer); }
235
236/* USB::Device#descriptor_iProduct */
237static VALUE rusb_devdesc_iProduct(VALUE v) { return INT2FIX(get_usb_device(v)->descriptor.iProduct); }
238
239/* USB::Device#descriptor_iSerialNumber */
240static VALUE rusb_devdesc_iSerialNumber(VALUE v) { return INT2FIX(get_usb_device(v)->descriptor.iSerialNumber); }
241
242/* USB::Device#descriptor_bNumConfigurations */
243static VALUE rusb_devdesc_bNumConfigurations(VALUE v) { return INT2FIX(get_usb_device(v)->descriptor.bNumConfigurations); }
244
245/* USB::Device#configurations */
246static VALUE
247rusb_device_config(VALUE v)
248{
249 struct usb_device *device = get_usb_device(v);
250 int i;
251 VALUE children = rb_ary_new2(device->descriptor.bNumConfigurations);
252 for (i = 0; i < device->descriptor.bNumConfigurations; i++)
253 rb_ary_store(children, i, rusb_config_descriptor_make(&device->config[i], v));
254 return children;
255}
256
257/* USB::Device#usb_open */
258static VALUE
259rusb_device_open(VALUE vdevice)
260{
261 struct usb_device *device = get_usb_device(vdevice);
262 usb_dev_handle *h = usb_open(device);
263 return rusb_dev_handle_new(h);
264}
265
266/* -------- USB::Configuration -------- */
267
268/* USB::Configuration#revoked? */
269static VALUE
270rusb_config_revoked_p(VALUE v)
271{
272 return RTEST(!check_usb_config_descriptor(v));
273}
274
275/* USB::Configuration#device */
276static VALUE rusb_config_device(VALUE v) { return get_rusb_config_descriptor(v)->parent; }
277
278/* USB::Configuration#bLength */
279static VALUE rusb_config_bLength(VALUE v) { return INT2FIX(get_usb_config_descriptor(v)->bLength); }
280
281/* USB::Configuration#bDescriptorType */
282static VALUE rusb_config_bDescriptorType(VALUE v) { return INT2FIX(get_usb_config_descriptor(v)->bDescriptorType); }
283
284/* USB::Configuration#wTotalLength */
285static VALUE rusb_config_wTotalLength(VALUE v) { return INT2FIX(get_usb_config_descriptor(v)->wTotalLength); }
286
287/* USB::Configuration#bNumInterfaces */
288static VALUE rusb_config_bNumInterfaces(VALUE v) { return INT2FIX(get_usb_config_descriptor(v)->bNumInterfaces); }
289
290/* USB::Configuration#bConfigurationValue */
291static VALUE rusb_config_bConfigurationValue(VALUE v) { return INT2FIX(get_usb_config_descriptor(v)->bConfigurationValue); }
292
293/* USB::Configuration#iConfiguration */
294static VALUE rusb_config_iConfiguration(VALUE v) { return INT2FIX(get_usb_config_descriptor(v)->iConfiguration); }
295
296/* USB::Configuration#bmAttributes */
297static VALUE rusb_config_bmAttributes(VALUE v) { return INT2FIX(get_usb_config_descriptor(v)->bmAttributes); }
298
299/* USB::Configuration#bMaxPower */
300static VALUE rusb_config_bMaxPower(VALUE v) { return INT2FIX(get_usb_config_descriptor(v)->MaxPower); }
301
302/* USB::Configuration#interfaces */
303static VALUE
304rusb_config_interfaces(VALUE v)
305{
306 struct usb_config_descriptor *p = get_usb_config_descriptor(v);
307 int i;
308 VALUE interface = rb_ary_new2(p->bNumInterfaces);
309 for (i = 0; i < p->bNumInterfaces; i++)
310 rb_ary_store(interface, i, rusb_interface_make(&p->interface[i], v));
311 return interface;
312}
313
314/* -------- USB::Interface -------- */
315
316/* USB::Interface#revoked? */
317static VALUE
318rusb_interface_revoked_p(VALUE v)
319{
320 return RTEST(!check_usb_interface(v));
321}
322
323/* USB::Interface#configuration */
324static VALUE rusb_interface_configuration(VALUE v) { return get_rusb_interface(v)->parent; }
325
326/* USB::Interface#num_altsetting */
327static VALUE rusb_interface_num_altsetting(VALUE v) { return INT2FIX(get_usb_interface(v)->num_altsetting); }
328
329/* USB::Interface#settings */
330static VALUE
331rusb_interface_settings(VALUE v)
332{
333 struct usb_interface *p = get_usb_interface(v);
334 int i;
335 VALUE altsetting = rb_ary_new2(p->num_altsetting);
336 for (i = 0; i < p->num_altsetting; i++)
337 rb_ary_store(altsetting, i, rusb_interface_descriptor_make(&p->altsetting[i], v));
338 return altsetting;
339}
340
341/* -------- USB::Setting -------- */
342
343/* USB::Setting#revoked? */
344static VALUE
345rusb_setting_revoked_p(VALUE v)
346{
347 return RTEST(!check_usb_interface_descriptor(v));
348}
349
350/* USB::Interface#interface */
351static VALUE rusb_setting_interface(VALUE v) { return get_rusb_interface_descriptor(v)->parent; }
352
353/* USB::Setting#bLength */
354static VALUE rusb_setting_bLength(VALUE v) { return INT2FIX(get_usb_interface_descriptor(v)->bLength); }
355
356/* USB::Setting#bDescriptorType */
357static VALUE rusb_setting_bDescriptorType(VALUE v) { return INT2FIX(get_usb_interface_descriptor(v)->bDescriptorType); }
358
359/* USB::Setting#bInterfaceNumber */
360static VALUE rusb_setting_bInterfaceNumber(VALUE v) { return INT2FIX(get_usb_interface_descriptor(v)->bInterfaceNumber); }
361
362/* USB::Setting#bAlternateSetting */
363static VALUE rusb_setting_bAlternateSetting(VALUE v) { return INT2FIX(get_usb_interface_descriptor(v)->bAlternateSetting); }
364
365/* USB::Setting#bNumEndpoints */
366static VALUE rusb_setting_bNumEndpoints(VALUE v) { return INT2FIX(get_usb_interface_descriptor(v)->bNumEndpoints); }
367
368/* USB::Setting#bInterfaceClass */
369static VALUE rusb_setting_bInterfaceClass(VALUE v) { return INT2FIX(get_usb_interface_descriptor(v)->bInterfaceClass); }
370
371/* USB::Setting#bInterfaceSubClass */
372static VALUE rusb_setting_bInterfaceSubClass(VALUE v) { return INT2FIX(get_usb_interface_descriptor(v)->bInterfaceSubClass); }
373
374/* USB::Setting#bInterfaceProtocol */
375static VALUE rusb_setting_bInterfaceProtocol(VALUE v) { return INT2FIX(get_usb_interface_descriptor(v)->bInterfaceProtocol); }
376
377/* USB::Setting#iInterface */
378static VALUE rusb_setting_iInterface(VALUE v) { return INT2FIX(get_usb_interface_descriptor(v)->iInterface); }
379
380/* USB::Setting#endpoints */
381static VALUE
382rusb_setting_endpoints(VALUE v)
383{
384 struct usb_interface_descriptor *p = get_usb_interface_descriptor(v);
385 int i;
386 VALUE endpoint = rb_ary_new2(p->bNumEndpoints);
387 for (i = 0; i < p->bNumEndpoints; i++)
388 rb_ary_store(endpoint, i, rusb_endpoint_descriptor_make(&p->endpoint[i], v));
389 return endpoint;
390}
391
392/* -------- USB::Endpoint -------- */
393
394/* USB::Endpoint#revoked? */
395static VALUE
396rusb_endpoint_revoked_p(VALUE v)
397{
398 return RTEST(!check_usb_endpoint_descriptor(v));
399}
400
401/* USB::Endpoint#setting */
402static VALUE rusb_endpoint_setting(VALUE v) { return get_rusb_endpoint_descriptor(v)->parent; }
403
404/* USB::Endpoint#bLength */
405static VALUE rusb_endpoint_bLength(VALUE v) { return INT2FIX(get_usb_endpoint_descriptor(v)->bLength); }
406
407/* USB::Endpoint#bDescriptorType */
408static VALUE rusb_endpoint_bDescriptorType(VALUE v) { return INT2FIX(get_usb_endpoint_descriptor(v)->bDescriptorType); }
409
410/* USB::Endpoint#bEndpointAddress */
411static VALUE rusb_endpoint_bEndpointAddress(VALUE v) { return INT2FIX(get_usb_endpoint_descriptor(v)->bEndpointAddress); }
412
413/* USB::Endpoint#bmAttributes */
414static VALUE rusb_endpoint_bmAttributes(VALUE v) { return INT2FIX(get_usb_endpoint_descriptor(v)->bmAttributes); }
415
416/* USB::Endpoint#wMaxPacketSize */
417static VALUE rusb_endpoint_wMaxPacketSize(VALUE v) { return INT2FIX(get_usb_endpoint_descriptor(v)->wMaxPacketSize); }
418
419/* USB::Endpoint#bInterval */
420static VALUE rusb_endpoint_bInterval(VALUE v) { return INT2FIX(get_usb_endpoint_descriptor(v)->bInterval); }
421
422/* USB::Endpoint#bRefresh */
423static VALUE rusb_endpoint_bRefresh(VALUE v) { return INT2FIX(get_usb_endpoint_descriptor(v)->bRefresh); }
424
425/* USB::Endpoint#bSynchAddress */
426static VALUE rusb_endpoint_bSynchAddress(VALUE v) { return INT2FIX(get_usb_endpoint_descriptor(v)->bSynchAddress); }
427
428/* -------- USB::DevHandle -------- */
429
430static VALUE rb_cUSB_DevHandle;
431
432void rusb_devhandle_free(void *_h)
433{
434 usb_dev_handle *h = (usb_dev_handle *)_h;
435 if (h) usb_close(h);
436}
437
438static VALUE
439rusb_dev_handle_new(usb_dev_handle *h)
440{
441 return Data_Wrap_Struct(rb_cUSB_DevHandle, 0, rusb_devhandle_free, h);
442}
443
444static usb_dev_handle *check_usb_devhandle(VALUE v)
445{
446 Check_Type(v, T_DATA);
447 if (RDATA(v)->dfree != rusb_devhandle_free) {
448 rb_raise(rb_eTypeError, "wrong argument type %s (expected USB::DevHandle)",
449 rb_class2name(CLASS_OF(v)));
450 }
451 return DATA_PTR(v);
452}
453
454static usb_dev_handle *get_usb_devhandle(VALUE v)
455{
456 usb_dev_handle *p = check_usb_devhandle(v); \
457 if (!p) {
458 rb_raise(rb_eArgError, "closed USB::DevHandle");
459 }
460 return p;
461}
462
463static int check_usb_error(char *reason, int ret)
464{
465 if (ret < 0) {
466 errno = -ret;
467 rb_sys_fail(reason);
468 }
469 return ret;
470}
471
472/* USB::DevHandle#usb_close */
473static VALUE
474rusb_close(VALUE v)
475{
476 usb_dev_handle *p = get_usb_devhandle(v);
477 check_usb_error("usb_close", usb_close(p));
478 DATA_PTR(v) = NULL;
479 return Qnil;
480}
481
482/* USB::DevHandle#usb_set_configuration(configuration) */
483static VALUE
484rusb_set_configuration(VALUE v, VALUE configuration)
485{
486 usb_dev_handle *p = get_usb_devhandle(v);
487 int ret = usb_set_configuration(p, NUM2INT(configuration));
488 check_usb_error("usb_set_configuration", ret);
489 return Qnil;
490}
491
492/* USB::DevHandle#usb_set_altinterface(alternate) */
493static VALUE
494rusb_set_altinterface(VALUE v, VALUE alternate)
495{
496 usb_dev_handle *p = get_usb_devhandle(v);
497 int ret = usb_set_altinterface(p, NUM2INT(alternate));
498 check_usb_error("usb_set_altinterface", ret);
499 return Qnil;
500}
501
502/* USB::DevHandle#usb_clear_halt(endpoint) */
503static VALUE
504rusb_clear_halt(VALUE v, VALUE ep)
505{
506 usb_dev_handle *p = get_usb_devhandle(v);
507 int ret = usb_clear_halt(p, NUM2UINT(ep));
508 check_usb_error("usb_clear_halt", ret);
509 return Qnil;
510}
511
512/* USB::DevHandle#usb_reset */
513static VALUE
514rusb_reset(VALUE v)
515{
516 usb_dev_handle *p = get_usb_devhandle(v);
517 int ret = usb_reset(p);
518 check_usb_error("usb_reset", ret);
519 /* xxx: call usb_close? */
520<