-
Notifications
You must be signed in to change notification settings - Fork 0
/
DataLinkLayer.java
151 lines (97 loc) · 4.43 KB
/
DataLinkLayer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// ===================================================================
// DataLinkLayer
// Scott F. H. Kaplan -- http://www.cs.amherst.edu/~sfkaplan
// September 2004
// ===================================================================
// ===================================================================
// A data link layer accepts a string of bytes, divides it into
// frames, adds some metadata, and sends the frame via its physical
// layer. Upon receiving a frame, the data link layer removes the
// metadata, potentially performs some checks on the data, and
// delivers the data to its client network layer.
abstract class DataLinkLayer {
// ===================================================================
// ===============================================================
// The constructor.
public void initialize (PhysicalLayer physicalLayer) {
// Sanity check
if (physicalLayer == null) {
throw new RuntimeException("No physical layer provided");
}
// Attempt to register with the physical layer.
physicalLayer.register(this);
// Keep a pointer to the physical layer.
this.physicalLayer = physicalLayer;
// Create incoming buffer space.
incomingBuffer = new byte[bufferSize];
bufferIndex = 0;
} // DataLinkLayer
// ===============================================================
// ===============================================================
// Allow a network layer to register as the client of this
// data link layer.
public void register (NetworkLayer client) {
// Is there already a client registered?
if (this.client != null) {
throw new RuntimeException();
}
// Hold a pointer to the client.
this.client = client;
} // register
// ===============================================================
// ===============================================================
// Allow a client to send a string of bytes on the medium.
abstract public void send (byte[] data);
// ===============================================================
// ===============================================================
// Allow the physical layer to deliver a byte into this layer's
// buffer.
void receive (byte data) {
// Add the new byte to the buffer of bytes.
incomingBuffer[bufferIndex] = data;
bufferIndex++;
// If this byte completes a frame, then process the frame,
// obtaining the original data (stripped of metadata).
byte[] originalData = null;
if (receivedCompleteFrame()) {
originalData = processFrame();
bufferIndex = 0;
}
// If the frame was processed successfully, deliver the
// processed frame to the client.
if (originalData != null) {
client.receive(originalData);
}
} // receive
// ===============================================================
// ===============================================================
// Determine whether the buffered data forms a complete frame.
abstract protected boolean receivedCompleteFrame ();
// ===============================================================
// ===============================================================
// Given a complete frame, process its contents, extracting
// metadata and performing any error checking, then delivering (if
// possible) the original data. (Return a null pointer if the
// data cannot be recovered.)
abstract protected byte[] processFrame ();
// ===============================================================
// ===============================================================
// DATA MEMBERS
// ===============================================================
// ===============================================================
// The medium to which this layer is connected.
PhysicalLayer physicalLayer;
// The data link layer above this physical layer.
NetworkLayer client;
// A buffer of bytes for data received from the physical layer.
// When a full frame is received, it is processed and the buffer
// is emptied.
byte[] incomingBuffer;
// The number of bytes received so far into the incoming buffer.
int bufferIndex;
// The incoming buffer size.
final int bufferSize = 32768;
// ===============================================================
// ===================================================================
} // class DataLinkLayer
// ===================================================================