// CSMAService.java package protocol; // protocol package import java.util.*; // import Java utility classes import support.*; // import Jasper support classes /** This is the class that supports sources/sinks for (de)multiplexing. @author Kenneth J. Turner @version 1.0 (24th July 2010, KJT): initial version */ public class CSMAService implements ProtocolEntity { /** Service send offer */ private final static String SEND = "Send data to "; /** Service message count */ private static int messageCount; /** PDU sent by service */ private PDU sduSent; /** Service entity name */ private String serviceName; /** Service provider */ private CSMAProtocol serviceProvider; /** Service provider events */ private Vector serviceEvents; /** Constructor for sources/sinks. @param serviceName service name */ public CSMAService(String serviceName) { this.serviceName = serviceName; // set service name initialise(); // initialise service entity } /** Return a protocol event with the given comment. @param comment protocol comment @return protocol event */ public ProtocolEvent comment(String comment) { return(new ProtocolEvent(ProtocolEvent.COMMENT, this, comment)); } /** Return a protocol event with an empty comment as a gap. @return protocol event */ public ProtocolEvent gap() { return(new ProtocolEvent(ProtocolEvent.COMMENT, this, "")); } /** Return the service name. @return service name */ public String getName() { return(serviceName); // return service name } /** Return services currently offered. @return list of services */ public Vector getServices() { Vector list = new Vector(); // initialise service list CSMAProtocol remoteProvider = // get remote service provider serviceProvider.protocolPeer; CSMAMedium protocolMedium = // get protocol medium serviceProvider.protocolMedium; String providerName = // get provider name serviceProvider.protocolName; // System.err.println("CSMAService.getServices - " + serviceName + // ": in <" + serviceProvider.protocolIn + "> out <" + // serviceProvider.protocolOut + ">"); boolean localIdle = // check if local protocol idle serviceProvider.protocolIn == null && // no incoming data pending? serviceProvider.protocolOut == null && // no outgoing data pending? !serviceProvider.protocolReceiving && // not receiving data? protocolMedium.isEmpty(providerName); // no outgoing PDUs in transit? boolean remoteIdle = // check if remote protocol idle remoteProvider.protocolIn == null && // no incoming data pending and remoteProvider.protocolState == CSMAProtocol.NORMAL; // no collision? // System.err.println("CSMAService.getServices - localIdle <" + // localIdle + "> remoteIdle <" + remoteIdle + ">\n"); if (localIdle && remoteIdle) { // local and remote idle? String name = // get peer system name serviceProvider.protocolPeer.protocolUser.getName(); list.addElement(SEND + name); // add send to list } return(list); // return service list } /** Initialise the service entity. */ public void initialise() { messageCount = 0; // initialise message count serviceEvents = new Vector();// initialise service events } /** Perform service. @param service service request @return resulting service events */ public Vector performService(String service) { serviceEvents = new Vector();// initialise service events if (service.startsWith(SEND)) { // send request? String message = "D" + messageCount; // create data message PDU sdu = // create SDU new CSMASdu(CSMASdu.DATA, message); serviceEvents.addElement( // add send event new ProtocolEvent(ProtocolEvent.SEND, sdu)); transmitPDU(sdu, serviceProvider); // send service message messageCount++; // increment message count } return(serviceEvents); // return service events } /** Receive an SDU. @param sdu SDU @return resulting service events */ public Vector receivePDU(PDU sdu) { serviceEvents = new Vector();// initialise service events serviceEvents.addElement( // deliver SDU new ProtocolEvent(ProtocolEvent.DELIVER, sdu)); serviceEvents.addElement(gap()); // add a vertical gap return(serviceEvents); // return service events } /** Set the local service provider. @param serviceProvider service provider */ public void setProvider(ProtocolEntity serviceProvider) { this.serviceProvider = // set local service provider (CSMAProtocol) serviceProvider; } /** Send an SDU. @param sdu SDU @param dest destination protocol entity */ public void transmitPDU(PDU sdu, ProtocolEntity destination) { sdu.setSource(this); // set source as this entity sdu.setDestination(destination); // set destination Vector receiveEvents = // receive SDU at destination destination.receivePDU(sdu); for (int i = 0; i < receiveEvents.size(); i++) // go through receive events serviceEvents.addElement( // append receive event receiveEvents.get(i)); sduSent = sdu; // stored the sent SDU } }