github.com/geniusesgroup/libgo@v0.0.0-20220713101832-828057a9d3d4/chapar/mux.go (about) 1 /* For license and copyright information please see LEGAL file in repository */ 2 3 package chapar 4 5 import ( 6 "../protocol" 7 ) 8 9 // Multiplexer implement protocol.LinkMultiplexer interface 10 // Hardware implementation has one difference from Software(this) implementation: 11 // Software: Receive method call Receive method of desire port 12 // Hardware: Receive method will call Send method of desire port 13 type Multiplexer struct { 14 // Ports store all available link port to other physical or logical devices! 15 // 256 is max ports that Chapar protocol support directly in one hop!! 16 ports [256]port 17 // UpperHandlers store all upper layer handlers 18 // 256 is max next header ID that Chapar protocol support! 19 upperHandlers [256]protocol.NetworkTransportOSMultiplexer 20 21 connections connections 22 } 23 24 // Init initializes new Multiplexer object otherwise panic will occur on un-registered port or handler call! 25 func (mux *Multiplexer) Init(pConnection protocol.NetworkPhysicalConnection) { 26 // mux.physicalConnection = pConnection 27 pConnection.RegisterLinkMultiplexer(mux) 28 29 var i byte 30 for i = 0; i <= 255; i++ { 31 var p = port{ 32 portNumber: i, 33 mux: mux, 34 // physicalConnection: TODO::: 35 } 36 mux.registerPort(p) 37 38 var nonUH = UpperHandlerNonExist{headerID: i} 39 mux.upperHandlers.RegisterHandler(nonUH) 40 } 41 42 mux.connections.init() 43 } 44 45 // RegisterTransportHandler registers new port on given ports pool! 46 func (mux *Multiplexer) RegisterTransportHandler(tm protocol.NetworkTransportOSMultiplexer) { 47 // TODO::: check handler exist already and warn user?? 48 mux.upperHandlers[tm.HeaderID()] = tm 49 } 50 51 // UnRegisterTransportHandler delete the port by given port number on given ports pool! 52 func (mux *Multiplexer) UnRegisterTransportHandler(tm protocol.NetworkTransportOSMultiplexer) { 53 var nonUH = UpperHandlerNonExist{headerID: tm.HeaderID()} 54 mux.upperHandlers.RegisterHandler(nonUH) 55 } 56 57 // removeTransportHandler delete the port by given port number on given ports pool! 58 func (mux *Multiplexer) removeTransportHandler(handlerID byte) { 59 var nonUH = UpperHandlerNonExist{headerID: handlerID} 60 mux.upperHandlers.RegisterHandler(nonUH) 61 } 62 63 func (mux *Multiplexer) getTransportHandler(id byte) protocol.NetworkTransportOSMultiplexer { 64 return mux.upperHandlers[id] 65 } 66 67 // Send send the payload to all ports async! 68 func (mux *Multiplexer) Send(frame []byte) (err protocol.Error) { 69 err = CheckFrame(frame) 70 if err != nil { 71 // TODO::: ??? 72 return 73 } 74 75 if IsBroadcastFrame(frame) { 76 err = mux.sendBroadcast(frame) 77 } else { 78 var portNum byte = GetNextPortNum(frame) 79 err = mux.getPort(portNum).Send(frame) 80 } 81 return 82 } 83 84 // SendBroadcast send the payload to all ports async! 85 func (mux *Multiplexer) SendBroadcast(nexHeaderID protocol.NetworkLinkNextHeaderID, payload protocol.Codec) (err protocol.Error) { 86 var payloadLen int = payload.Len() 87 if payloadLen > maxBroadcastPayloadLen { 88 return ErrMTU 89 } 90 91 var pathLen byte = maxHopCount 92 var payloadLoc int = 3 + int(pathLen) 93 var frameLength int = payloadLoc + payloadLen 94 var frame = make([]byte, frameLength) 95 96 SetHopCount(frame, broadcastHopCount) 97 SetNextHeader(frame, byte(nexHeaderID)) 98 payload.MarshalTo(frame[payloadLoc:]) 99 err = mux.sendBroadcast(frame) 100 return 101 } 102 103 // send the frame to all ports as BroadcastFrame! 104 func (mux *Multiplexer) sendBroadcast(frame []byte) (err protocol.Error) { 105 // send the frame to all ports as BroadcastFrame! 106 var portNum byte 107 for portNum = 0; portNum <= 255; portNum++ { 108 err = mux.getPort(portNum).Send(frame) 109 } 110 } 111 112 // Receive handles income frame to ports! 113 func (mux *Multiplexer) Receive(frame []byte) { 114 var err = CheckFrame(frame) 115 if err != nil { 116 // TODO::: ??? 117 return 118 } 119 120 IncrementNextHop(frame, pm.portNumber) 121 122 if IsBroadcastFrame(frame) { 123 err = mux.sendBroadcast(frame) 124 } else { 125 var portNum byte = GetNextPortNum(frame) 126 mux.getPort(portNum).Receive(frame) 127 } 128 } 129 130 // Shutdown ready the connection pools to shutdown!! 131 func (mux *Multiplexer) Shutdown() { 132 mux.connections.shutdown() 133 } 134 135 func (mux *Multiplexer) getPort(id byte) port { return mux.ports[id] } 136 137 func (mux *Multiplexer) registerPort(p port) { 138 // TODO::: check port exist already and warn user?? 139 mux.ports[p.PortNumber()] = p 140 } 141 142 func (mux *Multiplexer) unRegisterPort(p port) { 143 mux.removePort(p.PortNumber()) 144 } 145 146 func (mux *Multiplexer) removePort(portNumber byte) { 147 // mux.ports[portNumber].physicalConnection = TODO::: 148 }