manager.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package coap
  2. import (
  3. "net"
  4. "sparrow/pkg/server"
  5. "time"
  6. )
  7. const (
  8. // ResponseTimeout is the amount of time to wait for a
  9. // response.
  10. ResponseTimeout = time.Second * 2
  11. // ResponseRandomFactor is a multiplier for response backoff.
  12. ResponseRandomFactor = 1.5
  13. // MaxRetransmit is the maximum number of times a message will
  14. // be retransmitted.
  15. MaxRetransmit = 4
  16. maxPktlen = 1500
  17. )
  18. type Handler interface {
  19. ServeCOAP(l *net.UDPConn, a *net.UDPAddr, m Message) Message
  20. }
  21. type Manager struct {
  22. rh funcHandler
  23. }
  24. func NewManager() *Manager {
  25. return &Manager{}
  26. }
  27. func (m *Manager) FuncHandler(f func(l *net.UDPConn, a *net.UDPAddr, m Message) Message) Handler {
  28. m.rh = f
  29. return funcHandler(f)
  30. }
  31. type funcHandler func(l *net.UDPConn, a *net.UDPAddr, m Message) Message
  32. func (f funcHandler) ServeCOAP(l *net.UDPConn, a *net.UDPAddr, m Message) Message {
  33. return f(l, a, m)
  34. }
  35. func (m *Manager) Handler(conn *net.UDPConn) {
  36. buf := make([]byte, maxPktlen)
  37. for {
  38. nr, addr, err := conn.ReadFromUDP(buf)
  39. if err != nil {
  40. if neterr, ok := err.(net.Error); ok && (neterr.Temporary() || neterr.Timeout()) {
  41. time.Sleep(5 * time.Millisecond)
  42. continue
  43. }
  44. }
  45. tmp := make([]byte, nr)
  46. copy(tmp, buf)
  47. go m.handlerPacket(conn, tmp, addr)
  48. }
  49. }
  50. func (m *Manager) handlerPacket(l *net.UDPConn, data []byte, a *net.UDPAddr) {
  51. msg, err := ParseMessage(data)
  52. if err != nil {
  53. server.Log.Error(err)
  54. }
  55. rv := m.rh.ServeCOAP(l, a, msg)
  56. if rv != nil {
  57. Transmit(l, a, msg)
  58. }
  59. }
  60. func Transmit(l *net.UDPConn, a *net.UDPAddr, m Message) error {
  61. d, err := m.Encode()
  62. if err != nil {
  63. return err
  64. }
  65. if a == nil {
  66. _, err = l.Write(d)
  67. } else {
  68. _, err = l.WriteTo(d, a)
  69. }
  70. return err
  71. }
  72. // Receive a message.
  73. func Receive(l *net.UDPConn, buf []byte) (Message, error) {
  74. l.SetReadDeadline(time.Now().Add(ResponseTimeout))
  75. nr, _, err := l.ReadFromUDP(buf)
  76. if err != nil {
  77. return &BaseMessage{}, err
  78. }
  79. return ParseMessage(buf[:nr])
  80. }