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 package net.sf.bluecove.tests;
26
27 import java.io.IOException;
28
29 import org.bluecove.tester.log.Logger;
30 import org.bluecove.tester.util.IOUtils;
31 import org.bluecove.tester.util.RuntimeDetect;
32 import org.bluecove.tester.util.TimeUtils;
33
34 import net.sf.bluecove.CommunicationTesterL2CAP;
35 import net.sf.bluecove.Configuration;
36 import net.sf.bluecove.ConnectionHolderL2CAP;
37 import net.sf.bluecove.TestStatus;
38 import net.sf.bluecove.util.TimeStatistic;
39
40
41
42
43
44 public class L2TrafficGenerator {
45
46 static final int sequenceSizeMin = 16;
47
48 private static class Config {
49
50 int sequenceSleep = 0;
51
52 int sequenceSize = 0;
53
54 int durationMSec = 0;
55
56 boolean init(byte[] initialData, boolean server, String messagePrefix) throws IOException {
57 if (server) {
58 if (initialData != null) {
59 if (initialData.length >= 1) {
60 sequenceSleep = IOUtils.byteToUnsignedInt(initialData[0]);
61 }
62 if (initialData.length >= 2) {
63 sequenceSize = IOUtils.byteToUnsignedInt(initialData[1]);
64 }
65 if (initialData.length >= 3) {
66 durationMSec = IOUtils.byteToUnsignedInt(initialData[2]);
67 }
68 }
69 } else {
70 sequenceSize = Configuration.tgSize & 0xFF;
71 sequenceSleep = Configuration.tgSleep & 0xFF;
72 durationMSec = Configuration.tgDurationMin;
73 }
74
75 sequenceSleep = sequenceSleep * 10;
76 if (sequenceSize < sequenceSizeMin) {
77 sequenceSize = sequenceSizeMin;
78 }
79 switch (sequenceSize) {
80 case 251:
81
82 sequenceSize = 0x400;
83 break;
84 case 252:
85
86 sequenceSize = 0x800;
87 break;
88 case 253:
89
90 sequenceSize = 0xC00;
91 break;
92 case 254:
93
94 sequenceSize = 0x1000;
95 break;
96 case 255:
97
98 sequenceSize = 0x1400;
99 break;
100 }
101 Logger.debug(messagePrefix + " size selected " + sequenceSize + " byte");
102 Logger.debug(messagePrefix + " duration " + durationMSec + " minutes");
103 durationMSec *= 60000;
104 return true;
105 }
106 }
107
108 public static void trafficGeneratorClientInit(ConnectionHolderL2CAP c, int testType) throws IOException {
109 byte sequenceSleep = (byte) (Configuration.tgSleep & 0xFF);
110 byte sequenceSize = (byte) (Configuration.tgSize & 0xFF);
111 byte durationMin = (byte) (Configuration.tgDurationMin & 0xFF);
112 c.channel.send(CommunicationTesterL2CAP.startPrefix(testType, new byte[] { sequenceSleep, sequenceSize,
113 durationMin }));
114 }
115
116 public static void trafficGeneratorWrite(ConnectionHolderL2CAP c, byte[] initialData, boolean server,
117 final TestStatus testStatus) throws IOException {
118 Config cf = new Config();
119 if (!cf.init(initialData, server, "L2 write")) {
120 return;
121 }
122 if (cf.sequenceSleep > 0) {
123 Logger.debug("write sleep selected " + cf.sequenceSleep + " msec");
124 } else {
125 Logger.debug("write no sleep");
126 }
127
128 int transmitMTU = c.channel.getTransmitMTU();
129 if (transmitMTU < cf.sequenceSize) {
130 Logger.warn("L2 write size " + cf.sequenceSize + " is greater then MTU " + transmitMTU);
131 cf.sequenceSize = transmitMTU;
132 }
133
134 long sequenceSentCount = 0;
135 int reportedSize = 0;
136
137
138 byte[] data = new byte[cf.sequenceSize];
139 for (int i = 1; i < cf.sequenceSize; i++) {
140 data[i] = (byte) i;
141 }
142 long start = System.currentTimeMillis();
143 long reported = start;
144 try {
145 mainLoop: do {
146 IOUtils.long2Bytes(sequenceSentCount, 8, data, 0);
147 long sendTime = System.currentTimeMillis();
148 IOUtils.long2Bytes(sendTime, 8, data, 8);
149 c.channel.send(data);
150 sequenceSentCount++;
151 reportedSize += cf.sequenceSize;
152 c.active();
153 long now = System.currentTimeMillis();
154 if (now - reported > 5 * 1000) {
155 Logger
156 .debug("L2 Sent " + sequenceSentCount + " packet(s) "
157 + TimeUtils.bps(reportedSize, reported));
158 reported = now;
159 reportedSize = 0;
160 }
161 if ((cf.durationMSec != 0) && (now > start + cf.durationMSec)) {
162 break;
163 }
164 if (cf.sequenceSleep > 0) {
165 try {
166 Thread.sleep(cf.sequenceSleep);
167 } catch (InterruptedException e) {
168 break mainLoop;
169 }
170 c.active();
171 }
172 } while (c.isConnectionOpen() && (!testStatus.isRunCompleate()));
173 } finally {
174 testStatus.setRunCompleate();
175 Logger.debug("L2 Total " + sequenceSentCount + " packet(s)");
176 Logger.debug("L2 Total write speed " + TimeUtils.bps(sequenceSentCount * cf.sequenceSize, start));
177 }
178 }
179
180 public static void trafficGeneratorStatusReadStart(final ConnectionHolderL2CAP c, final TestStatus testStatus) {
181 Runnable r = new Runnable() {
182 public void run() {
183 try {
184 trafficGeneratorStatusRead(c, testStatus);
185 } catch (IOException e) {
186 Logger.error("reader", e);
187 }
188 }
189 };
190 Thread t = RuntimeDetect.cldcStub.createNamedThread(r, "L2tgStatusReciver");
191 t.start();
192 }
193
194 public static void trafficGeneratorStatusRead(ConnectionHolderL2CAP c, final TestStatus testStatus)
195 throws IOException {
196 try {
197 int receiveMTU = c.channel.getReceiveMTU();
198 byte[] dataReceived = new byte[receiveMTU];
199 mainLoop: do {
200 if (!c.channel.ready()) {
201 try {
202 Thread.sleep(100);
203 } catch (InterruptedException e) {
204 break mainLoop;
205 }
206 } else {
207 c.channel.receive(dataReceived);
208 c.active();
209 }
210 } while (c.isConnectionOpen() && (!testStatus.isRunCompleate()));
211 } finally {
212 testStatus.setRunCompleate();
213 }
214 }
215
216 public static void trafficGeneratorReadStart(final ConnectionHolderL2CAP c, final byte[] initialData,
217 final TestStatus testStatus) {
218 Runnable r = new Runnable() {
219 public void run() {
220 try {
221 trafficGeneratorRead(c, initialData, testStatus);
222 } catch (IOException e) {
223 Logger.error("reader", e);
224 }
225 }
226 };
227 Thread t = RuntimeDetect.cldcStub.createNamedThread(r, "L2tgReciver");
228 t.start();
229 }
230
231 public static void trafficGeneratorRead(ConnectionHolderL2CAP c, byte[] initialData, final TestStatus testStatus)
232 throws IOException {
233 long sequenceRecivedCount = 0;
234 long sequenceRecivedNumberLast = -1;
235 long sequenceOutOfOrderCount = 0;
236 TimeStatistic delay = new TimeStatistic();
237 long start = System.currentTimeMillis();
238 long reported = start;
239 long receiveTimeLast = 0;
240 long reportedSize = 0;
241 long totalSize = 0;
242 try {
243 int receiveMTU = c.channel.getReceiveMTU();
244 mainLoop: do {
245 if (!c.channel.ready()) {
246 try {
247 Thread.sleep(100);
248 } catch (InterruptedException e) {
249 break mainLoop;
250 }
251 continue;
252 }
253 byte[] dataReceived = new byte[receiveMTU];
254 int lengthdataReceived = c.channel.receive(dataReceived);
255 c.active();
256 long receiveTime = System.currentTimeMillis();
257 sequenceRecivedCount++;
258 long sendTime = 0;
259 reportedSize += lengthdataReceived;
260 totalSize += lengthdataReceived;
261
262 if (lengthdataReceived > 8) {
263 long sequenceRecivedNumber = IOUtils.bytes2Long(dataReceived, 0, 8);
264 if (sequenceRecivedNumberLast + 1 != sequenceRecivedNumber) {
265 sequenceOutOfOrderCount++;
266 } else if (lengthdataReceived > 18) {
267 sendTime = IOUtils.bytes2Long(dataReceived, 8, 8);
268 }
269 sequenceRecivedNumberLast = sequenceRecivedNumber;
270 } else {
271 sequenceOutOfOrderCount++;
272 }
273
274 if (receiveTimeLast != 0) {
275 delay.add(receiveTimeLast - receiveTime);
276 receiveTimeLast = receiveTime;
277 }
278
279 long now = receiveTime;
280 if (now - reported > 5 * 1000) {
281 Logger.debug("L2 Received " + sequenceRecivedCount + "/" + sequenceOutOfOrderCount
282 + "(er) packet(s) " + delay.avg() + " msec");
283 Logger.debug("L2 Received " + TimeUtils.bps(reportedSize, reported));
284 reported = now;
285 reportedSize = 0;
286 }
287
288 } while (c.isConnectionOpen() && (!testStatus.isRunCompleate()));
289 } finally {
290 testStatus.setRunCompleate();
291 Logger.debug("L2 Total Received " + sequenceRecivedCount + " packet(s)");
292 Logger.debug("L2 Total Misplaced " + sequenceOutOfOrderCount + " packet(s)");
293 Logger.debug("L2 avg interval " + delay.avg() + " msec");
294 Logger.debug("L2 Total read speed " + TimeUtils.bps(totalSize, start));
295 }
296 }
297 }