Documentation ¶
Index ¶
- Constants
- Variables
- func SetLogger(logger logrus.FieldLogger)
- func SetOnSerialPortOpenHandler(cb serialPortCb)
- func ValidMethod(method string) bool
- type Client
- func (c *Client) CancelObserve(response *Response) (*Response, error)
- func (c *Client) Do(req *Request) (res *Response, err error)
- func (c *Client) Get(url string) (*Response, error)
- func (c *Client) Observe(url string) (*Response, error)
- func (c *Client) Ping(host string) (*Response, error)
- func (c *Client) Post(url string, bodyType uint16, body io.Reader) (*Response, error)
- type Connection
- type CountingTokenGenerator
- type Interaction
- func (ia *Interaction) Close()
- func (ia *Interaction) Closed() bool
- func (ia *Interaction) HandleMessage(msg *coapmsg.Message)
- func (ia *Interaction) IsObserving() bool
- func (ia *Interaction) RoundTrip(ctx context.Context, reqMsg *coapmsg.Message) (resMsg *coapmsg.Message, err error)
- func (ia *Interaction) Token() Token
- type InteractionStore
- type Interactions
- type MessageId
- type NotifyFunc
- type PacketReader
- type PacketWriter
- type Parity
- type RandomTokenGenerator
- type Request
- type Response
- type RoundTripper
- type SafeBuffer
- func (b *SafeBuffer) Bytes() []byte
- func (b *SafeBuffer) Cap() int
- func (b *SafeBuffer) Grow(n int)
- func (b *SafeBuffer) Len() int
- func (b *SafeBuffer) Next(n int) []byte
- func (b *SafeBuffer) Read(p []byte) (n int, err error)
- func (b *SafeBuffer) ReadByte() (c byte, err error)
- func (b *SafeBuffer) ReadBytes(delim byte) (line []byte, err error)
- func (b *SafeBuffer) ReadFrom(r io.Reader) (n int64, err error)
- func (b *SafeBuffer) ReadRune() (r rune, size int, err error)
- func (b *SafeBuffer) ReadString(delim byte) (line string, err error)
- func (b *SafeBuffer) Reset()
- func (b *SafeBuffer) String() string
- func (b *SafeBuffer) Truncate(n int)
- func (b *SafeBuffer) UnreadByte() error
- func (b *SafeBuffer) UnreadRune() error
- func (b *SafeBuffer) Write(p []byte) (n int, err error)
- func (b *SafeBuffer) WriteByte(c byte) error
- func (b *SafeBuffer) WriteRune(r rune) (n int, err error)
- func (b *SafeBuffer) WriteString(s string) (n int, err error)
- func (b *SafeBuffer) WriteTo(w io.Writer) (n int64, err error)
- type SerialConnecter
- type SerialMode
- type SerialPort
- type SlipMuxReader
- type SlipMuxWriter
- type StopBits
- type Token
- type TokenGenerator
- type Transport
- type TransportUart
- type UartConnector
- type UartParams
Constants ¶
const ACK_RANDOM_FACTOR = 1.5
const MAX_RETRANSMIT = 4
const NSTART = 5 // Default in CoAP Spec is 1. But we do support more.
const OBSERVE_TIMEOUT = 256 * time.Second
Maximum length of an observe due to the RFC
const POSTPONED_RESPONSE_TIMEOUT = 30 * time.Second // How long to wait for a CON after we got an non-piggyback ACK
const UartScheme = "coap+uart"
Variables ¶
var AckTimeout = 10 * time.Second // Default 2 Seconds
var DefaultClient = NewClient()
DefaultClient is the default Client and is used by Get, Head, and Post.
var DefaultUartParams = UartParams{ Baud: 115200, Parity: ParityNone, StopBits: Stop1, DataBits: 8, InitialDTR: true, InitialRTS: false, }
var ERROR_READ_ACK = "Failed to read ACK"
var ERR_CONNECTION_CLOSED = errors.New("Connection is closed")
var PingOpenConnectionsInterval = 0 * time.Second
var READ_MESSAGE_CHAN_CLOSED = errors.New("Receive channel closed")
var READ_MESSAGE_CTX_DONE = errors.New("Read timeout")
var SlipMuxLogDiagnostic bool
var UartFlushOnRead = false
var UartKeepAliveInterval = 30 * time.Second
UartKeepAliveInterval defines how often the serial port is reopened. Set to 0 to disable reopening.
var UartUseSlipMux = false
UartUseSlipMux can be set to true to use SlipMux instead of SLIP
Functions ¶
func SetLogger ¶
func SetLogger(logger logrus.FieldLogger)
func SetOnSerialPortOpenHandler ¶
func SetOnSerialPortOpenHandler(cb serialPortCb)
SetOnSerialPortOpenHandler allows to set a callback that is called when ever a serial port is opened it allows e.g. to adjust RTS and DTR lines, flush buffers or just get a reference to the port
func ValidMethod ¶
Types ¶
type Client ¶
type Client struct { // Transport specifies the mechanism by which individual // CoAP requests are made. // If nil, DefaultTransport is used. Transport RoundTripper // Timeout specifies a time limit for requests made by this // Client. The timeout includes connection time, any // redirects, and reading the response body. The timer remains // running after Get, Head, Post, or Do return and will // interrupt reading of the Response.Body. // // A Timeout of zero means no timeout. // // The Client cancels requests to the underlying Transport // using the Request.Cancel mechanism. Requests passed // to Client.Do may still set Request.Cancel; both will // cancel the request. // // For compatibility, the Client will also use the deprecated // CancelRequest method on Transport if found. New // RoundTripper implementations should use Request.Cancel // instead of implementing CancelRequest. Timeout time.Duration // CoAP spcifies the constant NSTART (default = 1) to limit // the amount of parallel requests. 0 = no limit. // The default client has a value of 1 as proposed by the RFC. // For an UART connection only 1 parallel request is supported. MaxParallelRequests int32 // contains filtered or unexported fields }
A Client is an HTTP client. Its zero value (DefaultClient) is a usable client that uses DefaultTransport.
The Client's Transport typically has internal state (cached TCP connections), so Clients should be reused instead of created as needed. Clients are safe for concurrent use by multiple goroutines.
A Client is higher-level than a RoundTripper (such as Transport) and additionally handles CoAP details such parallel request limit
func (*Client) CancelObserve ¶
CancelObserve tells the server to stop sending Notifications about the endpoint related to the given response.
func (*Client) Get ¶
Get issues a GET to the specified URL.
When err is nil, resp always contains a non-nil resp.Body. Caller should close resp.Body when done reading from it.
To make a request with custom options, use NewRequest and DefaultClient.Do.
func (*Client) Observe ¶
Reserve issues a CoAP Get request with the observe option set.
In the response object the "Next" channel is set and can be used to receive the next response. calling "Close" on the response will stop the observation and notifies the server.
func (*Client) Ping ¶
Ping issues a CoAP Ping to the specified URL. Which is effectively and empty CON message that will be answered with RST
Host should be only scheme + hostname, no URL query to produce smaller ping messages
type Connection ¶
type Connection interface { PacketReader PacketWriter InteractionStore // Starts a loop that reads packets and forwards them to interactions Open() error Close() error Closed() bool Name() string }
Connection represents an interface to identify a CoAP connection which might be reused between requests. e.g. for Observe we have to listen for relevant updates.
type CountingTokenGenerator ¶
type CountingTokenGenerator struct {
// contains filtered or unexported fields
}
Mainly used for tests, uses 1 Byte tokens that simply count up
func (*CountingTokenGenerator) NextToken ¶
func (t *CountingTokenGenerator) NextToken() []byte
type Interaction ¶
type Interaction struct { // CancelObserve will stop the interaction to listen for Notifications StopListenForNotifications context.CancelFunc // Channel to hand over raw coap messages from notification updates // to the underlying transport where they can be converted into response structs NotificationCh chan *coapmsg.Message // contains filtered or unexported fields }
Interaction tracks one interaction between a CoAP client and Server. The Interaction is created with a request and ends with a response. An interaction is bound to a CoAP Token.
For observe multiple requests (register, deregister) and responses (Notifies) might belong to a single interaction
func (*Interaction) Close ¶
func (ia *Interaction) Close()
func (*Interaction) Closed ¶
func (ia *Interaction) Closed() bool
func (*Interaction) HandleMessage ¶
func (ia *Interaction) HandleMessage(msg *coapmsg.Message)
func (*Interaction) IsObserving ¶
func (ia *Interaction) IsObserving() bool
func (*Interaction) Token ¶
func (ia *Interaction) Token() Token
type InteractionStore ¶
type InteractionStore interface { FindInteraction(token Token, msgId MessageId) *Interaction StartInteraction(conn Connection, msg *coapmsg.Message) *Interaction RemoveInteraction(ia *Interaction) InteractionCount() int }
type Interactions ¶
type Interactions struct {
// contains filtered or unexported fields
}
func (*Interactions) FindInteraction ¶
func (ias *Interactions) FindInteraction(token Token, msgId MessageId) *Interaction
func (*Interactions) InteractionCount ¶
func (ias *Interactions) InteractionCount() int
func (*Interactions) RemoveInteraction ¶
func (ias *Interactions) RemoveInteraction(interaction *Interaction)
func (*Interactions) StartInteraction ¶
func (ias *Interactions) StartInteraction(conn Connection, reqMsg *coapmsg.Message) *Interaction
type NotifyFunc ¶
type NotifyFunc func(ia *Interaction, currResponse *coapmsg.Message)
type PacketReader ¶
Implemented by connections
type PacketWriter ¶
Implemented by connections
type RandomTokenGenerator ¶
type RandomTokenGenerator struct {
// contains filtered or unexported fields
}
func (*RandomTokenGenerator) NextToken ¶
func (t *RandomTokenGenerator) NextToken() []byte
type Request ¶
type Request struct { // Method specifies the HTTP method (GET, POST, PUT, etc.). // For client requests an empty string means GET. Method string // Confirmable CoAP requests will be confirmed by an ACK // from the server. Confirmable bool // URL specifies either the URI being requested (for server // requests) or the URL to access (for client requests). // // For server requests the URL is parsed from the URI // supplied in the CoAP message. (See RFC 7252, Section 6) // // For client requests, the URL's Host specifies the server to // connect to. URL *url.URL // The protocol version for incoming server requests. // // For client requests these fields are ignored. The CoAP // client code always uses CoAP/1. // See the docs on Transport for details. Proto string // "CoAP/1" ProtoVersion int // 1 - encoded as 2 bit field in CoAP messages // CoAP Options are like HTTP Headers and used in a similar way Options coapmsg.CoapOptions // Token specifies the Reuquest token that is used to identify the response // // If the Token is empty it will be issued by the Transport // The client can set a specific Token, e.g. to cancel a specific observe request Token Token // Body is the request's body. // // For client requests a nil body means the request has no // body, such as a GET request. The Client's Transport // is responsible for calling the Close method. // // For server requests the Request Body is always non-nil // but will return EOF immediately when no body is present. // The Server will close the request body. The Serve**** // Handler does not need to. Body io.ReadCloser // Cancel is an optional channel whose closure indicates that the client // request should be regarded as canceled. Not all implementations of // RoundTripper may support Cancel. // // For server requests, this field is not applicable. // // Deprecated: Use the Context and WithContext methods // instead. If a Request's Cancel field and context are both // set, it is undefined whether Cancel is respected. Cancel <-chan struct{} // contains filtered or unexported fields }
A Request represents a CoAP request received by a server or to be sent by a client.
The orientation for the structure is the http.Request to make a conversion as easy as possible and to make it more easy to understand for developers who are used to http requests
func NewRequest ¶
NewRequest returns a new Request given a method, URL, and optional body.
If the provided body is also an io.Closer, the returned Request.Body is set to body and will be closed by the Client methods Do, Post, and PostForm, and Transport.RoundTrip.
NewRequest returns a Request suitable for use with Client.Do or Transport.RoundTrip. To create a request for use with testing a Server Handler use either ReadRequest or manually update the Request fields. See the Request type's documentation for the difference between inbound and outbound request fields.
func (*Request) Context ¶
Context returns the request's context. To change the context, use WithContext.
The returned context is always non-nil; it defaults to the background context.
For outgoing client requests, the context controls cancelation.
For incoming server requests, the context is canceled when the ServeHTTP method returns. For its associated values, see ServerContextKey and LocalAddrContextKey.
type Response ¶
type Response struct { Status string // e.g. "2.05 Content" StatusCode uint8 // e.g. 69 - which is the int representation of 2.05 // Body represents the response body. // // The coap Client and Transport guarantee that Body is always // non-nil, even on responses without a body or responses with // a zero-length body. It is the caller's responsibility to // close Body. The default CoAP client's Transport does not // attempt to reuse connections ("keep-alive") unless the Body // is read to completion and is closed. // // The Body is automatically dechunked if the server replied // with a "chunked" Transfer-Encoding. // See: RFC 7959 (Block-wise transfers in CoAP) Body io.ReadCloser Options coapmsg.CoapOptions // Request is the request that was sent to obtain this Response. // Request's Body is nil (having already been consumed). // This is only populated for Client requests. Request *Request // contains filtered or unexported fields }
func CancelObserve ¶
type RoundTripper ¶
type RoundTripper interface { // RoundTrip executes a single CoAP transaction, returning // a Response for the provided Request. // // RoundTrip should not attempt to interpret the response. In // particular, RoundTrip must return err == nil if it obtained // a response, regardless of the response's CoAP status code. // A non-nil err should be reserved for failure to obtain a // response. Similarly, RoundTrip should not attempt to // handle higher-level protocol details such as redirects, // authentication, or cookies. // // RoundTrip should not modify the request, except for // consuming and closing the Request's Body. // // RoundTrip must always close the body, including on errors, // but depending on the implementation may do so in a separate // goroutine even after RoundTrip returns. This means that // callers wanting to reuse the body for subsequent requests // must arrange to wait for the Close call before doing so. // // The Request's URL and Header fields must be initialized. RoundTrip(*Request) (*Response, error) }
RoundTripper is an interface representing the ability to execute a single HTTP transaction, obtaining the Response for a given Request.
A RoundTripper must be safe for concurrent use by multiple goroutines.
var DefaultTransport RoundTripper = &Transport{ TransUart: NewTransportUart(), }
type SafeBuffer ¶
type SafeBuffer struct {
// contains filtered or unexported fields
}
func (*SafeBuffer) Bytes ¶
func (b *SafeBuffer) Bytes() []byte
func (*SafeBuffer) Cap ¶
func (b *SafeBuffer) Cap() int
func (*SafeBuffer) Grow ¶
func (b *SafeBuffer) Grow(n int)
func (*SafeBuffer) Len ¶
func (b *SafeBuffer) Len() int
func (*SafeBuffer) Next ¶
func (b *SafeBuffer) Next(n int) []byte
func (*SafeBuffer) ReadByte ¶
func (b *SafeBuffer) ReadByte() (c byte, err error)
func (*SafeBuffer) ReadString ¶
func (b *SafeBuffer) ReadString(delim byte) (line string, err error)
func (*SafeBuffer) Reset ¶
func (b *SafeBuffer) Reset()
func (*SafeBuffer) String ¶
func (b *SafeBuffer) String() string
func (*SafeBuffer) Truncate ¶
func (b *SafeBuffer) Truncate(n int)
func (*SafeBuffer) UnreadByte ¶
func (b *SafeBuffer) UnreadByte() error
func (*SafeBuffer) UnreadRune ¶
func (b *SafeBuffer) UnreadRune() error
func (*SafeBuffer) WriteByte ¶
func (b *SafeBuffer) WriteByte(c byte) error
func (*SafeBuffer) WriteString ¶
func (b *SafeBuffer) WriteString(s string) (n int, err error)
type SerialConnecter ¶
type SerialConnecter interface {
Connect(host string) (Connection, error)
}
type SerialMode ¶
type SerialMode struct { BaudRate int // The serial port bitrate (aka Baudrate) DataBits int // Size of the character (must be 5, 6, 7 or 8) Parity Parity // Parity (see Parity type for more info) StopBits StopBits // Stop bits (see StopBits type for more info) }
TODO: Use this struct instead of the bug.st one
type SerialPort ¶
type SlipMuxReader ¶
type SlipMuxReader struct {
// contains filtered or unexported fields
}
func NewSlipMuxReader ¶
func NewSlipMuxReader(reader io.Reader) *SlipMuxReader
func (*SlipMuxReader) ReadPacket ¶
func (r *SlipMuxReader) ReadPacket() ([]byte, bool, error)
type SlipMuxWriter ¶
type SlipMuxWriter struct {
// contains filtered or unexported fields
}
func NewSlipMuxWriter ¶
func NewSlipMuxWriter(writer io.Writer) *SlipMuxWriter
func (*SlipMuxWriter) WritePacket ¶
func (w *SlipMuxWriter) WritePacket(p []byte) (err error)
type TokenGenerator ¶
type TokenGenerator interface {
NextToken() []byte
}
func NewCountingTokenGenerator ¶
func NewCountingTokenGenerator() TokenGenerator
func NewRandomTokenGenerator ¶
func NewRandomTokenGenerator() TokenGenerator
type Transport ¶
type Transport struct {
TransUart RoundTripper
}
Transport that delegates to other transports based on the request URL scheme
type TransportUart ¶
type TransportUart struct { TokenGenerator TokenGenerator Connecter SerialConnecter // contains filtered or unexported fields }
Transport uses a Serial port to communicate via UART (e.g. RS232) All Serial parameters can be set on the transport The host of the request URL specifies the serial connection, e.g. COM3 The URI scheme must be coap+uart and valid URIs would be coap+uart://COM3/sensors/temperature coap+uart://ttyS2/sensors/temperature Since we can not have a slash (/) in the host name, on linux systems the /dev/ part of the device file handle is added implicitly https://tools.ietf.org/html/rfc3986#page-21 allows system specific Host lookups
The URI host can be set to "any" to take the first open port found
func NewTransportUart ¶
func NewTransportUart() *TransportUart
func (*TransportUart) RoundTrip ¶
func (t *TransportUart) RoundTrip(req *Request) (res *Response, err error)
RoundTrip takes care about one Request / Response roundtrip 1) Find / Open new Connection 2) Find / Create new interaction 3) Use interaction to do the actual RoundTip 4a) - No Observe -> Release interaction, close Connection if no interactions running 4b) - Observe -> Keep interaction until timeout
type UartConnector ¶
type UartConnector struct { UartParams // contains filtered or unexported fields }
func NewUartConnecter ¶
func NewUartConnecter() *UartConnector
func (*UartConnector) Connect ¶
func (c *UartConnector) Connect(host string) (Connection, error)
type UartParams ¶
type UartParams struct { // UART parameters. In future we might want to configure this per port. Baud int // BaudRate Parity Parity // Parity is the bit to use and defaults to ParityNone (no parity bit). StopBits StopBits // Number of stop bits to use. Default is 1 (1 stop bit). DataBits int InitialDTR bool InitialRTS bool }