View Javadoc

1   /**
2    *  BlueCove - Java library for Bluetooth
3    *  Copyright (C) 2006-2008 Vlad Skarzhevskyy
4    *
5    *  Licensed to the Apache Software Foundation (ASF) under one
6    *  or more contributor license agreements.  See the NOTICE file
7    *  distributed with this work for additional information
8    *  regarding copyright ownership.  The ASF licenses this file
9    *  to you under the Apache License, Version 2.0 (the
10   *  "License"); you may not use this file except in compliance
11   *  with the License.  You may obtain a copy of the License at
12   *
13   *    http://www.apache.org/licenses/LICENSE-2.0
14   *
15   *  Unless required by applicable law or agreed to in writing,
16   *  software distributed under the License is distributed on an
17   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18   *  KIND, either express or implied.  See the License for the
19   *  specific language governing permissions and limitations
20   *  under the License.
21   *
22   *  @author vlads
23   *  @version $Id: CommunicationTester.java 2607 2008-12-17 23:51:33Z skarzhevskyy $
24   */
25  package net.sf.bluecove;
26  
27  import java.io.DataInputStream;
28  import java.io.DataOutputStream;
29  import java.io.IOException;
30  import java.io.InputStream;
31  import java.io.OutputStream;
32  
33  import javax.bluetooth.LocalDevice;
34  import javax.bluetooth.RemoteDevice;
35  import javax.microedition.io.StreamConnection;
36  
37  import org.bluecove.tester.log.Logger;
38  import org.bluecove.tester.util.RuntimeDetect;
39  import org.bluecove.tester.util.TimeUtils;
40  
41  import junit.framework.Assert;
42  import net.sf.bluecove.tests.RfTrafficGenerator;
43  import net.sf.bluecove.tests.TwoThreadsPerConnection;
44  import net.sf.bluecove.tests.RfTrafficGenerator.Config;
45  import net.sf.bluecove.util.ValueHolder;
46  
47  public class CommunicationTester extends CommunicationData {
48  
49  	public static boolean dataOutputStreamFlush = true;
50  
51  	public static int clientConnectionOpenRetry = 3;
52  
53  	static void sendString(OutputStream os) throws IOException {
54  		DataOutputStream dos = new DataOutputStream(os);
55  		dos.writeUTF(stringData);
56  		if (dataOutputStreamFlush) {
57  			dos.flush();
58  		}
59  	}
60  
61  	static void readString(InputStream is) throws IOException {
62  		DataInputStream dis = new DataInputStream(is);
63  		String got = dis.readUTF();
64  		Assert.assertEquals("ReadString", stringData, got);
65  	}
66  
67  	static void sendUTFString(OutputStream os) throws IOException {
68  		DataOutputStream dos = new DataOutputStream(os);
69  		dos.writeUTF(stringUTFData);
70  		if (dataOutputStreamFlush) {
71  			dos.flush();
72  		}
73  	}
74  
75  	static void readUTFString(InputStream is) throws IOException {
76  		DataInputStream dis = new DataInputStream(is);
77  		String got = dis.readUTF();
78  		Assert.assertEquals("ReadString", stringUTFData, got);
79  	}
80  
81  	static void sendByte(OutputStream os) throws IOException {
82  		os.write(aKnowndPositiveByte);
83  		os.write(aKnowndNegativeByte);
84  
85  		// Test int conversions
86  		int bp = aKnowndPositiveByte;
87  		os.write(bp);
88  		int bn = aKnowndNegativeByte;
89  		os.write(bn);
90  
91  		for (int i = 1; i < byteCount; i++) {
92  			os.write((byte) i);
93  		}
94  		for (int i = 0; i < byteAray.length; i++) {
95  			os.write(byteAray[i]);
96  		}
97  		// The byte to be written is the eight low-order bits of the argument b.
98  		os.write(0xABC);
99  		os.write(aKnowndPositiveByte);
100 	}
101 
102 	static void readByte(InputStream is) throws IOException {
103 		Assert.assertEquals("positiveByte", aKnowndPositiveByte, (byte) is.read());
104 		Assert.assertEquals("negativeByte", aKnowndNegativeByte, (byte) is.read());
105 		Assert.assertEquals("positiveByte written(int)", aKnowndPositiveByte, (byte) is.read());
106 		Assert.assertEquals("negativeByte written(int)", aKnowndNegativeByte, (byte) is.read());
107 		for (int i = 1; i < byteCount; i++) {
108 			byte got = (byte) is.read();
109 			Assert.assertEquals("t1, byte [" + i + "]", (byte) i, got);
110 		}
111 		for (int i = 0; i < byteAray.length; i++) {
112 			byte got = (byte) is.read();
113 			Assert.assertEquals("t2, byte [" + i + "]", byteAray[i], got);
114 		}
115 		int abc = is.read();
116 		Assert.assertEquals("written(0xABC)", 0xBC, abc);
117 		Assert.assertEquals("positiveByte", aKnowndPositiveByte, (byte) is.read());
118 	}
119 
120 	static void sendBytes256(OutputStream os) throws IOException {
121 		// Write all 256 bytes
122 		int cnt = 0;
123 		for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
124 			try {
125 				os.write((byte) i);
126 				cnt++;
127 			} catch (IOException e) {
128 				Logger.debug("Sent only " + cnt + " bytes");
129 				throw e;
130 			}
131 		}
132 		// Send one more byte to see is 0xFF is not EOF
133 		os.write(aKnowndPositiveByte);
134 	}
135 
136 	static void readBytes256(InputStream is) throws IOException {
137 		// Read all 256 bytes
138 		int cnt = 0;
139 		for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
140 			byte got;
141 			try {
142 				got = (byte) is.read();
143 				cnt++;
144 			} catch (IOException e) {
145 				Logger.debug("Received only " + cnt + " bytes");
146 				throw e;
147 			}
148 			Assert.assertEquals("all bytes [" + i + "]", (byte) i, got);
149 		}
150 		Assert.assertEquals("conformation that 0xFF is not EOF", aKnowndPositiveByte, (byte) is.read());
151 	}
152 
153 	static void sendByteAray(OutputStream os) throws IOException {
154 		os.write(byteAray);
155 	}
156 
157 	static void readByteAray(InputStream is) throws IOException {
158 		byte[] byteArayGot = new byte[byteAray.length];
159 		int got = is.read(byteArayGot);
160 		Assert.assertEquals("byteAray.len", byteAray.length, got);
161 		for (int i = 0; i < byteAray.length; i++) {
162 			Assert.assertEquals("byte", byteAray[i], byteArayGot[i]);
163 		}
164 	}
165 
166 	static void sendDataStream(OutputStream os) throws IOException {
167 		DataOutputStream dos = new DataOutputStream(os);
168 		dos.writeUTF(stringData);
169 		dos.writeInt(1025);
170 		dos.writeLong(567890025);
171 		dos.writeBoolean(true);
172 		dos.writeBoolean(false);
173 		dos.writeChar('O');
174 		dos.writeShort(541);
175 		// CLDC_1_0 dos.writeFloat((float)3.14159);
176 		// CLDC_1_0 dos.writeDouble(Math.E);
177 		dos.writeByte(aKnowndPositiveByte);
178 		dos.writeByte(aKnowndNegativeByte);
179 		if (dataOutputStreamFlush) {
180 			dos.flush();
181 		}
182 	}
183 
184 	static void readDataStream(InputStream is) throws IOException {
185 		DataInputStream dis = new DataInputStream(is);
186 		String got = dis.readUTF();
187 		Assert.assertEquals("ReadString", stringData, got);
188 		Assert.assertEquals("ReadInt", 1025, dis.readInt());
189 		Assert.assertEquals("ReadLong", 567890025, dis.readLong());
190 		Assert.assertEquals("ReadBoolean", true, dis.readBoolean());
191 		Assert.assertEquals("ReadBoolean2", false, dis.readBoolean());
192 		Assert.assertEquals("ReadChar", 'O', dis.readChar());
193 		Assert.assertEquals("readShort", 541, dis.readShort());
194 		// CLDC_1_0 Assert.assertEquals("readFloat", (float)3.14159,
195 		// dis.readFloat(), (float)0.0000001);
196 		// CLDC_1_0 Assert.assertEquals("readDouble", Math.E, dis.readDouble(),
197 		// 0.0000000000000001);
198 		Assert.assertEquals("positiveByte", aKnowndPositiveByte, dis.readByte());
199 		Assert.assertEquals("negativeByte", aKnowndNegativeByte, dis.readByte());
200 	}
201 
202 	private static void sendStreamAvailable(InputStream is, OutputStream os) throws IOException {
203 		for (int i = 1; i < streamAvailableByteCount; i++) {
204 			os.write(i);
205 			if (i % 10 == 0) {
206 				os.flush();
207 			}
208 		}
209 		// Long test need confirmation
210 		os.flush();
211 		byte got = (byte) is.read();
212 		Assert.assertEquals("Confirmation byte", streamAvailableByteCount, got);
213 	}
214 
215 	private static void readStreamAvailable(InputStream is, OutputStream os) throws IOException {
216 		int available = 0;
217 		for (int i = 1; i < streamAvailableByteCount; i++) {
218 			boolean hasData = (available > 0);
219 			int tryCount = 0;
220 			while (!hasData) {
221 				// This blocks on Nokia(Srv) on second call connected to
222 				// Widcomm(Client)
223 				try {
224 					available = is.available();
225 				} catch (IOException e) {
226 					Logger.debug("(m1) Received only " + i + " bytes");
227 					throw e;
228 				}
229 				if (available > 0) {
230 					hasData = true;
231 				} else if (available < 0) {
232 					Assert.fail("negative available");
233 				}
234 				tryCount++;
235 				try {
236 					Thread.sleep(300);
237 				} catch (InterruptedException e) {
238 					Assert.fail("Test Interrupted");
239 				}
240 				if (tryCount > 70) {
241 					Assert.fail("Test Available took too long, got " + i + " bytes");
242 				}
243 			}
244 
245 			byte got;
246 			try {
247 				got = (byte) is.read();
248 			} catch (IOException e) {
249 				Logger.debug("(m2) Received only " + i + " bytes");
250 				throw e;
251 			}
252 			Assert.assertEquals("byte[" + i + "]", i, got);
253 			available--;
254 		}
255 		os.write(streamAvailableByteCount);
256 		os.flush();
257 	}
258 
259 	private static void sendEOF(ConnectionHolderStream c, TestStatus testStatus) throws IOException {
260 		c.os.write(aKnowndPositiveByte);
261 		c.os.flush();
262 		Assert.assertEquals("byte received", aKnowndNegativeByte, (byte) c.is.read());
263 		c.disconnected();
264 		c.os.close();
265 		c.is.close();
266 		testStatus.streamClosed = true;
267 	}
268 
269 	private static void readEOF(InputStream is, OutputStream os, TestStatus testStatus) throws IOException {
270 		Assert.assertEquals("byte", aKnowndPositiveByte, (byte) is.read());
271 		os.write(aKnowndNegativeByte);
272 		os.flush();
273 		long startWait = System.currentTimeMillis();
274 		Assert.assertEquals("EOF expected", -1, is.read());
275 		testStatus.streamClosed = true;
276 		Assert.assertFalse("Took too long to close", TimeUtils.since(startWait) > 7 * 1000);
277 		testStatus.isSuccess = true;
278 	}
279 
280 	private static void sendArayEOF(ConnectionHolderStream c, TestStatus testStatus) throws IOException {
281 		c.os.write(aKnowndPositiveByte);
282 		c.os.write(aKnowndNegativeByte);
283 		c.os.flush();
284 		// Let the server read the message
285 		try {
286 			Thread.sleep(1200);
287 		} catch (InterruptedException e) {
288 			Assert.fail("Test Interrupted");
289 		}
290 		c.disconnected();
291 		c.os.close();
292 		c.is.close();
293 		testStatus.streamClosed = true;
294 	}
295 
296 	private static void readArayEOF(InputStream is, OutputStream os, TestStatus testStatus) throws IOException {
297 		byte[] byteArayGot = new byte[3];
298 		int got = is.read(byteArayGot);
299 		if (got == 1) {
300 			int size = is.read(byteArayGot, 1, 2);
301 			if (size != -1) {
302 				got += size;
303 			}
304 		}
305 		Assert.assertEquals("byteAray.len", 2, got);
306 		Assert.assertEquals("byte1", aKnowndPositiveByte, byteArayGot[0]);
307 		Assert.assertEquals("byte2", aKnowndNegativeByte, byteArayGot[1]);
308 		int got2 = is.read(byteArayGot);
309 		Assert.assertEquals("EOF expected", -1, got2);
310 		testStatus.streamClosed = true;
311 		testStatus.isSuccess = true;
312 	}
313 
314 	private static void sendClosedConnection(ConnectionHolderStream c, TestStatus testStatus) throws IOException {
315 		c.os.write(aKnowndPositiveByte);
316 		c.os.write(aKnowndNegativeByte);
317 		c.os.flush();
318 		// Let the server read the message
319 		try {
320 			Thread.sleep(1200);
321 		} catch (InterruptedException e) {
322 			Assert.fail("Test Interrupted");
323 		}
324 		c.disconnected();
325 		c.os.close();
326 		c.is.close();
327 		testStatus.streamClosed = true;
328 
329 		try {
330 			c.os.write(byteAray);
331 			c.os.flush();
332 			Assert.fail("Can write to closed OutputStream");
333 		} catch (IOException ok) {
334 			testStatus.isSuccess = true;
335 		}
336 	}
337 
338 	private static void readClosedConnection(ConnectionHolderStream c, TestStatus testStatus) throws IOException {
339 		Assert.assertEquals("byte1", aKnowndPositiveByte, (byte) c.is.read());
340 		Assert.assertEquals("byte2", aKnowndNegativeByte, (byte) c.is.read());
341 		testStatus.streamClosed = true;
342 		try {
343 			Assert.assertEquals("EOF expected", -1, c.is.read());
344 		} catch (IOException e) {
345 			if (RuntimeDetect.isBlueCove) {
346 				Logger.error("EOF IOException not expected", e);
347 				Assert.fail("EOF IOException not expected [" + e.toString() + "]");
348 			}
349 		}
350 		c.disconnected();
351 		try {
352 			c.os.write(byteAray);
353 			c.os.flush();
354 			Assert.fail("Can write to closed BT Connection");
355 		} catch (IOException ok) {
356 			testStatus.isSuccess = true;
357 		}
358 	}
359 
360 	private static void serverRemoteDevice(StreamConnection conn, InputStream is, OutputStream os, TestStatus testStatus)
361 			throws IOException {
362 		RemoteDevice device = RemoteDevice.getRemoteDevice(conn);
363 		Logger.debug("is connected to BTAddress " + device.getBluetoothAddress());
364 		DataInputStream dis = new DataInputStream(is);
365 		DataOutputStream dos = new DataOutputStream(os);
366 		String gotBluetoothAddress = dis.readUTF();
367 		Assert.assertEquals("PairBTAddress", gotBluetoothAddress.toUpperCase(), device.getBluetoothAddress()
368 				.toUpperCase());
369 
370 		boolean remoreIsAuthenticated = dis.readBoolean();
371 		boolean remoreIsEncrypted = dis.readBoolean();
372 
373 		boolean isAuthenticated = device.isAuthenticated();
374 		boolean isEncrypted = device.isEncrypted();
375 
376 		dos.writeBoolean(isAuthenticated);
377 		dos.writeBoolean(isEncrypted);
378 		if (dataOutputStreamFlush) {
379 			dos.flush();
380 		}
381 
382 		if (Configuration.authenticate.booleanValue()) {
383 			if (!isAuthenticated) {
384 				Logger.error("wrong isAuthenticated " + isAuthenticated);
385 				testStatus.isError = true;
386 			} else {
387 				Logger.debug("isAuthenticated OK " + isAuthenticated);
388 			}
389 		} else {
390 			Logger.debug("isAuthenticated " + isAuthenticated);
391 		}
392 		if (remoreIsAuthenticated != isAuthenticated) {
393 			Logger.error("this Authenticated " + isAuthenticated + " != remote " + remoreIsAuthenticated);
394 			testStatus.isError = true;
395 		}
396 
397 		if (Configuration.encrypt.booleanValue()) {
398 			if (!isEncrypted) {
399 				Logger.error("wrong isEncrypted " + isEncrypted);
400 				testStatus.isError = true;
401 			} else {
402 				Logger.debug("isEncrypted OK " + isEncrypted);
403 			}
404 		} else if (isEncrypted && (remoreIsEncrypted == isEncrypted)) {
405 			Logger.debug("isEncrypted OK " + isEncrypted);
406 		} else {
407 			Logger.debug("isEncrypted " + isEncrypted);
408 		}
409 		if (remoreIsEncrypted != isEncrypted) {
410 			Logger.error("this Encrypted " + isEncrypted + " != remote " + remoreIsEncrypted);
411 			testStatus.isError = true;
412 		}
413 	}
414 
415 	private static void clientRemoteDevice(StreamConnection conn, InputStream is, OutputStream os, TestStatus testStatus)
416 			throws IOException {
417 		RemoteDevice device = RemoteDevice.getRemoteDevice(conn);
418 		Logger.debug("is connected toBTAddress " + device.getBluetoothAddress());
419 		DataOutputStream dos = new DataOutputStream(os);
420 		DataInputStream dis = new DataInputStream(is);
421 		dos.writeUTF(LocalDevice.getLocalDevice().getBluetoothAddress());
422 		if (dataOutputStreamFlush) {
423 			dos.flush();
424 		}
425 		Assert.assertEquals("PairBTAddress", testStatus.pairBTAddress.toUpperCase(), device.getBluetoothAddress()
426 				.toUpperCase());
427 
428 		boolean isAuthenticated = device.isAuthenticated();
429 		boolean isEncrypted = device.isEncrypted();
430 
431 		dos.writeBoolean(isAuthenticated);
432 		dos.writeBoolean(isEncrypted);
433 		if (dataOutputStreamFlush) {
434 			dos.flush();
435 		}
436 		boolean remoreIsAuthenticated = dis.readBoolean();
437 		boolean remoreIsEncrypted = dis.readBoolean();
438 
439 		if (Configuration.authenticate.booleanValue() == isAuthenticated) {
440 			Logger.debug("isAuthenticated OK " + Configuration.authenticate);
441 		} else if (Configuration.authenticate.booleanValue() && !isAuthenticated) {
442 			Logger.error("wrong isAuthenticated " + isAuthenticated);
443 		} else {
444 			Logger.debug("isAuthenticated OK " + isAuthenticated);
445 		}
446 		if (remoreIsAuthenticated != isAuthenticated) {
447 			Logger.error("this Authenticated " + isAuthenticated + " != remote " + remoreIsAuthenticated);
448 			testStatus.isError = true;
449 		}
450 
451 		if (Configuration.encrypt.booleanValue() == isEncrypted) {
452 			Logger.debug("isEncrypted OK " + Configuration.encrypt);
453 		} else if (Configuration.encrypt.booleanValue() && !isEncrypted) {
454 			Logger.error("wrong isEncrypted " + isEncrypted);
455 		} else {
456 			Logger.debug("isEncrypted OK " + isEncrypted);
457 		}
458 		if (remoreIsEncrypted != isEncrypted) {
459 			Logger.error("this Encrypted " + isEncrypted + " != remote " + remoreIsEncrypted);
460 			testStatus.isError = true;
461 		}
462 	}
463 
464 	static void sendByte4clientToClose(OutputStream os, InputStream is, TestStatus testStatus) throws IOException {
465 		os.write(aKnowndPositiveByte);
466 		os.flush();
467 
468 		TimeUtils.sleep(1 * 1000);
469 
470 		// Do not send any reply to client.
471 		testStatus.streamClosed = true;
472 
473 		long startWait = System.currentTimeMillis();
474 		// wait for client to close connection, This has been tested in
475 		// TEST_EOF_READ
476 		int eof = 0;
477 		try {
478 			eof = is.read();
479 			Assert.assertEquals("EOF expected", -1, eof);
480 		} catch (IOException e) {
481 			Logger.debug("OK conn.closed");
482 		}
483 		Assert.assertFalse("Took too long to close", TimeUtils.since(startWait) > 7 * 1000);
484 		testStatus.isSuccess = true;
485 	}
486 
487 	static void reciveByteAndCloseStream(boolean testArray, final ConnectionHolderStream c, TestStatus testStatus)
488 			throws IOException {
489 		Assert.assertEquals("byte", aKnowndPositiveByte, (byte) c.is.read());
490 		final ValueHolder whenClose = new ValueHolder();
491 		final ValueHolder alreadyClose = new ValueHolder(false);
492 		final ValueHolder whoClose = new ValueHolder();
493 		final boolean debug = true;
494 		Runnable r = new Runnable() {
495 			public void run() {
496 				TimeUtils.sleep(500);
497 				c.disconnected();
498 				if (debug) {
499 					Logger.debug("try to closed");
500 				}
501 				whenClose.valueLong = System.currentTimeMillis();
502 				whoClose.valueInt = 1;
503 				try {
504 					// No effect on Nokia
505 					c.conn.close();
506 				} catch (IOException e) {
507 					Logger.debug("error in conn close", e);
508 				}
509 				if (debug) {
510 					Logger.debug("conn.closed");
511 				}
512 				whenClose.valueLong = System.currentTimeMillis();
513 				TimeUtils.sleep(100);
514 				if (!alreadyClose.valueBoolean) {
515 					TimeUtils.sleep(600);
516 					whenClose.valueLong = System.currentTimeMillis();
517 					whoClose.valueInt = 2;
518 					try {
519 						c.is.close();
520 					} catch (IOException e) {
521 						Logger.debug("error in is close", e);
522 					}
523 					if (debug) {
524 						Logger.debug("is.closed");
525 					}
526 					whenClose.valueLong = System.currentTimeMillis();
527 					TimeUtils.sleep(100);
528 					if (!alreadyClose.valueBoolean) {
529 						TimeUtils.sleep(600);
530 						whenClose.valueLong = System.currentTimeMillis();
531 						whoClose.valueInt = 3;
532 						try {
533 							c.os.close();
534 						} catch (IOException e) {
535 							Logger.debug("error in os close", e);
536 						}
537 						if (debug) {
538 							Logger.debug("os.closed");
539 						}
540 						whenClose.valueLong = System.currentTimeMillis();
541 					}
542 				}
543 				if (debug) {
544 					Logger.debug("close thread finished");
545 				}
546 			}
547 		};
548 		Thread t = RuntimeDetect.cldcStub.createNamedThread(r, "ReciveStreamCloser");
549 		t.start();
550 
551 		testStatus.streamClosed = true;
552 		// This will stuck since server is not sending any more data.
553 		// conn.close() should force read() to throw exception or return -1.
554 		int eof = 0;
555 		try {
556 			if (debug) {
557 				Logger.debug("try to read EOF");
558 			}
559 			// This is function under test
560 			if (testArray) {
561 				byte[] buf = new byte[2];
562 				eof = c.is.read(buf, 0, buf.length);
563 			} else {
564 				eof = c.is.read();
565 			}
566 			Assert.assertEquals("EOF expected", -1, eof);
567 			Logger.debug("OK read on conn.closed GOT EOF");
568 		} catch (IOException e) {
569 			Logger.debug("OK read on conn.closed throws Exception", e);
570 		} finally {
571 			if (debug) {
572 				Logger.debug("read EOF ends");
573 			}
574 		}
575 		alreadyClose.valueBoolean = true;
576 		long returenedDelay = System.currentTimeMillis() - whenClose.valueLong;
577 		if ((returenedDelay < 2 * 1000) || (returenedDelay > -2 * 1000)) {
578 			testStatus.isSuccess = true;
579 		} else {
580 			Assert.fail("Took too long " + (returenedDelay) + " to return");
581 		}
582 		switch (whoClose.valueInt) {
583 		case 1:
584 			Logger.debug("Closed by StreamConnection.close()");
585 			break;
586 		case 2:
587 			Logger.debug("Closed by InputStream.close()");
588 			break;
589 		case 3:
590 			Logger.debug("Closed by OutputStream.close()");
591 			break;
592 		default:
593 			Assert.fail("Closed by unknown source");
594 		}
595 	}
596 
597 	static void sendByteArayLarge(ConnectionHolderStream c, InputStream is, OutputStream os, int araySize)
598 			throws IOException {
599 		long start = System.currentTimeMillis();
600 		c.setTestTimeOutSec(araySize / 1000);
601 		byte[] byteArayLarge = new byte[araySize];
602 		for (int i = 0; i < araySize; i++) {
603 			byteArayLarge[i] = (byte) (i & 0xF);
604 		}
605 		os.write(byteArayLarge);
606 		c.active();
607 		os.flush();
608 		int ok = is.read();
609 		c.active();
610 		Assert.assertEquals("confirmation expected", 1, ok);
611 		Logger.debug("send speed " + TimeUtils.bps(araySize, start));
612 	}
613 
614 	static void readByteArayLarge(ConnectionHolderStream c, InputStream is, OutputStream os, int araySize)
615 			throws IOException {
616 		long start = System.currentTimeMillis();
617 		byte[] byteArayGot = new byte[araySize];
618 		int got = 0;
619 		c.setTestTimeOutSec(araySize / 1000);
620 		boolean readInterrupted = true;
621 		try {
622 			while (got < araySize) {
623 				int read = is.read(byteArayGot, got, araySize - got);
624 				if (read == -1) {
625 					break;
626 				}
627 				got += read;
628 				c.active();
629 			}
630 			readInterrupted = false;
631 		} finally {
632 			if (readInterrupted) {
633 				Logger.debug("Received only " + got);
634 			}
635 		}
636 
637 		Assert.assertEquals("byteArayLarge.len", araySize, got);
638 		for (int i = 0; i < araySize; i++) {
639 			Assert.assertEquals("byte", (i & 0xF), byteArayGot[i]);
640 		}
641 		os.write(1);
642 		c.active();
643 		os.flush();
644 		Logger.debug("read speed " + TimeUtils.bps(araySize, start));
645 	}
646 
647 	public static void runTest(int testType, boolean server, ConnectionHolderStream c, TestStatus testStatus)
648 			throws IOException {
649 		InputStream is = c.is;
650 		OutputStream os = c.os;
651 		switch (testType) {
652 		case TEST_STRING:
653 			testStatus.setName("STRING");
654 			if (server) {
655 				CommunicationTester.readString(is);
656 			} else {
657 				CommunicationTester.sendString(os);
658 			}
659 			break;
660 		case TEST_STRING_BACK:
661 			testStatus.setName("STRING_BACK");
662 			if (!server) {
663 				CommunicationTester.readString(is);
664 			} else {
665 				CommunicationTester.sendString(os);
666 			}
667 			break;
668 		case TEST_BYTE:
669 			testStatus.setName("BYTE");
670 			if (server) {
671 				CommunicationTester.readByte(is);
672 			} else {
673 				CommunicationTester.sendByte(os);
674 			}
675 			break;
676 		case TEST_BYTE_BACK:
677 			testStatus.setName("BYTE_BACK");
678 			if (!server) {
679 				CommunicationTester.readByte(is);
680 			} else {
681 				CommunicationTester.sendByte(os);
682 			}
683 			break;
684 		case TEST_STRING_UTF:
685 			testStatus.setName("STRING_UTF");
686 			if (server) {
687 				CommunicationTester.readUTFString(is);
688 			} else {
689 				CommunicationTester.sendUTFString(os);
690 			}
691 			break;
692 		case TEST_STRING_UTF_BACK:
693 			testStatus.setName("STRING_UTF_BACK");
694 			if (!server) {
695 				CommunicationTester.readUTFString(is);
696 			} else {
697 				CommunicationTester.sendUTFString(os);
698 			}
699 			break;
700 		case TEST_BYTE_ARRAY:
701 			testStatus.setName("BYTE_ARRAY");
702 			if (server) {
703 				CommunicationTester.readByteAray(is);
704 			} else {
705 				CommunicationTester.sendByteAray(os);
706 			}
707 			break;
708 		case TEST_BYTE_ARRAY_BACK:
709 			testStatus.setName("BYTE_ARRAY_BACK");
710 			if (!server) {
711 				CommunicationTester.readByteAray(is);
712 			} else {
713 				CommunicationTester.sendByteAray(os);
714 			}
715 			break;
716 		case TEST_DataStream:
717 			testStatus.setName("DataStream");
718 			if (server) {
719 				CommunicationTester.readDataStream(is);
720 			} else {
721 				CommunicationTester.sendDataStream(os);
722 			}
723 			break;
724 		case TEST_DataStream_BACK:
725 			testStatus.setName("DataStream_BACK");
726 			if (!server) {
727 				CommunicationTester.readDataStream(is);
728 			} else {
729 				CommunicationTester.sendDataStream(os);
730 			}
731 			break;
732 		case TEST_StreamAvailable:
733 			testStatus.setName("StreamAvailable");
734 			if (server) {
735 				CommunicationTester.readStreamAvailable(is, os);
736 			} else {
737 				CommunicationTester.sendStreamAvailable(is, os);
738 			}
739 			break;
740 		case TEST_StreamAvailable_BACK:
741 			testStatus.setName("StreamAvailable_BACK");
742 			if (!server) {
743 				CommunicationTester.readStreamAvailable(is, os);
744 			} else {
745 				CommunicationTester.sendStreamAvailable(is, os);
746 			}
747 			break;
748 		case TEST_EOF_READ:
749 			testStatus.setName("EOF_READ");
750 			if (server) {
751 				CommunicationTester.readEOF(is, os, testStatus);
752 			} else {
753 				CommunicationTester.sendEOF(c, testStatus);
754 			}
755 			break;
756 		case TEST_EOF_READ_BACK:
757 			testStatus.setName("EOF_READ_BACK");
758 			if (!server) {
759 				CommunicationTester.readEOF(is, os, testStatus);
760 			} else {
761 				CommunicationTester.sendEOF(c, testStatus);
762 			}
763 			break;
764 		case TEST_EOF_READ_ARRAY:
765 			testStatus.setName("EOF_READ_ARRAY");
766 			if (server) {
767 				CommunicationTester.readArayEOF(is, os, testStatus);
768 			} else {
769 				CommunicationTester.sendArayEOF(c, testStatus);
770 			}
771 			break;
772 		case TEST_EOF_READ_ARRAY_BACK:
773 			testStatus.setName("EOF_READ_ARRAY_BACK");
774 			if (!server) {
775 				CommunicationTester.readArayEOF(is, os, testStatus);
776 			} else {
777 				CommunicationTester.sendArayEOF(c, testStatus);
778 			}
779 			break;
780 		case TEST_CONNECTION_INFO:
781 			testStatus.setName("TEST_CONNECTION_INFO");
782 			if (server) {
783 				CommunicationTester.serverRemoteDevice(c.conn, is, os, testStatus);
784 			} else {
785 				CommunicationTester.clientRemoteDevice(c.conn, is, os, testStatus);
786 			}
787 			break;
788 		case TEST_CLOSED_CONNECTION:
789 			testStatus.setName("CLOSED_CONNECTION");
790 			if (server) {
791 				CommunicationTester.readClosedConnection(c, testStatus);
792 			} else {
793 				CommunicationTester.sendClosedConnection(c, testStatus);
794 			}
795 			break;
796 		case TEST_CLOSED_CONNECTION_BACK:
797 			testStatus.setName("CLOSED_CONNECTION_BACK");
798 			if (!server) {
799 				CommunicationTester.readClosedConnection(c, testStatus);
800 			} else {
801 				CommunicationTester.sendClosedConnection(c, testStatus);
802 			}
803 			break;
804 		case TEST_BYTES_256:
805 			testStatus.setName("BYTES256");
806 			if (server) {
807 				CommunicationTester.readBytes256(is);
808 			} else {
809 				CommunicationTester.sendBytes256(os);
810 			}
811 			break;
812 		case TEST_BYTES_256_BACK:
813 			testStatus.setName("BYTES256_BACK");
814 			if (!server) {
815 				CommunicationTester.readBytes256(is);
816 			} else {
817 				CommunicationTester.sendBytes256(os);
818 			}
819 			break;
820 		case TEST_CAN_CLOSE_READ_ON_CLIENT:
821 			testStatus.setName("CAN_CLOSE_READ_ON_CLIENT");
822 			if (server) {
823 				CommunicationTester.sendByte4clientToClose(os, is, testStatus);
824 			} else {
825 				CommunicationTester.reciveByteAndCloseStream(false, c, testStatus);
826 			}
827 			break;
828 		case TEST_CAN_CLOSE_READ_ON_SERVER:
829 			testStatus.setName("CAN_CLOSE_READ_ON_SERVER");
830 			if (!server) {
831 				CommunicationTester.sendByte4clientToClose(os, is, testStatus);
832 			} else {
833 				CommunicationTester.reciveByteAndCloseStream(false, c, testStatus);
834 			}
835 			break;
836 		case TEST_CAN_CLOSE_READ_ARRAY_ON_CLIENT:
837 			testStatus.setName("CAN_CLOSE_READ_ARRAY_ON_CLIENT");
838 			if (server) {
839 				CommunicationTester.sendByte4clientToClose(os, is, testStatus);
840 			} else {
841 				CommunicationTester.reciveByteAndCloseStream(true, c, testStatus);
842 			}
843 			break;
844 		case TEST_CAN_CLOSE_READ_ARRAY_ON_SERVER:
845 			testStatus.setName("CAN_CLOSE_READ_ARRAY_ON_SERVER");
846 			if (!server) {
847 				CommunicationTester.sendByte4clientToClose(os, is, testStatus);
848 			} else {
849 				CommunicationTester.reciveByteAndCloseStream(true, c, testStatus);
850 			}
851 			break;
852 		case TEST_TWO_THREADS_SYNC_BYTES:
853 			testStatus.setName("TWO_THREADS_SYNC_BYTES");
854 			TwoThreadsPerConnection.start(c, 1, true);
855 			break;
856 		case TEST_TWO_THREADS_SYNC_ARRAYS:
857 			testStatus.setName("TWO_THREADS_SYNC_ARRAYS");
858 			TwoThreadsPerConnection.start(c, 64, true);
859 			break;
860 		case TEST_TWO_THREADS_BYTES:
861 			testStatus.setName("TWO_THREADS_BYTES");
862 			TwoThreadsPerConnection.start(c, 1, false);
863 			break;
864 		case TEST_TWO_THREADS_ARRAYS:
865 			testStatus.setName("TWO_THREADS_ARRAYS");
866 			TwoThreadsPerConnection.start(c, 64, false);
867 			break;
868 		case TEST_8K_PLUS_BYTE_ARRAY:
869 			testStatus.setName("8K_PLUS_BYTE_ARRAY");
870 			if (server) {
871 				CommunicationTester.readByteArayLarge(c, is, os, byteAray8KPlusSize);
872 			} else {
873 				CommunicationTester.sendByteArayLarge(c, is, os, byteAray8KPlusSize);
874 			}
875 			break;
876 		case TEST_8K_PLUS_BYTE_ARRAY_BACK:
877 			testStatus.setName("8K_PLUS_BYTE_ARRAY_BACK");
878 			if (!server) {
879 				CommunicationTester.readByteArayLarge(c, is, os, byteAray8KPlusSize);
880 			} else {
881 				CommunicationTester.sendByteArayLarge(c, is, os, byteAray8KPlusSize);
882 			}
883 			break;
884 		case TEST_64K_PLUS_BYTE_ARRAY:
885 			testStatus.setName("64K_PLUS_BYTE_ARRAY");
886 			if (server) {
887 				CommunicationTester.readByteArayLarge(c, is, os, byteAray64KPlusSize);
888 			} else {
889 				CommunicationTester.sendByteArayLarge(c, is, os, byteAray64KPlusSize);
890 			}
891 			break;
892 		case TEST_64K_PLUS_BYTE_ARRAY_BACK:
893 			testStatus.setName("64K_PLUS_BYTE_ARRAY_BACK");
894 			if (!server) {
895 				CommunicationTester.readByteArayLarge(c, is, os, byteAray64KPlusSize);
896 			} else {
897 				CommunicationTester.sendByteArayLarge(c, is, os, byteAray64KPlusSize);
898 			}
899 			break;
900 
901 		case TEST_128K_BYTE_ARRAY_X_10:
902 			testStatus.setName("128K_BYTE_ARRAY_X_10");
903 			for (int i = 0; i < 10; i++) {
904 				if (server) {
905 					CommunicationTester.readByteArayLarge(c, is, os, byteAray128KSize);
906 				} else {
907 					CommunicationTester.sendByteArayLarge(c, is, os, byteAray128KSize);
908 				}
909 			}
910 			break;
911 		case TEST_128K_BYTE_ARRAY_X_10_BACK:
912 			testStatus.setName("128K_BYTE_ARRAY_X_10_BACK");
913 			for (int i = 0; i < 10; i++) {
914 				if (!server) {
915 					CommunicationTester.readByteArayLarge(c, is, os, byteAray128KSize);
916 				} else {
917 					CommunicationTester.sendByteArayLarge(c, is, os, byteAray128KSize);
918 				}
919 			}
920 			break;
921 
922 		// ---- TRAFFIC GENERATORS
923 		case TRAFFIC_GENERATOR_WRITE:
924 			testStatus.setName("RFgenW");
925 			if (server) {
926 				Config cfg = RfTrafficGenerator.getConfig(c, server, "RF write");
927 				if (cfg != null) {
928 					RfTrafficGenerator.trafficGeneratorStatusReadStart(c, testStatus);
929 					RfTrafficGenerator.trafficGeneratorWrite(c, cfg, testStatus);
930 				}
931 			} else {
932 				RfTrafficGenerator.trafficGeneratorClientInit(c);
933 				RfTrafficGenerator.trafficGeneratorRead(c, server, testStatus);
934 			}
935 			break;
936 		case TRAFFIC_GENERATOR_READ:
937 			testStatus.setName("RFgenR");
938 			if (server) {
939 				RfTrafficGenerator.trafficGeneratorRead(c, server, testStatus);
940 			} else {
941 				RfTrafficGenerator.trafficGeneratorClientInit(c);
942 				Config cfg = RfTrafficGenerator.getConfig(c, server, "RF write");
943 				if (cfg != null) {
944 					RfTrafficGenerator.trafficGeneratorStatusReadStart(c, testStatus);
945 					RfTrafficGenerator.trafficGeneratorWrite(c, cfg, testStatus);
946 				}
947 			}
948 			break;
949 		case TRAFFIC_GENERATOR_READ_WRITE:
950 			testStatus.setName("RFgenRW");
951 			if (!server) {
952 				RfTrafficGenerator.trafficGeneratorClientInit(c);
953 			}
954 			Config cfg = RfTrafficGenerator.getConfig(c, server, "RF write");
955 			if (cfg != null) {
956 				RfTrafficGenerator.trafficGeneratorReadStart(c, server, testStatus);
957 				RfTrafficGenerator.trafficGeneratorWrite(c, cfg, testStatus);
958 			}
959 			break;
960 		case TEST_SERVER_TERMINATE:
961 			return;
962 		default:
963 			Assert.fail("Invalid test#" + testType);
964 		}
965 	}
966 }