diff --git a/README.markdown b/README.markdown index 748fe6f..3be8dfa 100644 --- a/README.markdown +++ b/README.markdown @@ -6,3 +6,11 @@ some preliminary work on `SUBSCRIBE` support from [shelby]: http://tools.ietf.org/html/draft-shelby-core-coap-01 [coap]: http://tools.ietf.org/html/rfc7252 + +## Differences from original `dustin/go-coap` + +1. Added minor helper function to populate URI options. +2. Added configurable receive timeout in backgwards compatible way. Changed `ResponseTimeout` variable to `DefaultResponseTimeout` to emphasise its role change and to be able to track down its usage within package. +3. Example programs package references have been changed from `dustin/go-coap` to `Kulak/go-coap`. + +Motivation for all this change: need to support existing application functionality. \ No newline at end of file diff --git a/client.go b/client.go index 95cf03f..c6ec48b 100644 --- a/client.go +++ b/client.go @@ -6,9 +6,9 @@ import ( ) const ( - // ResponseTimeout is the amount of time to wait for a + // DefaultResponseTimeout is the amount of time to wait for a // response. - ResponseTimeout = time.Second * 2 + DefaultResponseTimeout = time.Second * 2 // ResponseRandomFactor is a multiplier for response backoff. ResponseRandomFactor = 1.5 // MaxRetransmit is the maximum number of times a message will @@ -18,12 +18,18 @@ const ( // Conn is a CoAP client connection. type Conn struct { - conn *net.UDPConn - buf []byte + conn *net.UDPConn + buf []byte + responseTimeout time.Duration } // Dial connects a CoAP client. func Dial(n, addr string) (*Conn, error) { + return DialWithTimeout(n, addr, DefaultResponseTimeout) +} + +// DialWithTimeout provides control of response timeout. +func DialWithTimeout(n, addr string, responseTimeout time.Duration) (*Conn, error) { uaddr, err := net.ResolveUDPAddr(n, addr) if err != nil { return nil, err @@ -34,7 +40,7 @@ func Dial(n, addr string) (*Conn, error) { return nil, err } - return &Conn{s, make([]byte, maxPktLen)}, nil + return &Conn{s, make([]byte, maxPktLen), responseTimeout}, nil } // Send a message. Get a response if there is one. @@ -48,7 +54,7 @@ func (c *Conn) Send(req Message) (*Message, error) { return nil, nil } - rv, err := Receive(c.conn, c.buf) + rv, err := Receive(c.conn, c.buf, c.responseTimeout) if err != nil { return nil, err } @@ -58,7 +64,7 @@ func (c *Conn) Send(req Message) (*Message, error) { // Receive a message. func (c *Conn) Receive() (*Message, error) { - rv, err := Receive(c.conn, c.buf) + rv, err := Receive(c.conn, c.buf, c.responseTimeout) if err != nil { return nil, err } diff --git a/client_test.go b/client_test.go new file mode 100644 index 0000000..bbba847 --- /dev/null +++ b/client_test.go @@ -0,0 +1,51 @@ +package coap_test + +import ( + "testing" + + coap "github.com/Kulak/go-coap" + + "time" + + "math" +) + +func TestTimeoutDefaults(t *testing.T) { + testTimeout(t, coap.DefaultResponseTimeout) +} + +func TestTimeout6sec(t *testing.T) { + testTimeout(t, 6*time.Second) +} + +func testTimeout(t *testing.T, expectedTimeout time.Duration) { + // send to IP address without CoAP EP + req := coap.Message{ + Type: coap.Confirmable, + Code: coap.GET, + MessageID: 12345, + Payload: []byte("undeliverable"), + } + req.SetOption(coap.MaxAge, 3) + req.SetPathString("/some/path") + + c, err := coap.DialWithTimeout("udp", "192.168.254.254:5683", expectedTimeout) + if err != nil { + t.Errorf("Error dialing: %v", err) + return + } + + start := time.Now() + _, err = c.Send(req) + end := time.Now() + timeout := end.Sub(start) + if err != nil { + // that's not going to get printed unless test fails + t.Logf("Error sending request: %v", err) + if math.Abs(timeout.Seconds()-expectedTimeout.Seconds()) > 0.1 { + t.Fatalf("Expected timeout %v, got %v", expectedTimeout, timeout) + } + return + } + t.Fatal("Response shall timeout.") +} diff --git a/example/client/goap_client.go b/example/client/goap_client.go index 2dcaa39..994416d 100644 --- a/example/client/goap_client.go +++ b/example/client/goap_client.go @@ -3,7 +3,7 @@ package main import ( "log" - "github.com/dustin/go-coap" + "github.com/Kulak/go-coap" ) func main() { diff --git a/example/obsclient/obsclient.go b/example/obsclient/obsclient.go index 77507f9..71a5cb5 100644 --- a/example/obsclient/obsclient.go +++ b/example/obsclient/obsclient.go @@ -3,7 +3,7 @@ package main import ( "log" - "github.com/dustin/go-coap" + "github.com/Kulak/go-coap" ) func main() { diff --git a/example/obsserver/obsserver.go b/example/obsserver/obsserver.go index 42736f6..8792910 100644 --- a/example/obsserver/obsserver.go +++ b/example/obsserver/obsserver.go @@ -6,7 +6,7 @@ import ( "net" "time" - "github.com/dustin/go-coap" + "github.com/Kulak/go-coap" ) func periodicTransmitter(l *net.UDPConn, a *net.UDPAddr, m *coap.Message) { diff --git a/example/server/coap_server.go b/example/server/coap_server.go index 84dfd7a..b35b16c 100644 --- a/example/server/coap_server.go +++ b/example/server/coap_server.go @@ -4,7 +4,7 @@ import ( "log" "net" - "github.com/dustin/go-coap" + "github.com/Kulak/go-coap" ) func main() { diff --git a/server.go b/server.go index 945af2c..0325c24 100644 --- a/server.go +++ b/server.go @@ -57,8 +57,8 @@ func Transmit(l *net.UDPConn, a *net.UDPAddr, m Message) error { } // Receive a message. -func Receive(l *net.UDPConn, buf []byte) (Message, error) { - l.SetReadDeadline(time.Now().Add(ResponseTimeout)) +func Receive(l *net.UDPConn, buf []byte, responseTimeout time.Duration) (Message, error) { + l.SetReadDeadline(time.Now().Add(responseTimeout)) nr, _, err := l.ReadFromUDP(buf) if err != nil {