/** * BlueCove - Java library for Bluetooth * Copyright (C) 2006-2009 Vlad Skarzhevskyy * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * @author vlads * @version $Id$ */ package net.sf.bluecove.tests; import java.io.IOException; import org.bluecove.tester.log.Logger; import org.bluecove.tester.util.IOUtils; import org.bluecove.tester.util.RuntimeDetect; import org.bluecove.tester.util.TimeUtils; import net.sf.bluecove.Configuration; import net.sf.bluecove.ConnectionHolderStream; import net.sf.bluecove.TestStatus; /** * * */ public class RfTrafficGenerator { final static int sequenceSizeMin = 18; public static final byte END_MARKER = -1; public static class Config { int sequenceSleep; int sequenceSize; int durationMSec = 0; boolean init(ConnectionHolderStream c, boolean server, String messagePrefix) throws IOException { if (server) { sequenceSleep = c.is.read(); if (sequenceSleep == -1) { Logger.debug("EOF received"); return false; } sequenceSize = c.is.read(); if (sequenceSize == -1) { Logger.debug("EOF received"); return false; } durationMSec = c.is.read(); if (durationMSec == -1) { Logger.debug("EOF received"); return false; } } else { sequenceSize = Configuration.tgSize & 0xFF; sequenceSleep = Configuration.tgSleep & 0xFF; durationMSec = Configuration.tgDurationMin; } sequenceSleep = sequenceSleep * 10; if (sequenceSize < sequenceSizeMin) { sequenceSize = sequenceSizeMin; } switch (sequenceSize) { case 251: // 1K sequenceSize = 0x400; break; case 252: // 2K sequenceSize = 0x800; break; case 253: // 3K sequenceSize = 0xC00; break; case 254: // 4K sequenceSize = 0x1000; break; case 255: // 5K sequenceSize = 0x1400; break; } Logger.debug(messagePrefix + " size selected " + sequenceSize + " byte"); Logger.debug(messagePrefix + " duration " + durationMSec + " minutes"); durationMSec *= 60000; return true; } } public static Config getConfig(ConnectionHolderStream c, boolean server, String messagePrefix) throws IOException { Config cf = new Config(); if (cf.init(c, server, messagePrefix)) { return cf; } else { return null; } } public static void trafficGeneratorClientInit(ConnectionHolderStream c) throws IOException { byte sequenceSleep = (byte) (Configuration.tgSleep & 0xFF); byte sequenceSize = (byte) (Configuration.tgSize & 0xFF); byte durationMin = (byte) (Configuration.tgDurationMin & 0xFF); c.os.write(sequenceSleep); c.os.write(sequenceSize); c.os.write(durationMin); c.os.flush(); } public static void trafficGeneratorWrite(ConnectionHolderStream c, Config cfg, TestStatus testStatus) throws IOException { if (cfg.sequenceSleep > 0) { Logger.debug("RF write sleep selected " + cfg.sequenceSleep + " msec"); } else { Logger.debug("RF write no sleep"); } long sequenceSentCount = 0; int reportedSize = 0; // Create test data byte[] data = new byte[cfg.sequenceSize]; for (int i = 1; i < cfg.sequenceSize; i++) { data[i] = (byte) i; } long start = System.currentTimeMillis(); long reported = start; try { mainLoop: do { IOUtils.long2Bytes(sequenceSentCount, 8, data, 0); long sendTime = System.currentTimeMillis(); IOUtils.long2Bytes(sendTime, 8, data, 8); boolean finalArray = false; if ((cfg.durationMSec != 0) && (sendTime > start + cfg.durationMSec)) { finalArray = true; data[cfg.sequenceSize - 2] = END_MARKER; data[cfg.sequenceSize - 1] = END_MARKER; } c.os.write(data); sequenceSentCount++; reportedSize += cfg.sequenceSize; c.active(); long now = System.currentTimeMillis(); if (now - reported > 5 * 1000) { Logger.debug("RF Sent " + sequenceSentCount + " array(s) " + TimeUtils.bps(reportedSize, reported)); reported = now; reportedSize = 0; } if (finalArray) { break; } if (cfg.sequenceSleep > 0) { try { Thread.sleep(cfg.sequenceSleep); } catch (InterruptedException e) { break mainLoop; } c.active(); } } while (c.isConnectionOpen() && (!testStatus.isRunCompleate())); } finally { testStatus.setRunCompleate(); String m; m = "RF Total " + sequenceSentCount + " array(s)"; testStatus.addReplyMessage(m); Logger.debug(m); long totalB = sequenceSentCount * cfg.sequenceSize; m = "RF Total " + (totalB / 1024) + " KBytes"; testStatus.addReplyMessage(m); Logger.debug(m); m = "RF Total write speed " + TimeUtils.bps(totalB, start); testStatus.addReplyMessage(m); Logger.debug(m); } } public static void trafficGeneratorStatusReadStart(final ConnectionHolderStream c, final TestStatus testStatus) { Runnable r = new Runnable() { public void run() { try { trafficGeneratorStatusRead(c, testStatus); } catch (IOException e) { Logger.error("reader", e); } } }; Thread t = RuntimeDetect.cldcStub.createNamedThread(r, "RFtgStatusReciver"); t.start(); } public static void trafficGeneratorStatusRead(ConnectionHolderStream c, final TestStatus testStatus) throws IOException { try { int endMakerStatus = 0; byte[] byteAray = new byte[1]; while (c.isConnectionOpen() && (!testStatus.isRunCompleate())) { if (c.is.available() > 0) { int read = c.is.read(byteAray); if (read == -1) { testStatus.setStreamClosed(); break; } endMakerStatus = detectEndMaker(endMakerStatus, byteAray, read); if (endMakerStatus > 0) { break; } c.active(); } else { try { Thread.sleep(100); } catch (InterruptedException e) { break; } } } } finally { testStatus.setRunCompleate(); } } public static void trafficGeneratorReadStart(final ConnectionHolderStream c, final boolean server, final TestStatus testStatus) { Runnable r = new Runnable() { public void run() { try { trafficGeneratorRead(c, server, testStatus); } catch (IOException e) { Logger.error("reader", e); } } }; Thread t = RuntimeDetect.cldcStub.createNamedThread(r, "RFtgReciver"); t.start(); } /** * Expects 2 END_MARKER bytes */ public static int detectEndMaker(int endMakerStatus, byte[] byteAray, int len) { if (len > 0) { if (byteAray[len - 1] == END_MARKER) { if (len == 1) { if (endMakerStatus < 0) { return 1; } else { return -1; } } else if (byteAray[len - 2] == END_MARKER) { return 1; } } return 0; } else { return endMakerStatus; } } public static void trafficGeneratorRead(ConnectionHolderStream c, boolean server, final TestStatus testStatus) throws IOException { Config cf = new Config(); if (!cf.init(c, server, "RF read")) { return; } long totalSize = 0; long sequenceReceivedCount = 0; long start = System.currentTimeMillis(); long reported = start; long reportedSize = 0; byte[] byteAray = new byte[cf.sequenceSize]; int endMakerStatus = 0; try { while (c.isConnectionOpen() && (!testStatus.isRunCompleate())) { int read = c.is.read(byteAray); if (read == -1) { testStatus.setStreamClosed(); break; } endMakerStatus = detectEndMaker(endMakerStatus, byteAray, read); if (endMakerStatus > 0) { break; } sequenceReceivedCount++; totalSize += read; reportedSize += read; c.active(); long now = System.currentTimeMillis(); if (now - reported > 5 * 1000) { Logger.debug("RF Received " + sequenceReceivedCount + " array(s) " + TimeUtils.bps(reportedSize, reported)); reported = now; reportedSize = 0; } } } finally { testStatus.setRunCompleate(); String m; m = "RF Total " + sequenceReceivedCount + " array(s)"; testStatus.addReplyMessage(m); Logger.debug(m); m = "RF Total " + (totalSize / 1024) + " KBytes"; testStatus.addReplyMessage(m); Logger.debug(m); m = "RF Total read speed " + TimeUtils.bps(totalSize, start); testStatus.addReplyMessage(m); Logger.debug(m); } } }