ptolemy.domains.ptinyos.kernel
Class PtinyOSDirector

java.lang.Object
  extended by ptolemy.kernel.util.NamedObj
      extended by ptolemy.kernel.util.Attribute
          extended by ptolemy.actor.Director
              extended by ptolemy.domains.ptinyos.kernel.PtinyOSDirector
All Implemented Interfaces:
java.io.Serializable, java.lang.Cloneable, Executable, Initializable, Changeable, Debuggable, DebugListener, Derivable, ModelErrorHandler, MoMLExportable, Moveable, Nameable

public class PtinyOSDirector
extends Director

A director for generating, compiling, and simulating nesC code from TinyOS components.

TinyOS is an event-driven operating system designed for sensor network nodes that have very limited resources (e.g., 8K bytes of program memory, 512 bytes of RAM). (More info at http://www.tinyos.net).

nesC is an extension to the C programming language designed to embody the structuring concepts and execution model of TinyOS. (More info at http://nescc.sourceforge.net).

TOSSIM is a C-based simulator for homogeneous TinyOS networks, where all nodes run the same TinyOS program. (More info at http://www.cs.berkeley.edu/~pal/research/tossim.html).

This version of the PtinyOSDirector is for use with TinyOS 1.x only. It is not compatible with TinyOS 2.x.

When embedded in a model containing nesC components (component descriptions converted to MoML from the TinyOS 1.x library using $PTII/ptolemy/domains/ptinyos/util/nc2moml/nc2moml), this director can generate the top-level nesC application file (.nc). This director can also compile the nesC application for use with any TinyOS 1.x-compatible hardware (e.g., mica), or for simulation within Ptolemy II.

When this director is used for code generation only, and not simulation, the user sets the PtinyOSDirector target parameter to a string such as "mica", "mica2", "pc", or another TinyOS 1.x-compatible target. The director will generate a nesC application file (.nc) and a makefile for the application.

When this director is used in simulation mode, the user sets the PtinyOSDirector target parameter to the string "ptII". In addition to the previously mentioned nesC application file (.nc) and a makefile for the application, ththe director will generate a Java loader file (.java). This loader file implements PtinyOSLoader, which is used as a wrapper for calls to JNI methods in TOSSIM. The director uses the nesC compiler to compile the .nc file into a pre-processed C file. It then uses a C compiler to compile the C file into a shared object (the TOSSIM shared object). The C compiler is usually gcc, though it can use another compiler if $PTCC (defined in $PTII/mk/ptII.mk and used in $TOSROOT/contrib/ptII/ptinyos/tools/make/ptII/ptII.rules) is modified. The director then uses the Java compiler to compile the Java loader file into a .class file. Finally, this director loads the resulting .class using the Java loader, which loads the TOSSIM shared object.

For more information on compilation rules, see: $TOSROOT/contrib/ptII/ptinyos/tools/make/ptII/ptII.rules

TOSSIM contains its own discrete event simulation engine, which consists of a main scheduling loop and a discrete event queue. Events in this queue are ordered by timestamp, which is implemented as a long long (a 64-bit integer on most systems; this is a standard type used in gcc). The timestamp value is a representation of the number of ticks of a 4 MHz clock (the original CPU frequency of the Rene/Mica motes). After initializing its data structures and performing other initialization routines, TOSSIM creates a boot-up event and places the event in its event queue. The version of TOSSIM compiled by this director contains additional calls that are not in the original version of TOSSIM. These calls are JNI calls that cause the TOSSIM scheduler to communicate all events to the PtinyOSDirector, and allow events (and sensor values) generated by Ptolemy II to be passed to the TOSSIM scheduler.

Since TOSSIM operates on a 4MHz clock, users will usually set the timeResolution parameter of this director to the value 0.25E-6, since TOSSIM cannot detect changes in sensor values with time differences less than this time resolution.

When the nesC compiler generates the pre-processed C file for TOSSIM, it automatically generates support for homogeneous networks by instrumenting all component state variables with an array. The array stores the state for each node. Therefore, array index 0 stores the state for node 0, and so on. This director only uses one node per instance of TOSSIM, and hence, only uses array index 0 for all variables. Models containing multiple nodes are created by using a separate PtinyOSDirector (and hence a separate instance of TOSSIM) for each node. In TOSSIM, node 0 is the base station, which is the sink for routing. This director overrides the built-in id number using the nodeID and baseStation parameters, and passes a node ID value to the nesC compiler so that it is hard coded into TOSSIM.

TOSSIM uses TCP/IP sockets attached to network ports for commands and events in order to communicate with external tools, such as TinyViz, a Java-based visualization tool for TOSSIM. We retain these ports for backwards compatibility with TinyViz and other tools. The port numbers are set in commandPort and eventPort. Because of limitations in the implementation of TOSSIM, a separate instance of TinyViz must be attached to each instance of TOSSIM.

Since:
Ptolemy II 5.1
Version:
$Id: PtinyOSDirector.java 57040 2010-01-27 20:52:32Z cxh $
Author:
Elaine Cheong, Yang Zhao, Edward A. Lee
See Also:
Serialized Form
Accepted Rating:
Yellow (celaine)
Proposed Rating:
Yellow (celaine)

Nested Class Summary
private static class PtinyOSDirector._CodeString
          Class for creating a StringBuffer that represents generated code.
private  class PtinyOSDirector._StreamReaderThread
          Private class that reads a stream in a thread.
 
Nested classes/interfaces inherited from class ptolemy.kernel.util.NamedObj
NamedObj.ContainedObjectsIterator
 
Field Summary
private  PtinyOSLoader _loader
           
private  long _startTime
           
private static java.lang.String _unnamed
           
private  long _version
           
 SharedParameter baseStation
          Specifies the name of the base station as a string value.
 Parameter bootTimeRange
          TOSSIM setting for the number of seconds over which nodes may boot.
 PtinyOSNodeParameter commandPort
          Port number for the TOSSIM command server socket.
 Parameter confirmOverwrite
          Flag to ask for confirmation before overwriting.
 FileParameter destinationDirectory
          Output directory for generated code.
 Parameter eventPort
          Port number for the TOSSIM event server socket.
 PtinyOSNodeParameter nodeID
          Node ID of this node.
 Parameter numberOfNodes
          Number of nodes to simulate per instance of TOSSIM.
 StringParameter pflags
          Additional flags passed to the nesC compiler.
 SharedParameter simulate
          Flag for choosing whether to simulate the model in ptII.
 StringParameter target
          Compilation target for the generated nesC code.
 FileParameter tosDir
          Path to the tos directory of the TinyOS tree.
 FileParameter tosRoot
          Path to the root of the TinyOS tree.
 
Fields inherited from class ptolemy.actor.Director
_actorsFinishedExecution, _currentTime, _finishRequested, _initializables, _stopRequested, timeResolution
 
Fields inherited from class ptolemy.kernel.util.NamedObj
_changeListeners, _changeLock, _changeRequests, _debugging, _debugListeners, _elementName, _isPersistent, _verbose, _workspace, ATTRIBUTES, CLASSNAME, COMPLETE, CONTENTS, DEEP, FULLNAME, LINKS
 
Fields inherited from interface ptolemy.actor.Executable
COMPLETED, NOT_READY, STOP_ITERATING
 
Constructor Summary
PtinyOSDirector()
          Construct a director in the default workspace with an empty string as its name.
PtinyOSDirector(CompositeEntity container, java.lang.String name)
          Construct a director with the specified container and name.
PtinyOSDirector(Workspace workspace)
          Construct a director in the workspace with an empty name.
 
Method Summary
private  void _compile(java.lang.String makefileName)
          Compile the generated code by calling make on the generated file from _generateMakefile().
private  boolean _confirmOverwrite(java.io.File file)
          Confirm overwrite of file if the confirmOverwrite parameter is set to true.
private  java.lang.String _generateCode(CompositeActor model)
          Generate nesC code for the given model.
private  void _generateLoader()
          Generate Java loader file. ===== Begin example Loader.java (from Dec 4, 2006) ===== import java.net.ServerSocket; import java.nio.channels.Selector; import java.nio.channels.SelectableChannel; import java.nio.channels.SocketChannel; import ptolemy.domains.ptinyos.kernel.PtinyOSLoader; import ptolemy.domains.ptinyos.kernel.PtinyOSDirector; import ptolemy.kernel.util.InternalErrorException; import ptolemy.util.MessageHandler; public class Loader_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0 implements PtinyOSLoader { public void load(String path, PtinyOSDirector director) { String fileSeparator = System.getProperty("file.separator"); String toBeLoaded = path + fileSeparator + System.mapLibraryName("_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0"); toBeLoaded = toBeLoaded.replace('\\', '/'); System.out.println("_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0.java : about to load " + toBeLoaded); System.load(toBeLoaded); this.director = director; } public int main(String argsToMain[]) throws InternalErrorException { return main_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0(argsToMain); } public void startThreads() { try { this.eventAcceptThread = new EventAcceptThread(); this.eventAcceptThread.start(); this.commandReadThread = new CommandReadThread(); this.commandReadThread.start(); } catch (Exception ex) { MessageHandler.error("Could not join thread
private  java.lang.String _generateMakefile()
          Generate makefile. ===== Begin example makefile (from Dec 9, 20060) ===== TOSROOT=/home/celaine/ptII/vendors/ptinyos/tinyos-1.x TOSDIR=/home/celaine/ptII/vendors/ptinyos/tinyos-1.x/tos TOSMAKE_PATH += $(TOSROOT)/contrib/ptII/ptinyos/tools/make COMPONENT=_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor1 PFLAGS += -I%T/lib/Counters PFLAGS += -DCOMMAND_PORT=10584 -DEVENT_PORT=10585 PFLAGS +=-D_PTII_NODEID=1 MY_PTCC_FLAGS += -D_PTII_NODE_NAME=_1SenseToLeds_1InWireless_1MicaBoard_1MicaCompositeActor1 PFLAGS += "-I$(TOSROOT)/contrib/ptII/ptinyos/beta/TOSSIM-packet" include /home/celaine/ptII/mk/ptII.mk include /home/celaine/ptII/vendors/ptinyos/tinyos-1.x/tools/make/Makerules ===== End example makefile (from Dec 9, 2006) =====
private  long _getModelTimeAsLongValue()
          Get the current model time and return the long value.
private  java.lang.String _includeConnection(CompositeActor model)
          Generate code for the nesC interface connections.
private static java.lang.String _includeConnection(CompositeActor model, Actor actor)
          Generate code for the connections.
private static java.lang.String _includeModule(CompositeActor model)
          Generate code for the nesC components used in the model.
private  void _initializeParameters()
          Initialize parameters.
private static java.lang.String _interfaceProvides(CompositeActor model)
          Generate nesC code describing the input ports.
private static java.lang.String _interfaceUses(CompositeActor model)
          Generate nesC code describing the output ports.
private  boolean _isTopLevelNC()
          Return true if this PtinyOSDirector is not contained by a opaque composite that is itself controlled by a PtinyOSDirector.
private static boolean _needsInputDriver(Actor actor)
          Return true if the given actor has at least one input port, which requires it to have an input driver.
private  java.lang.String _sanitizedFullName(NamedObj obj)
          Get the sanitized full name with workspace version number appended, or "Unnamed" with version number appended if no name.
private  NamedObj _toplevelNC()
          Looks for the topmost container that contains a PtinyOSDirector director.
 java.nio.channels.SocketChannel acceptConnection(java.nio.channels.SelectableChannel serverSocketChannel)
          Accept a connection on a java.nio.channels.ServerSocketChannel.
 void enqueueEvent(java.lang.String newTime)
          Enqueue the next TOSSIM event into ptII at the specified time by calling fireAt().
 void fire()
          If the simulate parameter is true, process one event in the TOSSIM event queue and run tasks in task queue.
 char getCharParameterValue(java.lang.String parameter)
          Get a DoubleToken from the named parameter and convert it to a char.
 void initialize()
          If the simulate parameter is true, then load the TOSSIM shared library and call TOSSIM main(), by using Java loader calls.
 boolean postfire()
          Return true if simulation is requested, so that simulated event handling can proceed.
 void preinitialize()
          Generate nesC code in a .nc file.
 void receivePacket(java.lang.String packet)
          If the simulate parameter is true, notify the loader that a packet has been received.
 void selectorClose(java.nio.channels.Selector selector)
          Close the java.nio.channels.Selector.
 java.nio.channels.Selector selectorCreate(java.net.ServerSocket serverSocket, boolean opAccept, boolean opConnect, boolean opRead, boolean opWrite)
          Create a java.nio.channels.Selector and register the ServerSocketChannel of the ServerSocket with the Selector.
 void selectorRegister(java.nio.channels.Selector selector, java.nio.channels.SelectableChannel socketChannel, boolean opAccept, boolean opConnect, boolean opRead, boolean opWrite)
          Register the channel with the java.nio.channels.Selector.
 java.nio.channels.SelectableChannel selectSocket(java.nio.channels.Selector selector, boolean[] notNullIfClosing, boolean opAccept, boolean opConnect, boolean opRead, boolean opWrite)
          Returns a selected channel, or null if none found.
 boolean sendToPort(java.lang.String portName, java.lang.String expression)
          Send an expression to a ptII port.
 void serverSocketClose(java.net.ServerSocket serverSocket)
          Close the java.net.ServerSocket.
 java.net.ServerSocket serverSocketCreate(short port)
          Create a non-blocking server socket and check for connections on the port specified by port.
 void socketChannelClose(java.nio.channels.SelectableChannel socketChannel)
          Close the java.nio.channels.SocketChannel.
 int socketChannelRead(java.nio.channels.SocketChannel socketChannel, byte[] readBuffer)
          Read from a java.nio.channels.SocketChannel into readBuffer.
 int socketChannelWrite(java.nio.channels.SocketChannel socketChannel, byte[] writeBuffer)
          Write the bytes in writeBuffer to a java.nio.channels.SocketChannel.
 void tosDebug(java.lang.String debugMode, java.lang.String message, java.lang.String nodeID)
          Print a debug message.
 void wrapup()
          If the simulate parameter is true, call wrapup() in TOSSIM to shut down threads created in initialize().
 
Methods inherited from class ptolemy.actor.Director
_description, _fireContainerAt, _isEmbedded, _isTopLevel, _transferInputs, _transferOutputs, addInitializable, attributeChanged, createSchedule, defaultDependency, finish, fireAt, fireAt, fireAtCurrentTime, getCausalityInterface, getCurrentTime, getErrorTolerance, getGlobalTime, getModelNextIterationTime, getModelStartTime, getModelStopTime, getModelTime, getNextIterationTime, getStartTime, getStopTime, getTimeResolution, implementsStrictActorSemantics, initialize, invalidateResolvedTypes, invalidateSchedule, isFireFunctional, isStopRequested, isStrict, iterate, newReceiver, prefire, preinitialize, removeInitializable, requestInitialization, setContainer, setCurrentTime, setModelTime, stop, stopFire, suggestedModalModelDirectors, supportMultirateFiring, terminate, transferInputs, transferOutputs
 
Methods inherited from class ptolemy.kernel.util.Attribute
_checkContainer, _getContainedObject, _propagateExistence, clone, getContainer, moveDown, moveToFirst, moveToIndex, moveToLast, moveUp, setName, updateContent
 
Methods inherited from class ptolemy.kernel.util.NamedObj
_addAttribute, _adjustOverride, _attachText, _cloneFixAttributeFields, _debug, _debug, _debug, _debug, _debug, _exportMoMLContents, _getIndentPrefix, _isMoMLSuppressed, _markContentsDerived, _propagateValue, _recordDecoratedAttributes, _removeAttribute, _splitName, _stripNumericSuffix, _validateSettables, addChangeListener, addDebugListener, attributeList, attributeList, attributeTypeChanged, clone, containedObjectsIterator, deepContains, depthInHierarchy, description, description, event, executeChangeRequests, exportMoML, exportMoML, exportMoML, exportMoML, exportMoML, exportMoMLPlain, getAttribute, getAttribute, getAttributes, getChangeListeners, getClassName, getDecoratorAttribute, getDecoratorAttributes, getDerivedLevel, getDerivedList, getDisplayName, getElementName, getFullName, getModelErrorHandler, getName, getName, getPrototypeList, getSource, handleModelError, isDeferringChangeRequests, isOverridden, isPersistent, lazyContainedObjectsIterator, message, propagateExistence, propagateValue, propagateValues, removeChangeListener, removeDebugListener, requestChange, setClassName, setDeferringChangeRequests, setDerivedLevel, setDisplayName, setModelErrorHandler, setPersistent, setSource, sortContainedObjects, toplevel, toString, uniqueName, validateSettables, workspace
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

baseStation

public SharedParameter baseStation
Specifies the name of the base station as a string value. The value defaults to the string "\"MicaBoard\"".


bootTimeRange

public Parameter bootTimeRange
TOSSIM setting for the number of seconds over which nodes may boot. The node(s) boots at a random time within this time frame (time starts at 0 seconds). The value defaults to 10 and is of type IntToken.


commandPort

public PtinyOSNodeParameter commandPort
Port number for the TOSSIM command server socket. The value defaults to 10584.


confirmOverwrite

public Parameter confirmOverwrite
Flag to ask for confirmation before overwriting. If false, then overwrite the specified file without asking, if the file exists. If true, then ask for confirmation before overwriting, if the file exists. The value defaults to false, and is of type BooleanToken.


destinationDirectory

public FileParameter destinationDirectory
Output directory for generated code. The value defaults to the current working directory (the ptII expression $CWD).


eventPort

public Parameter eventPort
Port number for the TOSSIM event server socket. This is a public value so that the port number can be set by hand, if necessary. The value defaults to (commandPort + 1).


nodeID

public PtinyOSNodeParameter nodeID
Node ID of this node. This is a substitute for TOS_LOCAL_ADDRESS, which in TOSSIM is normally set to the node array index. However, we assume only one node per TOSSIM. To avoid all nodes being set to the same ID, we use this parameter. In practice, the range is limited by numberOfNodes, and should be such that enough network ports are available for each instance of commandPort and eventPort, though this is not enforced. The value defaults to 1. Normally, the value of this parameter does not need to be changed, since the use of the PtinyOSNodeParameter type for this parameter will cause the value of the node ID to be automatically incremented for each new node in the model. Users should only change this parameter to force a node to have a particular node ID value.


numberOfNodes

public Parameter numberOfNodes
Number of nodes to simulate per instance of TOSSIM. The value defaults to 1, is of type IntToken, and is set to be NOT_EDITABLE.


pflags

public StringParameter pflags
Additional flags passed to the nesC compiler. This can be used, for example, to include additional compilation directories. The value defaults to "-I%T/lib/Counters". "-I" is the normal gcc include directory option. "%T" is a nesC compiler flag that is equivalent to the value of $TOSDIR.


simulate

public SharedParameter simulate
Flag for choosing whether to simulate the model in ptII. The value defaults to true, and is of type BooleanToken. If false, this director only generates files and does not atempt to simulate the model.


target

public StringParameter target
Compilation target for the generated nesC code. Target can be any TinyOS-compatible target, such as mica, mica2, pc, or ptII. The value defaults to "ptII". If target is blank, but simulate is true, then the model will assume that the ptII target has already been compiled and will attempt to simulate.


tosDir

public FileParameter tosDir
Path to the tos directory of the TinyOS tree. TinyOS can be obtained from http://www.tinyos.net. The value defaults to $PTII/vendors/ptinyos/tinyos-1.x/tos


tosRoot

public FileParameter tosRoot
Path to the root of the TinyOS tree. TinyOS can be obtained from http://www.tinyos.net. The value defaults to $PTII/vendors/ptinyos/tinyos-1.x


_loader

private PtinyOSLoader _loader

_unnamed

private static java.lang.String _unnamed

_version

private long _version

_startTime

private long _startTime
Constructor Detail

PtinyOSDirector

public PtinyOSDirector()
Construct a director in the default workspace with an empty string as its name. The director is added to the list of objects in the workspace. Increment the version number of the workspace.


PtinyOSDirector

public PtinyOSDirector(Workspace workspace)
Construct a director in the workspace with an empty name. The director is added to the list of objects in the workspace. Increment the version number of the workspace.

Parameters:
workspace - The workspace of this object.

PtinyOSDirector

public PtinyOSDirector(CompositeEntity container,
                       java.lang.String name)
                throws IllegalActionException,
                       NameDuplicationException
Construct a director with the specified container and name.

Parameters:
container - The container.
name - The name of the director.
Throws:
IllegalActionException - If the director is not of an acceptable attribute for the container.
NameDuplicationException - If the name coincides with an attribute already in the container.
Method Detail

enqueueEvent

public void enqueueEvent(java.lang.String newTime)
Enqueue the next TOSSIM event into ptII at the specified time by calling fireAt().

This is a JNI method that gets called by TOSSIM through the Java loader.

Parameters:
newTime - A string representation of the time of the next event. In TOSSIM, unit of time is a tick of a 4MHz clock, and time is stored in a long long in C (a 64-bit integer on most systems).

fire

public void fire()
          throws IllegalActionException
If the simulate parameter is true, process one event in the TOSSIM event queue and run tasks in task queue. This method gets the model time from the director and calls PtinyOSLoader.processEvent(long) with the time as the argument, which invokes TOSSIM.

Specified by:
fire in interface Executable
Overrides:
fire in class Director
Throws:
IllegalActionException - If the fire() method of the super class throws it, or getting a token from the simulateparameter throws it.

getCharParameterValue

public char getCharParameterValue(java.lang.String parameter)
Get a DoubleToken from the named parameter and convert it to a char.

This is a JNI method that gets called by TOSSIM through the Java loader to get a sensor value.

Parameters:
parameter - The parameter.
Returns:
The parameter value, or 0 if the port is not connected or not found or a token cannot be obtained succesfully.

initialize

public void initialize()
                throws IllegalActionException
If the simulate parameter is true, then load the TOSSIM shared library and call TOSSIM main(), by using Java loader calls.

The sequence of calls is as follows (assuming simulate is true):

Specified by:
initialize in interface Initializable
Overrides:
initialize in class Director
Throws:
IllegalActionException - If there is a problem initializing the director, such as a problem loading the JNI loader.

postfire

public boolean postfire()
                 throws IllegalActionException
Return true if simulation is requested, so that simulated event handling can proceed.

Specified by:
postfire in interface Executable
Overrides:
postfire in class Director
Returns:
The value of result of the call to postfire() of the super class && the value of the simulate parameter
Throws:
IllegalActionException - If thrown while reading the simulate parameter.

preinitialize

public void preinitialize()
                   throws IllegalActionException
Generate nesC code in a .nc file. If this director is the top most PtinyOSDirector, and the target parameter is non-empty then a .java loader file and a makefile are created. This methods then compiles the .nc and .java files by calling make. The .java file implements the PtinyOSLoader interface.

The sequence of calls is as follows:

Specified by:
preinitialize in interface Initializable
Overrides:
preinitialize in class Director
Throws:
IllegalActionException - If the container is not an instance of CompositeActor, the destination directory does not exist and cannot be created, or the nesC file cannot be written.

receivePacket

public void receivePacket(java.lang.String packet)
                   throws IllegalActionException
If the simulate parameter is true, notify the loader that a packet has been received. The PtinyOSCompositeActor.fire() method calls this method with the string value of the input packet.

The sequence of calls is as follows:

This is a wrapper for a native method, where the PtinyOSDirector calls this method (Java) to activate routines in TOSSIM (C).

Parameters:
packet - The string value of the packet to send to TOSSIM.
Throws:
IllegalActionException - If there is a problem reading the simulate parameter.

sendToPort

public boolean sendToPort(java.lang.String portName,
                          java.lang.String expression)
Send an expression to a ptII port. This is used, for example, to send LED or packet data from TOSSIM to the rest of the Ptolemy II model.

This is a JNI method that gets called by TOSSIM through the Java loader to send a value to a ptII port.

The sequence of calls is as follows:

Parameters:
portName - The name of the port.
expression - The expression to send to the ptII port.
Returns:
true if the expression was successfully sent, false if the port is not connected or not found.

tosDebug

public void tosDebug(java.lang.String debugMode,
                     java.lang.String message,
                     java.lang.String nodeID)
Print a debug message.

This is a JNI method that gets called by TOSSIM through the Java loader to print a debug message.

Parameters:
debugMode - A long long in C (currently unused).
message - A char * in C.
nodeID - A short in C.

wrapup

public void wrapup()
            throws IllegalActionException
If the simulate parameter is true, call wrapup() in TOSSIM to shut down threads created in initialize().

The sequence of calls is as follows:

This is a wrapper for a native method, where the PtinyOSDirector calls this method (Java) to activate routines in TOSSIM (C).

Specified by:
wrapup in interface Initializable
Overrides:
wrapup in class Director
Throws:
IllegalActionException - If the wrapup() method of one of the associated actors throws it.

acceptConnection

public java.nio.channels.SocketChannel acceptConnection(java.nio.channels.SelectableChannel serverSocketChannel)
Accept a connection on a java.nio.channels.ServerSocketChannel. If serverSocketChannel is blocking, this method blocks.

This is a JNI method that gets called by TOSSIM through the Java loader.

Parameters:
serverSocketChannel - The ServerSocketChannel on which connections are accepted.
Returns:
The SocketChannel for the connection that was accepted, null if error.

selectorClose

public void selectorClose(java.nio.channels.Selector selector)
Close the java.nio.channels.Selector.

This is a JNI method that gets called by TOSSIM through the Java loader.

Parameters:
selector - The Selector that should be closed.

selectorCreate

public java.nio.channels.Selector selectorCreate(java.net.ServerSocket serverSocket,
                                                 boolean opAccept,
                                                 boolean opConnect,
                                                 boolean opRead,
                                                 boolean opWrite)
Create a java.nio.channels.Selector and register the ServerSocketChannel of the ServerSocket with the Selector.

This is a JNI method that gets called by TOSSIM through the Java loader.

Parameters:
serverSocket - The ServerSocket whose channel should be registered with the Selector created.
opAccept - True if this SelectionKey option should be enabled when registering the ServerSocketChannel to the Selector.
opConnect - True if this SelectionKey option should be enabled when registering the ServerSocketChannel to the Selector.
opRead - True if this SelectionKey option should be enabled when registering the ServerSocketChannel to the Selector.
opWrite - True if this SelectionKey option should be enabled when registering the ServerSocketChannel to the Selector.
Returns:
The Selector created, or null if error.

selectorRegister

public void selectorRegister(java.nio.channels.Selector selector,
                             java.nio.channels.SelectableChannel socketChannel,
                             boolean opAccept,
                             boolean opConnect,
                             boolean opRead,
                             boolean opWrite)
Register the channel with the java.nio.channels.Selector.

This is a JNI method that gets called by TOSSIM through the Java loader.

Parameters:
selector - The selector to which the channel should be registered.
socketChannel - The SocketChannel that should be registered.
opAccept - True if this SelectionKey option should be enabled when registering the SocketChannel to the Selector.
opConnect - True if this SelectionKey option should be enabled when registering the SocketChannel to the Selector.
opRead - True if this SelectionKey option should be enabled when registering the SocketChannel to the Selector.
opWrite - True if this SelectionKey option should be enabled when registering the SocketChannel to the Selector.

selectSocket

public java.nio.channels.SelectableChannel selectSocket(java.nio.channels.Selector selector,
                                                        boolean[] notNullIfClosing,
                                                        boolean opAccept,
                                                        boolean opConnect,
                                                        boolean opRead,
                                                        boolean opWrite)
Returns a selected channel, or null if none found. In selectorClose(Selector), Selector.close() is called, but because of a bug in J2SE described in http://forum.java.sun.com/thread.jspa?threadID=293213&messageID=2671029, the call to Selector.close() in selectorClose(Selector) may never return because a thread is blocked in the call to Selector.select() in this method. So, selectorClose(Selector) also calls Selector.wakeup(), but we have to make sure that this method (and the call to Selector.select()) is not called again, before the Selector is closed, especially since the call to this method will usually be in a loop. We use notNullIfClosing as a flag to indicate that this method should not be called again. We assume that notNullIfClosing is a boolean array of at least size 1. notNullIfClosing[0] is set to true if this method should not be called again, otherwise it is not modified.

This is a JNI method that gets called by TOSSIM through the Java loader.

Parameters:
selector - The channel selector.
notNullIfClosing - notNullIfClosing[0] set to TRUE if returning NULL, otherwise left as is.
opAccept - True if this SelectionKey option should be enabled when returning a non-null SelectableChannel.
opConnect - True if this SelectionKey option should be enabled when returning a non-null SelectableChannel.
opRead - True if this SelectionKey option should be enabled when returning a non-null SelectableChannel.
opWrite - True if this SelectionKey option should be enabled when returning a non-null SelectableChannel.
Returns:
The selected channel, or null if none.

serverSocketClose

public void serverSocketClose(java.net.ServerSocket serverSocket)
Close the java.net.ServerSocket.

This is a JNI method that gets called by TOSSIM through the Java loader.

Parameters:
serverSocket - The ServerSocket to be closed.

serverSocketCreate

public java.net.ServerSocket serverSocketCreate(short port)
Create a non-blocking server socket and check for connections on the port specified by port.

This is a JNI method that gets called by TOSSIM through the Java loader.

Parameters:
port - The port number on which to create a server socket.
Returns:
The ServerSocket created, or null if error.

socketChannelClose

public void socketChannelClose(java.nio.channels.SelectableChannel socketChannel)
Close the java.nio.channels.SocketChannel.

This is a JNI method that gets called by TOSSIM through the Java loader.

Parameters:
socketChannel - The SocketChannel to close.

socketChannelRead

public int socketChannelRead(java.nio.channels.SocketChannel socketChannel,
                             byte[] readBuffer)
Read from a java.nio.channels.SocketChannel into readBuffer.

This is a JNI method that gets called by TOSSIM through the Java loader.

Parameters:
socketChannel - SocketChannel from which to read.
readBuffer - The bytes read.
Returns:
Number of bytes read. Returns 0 if end of stream reached, -1 if error.

socketChannelWrite

public int socketChannelWrite(java.nio.channels.SocketChannel socketChannel,
                              byte[] writeBuffer)
Write the bytes in writeBuffer to a java.nio.channels.SocketChannel.

This is a JNI method that gets called by TOSSIM through the Java loader.

Parameters:
socketChannel - The SocketChannel on which to write.
writeBuffer - The bytes to write.
Returns:
Number of bytes written. -1 if error.

_compile

private void _compile(java.lang.String makefileName)
               throws IllegalActionException
Compile the generated code by calling make on the generated file from _generateMakefile().

Parameters:
makefileName - The name of the makefile.
Throws:
IllegalActionException - If there is a problem accessing the destinationDirectory or target parameters or if the make subprocess fails or returns a non-zero value.

_confirmOverwrite

private boolean _confirmOverwrite(java.io.File file)
                           throws IllegalActionException
Confirm overwrite of file if the confirmOverwrite parameter is set to true. Return true if ok to write file, throw IllegalActionException if the user cancels the ovewrite.

Parameters:
file - File to be written.
Returns:
True if ok to write file.
Throws:
IllegalActionException - If code generation should be halted.

_generateCode

private java.lang.String _generateCode(CompositeActor model)
                                throws IllegalActionException
Generate nesC code for the given model. This does not descend hierarchically into contained composites. It simply generates code for the top level of the specified model.

Parameters:
model - The model for which to generate code.
Returns:
A String representation of the nesC code.
Throws:
IllegalActionException

_generateLoader

private void _generateLoader()
                      throws IllegalActionException
Generate Java loader file. ===== Begin example Loader.java (from Dec 4, 2006) ===== import java.net.ServerSocket; import java.nio.channels.Selector; import java.nio.channels.SelectableChannel; import java.nio.channels.SocketChannel; import ptolemy.domains.ptinyos.kernel.PtinyOSLoader; import ptolemy.domains.ptinyos.kernel.PtinyOSDirector; import ptolemy.kernel.util.InternalErrorException; import ptolemy.util.MessageHandler; public class Loader_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0 implements PtinyOSLoader { public void load(String path, PtinyOSDirector director) { String fileSeparator = System.getProperty("file.separator"); String toBeLoaded = path + fileSeparator + System.mapLibraryName("_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0"); toBeLoaded = toBeLoaded.replace('\\', '/'); System.out.println("_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0.java : about to load " + toBeLoaded); System.load(toBeLoaded); this.director = director; } public int main(String argsToMain[]) throws InternalErrorException { return main_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0(argsToMain); } public void startThreads() { try { this.eventAcceptThread = new EventAcceptThread(); this.eventAcceptThread.start(); this.commandReadThread = new CommandReadThread(); this.commandReadThread.start(); } catch (Exception ex) { MessageHandler.error("Could not join thread.", ex); } } public boolean joinThreads() { try { if (this.commandReadThread != null) { this.commandReadThread.join(); } if (this.eventAcceptThread != null) { this.eventAcceptThread.join(); } return true; } catch (Exception ex) { MessageHandler.error("Could not join thread.", ex); } return false; } public void wrapup() { wrapup_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0(); } public void processEvent(long currentTime) { processEvent_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0(currentTime); } public void receivePacket(long currentTime, String packet) { receivePacket_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0(currentTime, packet); } public void enqueueEvent(String newTime) { this.director.enqueueEvent(newTime); } public char getCharParameterValue(String param) { return this.director.getCharParameterValue(param); } public boolean sendToPort(String portName, String expression) { return this.director.sendToPort(portName, expression); } public void tosDebug(String debugMode, String message, String nodeID) { this.director.tosDebug(debugMode, message, nodeID); } public ServerSocket serverSocketCreate(short port) { return this.director.serverSocketCreate(port); } public void serverSocketClose(ServerSocket serverSocket) { this.director.serverSocketClose(serverSocket); } public Selector selectorCreate(ServerSocket serverSocket, boolean opAccept, boolean opConnect, boolean opRead, boolean opWrite) { return this.director.selectorCreate(serverSocket, opAccept, opConnect, opRead, opWrite); } public void selectorRegister(Selector selector, SelectableChannel SocketChannel, boolean opAccept, boolean opConnect, boolean opRead, boolean opWrite) { this.director.selectorRegister(selector, SocketChannel, opAccept, opConnect, opRead, opWrite); } public void selectorClose(Selector selector) { this.director.selectorClose(selector); } public SelectableChannel selectSocket(Selector selector, boolean[] notNullIfClosing, boolean opAccept, boolean opConnect, boolean opRead, boolean opWrite) { return this.director.selectSocket(selector, notNullIfClosing, opAccept, opConnect, opRead, opWrite); } public SocketChannel acceptConnection(SelectableChannel serverSocketChannel) { return this.director.acceptConnection(serverSocketChannel); } public void socketChannelClose(SelectableChannel socketChannel) { this.director.socketChannelClose(socketChannel); } public int socketChannelWrite(SocketChannel socketChannel, byte[] writeBuffer) { return this.director.socketChannelWrite(socketChannel, writeBuffer); } public int socketChannelRead(SocketChannel socketChannel, byte[] readBuffer) { return this.director.socketChannelRead(socketChannel, readBuffer); } private PtinyOSDirector director; private native int main_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0(String argsToMain[]) throws InternalErrorException ; private native void commandReadThread_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0(); private native void eventAcceptThread_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0(); private native void wrapup_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0(); private native void processEvent_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0(long currentTime); private native void receivePacket_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0(long currentTime, String packet); private CommandReadThread commandReadThread; private EventAcceptThread eventAcceptThread; class CommandReadThread extends Thread { public void run() { commandReadThread_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0(); } } class EventAcceptThread extends Thread { public void run() { eventAcceptThread_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor0(); } } } ===== End example Loader.java =====

Throws:
IllegalActionException - If thrown when confirming overwrite, or if writing to the file fails.

_generateMakefile

private java.lang.String _generateMakefile()
                                    throws IllegalActionException,
                                           CancelException
Generate makefile. ===== Begin example makefile (from Dec 9, 20060) ===== TOSROOT=/home/celaine/ptII/vendors/ptinyos/tinyos-1.x TOSDIR=/home/celaine/ptII/vendors/ptinyos/tinyos-1.x/tos TOSMAKE_PATH += $(TOSROOT)/contrib/ptII/ptinyos/tools/make COMPONENT=_SenseToLeds_InWireless_MicaBoard_MicaCompositeActor1 PFLAGS += -I%T/lib/Counters PFLAGS += -DCOMMAND_PORT=10584 -DEVENT_PORT=10585 PFLAGS +=-D_PTII_NODEID=1 MY_PTCC_FLAGS += -D_PTII_NODE_NAME=_1SenseToLeds_1InWireless_1MicaBoard_1MicaCompositeActor1 PFLAGS += "-I$(TOSROOT)/contrib/ptII/ptinyos/beta/TOSSIM-packet" include /home/celaine/ptII/mk/ptII.mk include /home/celaine/ptII/vendors/ptinyos/tinyos-1.x/tools/make/Makerules ===== End example makefile (from Dec 9, 2006) =====

Throws:
IllegalActionException - If thrown when accessing a parameter or if there is an error writing to the file.
CancelException - If the directory named by the ptolemy.ptII.tosroot property does not exist.

_getModelTimeAsLongValue

private long _getModelTimeAsLongValue()
Get the current model time and return the long value.

Returns:
The model time as a long value, or 0 if the model time is null.

_includeConnection

private java.lang.String _includeConnection(CompositeActor model)
Generate code for the nesC interface connections. The order of ports in the model is the order in which the connections are generated.

Parameters:
model - The model containing nesC components for which to generate code.
Returns:
The code for the connections, or an empty string if error.

_includeConnection

private static java.lang.String _includeConnection(CompositeActor model,
                                                   Actor actor)
Generate code for the connections. Called from _includeConnection(CompositeActor).

Parameters:
model - The model containing nesC components for which to generate code.
actor - The actor representing the nesC component for which to generate code.
Returns:
The connections code.

_includeModule

private static java.lang.String _includeModule(CompositeActor model)
                                        throws IllegalActionException
Generate code for the nesC components used in the model.

Parameters:
model - The model containing nesC components for which to generate code.
Returns:
The code listing the components used in the model.
Throws:
IllegalActionException

_initializeParameters

private void _initializeParameters()
Initialize parameters. Set all parameters to their default values.


_interfaceProvides

private static java.lang.String _interfaceProvides(CompositeActor model)
                                            throws IllegalActionException
Generate nesC code describing the input ports. Input ports are described in nesC as interfaces that this module "provides".

Parameters:
model - The model containing nesC components for which to generate code.
Returns:
The code describing the input ports.
Throws:
IllegalActionException

_interfaceUses

private static java.lang.String _interfaceUses(CompositeActor model)
                                        throws IllegalActionException
Generate nesC code describing the output ports. Output ports are described in nesC as interfaces that this module "uses".

Parameters:
model - The model containing nesC components for which to generate code.
Returns:
The code listing the interfaces used.
Throws:
IllegalActionException

_isTopLevelNC

private boolean _isTopLevelNC()
Return true if this PtinyOSDirector is not contained by a opaque composite that is itself controlled by a PtinyOSDirector.


_needsInputDriver

private static boolean _needsInputDriver(Actor actor)
Return true if the given actor has at least one input port, which requires it to have an input driver.

Parameters:
actor - Actor to inspect.
Returns:
True if the given actor has at least one input port.

_sanitizedFullName

private java.lang.String _sanitizedFullName(NamedObj obj)
Get the sanitized full name with workspace version number appended, or "Unnamed" with version number appended if no name.

Parameters:
obj - The NamedObj to inspect.
Returns:
String The sanitized full name of the NamedObj.

_toplevelNC

private NamedObj _toplevelNC()
Looks for the topmost container that contains a PtinyOSDirector director. NOTE: returns this container if this container is not an instanceof CompositeActor.