GithubHelp home page GithubHelp logo

kylelemons / gousb Goto Github PK

View Code? Open in Web Editor NEW
95.0 5.0 38.0 3.25 MB

Idiomatic Go bindings for libusb-1.0

Home Page: http://godoc.org/github.com/kylelemons/gousb/usb

License: Apache License 2.0

Shell 0.11% Go 99.36% C 0.39% Smarty 0.14%

gousb's Introduction

Deprecated

This package was deprecated in favor of https://github.com/google/gousb.

This package will still receive bugfixes for reported issues, but it will no longer be expanded with new functionality.

Note that the new package is not a drop-in replacement, as some elements of the API have changed. The most important changes:

  • device configurations and interfaces now need to be explicitly claimed before an endpoint can be used.
  • InEndpoint and OutEndpoint are distinct types, with In supporting only read operations and Out supporting only write operations.
  • InEndpoint has a Stream functionality that allows for a buffered high-bandwidth data transfer.
  • all the details of USB representation are hidden behind meaningful types. It should no longer be necessary to use bitmasks for anything.
  • ListDevices is renamed to OpenDevices.

Introduction

Build Status GoDoc Coverage Status

The gousb package is an attempt at wrapping the libusb library into a Go-like binding.

Supported platforms include:

  • linux
  • darwin
  • windows

Contributing

Because I am a Google employee, contributing to this project will require signing the Google CLA. This is the same agreement that is required for contributing to Go itself, so if you have already filled it out for that, you needn't fill it out again. You will need to send me the email address that you used to sign the agreement so that I can verify that it is on file before I can accept pull requests.

Installation

Dependencies

You must first install libusb-1.0. This is pretty straightforward on linux and darwin. The cgo package should be able to find it if you install it in the default manner or use your distribution's package manager. How to tell cgo how to find one installed in a non-default place is beyond the scope of this README.

Note: If you are installing this on darwin, you will probably need to run fixlibusb_darwin.sh /usr/local/lib/libusb-1.0/libusb.h because of an LLVM incompatibility. It shouldn't break C programs, though I haven't tried it in anger.

Example: lsusb

The gousb project provides a simple but useful example: lsusb. This binary will list the USB devices connected to your system and various interesting tidbits about them, their configurations, endpoints, etc. To install it, run the following command:

go get -v github.com/kylelemons/gousb/lsusb

gousb

If you installed the lsusb example, both libraries below are already installed.

Installing the primary gousb package is really easy:

go get -v github.com/kylelemons/gousb/usb

There is also a usbid package that will not be installed by default by this command, but which provides useful information including the human-readable vendor and product codes for detected hardware. It's not installed by default and not linked into the usb package by default because it adds ~400kb to the resulting binary. If you want both, they can be installed thus:

go get -v github.com/kylelemons/gousb/usb{,id}

Notes for installation on Windows

You'll need:

Make sure the libusb-1.0.pc pkg-config file from libusb was installed and that the result of the pkg-config --cflags libusb-1.0 command shows the correct include path for installed libusb.

After that you can continue with instructions for lsusb/gousb above.

Documentation

The documentation can be viewed via local godoc or via the excellent godoc.org:

gousb's People

Contributors

krasin avatar kylelemons avatar nkovacs avatar nodtem66 avatar pjvds avatar stapelberg avatar vincentserpoul avatar zagrodzki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

gousb's Issues

Using with Homebrew's libusb

I'm not sure, but I'm guessing my problem relates to using Homebrew's libusb 1.0.19 on OS X. Here's what I get when trying to install lsusb:

$ cd ~/development/foss-projects/github.com/kylelemons/gousb
$ ./fixlibusb_darwin.sh /usr/local/include/libusb-1.0/libusb.h
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/c++/4.2.1
It looks like you've already run this script (/usr/local/include/libusb-1.0/libusb.h.orig exists)
$ go get -v github.com/kylelemons/gousb/lsusb
github.com/kylelemons/gousb/usb
# github.com/kylelemons/gousb/usb
../../../../go/src/github.com/kylelemons/gousb/usb/config.go:17:11: fatal error: 'libusb-1.0/libusb.h' file not found
 #include <libusb-1.0/libusb.h>
          ^
1 error generated.

Race condition when closing Context

Context.Close() closes the c.done channel, but does not wait for the goroutine created in NewContext to exit. This can result in libusb_handle_events_timeout_completed being called after libusb_exit and/or with ctx==nil.

One way around this is to simply have a sync.WaitGroup as part of the context.

Endpoint problem

I tried the new /google/gousb, I used to be able to do this:
epRead, err := dev.OpenEndpoint(1, 0, 0, uint8(1)|uint8(usb.ENDPOINT_DIR_IN))
epWrite, err := dev.OpenEndpoint(1, 0, 0, uint8(1)|uint8(usb.ENDPOINT_DIR_OUT))

