From d31b80a2fdcb6cfca3180585664d3b45c6d7da48 Mon Sep 17 00:00:00 2001 From: saji Date: Wed, 10 May 2023 19:02:57 -0500 Subject: [PATCH] xbee: add timeout to at command --- xbee/at.go | 9 ++++++++- xbee/session.go | 40 ++++++++++++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/xbee/at.go b/xbee/at.go index b2fb529..dc000eb 100644 --- a/xbee/at.go +++ b/xbee/at.go @@ -136,4 +136,11 @@ func encodeRemoteATCommand(at ATCmd, idx uint8, queued bool, destination uint64) // let's actually define some AT commands now. -// TODO: should we just use a function. +type NetworkDevice struct { + Addr XBeeAddr + Identifier string + DeviceType byte + ProfileNum uint16 + MfrId uint16 + RSSI byte +} diff --git a/xbee/session.go b/xbee/session.go index 73605df..b64c046 100644 --- a/xbee/session.go +++ b/xbee/session.go @@ -18,6 +18,7 @@ import ( "strconv" "strings" "sync" + "time" "go.bug.st/serial" "golang.org/x/exp/slog" @@ -29,16 +30,14 @@ import ( // XBeeAddr is an XBee device address. type XBeeAddr uint64 -func (addr XBeeAddr)String() string { +func (addr XBeeAddr) String() string { return fmt.Sprintf("%X", uint64(addr)) } - func (addr XBeeAddr) Network() string { return "xbee" } - // Session represents a connection to a locally-attached XBee. The connection can be through // serial/USB or TCP/IP depending on what is supported by the device. // Session implements the net.Conn interface, so it can be used anywhere a net.Conn can be used. @@ -151,7 +150,6 @@ func (sess *Session) Write(p []byte) (int, error) { } - // internal function used by Conn to write data to a specific address. func (sess *Session) writeAddr(p []byte, dest uint64) (n int, err error) { @@ -220,7 +218,13 @@ func (sess *Session) ATCommand(cmd [2]rune, data []byte, queued bool) ([]byte, e // TODO: add timeout. - resp, err := ParseATCmdResponse(<-ch) + var respBytes []byte + select { + case respBytes = <-ch: + case <-time.After(1 * time.Second): + return nil, errors.New("timeout waiting for response frame") + } + resp, err := ParseATCmdResponse(respBytes) if err != nil { return nil, err } @@ -244,31 +248,47 @@ func (sess *Session) Close() error { return sess.ioDev.Close() } - func (sess *Session) LocalAddr() XBeeAddr { // TODO: should we get this once at the start? and then just store it? sh, _ := sess.ATCommand([2]rune{'S', 'H'}, nil, false) sl, _ := sess.ATCommand([2]rune{'S', 'L'}, nil, false) addr := uint64(binary.BigEndian.Uint32(sh)) << 32 & uint64(binary.BigEndian.Uint32(sl)) - return XBeeAddr(addr) + return XBeeAddr(addr) } func (sess *Session) RemoteAddr() XBeeAddr { return 0xFFFF } +/* +The session implements a io.Writer and io.Reader, but does not +have a way of connecting to a specific XBee by default. To do this, we would +need to either pass an address to the write and read methods (breaking io.ReadWriter), +or add another command. Rather than do that, we can make a "Conn" class, which represents +a single connection to a device on the network. + +*/ + // Conn is a connection to a specific remote XBee. Conn allows for the user to // contact one Xbee for point-to-point communications. This enables ACK packets // for reliable transmission. type Conn struct { parent *Session - log slog.Logger - addr uint64 + addr XBeeAddr } func (c *Conn) Write(p []byte) (int, error) { - return c.parent.writeAddr(p, c.addr) + return c.parent.writeAddr(p, uint64(c.addr)) +} + +func (c *Conn) Close() error { + + return nil +} + +func (c *Conn) GetRSSI() int { + return 0 } /*