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  }