1package main
2
3import (
4 "net"
5)
6
7type CoapEndpoint struct {
8 conn net.PacketConn
9 lastAddr *net.Addr
10 // XXX: mutex?
11
12 RX <-chan []byte
13 TX chan<- []byte
14}
15
16func NewCoapEP(addr string) (*CoapEndpoint, error) {
17 conn, err := net.ListenPacket("udp", addr)
18 if err != nil {
19 return nil, err
20 }
21
22 rx := make(chan []byte)
23 tx := make(chan []byte)
24
25 ep := &CoapEndpoint{
26 conn: conn,
27 lastAddr: nil,
28 RX: rx,
29 TX: tx,
30 }
31
32 go ep.sndLoop(tx)
33 go ep.rcvLoop(rx)
34
35 return ep, nil
36}
37
38func (c *CoapEndpoint) sndLoop(ch <-chan []byte) {
39 for {
40 data := <-ch
41
42 if c.lastAddr == nil {
43 logger.Println("[CoapEndpoint] Unexpected CoAP send")
44 continue
45 }
46
47 _, err := c.conn.WriteTo(data, *c.lastAddr)
48 if err != nil {
49 logger.Println("[CoapEndpoint] WriteTo failed", err)
50 continue
51 }
52 }
53}
54
55func (c *CoapEndpoint) rcvLoop(ch chan<- []byte) {
56 buf := make([]byte, bufSize)
57
58 for {
59 n, addr, err := c.conn.ReadFrom(buf)
60 if err != nil {
61 logger.Println("[CoapEndpoint] ReadFrom failed", err)
62 continue
63 }
64
65 c.lastAddr = &addr
66 ch <- buf[0:n]
67 }
68}
69
70func (c *CoapEndpoint) Close() {
71 // close(c.Chan)
72 c.conn.Close()
73}