1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- package coap
- import (
- "net"
- "sparrow/pkg/server"
- "time"
- )
- const (
- // ResponseTimeout is the amount of time to wait for a
- // response.
- ResponseTimeout = time.Second * 2
- // ResponseRandomFactor is a multiplier for response backoff.
- ResponseRandomFactor = 1.5
- // MaxRetransmit is the maximum number of times a message will
- // be retransmitted.
- MaxRetransmit = 4
- maxPktlen = 1500
- )
- type Handler interface {
- ServeCOAP(l *net.UDPConn, a *net.UDPAddr, m Message) Message
- }
- type Manager struct {
- rh funcHandler
- }
- func NewManager() *Manager {
- return &Manager{}
- }
- func (m *Manager) FuncHandler(f func(l *net.UDPConn, a *net.UDPAddr, m Message) Message) Handler {
- m.rh = f
- return funcHandler(f)
- }
- type funcHandler func(l *net.UDPConn, a *net.UDPAddr, m Message) Message
- func (f funcHandler) ServeCOAP(l *net.UDPConn, a *net.UDPAddr, m Message) Message {
- return f(l, a, m)
- }
- func (m *Manager) Handler(conn *net.UDPConn) {
- buf := make([]byte, maxPktlen)
- for {
- nr, addr, err := conn.ReadFromUDP(buf)
- if err != nil {
- if neterr, ok := err.(net.Error); ok && (neterr.Temporary() || neterr.Timeout()) {
- time.Sleep(5 * time.Millisecond)
- continue
- }
- }
- tmp := make([]byte, nr)
- copy(tmp, buf)
- go m.handlerPacket(conn, tmp, addr)
- }
- }
- func (m *Manager) handlerPacket(l *net.UDPConn, data []byte, a *net.UDPAddr) {
- msg, err := ParseMessage(data)
- if err != nil {
- server.Log.Error(err)
- }
- rv := m.rh.ServeCOAP(l, a, msg)
- if rv != nil {
- Transmit(l, a, msg)
- }
- }
- func Transmit(l *net.UDPConn, a *net.UDPAddr, m Message) error {
- d, err := m.Encode()
- if err != nil {
- return err
- }
- if a == nil {
- _, err = l.Write(d)
- } else {
- _, err = l.WriteTo(d, a)
- }
- return err
- }
- // Receive a message.
- func Receive(l *net.UDPConn, buf []byte) (Message, error) {
- l.SetReadDeadline(time.Now().Add(ResponseTimeout))
- nr, _, err := l.ReadFromUDP(buf)
- if err != nil {
- return &BaseMessage{}, err
- }
- return ParseMessage(buf[:nr])
- }
|