Example #1
0
File: usb.go Project: hanwen/usb
// Set the active configuration for a device. The argument should be
// a ConfigurationValue, as given in the ConfigDescriptor.
func (h *DeviceHandle) SetConfiguration(c byte) error {
	err := C.libusb_set_configuration(h.me(), C.int(c))
	return toErr(err)
}
Example #2
0
func (d *Device) OpenEndpoint(conf, iface, setup, epoint uint8) (Endpoint, error) {
	end := &endpoint{
		Device: d,
	}

	var setAlternate bool
	for _, c := range d.Configs {
		if c.Config != conf {
			continue
		}
		debug.Printf("found conf: %#v\n", c)
		for _, i := range c.Interfaces {
			if i.Number != iface {
				continue
			}
			debug.Printf("found iface: %#v\n", i)
			for i, s := range i.Setups {
				if s.Alternate != setup {
					continue
				}
				setAlternate = i != 0

				debug.Printf("found setup: %#v [default: %v]\n", s, !setAlternate)
				for _, e := range s.Endpoints {
					debug.Printf("ep %02x search: %#v\n", epoint, s)
					if e.Address != epoint {
						continue
					}
					end.InterfaceSetup = s
					end.EndpointInfo = e
					switch tt := TransferType(e.Attributes) & TRANSFER_TYPE_MASK; tt {
					case TRANSFER_TYPE_BULK:
						end.xfer = bulk_xfer
					case TRANSFER_TYPE_INTERRUPT:
						end.xfer = interrupt_xfer
					case TRANSFER_TYPE_ISOCHRONOUS:
						end.xfer = isochronous_xfer
					default:
						return nil, fmt.Errorf("usb: %s transfer is unsupported", tt)
					}
					goto found
				}
				return nil, fmt.Errorf("usb: unknown endpoint %02x", epoint)
			}
			return nil, fmt.Errorf("usb: unknown setup %02x", setup)
		}
		return nil, fmt.Errorf("usb: unknown interface %02x", iface)
	}
	return nil, fmt.Errorf("usb: unknown configuration %02x", conf)

found:

	// Set the configuration
	var activeConf C.int
	if errno := C.libusb_get_configuration(d.handle, &activeConf); errno < 0 {
		return nil, fmt.Errorf("usb: getcfg: %s", usbError(errno))
	}
	if int(activeConf) != int(conf) {
		if errno := C.libusb_set_configuration(d.handle, C.int(conf)); errno < 0 {
			return nil, fmt.Errorf("usb: setcfg: %s", usbError(errno))
		}
	}

	// Claim the interface
	if errno := C.libusb_claim_interface(d.handle, C.int(iface)); errno < 0 {
		return nil, fmt.Errorf("usb: claim: %s", usbError(errno))
	}

	// Increment the claim count
	d.lock.Lock()
	d.claimed[iface]++
	d.lock.Unlock() // unlock immediately because the next calls may block

	// Choose the alternate
	if setAlternate {
		if errno := C.libusb_set_interface_alt_setting(d.handle, C.int(iface), C.int(setup)); errno < 0 {
			debug.Printf("altsetting error: %s", usbError(errno))
			return nil, fmt.Errorf("usb: setalt: %s", usbError(errno))
		}
	}

	return end, nil
}
Example #3
0
func (d *Device) OpenEndpoint(conf, iface, setup, epoint uint8) (Endpoint, error) {
	end := &endpoint{
		Device: d,
	}

	for _, c := range d.Configs {
		if c.Config != conf {
			continue
		}
		fmt.Printf("found conf: %#v\n", c)
		for _, i := range c.Interfaces {
			if i.Number != iface {
				continue
			}
			fmt.Printf("found iface: %#v\n", i)
			for _, s := range i.Setups {
				if s.Alternate != setup {
					continue
				}
				fmt.Printf("found setup: %#v\n", s)
				for _, e := range s.Endpoints {
					fmt.Printf("ep %02x search: %#v\n", epoint, s)
					if e.Address != epoint {
						continue
					}
					end.InterfaceSetup = s
					end.EndpointInfo = e
					switch tt := TransferType(e.Attributes) & TRANSFER_TYPE_MASK; tt {
					case TRANSFER_TYPE_BULK:
						end.xfer = bulk_xfer
					case TRANSFER_TYPE_INTERRUPT:
						end.xfer = interrupt_xfer
					case TRANSFER_TYPE_ISOCHRONOUS:
						end.xfer = isochronous_xfer
					default:
						return nil, fmt.Errorf("usb: %s transfer is unsupported", tt)
					}
					goto found
				}
				return nil, fmt.Errorf("usb: unknown endpoint %02x", epoint)
			}
			return nil, fmt.Errorf("usb: unknown setup %02x", setup)
		}
		return nil, fmt.Errorf("usb: unknown interface %02x", iface)
	}
	return nil, fmt.Errorf("usb: unknown configuration %02x", conf)

found:
	// Increment the claim count
	d.lock.Lock()
	defer d.lock.Unlock()

	// Only claim when needed
	if d.claimed[iface] <= 0 {
		// Set the configuration
		if errno := C.libusb_set_configuration(d.handle, C.int(conf)); errno < 0 {
			return nil, fmt.Errorf("usb: setcfg: %s", usbError(errno))
		}

		fmt.Printf("claiming interface %v", iface)
		// Claim the interface
		if errno := C.libusb_claim_interface(d.handle, C.int(iface)); errno < 0 {
			return nil, fmt.Errorf("usb: claim: %s", usbError(errno))

			d.claimed[iface]++
		}

		// Choose the alternate
		// if errno := C.libusb_set_interface_alt_setting(d.handle, C.int(iface), C.int(setup)); errno < 0 {
		// 	// This doesn't seem to work on Mac OS X, it works on my Ubuntu machine.
		// 	log.Printf("ignoring altsetting error: %s", usbError(errno))
		// }
	}

	return end, nil
}
Example #4
0
// SetConfig attempts to change the active configuration.
// The cfg provided is the config id (not the index) of the configuration to set,
// which corresponds to the ConfigInfo.Config field.
func (d *Device) SetConfig(cfg uint8) error {
	if errno := C.libusb_set_configuration(d.handle, C.int(cfg)); errno < 0 {
		return usbError(errno)
	}
	return nil
}
Example #5
0
File: usb.go Project: thequux/gousb
// Set the active configuration
func (h *DeviceHandle) SetConfiguration(config int) *UsbError {
	return returnUsbError(C.libusb_set_configuration(h.handle, C.int(config)))
}