I'm new to the go programming language. Trying to use gousb to access an epson receipt printer.
So I took some example code from the repo and repurposed it a bit just to validate that I could access the printer.
I can see the printer and enumerate the endpoints. I receive this output:
Printer found: 020.005 Receipt Printer M129C/TM-T70 (Seiko Epson Corp.)
Length of device array: 1
[0] 020.005 04b8 - 0202
[0] Config 01 [1]
[0]--------------[0]
[0] Interface 00 Setup 00 [0]
Vendor Specific Class (Vendor Specific Subclass)
[0] [1] Endpoint #1 OUT bulk - unsynchronized data [64 0] [OUT]
[1] [130] Endpoint #2 IN bulk - unsynchronized data [64 0] [IN]
My understanding is that if I want to write something to the printer, I would open the endpoint that corresponds to [OUT]. Aand this is where my trouble begins.
If I use outEP, err := thePrinter.OpenEndpoint(1,0,0,0)
, I receive a seg fault. If I pass a 1, gousb assumes I'm trying to access endpoint 130 [IN].
So.. What do I pass as the endpoint ID to access the OUT endpoint?
Code:
package main
import (
"fmt"
"strings"
"github.com/kylelemons/gousb/usb"
"github.com/kylelemons/gousb/usbid"
"C"
)
func main() {
ctx := usb.NewContext()
defer ctx.Close()
ctx.Debug(3)
var thePrinter *usb.Device
devs, _ := ctx.ListDevices(func(desc *usb.Descriptor) bool {
if strings.Contains(usbid.Describe(desc), "Seiko Epson Corp") {
fmt.Printf("Printer found: %03d.%03d %s
", desc.Bus, desc.Address, usbid.Describe(desc))
return true
} else {
return false
}
})
fmt.Printf("Length of device array: %d
", len(devs))
for x, dev := range devs {
fmt.Printf("[%d] %03d.%03d %s - %s
", x, dev.Bus, dev.Address, dev.Vendor, dev.Product)
for i, cfg := range dev.Configs {
// This loop just uses more of the built-in and usbid pretty printing to list
// the USB devices.
fmt.Printf(" [%d] %s [%d]
", i, cfg, cfg.Config)
for j, alt := range cfg.Interfaces {
fmt.Printf(" [%d]--------------[%d]
", j, alt.Number)
for k, iface := range alt.Setups {
fmt.Printf(" [%d] %s [%d]
", k, iface, iface.Number)
fmt.Printf(" %s
", usbid.Classify(iface))
for l, end := range iface.Endpoints {
fmt.Printf(" [%d] [%d] %s [%s]
", l, end.Address, end, end.Direction() )
}
}
}
fmt.Printf(" --------------
")
}
thePrinter=dev
}
outEP, err := thePrinter.OpenEndpoint(1,0,0,1)
fmt.Printf("OpenEndpoint Err: [%s]
", err)
fmt.Printf("direction: [%s] %d
", outEP.Info().Direction(), outEP.Info().Address)
message := []byte("hi there!
")
_, outerr := outEP.Write(message)
fmt.Printf("write Err: [%s]", outerr)
}
EDIT: I was asked to examine the error returned by OpenEndpoint prior to looking at the value of the endpoint. Here is what was returned (it was nil)
OpenEndpoint Err: [%!s(<nil>)]
direction: [IN] 130
OpenEndpoint Err: [%!s(<nil>)]
libusb: warning [libusb_exit] application left some devices open
write Err: [usb: write: not an OUT endpoint]
[Finished in 1.512s]
This is what I receive when I send an endpoint number of zero:
OpenEndpoint Err: [usb: unknown endpoint 00]
libusb: warning [libusb_exit] application left some devices open
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x41e94c4]
goroutine 1 [running]:
main.main()
/Users/.../go/src/github.com/deltasonic/epson/main.go:63 +0xcb4
exit status 2
[Finished in 0.817s]
EDIT:
I'm attempting this on a mac, Mac OS 10.12.