/* * Author: Wenbing Zhao * Last Modified: 9/18/2006 * For EEC484/584 Project 1 */ import java.util.*; public abstract class DataLinkLayer { public static final int MAX_SEQ = 1; public static final int EVENT_FRAME_ARRIVAL = 0; public static final int EVENT_TIMEOUT = 1; public static final int EVENT_PACKET_TOSEND = 2; public static final long TIMEOUT = 1000; // in millisecond java.util.Timer m_timer; SendTimerTask m_timerTask = new SendTimerTask(); // state variable to indicate if we should process an event boolean m_wakeup = false; // state variable to indicate the type of event that occurred int m_event = -1; PhysicalLayer m_physicalLayer = null; public DataLinkLayer(PhysicalLayer pl) { m_physicalLayer = pl; } // to be implemented by sub-classes for actual sending side // and receiving side protocol public abstract void run(); int increment(int seq) { int newseq; if(seq < MAX_SEQ) newseq = seq + 1; else newseq = 0; return newseq; } void sendFrameToPhysicalLayer(Frame frame) { m_physicalLayer.send(frame.toBytes()); } Frame receiveFrameFromPhysicalLayer() { byte[] receivedData = m_physicalLayer.receive(); Frame frame = new Frame(receivedData); return frame; } void startTimer() { try { m_timer = new java.util.Timer(); m_timer.schedule(new SendTimerTask(), TIMEOUT); } catch(Exception e) {} } void stopTimer() { try { m_timer.cancel(); } catch(Exception e) {} } public synchronized int waitForEvent() { while(!m_wakeup) { try { wait(); } catch (InterruptedException e) {} } m_wakeup = false; return m_event; } public synchronized void onFrameArrival() { m_wakeup = true; m_event = EVENT_FRAME_ARRIVAL; notifyAll(); } public synchronized void onTimeout() { m_wakeup = true; m_event = EVENT_TIMEOUT; notifyAll(); } public class SendTimerTask extends TimerTask { public void run() { onTimeout(); } } }