/** * Copyright (c) 2011-2014, OpenIoT * * This file is part of OpenIoT. * * OpenIoT is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, version 3 of the License. * * OpenIoT is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with OpenIoT. If not, see <http://www.gnu.org/licenses/>. * * Contact: OpenIoT mailto: info@openiot.eu * @author Ali Salehi * @author Mehdi Riahi */ package org.openiot.gsn.wrappers.wsn.simulator; import org.openiot.gsn.beans.AddressBean; import org.openiot.gsn.beans.DataField; import org.openiot.gsn.beans.DataTypes; import org.openiot.gsn.beans.StreamElement; import org.openiot.gsn.utils.ParamParser; import org.openiot.gsn.wrappers.AbstractWrapper; import java.io.Serializable; import java.util.ArrayList; import org.apache.log4j.Logger; public class WSNSWrapper extends AbstractWrapper implements DataListener { private final transient Logger logger = Logger.getLogger( WSNSWrapper.class ); private static int threadCounter = 0; /** * The rate, set the rate in which the network is re-revaluated. If the rate * is 1000, then the network is reevaluated every seconds. If the rate is * negative, the network will stop evaluating it self after specified number * of cycles. */ private static String RATE_KEY = "rate"; /** * The Rate is specified in msec. */ private static int RATE_DEFAULT_VALUE = 2000; private int rate = RATE_DEFAULT_VALUE; private static int NODE_COUNT_DEFAULT_VALUE = 10; private static String NODE_COUNT_KEY = "node_count"; private int node_count = NODE_COUNT_DEFAULT_VALUE; private WirelessNode [ ] nodes; private ArrayList < DataPacket > dataBuffer = new ArrayList < DataPacket >( ); private String STEP_COUNTER = "steps"; private static final int STEP_COUNTER_DEFAULT_VALUE = -1; private int step_counter = STEP_COUNTER_DEFAULT_VALUE; public boolean initialize ( ) { setName( "WirelessSensorNetworkSimulatorWrapper-Thread" + ( ++threadCounter ) ); AddressBean addressBean = getActiveAddressBean( ); /** * Reading the initialization paramteters from the XML Configurations * provided. */ if ( addressBean.getPredicateValue( NODE_COUNT_KEY ) != null ) { node_count = ParamParser.getInteger( ( String ) addressBean.getPredicateValue( NODE_COUNT_KEY ) , NODE_COUNT_DEFAULT_VALUE ); if ( node_count <= 0 ) { logger.warn( "The specified >node_count< parameter for the >WSNWrapper< shouldn't be a negative number.\nGSN uses the default node_count (" + NODE_COUNT_DEFAULT_VALUE + ")." ); node_count = NODE_COUNT_DEFAULT_VALUE; } } if ( addressBean.getPredicateValue( STEP_COUNTER ) != null ) { step_counter = ParamParser.getInteger( ( String ) addressBean.getPredicateValue( STEP_COUNTER ) , STEP_COUNTER_DEFAULT_VALUE ); if ( step_counter <= 0 ) { logger.warn( "The specified >step_counter< parameter for the >WSNWrapper< shouldn't be a negative number.\nGSN disables the step_counter (-1)." ); step_counter = -1; } } if ( addressBean.getPredicateValue( NODE_COUNT_KEY ) != null ) node_count = ParamParser.getInteger( ( String ) addressBean.getPredicateValue( NODE_COUNT_KEY ) , NODE_COUNT_DEFAULT_VALUE ); if ( addressBean.getPredicateValue( RATE_KEY ) != null ) { rate = ParamParser.getInteger( ( String ) addressBean.getPredicateValue( RATE_KEY ) , RATE_DEFAULT_VALUE ); if ( rate <= 0 ) { logger.warn( "The specified rate parameter for the >WSNWrapper< shouldn't be a negative number.\nGSN uses the default rate (" + RATE_DEFAULT_VALUE + ")." ); rate = RATE_DEFAULT_VALUE; } } return true; } public void run ( ) { nodes = initializeNodes( node_count ); for ( int i = 0 ; i < node_count ; i++ ) nodes[ i ].addDataListener( this ); long tempStepCounter = 0; while ( isActive( ) ) { if ( tempStepCounter <= step_counter || step_counter == -1 ) { tempStepCounter++; if ( !listeners.isEmpty( ) && dataBuffer.size( ) > 0 ) { DataPacket dataPacket; synchronized ( dataBuffer ) { dataPacket = dataBuffer.remove( 0 ); } StreamElement streamElement = new StreamElement( new String [ ] { "NODE_ID" , "PARENT_ID" , "TEMPREATURE" } , new Byte [ ] { DataTypes.INTEGER , DataTypes.INTEGER , DataTypes.INTEGER } , new Serializable [ ] { dataPacket.getIdentifier( ) , dataPacket.getParent( ) , dataPacket.getValue( ) } , System.currentTimeMillis( ) ); postStreamElement( streamElement ); if ( dataBuffer.size( ) > 0 ) continue; } } try { Thread.sleep( rate ); } catch ( InterruptedException e ) { logger.error( e.getMessage( ) , e ); } } for ( WirelessNode node : nodes ) node.stopNode( ); } private static final DataField[] dataField = new DataField[] {new DataField( "NODE_ID" , DataTypes.INTEGER_NAME , "Node's identification." ) , new DataField( "PARENT_ID" , DataTypes.INTEGER_NAME , "Parent Node's identification." ) , new DataField( "TEMPREATURE" , DataTypes.INTEGER_NAME , "incremental int" )}; public DataField [] getOutputFormat ( ) { return dataField; } public static int randomNumber ( int fromNo , int toNo ) { return ( int ) ( ( Math.random( ) * ( toNo - fromNo + 1 ) ) + fromNo ); } public WirelessNode [ ] initializeNodes ( int nodeCount ) throws RuntimeException { if ( nodeCount <= 0 ) throw new RuntimeException( "Wireless Sensor Network Simulator (WSNS) can't create a network with zero or negative number of nodes : " + nodeCount ); WirelessNode [ ] nodes = new WirelessNode [ nodeCount ]; for ( int i = 0 ; i < nodeCount ; i++ ) { nodes[ i ] = new WirelessNode( i ); nodes[ i ].setName( "WSNS-Node-" + i ); } for ( int i = 1 ; i < nodeCount ; i++ ) nodes[ i ].setParent( nodes[ randomNumber( i - 1 , 0 ) ] ); for ( int i = 1 ; i < nodeCount ; i++ ) nodes[ i ].start( ); return nodes; } public void newDataAvailable ( DataPacket dataPacket ) { synchronized ( dataBuffer ) { dataBuffer.add( dataPacket ); } } public void dispose ( ) { } public String getWrapperName() { return "Wireless Sensor Network Simulator"; } }