xbee: add timeout to at command

This commit is contained in:
saji 2023-05-10 19:02:57 -05:00
parent 8740fafca2
commit d31b80a2fd
2 changed files with 38 additions and 11 deletions

View file

@ -136,4 +136,11 @@ func encodeRemoteATCommand(at ATCmd, idx uint8, queued bool, destination uint64)
// let's actually define some AT commands now. // 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
}

View file

@ -18,6 +18,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"time"
"go.bug.st/serial" "go.bug.st/serial"
"golang.org/x/exp/slog" "golang.org/x/exp/slog"
@ -29,16 +30,14 @@ import (
// XBeeAddr is an XBee device address. // XBeeAddr is an XBee device address.
type XBeeAddr uint64 type XBeeAddr uint64
func (addr XBeeAddr)String() string { func (addr XBeeAddr) String() string {
return fmt.Sprintf("%X", uint64(addr)) return fmt.Sprintf("%X", uint64(addr))
} }
func (addr XBeeAddr) Network() string { func (addr XBeeAddr) Network() string {
return "xbee" return "xbee"
} }
// Session represents a connection to a locally-attached XBee. The connection can be through // 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. // 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. // 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. // internal function used by Conn to write data to a specific address.
func (sess *Session) writeAddr(p []byte, dest uint64) (n int, err error) { 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. // 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 { if err != nil {
return nil, err return nil, err
} }
@ -244,7 +248,6 @@ func (sess *Session) Close() error {
return sess.ioDev.Close() return sess.ioDev.Close()
} }
func (sess *Session) LocalAddr() XBeeAddr { func (sess *Session) LocalAddr() XBeeAddr {
// TODO: should we get this once at the start? and then just store it? // TODO: should we get this once at the start? and then just store it?
sh, _ := sess.ATCommand([2]rune{'S', 'H'}, nil, false) sh, _ := sess.ATCommand([2]rune{'S', 'H'}, nil, false)
@ -258,17 +261,34 @@ func (sess *Session) RemoteAddr() XBeeAddr {
return 0xFFFF 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 // 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 // contact one Xbee for point-to-point communications. This enables ACK packets
// for reliable transmission. // for reliable transmission.
type Conn struct { type Conn struct {
parent *Session parent *Session
log slog.Logger addr XBeeAddr
addr uint64
} }
func (c *Conn) Write(p []byte) (int, error) { 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
} }
/* /*