-
Notifications
You must be signed in to change notification settings - Fork 61
/
bus.go
117 lines (95 loc) · 2.16 KB
/
bus.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package can
import (
"io"
"net"
)
// Bus represents the CAN bus.
// Handlers can subscribe to receive frames.
// Frame are sent using the *Publish* method.
type Bus struct {
rwc ReadWriteCloser
handler []Handler
}
// NewBusForInterfaceWithName returns a bus from the network interface with name ifaceName.
func NewBusForInterfaceWithName(ifaceName string) (*Bus, error) {
iface, err := net.InterfaceByName(ifaceName)
if err != nil {
return nil, err
}
conn, err := NewReadWriteCloserForInterface(iface)
if err != nil {
return nil, err
}
return NewBus(conn), nil
}
// NewBus returns a new CAN bus.
func NewBus(rwc ReadWriteCloser) *Bus {
return &Bus{
rwc: rwc,
handler: make([]Handler, 0),
}
}
// ConnectAndPublish starts handling CAN frames to publish them to handlers.
func (b *Bus) ConnectAndPublish() error {
for {
err := b.publishNextFrame()
if err != nil {
return err
}
}
return nil
}
// Disconnect stops handling CAN frames.
func (b *Bus) Disconnect() error {
return b.rwc.Close()
}
// Subscribe adds a handler to the bus.
func (b *Bus) Subscribe(handler Handler) {
b.handler = append(b.handler, handler)
}
// SubscribeFunc adds a function as handler.
func (b *Bus) SubscribeFunc(fn HandlerFunc) {
handler := NewHandler(fn)
b.Subscribe(handler)
}
// Unsubscribe removes a handler.
func (b *Bus) Unsubscribe(handler Handler) {
for i, h := range b.handler {
if h == handler {
b.handler = append(b.handler[:i], b.handler[i+1:]...)
return
}
}
}
// Publish publishes a frame on the bus.
//
// Frames publishes with the Publish methods are not received by handlers.
func (b *Bus) Publish(frame Frame) error {
return b.rwc.WriteFrame(frame)
}
func (b *Bus) contains(handler Handler) bool {
for _, h := range b.handler {
if h == handler {
return true
}
}
return false
}
func (b *Bus) publishNextFrame() error {
frame := Frame{}
err := b.rwc.ReadFrame(&frame)
if err != nil {
b.rwc.Close()
if err != io.EOF { // EOF is not an error, it happens when calling rwc.Close()
return err
}
return nil
}
b.publish(frame)
return nil
}
func (b *Bus) publish(frame Frame) {
for _, h := range b.handler {
h.Handle(frame)
}
}