You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

281 lines
8.3 KiB
Java

// MUXProtocol.java
package protocol; // protocol package
import java.util.*; // import Java utility classes
import support.*; // import Jasper support classes
/**
This is the class that supports the (de)multiplexing protocol. It handles
both synchronous and asynchronous modes.
@author Kenneth J. Turner
@version 1.0 (20th July 2010, KJT): initial version
*/
public class MUXProtocol implements ProtocolEntity {
/** Service send offer */
private final static String RECEIVE = "Send data to ";
/** Protocol send offer */
private final static String SEND =
"Multiplex and send ";
/** Protocol send all available offer */
private final static String SEND_ALL = SEND + "all available data";
/** Protocol send one offer */
private final static String SEND_ONE = SEND + "the individual data";
/** Service source offer */
private final static String SINK = "Sink ";
/** Protocol events */
private Vector<ProtocolEvent> protocolEvents;
/** Protocol PDU received */
private MUXPdu protocolIn;
/** Protocol channel */
private Medium protocolMedium;
/** Protocol protocol mode (true = asynchronous, false = synchronous) */
public static boolean protocolMode;
/** Protocol name */
private String protocolName;
/** Protocol PDU sent */
private MUXPdu protocolOut;
/** Protocol peer */
private MUXProtocol protocolPeer;
/** Protocol user */
private MUXService protocolUser;
/**
Constructor for a (de)multiplexer.
@param protocolMedium channel
@param protocolName protocol name
*/
public MUXProtocol(Medium protocolMedium, String protocolName) {
this.protocolName = protocolName; // set protocol name
this.protocolMedium = protocolMedium; // set protocol medium
initialise(); // initialise protocol
}
/**
Return a protocol event with the given comment.
@param comment protocol comment
@return protocol event
*/
private ProtocolEvent comment(String comment) {
return(new ProtocolEvent(ProtocolEvent.COMMENT, this, comment));
}
/**
Get the protocol mode.
@return protocol mode (true = asynchronous, false = synchronous)
*/
public boolean getMode() {
return(protocolMode); // return protocol mode
}
/**
Get the protocol name.
@return protocol name
*/
public String getName() {
return(protocolName); // return protocol name
}
/**
Get the protocol peer.
@return protocol peer
*/
public MUXProtocol getPeer() {
return(protocolPeer); // return protocol peer
}
/**
Get protocol input.
@return protocol input
*/
public MUXPdu getProtocolIn() {
return(protocolIn); // return protocol input
}
/**
Get protocol output.
@return protocol output
*/
public MUXPdu getProtocolOut() {
return(protocolOut); // return protocol output
}
/**
Return services currently offered.
@return list of protocol services
*/
public Vector<String> getServices() {
Vector<String> list = new Vector<String>(); // initialise protocol services
int firstSDU = protocolOut.firstSDU(); // get first SDU index
if (firstSDU >= 0) { // SDU available?
if (protocolMode) // asynchronous?
list.add(SEND_ONE); // append send one offer
else // synchronous
list.add(SEND_ALL); // append send all offer
}
String[] sduList = // get SDU list from PDU
((MUXPdu) protocolIn).getSDUs();
for (int i = 0; i < sduList.length; i++) { // go through SDUs
String data = sduList[i]; // get SDU data
if (data != null) // SDU available?
list.add(RECEIVE + SINK + i); // append protocol receive offer
}
return (list); // return protocol service list
}
/**
Initialise the protocol entity.
*/
public void initialise() {
protocolEvents = new Vector<ProtocolEvent>();// initialise protocol events
protocolIn = new MUXPdu(); // initialise protocol input
protocolOut = new MUXPdu(); // initialise protocol output
}
/**
Perform service.
@param service service request
@return resulting protocol events
*/
public Vector<ProtocolEvent> performService(String service) {
protocolEvents = new Vector<ProtocolEvent>(); // initialise protocol events
if (service.startsWith(SEND)) { // send all request?
protocolEvents.addElement( // add send event
new ProtocolEvent(ProtocolEvent.TRANSMIT, protocolOut));
protocolEvents.addElement( // add receive event
new ProtocolEvent(ProtocolEvent.RECEIVE, protocolOut));
transmitPDU(protocolOut, protocolPeer); // send protocol PDU
protocolOut = new MUXPdu(); // re-initialise sent PDU
}
else if (service.startsWith(RECEIVE)) { // receive request?
int sinkStart = // get start of sink index
service.indexOf(SINK) + SINK.length();
int sink = // get source index
Integer.parseInt(service.substring(sinkStart));
String[] sduList = protocolIn.getSDUs(); // get SDU list from PDU
String data = sduList[sink]; // get SDU data
MUXSdu sdu = new MUXSdu(sink, data); // create SDU
transmitPDU(sdu, protocolUser); // send to service user
protocolIn.setSDU(sink, null); // remove sink SDU data
}
return(protocolEvents); // return protocol events
}
/**
Receive PDU.
@param pdu PDU
@return resulting protocol events
*/
public Vector<ProtocolEvent> receivePDU(PDU pdu) {
protocolEvents = new Vector<ProtocolEvent>(); // initialise event list
if (pdu != null) { // non-empty PDU?
String pduType = pdu.type; // get PDU type
if (pduType.equals(MUXSdu.TYPE)) { // service user message?
int source = ((MUXSdu) pdu).entity; // get source index
String data = ((MUXSdu) pdu).sdu; // get service user data
String comment; // declare protocol comment
if (protocolMode) { // asynchronous?
comment = // set comment from presence
protocolOut.firstSDU() >= 0 ? "Overwritten" : "Stored";
protocolOut = new MUXPdu(); // initialise protocol output
}
else // synchronous
comment = // set comment from presence
protocolOut.getSDU(source) != null ? "Overwritten" : "Stored";
protocolOut.setSDU(source, data); // store source SDU data
protocolEvents.addElement( // add receive comment event
comment(comment));
}
else if (pduType.equals(MUXPdu.TYPE)) { // protocol peer message?
String comment = // set comment from presence
protocolIn.firstSDU() >= 0 ? "Overwritten" : "Stored";
protocolIn = (MUXPdu) pdu; // store received PDU
protocolEvents.addElement( // add receive comment event
comment(comment));
}
}
return(protocolEvents); // return protocol events
}
/**
Set the protocol mode.
@param protocolMode protocol mode (true = asynchronous,
false = synchronous)
*/
public void setMode(boolean protocolMode) {
this.protocolMode = protocolMode; // set protocol mode
}
/**
Set the protocol peer.
@param protocolPeer protocol peer
*/
public void setPeer(ProtocolEntity protocolPeer) {
this.protocolPeer = // set protocol peer
(MUXProtocol) protocolPeer;
}
/**
Set the protocol service.
@param protocolUser protocol service user
*/
public void setUser(ProtocolEntity protocolUser) {
this.protocolUser = // set service user
(MUXService) protocolUser;
}
/**
Send PDU.
@param pdu PDU
@param destination protocol destination
*/
public void transmitPDU(PDU pdu, ProtocolEntity destination) {
pdu.setSource(this); // set protocol entity as source
pdu.setDestination(destination); // set message destination
Vector<ProtocolEvent> receiveEvents; // declare receive events
if (destination == protocolPeer) { // for protocol peer?
receiveEvents = // receive PDU at medium
protocolPeer.receivePDU(pdu);
}
else // for service user?
receiveEvents = // receive PDU at user
protocolUser.receivePDU(pdu);
for (int i = 0; i < receiveEvents.size(); i++) // go through receive events
protocolEvents.addElement( // append receive event
receiveEvents.get(i));
}
}