Now with the new interface when I do this:
epRead, err := dev.intf.InEndpoint(1)
epWrite, err := dev.intf.OutEndpoint(1)

It gives me this error:
ep #1 OUT (address 0x01) bulk [64 bytes] is not an IN endpoint

Appveyor build

I'm trying to build a project that uses this library, and I need it to compile on windows.
Do you think it would be possible to add an appveyor build to this repo, so running on windows could be tested, and also give us some idea of how to build our own projects?

I did a choco install pkgconfiglite
but I'm completely lost when installing libusb. I have no idea where to put the headers, libs, etc.

Embedded libusb?

Requiring users to manually fetch and install dependent C libraries (libusb in this case) can often be a bit problematic, both because it may be non trivial as well as because it's a huge PITA, and makes the Go package non go-gettable and non self contained.

A nicer approach usually is to vendor in the C library into the Go codebase, and set up all the messy compilation/linker options from Go. Then the Go library itself would become beautifully self contained without any outside dependencies.

I was wondering whether you had any plans on doing such a thing, or whether you would be interested in contributions towards that end? I managed to fairly quickly do this integration on Linux on my machine, but I'd rather have the changes upstreamed opposed to maintaining a vendored copy in our repo (obviously because I don't want to constantly backport changes from upstream).

Tell me if this is something you'd like and I can send some PRs your way.

Writing or copying files to USB devices

Hi there,

I have the following range loop, I'm attempting to write a file output to each device. Is this possible?

for _, dev := range devs {
        // Once the device has been selected from ListDevices, it is opened
        // and can be interacted with.

        conf, err := dev.ActiveConfig()
        if err != nil {
            log.Fatalf("Cannot get active config: %s", err)
        }

        write, err := dev.OpenEndpoint(conf, uint8(0),
            uint8(0), uint8(2)|uint8(usb.ENDPOINT_DIR_OUT))
        if err != nil {
            log.Fatalf("Failed to open write endpoint: %s", err)
        }

        write.Write([]byte("test"))
}

xfer_callback panic

I recently ran into a few cases in which the channel in xfer_callback was either nil or already closed, causing a panic.

Looking at the code, I'm not sure the usage of the user_data member (which holds the done channel) is valid. According to CGO's documentation, C may not keep a copy of a Go pointer after the call returns, and it looks like the case here.

One workaround for this is to hold a mapping from IDs to usbTransfer pointers, and set user_data to the ID rather than to the done channel. xfer_callback can then retrieve the relevant usbTransfer pointer and close its done channel.

Segfault if more than one usb context created

Hi Kyle,

I have a code that does something like:

ctx := usb.NewContext()
... // scan devices
ctx.Close()
...
ctx := usb.NewContext()
... // bulk transfer requested, segfault received

It appears that libusb does not allow to access any libusb routines (including libusb_init), once libusb_exit is called. See http://libusb.sourceforge.net/api-1.0/group__lib.html

A soft reproducer that does not require an actual device and an example stack trace from a real program can be found here: https://gist.github.com/krasin/6228396

Two questions:

  1. Is my understanding correct and the users are supposed to have one usb.Context that spans for the whole program life?
  2. If yes, would you like to consider an API change, to make a mistake like I did impossible? At least, only the first usb.NewContext should succeed. All successive calls must return an error ("usb.NewContext may be called just once per program run" or something like that)

libusbx

Hi,
In order to test gousb with libusbx.org, I made small changes so that gousb uses my compiled-from-git libusbx. lsusb worked fine. Then I did:
go test -covermode count -coverprofile c.txt gousb/usb
and some tests failed.
Did you get a chance to try libusbx with gousb?

read systematic timeouts

When I try to read from my device, I always get the following error:

[IO Connect Endpoint 1 IN  interrupt - unsynchronized data [64 0]]
2017/02/18 00:18:50 bulk: interrupt failed: libusb: transfer timed out
2017/02/18 00:18:50 read: libusb: transfer timed out

I tried with different usb devices, same issue.
I successfully manage to read and write the device with the node-hid library, so the devices are not faulty

I use the following code to read:

	rep := make([]byte, 64)
	num, err := epIn.Read(rep)
	if err != nil {
		log.Fatalf("read: %s", err)
	}
	log.Printf("read %d bytes: %v\n", num, rep)

Any idea?
Is it me not RTFM or an potential issue with the lib?

Partial data on timeouts

Hi,

In case an error is returned from libusb_bulk_transfer or libusb_interrupt_transfer, cnt is disregarded and 0 is returned. However, partial data may have been transferred in case of a timeout error. From libusb's documentation:
Also check transferred when dealing with a timeout error code. libusb may have to split your transfer into a number of chunks to satisfy underlying O/S requirements, meaning that the timeout may expire after the first few chunks have completed. libusb is careful not to lose any data that may have been transferred; do not assume that timeout conditions indicate a complete lack of I/O.

Thanks,
Ido.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.