Closed cmaglie closed 7 years ago
Moreover I don't know if the all the constants in serial_openbsd.go
are correct, something to check with C headers file on a live system.
Great, thanks. I'll give it a try on Monday.
If it's any help before I get to it, you can probably check out the headers in question without doing an install by looking in the release sets: https://ftp4.usa.openbsd.org/pub/OpenBSD/6.0/amd64/ . Presumably either base60.tgz or comp60.tgz would have what you need.
Thanks, I gave it a spin this morning. I first updated my code to use your OpenBSD branch and tested on OS X with the tool attached - it worked perfectly. When compiling on OpenBSD and moving the cable over there for testing, I seem to see similar behavior I saw previously with tarm/serial: the first run seems to go successfully, followed by returning an ASCII linefeed (10) on all successive attempts.
For reference: the tool I'm using, when sent the status command (two bytes), will return one byte with either an ASCII 0 to signify off, and an ASCII 1 to signify on. The only time I've ever seen the linefeed is when debugging on OpenBSD.
Here's something sample code slimmed down:
func ExitOnErr(msg string, err error) {
if err != nil {
log.Fatalf("%v - %v", msg, err)
}
}
func RunCmd(line string, id byte) {
m := &serial.Mode{
BaudRate: 115200,
}
s, err := serial.Open(line, m)
if err != nil {
ExitOnErr("Open serial port failure", err)
}
_, err = s.Write([]byte{254, id})
if err != nil {
ExitOnErr("Serial port write failure", err)
}
buf := make([]byte, 2)
n, err := s.Read(buf)
fmt.Printf("n: %d\n", n)
if err != nil {
ExitOnErr("Serial port read failure", err)
}
err = s.Close()
if err != nil {
ExitOnErr("Serial port close failure", err)
}
fmt.Printf("%v\n", buf[:n])
}
$ ./doorctl -r 1 -c status
n: 1
[1]
$ ./doorctl -r 1 -c status
n: 1
[10]
$ ./doorctl -r 1 -c status
n: 1
[10]
Let me know if more OpenBSD-specific info might help. Thanks.
It turns out the cause of the behavior I was seeing on OpenBSD was needing to explicitly flush the USB/serial concoction first: https://github.com/tarm/serial/blob/master/serial_posix.go#L189
Not sure if go-serial has a semantic for that, I didn't see it in the Godoc. Thanks for the effort thus far!
@bconway
I've updated the PR, now there are two new methods ResetInputBuffer
and ResetOutputBuffer
, courtesy of @albenik ;-). Would you like to try it?
the first run seems to go successfully, followed by returning an ASCII linefeed (10) on all successive attempts.
I'm wondering where this LF comes from? Is it part of the protocol? If yes you should read it before exiting to "consume" it, if not it would be nice to understand where it comes from.
Thanks for the heads up. I spoke with the vendor and verified that their device never sends an LF. I'm thinking this may be part of either OpenBSD's handling of serial port buffers or something in their FTDI driver, though I'm not currently in a position to dig too deeply into that. I also haven't tried it on Linux hardware for comparison, as I don't have much (physical) on hand.
I did refactor the code earlier and verified that if I try to read more than the LF after sending the command, I only end up blocking and waiting forever for another response that never arrives (though admittedly I didn't try reading first to see if the LF was already present to clear it and then send the command - the flush seemed like a better work-around).
See #27
This is just a tentative, I don't have a OpenBSD box to try this out.
The Termios struct in OpenBSD is:
where
Ispeed
andOspeed
are, incredibly, defined asint32
instead ofuint32
. This may not be a problem in C where casts are implicit but it is in golang where a compiler error occurs. To fix this I had to add a functionfunc toTermiosSpeedType(speed uint32) int32
to convert from Cflag type to I/Ospeed type./cc @bconway