-
Notifications
You must be signed in to change notification settings - Fork 5
/
mux.go
148 lines (122 loc) · 4.28 KB
/
mux.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* For license and copyright information please see LEGAL file in repository */
package chapar
import (
"../protocol"
)
// Multiplexer implement protocol.LinkMultiplexer interface
// Hardware implementation has one difference from Software(this) implementation:
// Software: Receive method call Receive method of desire port
// Hardware: Receive method will call Send method of desire port
type Multiplexer struct {
// Ports store all available link port to other physical or logical devices!
// 256 is max ports that Chapar protocol support directly in one hop!!
ports [256]port
// UpperHandlers store all upper layer handlers
// 256 is max next header ID that Chapar protocol support!
upperHandlers [256]protocol.NetworkTransportOSMultiplexer
connections connections
}
// Init initializes new Multiplexer object otherwise panic will occur on un-registered port or handler call!
func (mux *Multiplexer) Init(pConnection protocol.NetworkPhysicalConnection) {
// mux.physicalConnection = pConnection
pConnection.RegisterLinkMultiplexer(mux)
var i byte
for i = 0; i <= 255; i++ {
var p = port{
portNumber: i,
mux: mux,
// physicalConnection: TODO:::
}
mux.registerPort(p)
var nonUH = UpperHandlerNonExist{headerID: i}
mux.upperHandlers.RegisterHandler(nonUH)
}
mux.connections.init()
}
// RegisterTransportHandler registers new port on given ports pool!
func (mux *Multiplexer) RegisterTransportHandler(tm protocol.NetworkTransportOSMultiplexer) {
// TODO::: check handler exist already and warn user??
mux.upperHandlers[tm.HeaderID()] = tm
}
// UnRegisterTransportHandler delete the port by given port number on given ports pool!
func (mux *Multiplexer) UnRegisterTransportHandler(tm protocol.NetworkTransportOSMultiplexer) {
var nonUH = UpperHandlerNonExist{headerID: tm.HeaderID()}
mux.upperHandlers.RegisterHandler(nonUH)
}
// removeTransportHandler delete the port by given port number on given ports pool!
func (mux *Multiplexer) removeTransportHandler(handlerID byte) {
var nonUH = UpperHandlerNonExist{headerID: handlerID}
mux.upperHandlers.RegisterHandler(nonUH)
}
func (mux *Multiplexer) getTransportHandler(id byte) protocol.NetworkTransportOSMultiplexer {
return mux.upperHandlers[id]
}
// Send send the payload to all ports async!
func (mux *Multiplexer) Send(frame []byte) (err protocol.Error) {
err = CheckFrame(frame)
if err != nil {
// TODO::: ???
return
}
if IsBroadcastFrame(frame) {
err = mux.sendBroadcast(frame)
} else {
var portNum byte = GetNextPortNum(frame)
err = mux.getPort(portNum).Send(frame)
}
return
}
// SendBroadcast send the payload to all ports async!
func (mux *Multiplexer) SendBroadcast(nexHeaderID protocol.NetworkLinkNextHeaderID, payload protocol.Codec) (err protocol.Error) {
var payloadLen int = payload.Len()
if payloadLen > maxBroadcastPayloadLen {
return ErrMTU
}
var pathLen byte = maxHopCount
var payloadLoc int = 3 + int(pathLen)
var frameLength int = payloadLoc + payloadLen
var frame = make([]byte, frameLength)
SetHopCount(frame, broadcastHopCount)
SetNextHeader(frame, byte(nexHeaderID))
payload.MarshalTo(frame[payloadLoc:])
err = mux.sendBroadcast(frame)
return
}
// send the frame to all ports as BroadcastFrame!
func (mux *Multiplexer) sendBroadcast(frame []byte) (err protocol.Error) {
// send the frame to all ports as BroadcastFrame!
var portNum byte
for portNum = 0; portNum <= 255; portNum++ {
err = mux.getPort(portNum).Send(frame)
}
}
// Receive handles income frame to ports!
func (mux *Multiplexer) Receive(frame []byte) {
var err = CheckFrame(frame)
if err != nil {
// TODO::: ???
return
}
IncrementNextHop(frame, pm.portNumber)
if IsBroadcastFrame(frame) {
err = mux.sendBroadcast(frame)
} else {
var portNum byte = GetNextPortNum(frame)
mux.getPort(portNum).Receive(frame)
}
}
// Shutdown ready the connection pools to shutdown!!
func (mux *Multiplexer) Shutdown() {
mux.connections.shutdown()
}
func (mux *Multiplexer) getPort(id byte) port { return mux.ports[id] }
func (mux *Multiplexer) registerPort(p port) {
// TODO::: check port exist already and warn user??
mux.ports[p.PortNumber()] = p
}
func (mux *Multiplexer) unRegisterPort(p port) {
mux.removePort(p.PortNumber())
}
func (mux *Multiplexer) removePort(portNumber byte) {
// mux.ports[portNumber].physicalConnection = TODO:::
}