Recent Changes - Search:

Sunspot

Main.Sunspot History

Hide minor edits - Show changes to output

November 20, 2012, at 09:29 PM by 87.203.80.191 -
Changed line 590 from:
--------------------------------------------------------------------------
to:
----
Changed line 597 from:
--------------------------------------------------------------------------
to:
----
November 20, 2012, at 09:28 PM by 87.203.80.191 -
Changed lines 1227-1229 from:
System.out.println("NEW_NB;" + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + ";Time;" + [[<<]]System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + ";bd_neighbors;" + bi_neighs.getSize() + ";");
to:
System.out.println("NEW_NB;" + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + ";Time;" +

System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + ";bd_neighbors;" + bi_neighs.getSize() + ";");
Changed lines 1234-1236 from:
System.out.println("NEW_NB_BIDI;" + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + ";Time;" + [[<<]]System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + ";bd_neighbors;" + bi_neighs.getSize() + ";");
to:
System.out.println("NEW_NB_BIDI;" + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + ";Time;" +

System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + ";bd_neighbors;" + bi_neighs.getSize() + ";");
Changed lines 1244-1245 from:
// System.out.println("Inserted Node with address: " + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + " " + [[<<]]
to:
// System.out.println("Inserted Node with address: " + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + " " +
Changed lines 1275-1279 from:
System.out.println("LOST_NB_BIDI;" + IEEEAddress.toDottedHex(tmp.getMyaddress().longValue()) + ";Time;" + [[<<]] System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + [[<<]]";bd_neighbors;" + bi_neighs.getSize() + ";");
to:
System.out.println("LOST_NB_BIDI;" + IEEEAddress.toDottedHex(tmp.getMyaddress().longValue()) + ";Time;" +

System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() +

";bd_neighbors;" + bi_neighs.getSize() + ";");
November 20, 2012, at 09:27 PM by 87.203.80.191 -
Changed line 187 from:
Parameter sw represents the switch that was pressed/released.
to:
Parameter sw represents [[<<]] the switch that was pressed/released.
Changed line 294 from:
*To establish a point-to-point connection both ends must open connections specifying the same portNo and corresponding IEEE addresses. Port numbers between 0 and 31 are reserved for system services.
to:
*To establish a point-to-point connection both ends must open connections specifying the same portNo and corresponding IEEE addresses. [[<<]] Port numbers between 0 and 31 are reserved for system services.
November 20, 2012, at 09:25 PM by 87.203.80.191 -
Changed line 1227 from:
System.out.println("NEW_NB;" + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + ";Time;" + System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + ";bd_neighbors;" + bi_neighs.getSize() + ";");
to:
System.out.println("NEW_NB;" + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + ";Time;" + [[<<]]System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + ";bd_neighbors;" + bi_neighs.getSize() + ";");
Changed line 1232 from:
System.out.println("NEW_NB_BIDI;" + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + ";Time;" + System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + ";bd_neighbors;" + bi_neighs.getSize() + ";");
to:
System.out.println("NEW_NB_BIDI;" + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + ";Time;" + [[<<]]System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + ";bd_neighbors;" + bi_neighs.getSize() + ";");
Changed line 1240 from:
// System.out.println("Inserted Node with address: " + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + " " +
to:
// System.out.println("Inserted Node with address: " + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + " " + [[<<]]
Changed line 1270 from:
System.out.println("LOST_NB_BIDI;" + IEEEAddress.toDottedHex(tmp.getMyaddress().longValue()) + ";Time;" + System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + ";bd_neighbors;" + bi_neighs.getSize() + ";");
to:
System.out.println("LOST_NB_BIDI;" + IEEEAddress.toDottedHex(tmp.getMyaddress().longValue()) + ";Time;" + [[<<]] System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + [[<<]]";bd_neighbors;" + bi_neighs.getSize() + ";");
November 20, 2012, at 09:24 PM by 87.203.80.191 -
Changed lines 6-7 from:
the environment and their users in completely new ways. A Java programmer can use standard Java development tools such as NetBeans to write code.
to:
the environment and their users in completely new ways. A Java programmer can use standard Java development [[<<]]
tools such as NetBeans to write code.
November 20, 2012, at 09:24 PM by 87.203.80.191 -
Changed lines 3-5 from:
Project SunSPOT was created to encourage the development of new applications and devices. \\
It
is designed from the ground up to allow programmers who never before worked with embedded \\
devices to think beyond the keyboard, mouse and screen and write programs that interact with each other, \\
to:
Project SunSPOT was created to encourage the development of new applications and devices. [[<<]]
It
is designed from the ground up to allow programmers who never before worked with embedded [[<<]]
devices to think beyond the keyboard, mouse and screen and write programs that interact with each other, [[<<]]
November 20, 2012, at 09:23 PM by 87.203.80.191 -
Changed line 3 from:
Project SunSPOT was created to encourage the development of new applications and devices. \\\
to:
Project SunSPOT was created to encourage the development of new applications and devices. \\
November 20, 2012, at 09:22 PM by 87.203.80.191 -
Changed line 3 from:
Project SunSPOT was created to encourage the development of new applications and devices. \\
to:
Project SunSPOT was created to encourage the development of new applications and devices. \\\
November 20, 2012, at 09:21 PM by 87.203.80.191 -
Changed line 6 from:
the environment and their users in completely new ways. A Java programmer can use standard Java development tools such as NetBeans to write code.
to:
the environment and their users in completely new ways. A Java programmer can use standard Java development tools such as NetBeans to write code.
November 20, 2012, at 09:21 PM by 87.203.80.191 -
Changed lines 4-5 from:
It is designed from the ground up to allow programmers who never before worked with embedded\\
devices to think beyond the keyboard, mouse and screen and write programs that interact with each other,\\
to:
It is designed from the ground up to allow programmers who never before worked with embedded \\
devices to think beyond the keyboard, mouse and screen and write programs that interact with each other, \\
November 20, 2012, at 09:20 PM by 87.203.80.191 -
Changed lines 3-5 from:
Project SunSPOT was created to encourage the development of new applications and devices.
It
is designed from the ground up to allow programmers who never before worked with embedded
devices to think beyond the keyboard, mouse and screen and write programs that interact with each other,
to:
Project SunSPOT was created to encourage the development of new applications and devices. \\
It
is designed from the ground up to allow programmers who never before worked with embedded\\
devices to think beyond the keyboard, mouse and screen and write programs that interact with each other,\\
Changed lines 1239-1240 from:
// System.out.println("Inserted Node with address: " + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + " " + bi_neighs.getSize());
to:
// System.out.println("Inserted Node with address: " + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + " " +
bi_neighs.getSize());
November 20, 2012, at 09:18 PM by 87.203.80.191 -
Changed lines 3-4 from:
Project SunSPOT was created to encourage the development of new applications and devices. \\
It
is designed from the ground up to allow programmers who never before worked with embedded \\devices to think beyond the keyboard, mouse and screen and write programs that interact with each other, the environment and their users in \\completely new ways. A Java programmer can use standard Java development tools such as NetBeans to write code.\\
to:
Project SunSPOT was created to encourage the development of new applications and devices.
It
is designed from the ground up to allow programmers who never before worked with embedded
devices to think beyond the keyboard, mouse and screen and write programs that interact with each other,
the environment and their users in completely new ways. A Java programmer can use standard Java development tools such as NetBeans to write code.
November 20, 2012, at 09:17 PM by 87.203.80.191 -
Changed line 4 from:
It is designed from the ground up to allow programmers who never before worked with embedded devices to think beyond the keyboard, mouse and screen and write programs that interact with each other, the environment and their users in completely new ways. A Java programmer can use standard Java development tools such as NetBeans to write code.
to:
It is designed from the ground up to allow programmers who never before worked with embedded \\devices to think beyond the keyboard, mouse and screen and write programs that interact with each other, the environment and their users in \\completely new ways. A Java programmer can use standard Java development tools such as NetBeans to write code.\\
November 20, 2012, at 09:16 PM by 87.203.80.191 -
Changed line 3 from:
Project SunSPOT was created to encourage the development of new applications and devices.
to:
Project SunSPOT was created to encourage the development of new applications and devices. \\
Changed line 509 from:
!!Radio Demo (unicast) - MIDlet app}
to:
!!Radio Demo (unicast) - MIDlet app
November 20, 2012, at 09:15 PM by 87.203.80.191 -
Changed lines 500-503 from:
--> final String rcvMsg = dg.readUTF();

--> //System.out.println("Received Datagram from " + dg.getAddress());
--> System.out.println("Received msg: " + rcvMsg
to:
final String rcvMsg = dg.readUTF();

//System.out.println("Received Datagram from " + dg.getAddress());
System.out.println("Received msg: " + rcvMsg
November 20, 2012, at 09:14 PM by 87.203.80.191 -
Deleted lines 5-7:

Changed lines 104-105 from:
**other IDE specific or not directories may exist or appear after the build process, such as \textit{suite/} where the jar app is saved.
to:
**other IDE specific or not directories may exist or appear after the build process, such as suite where the jar app is saved.
Changed lines 169-170 from:
* Setup a switch listener to monitor both switches for press or release events. \textit{MIDlet} should implement \textit{ISwitchListener}. \\ Add on \textit{startApp()} the following lines:
to:
* Setup a switch listener to monitor both switches for press or release events. '''MIDlet''' should implement '''ISwitchListener''' .
\\ Add on '''startApp()''' the following lines:
Changed lines 224-225 from:
*Initialize an \textit{ITriColorLED} array which controls the built in LEDs.
to:
*Initialize an '''ITriColorLED''' array which controls the built in LEDs.
Changed lines 235-236 from:
*Update the implementation code of \textit{switchPressed()} callback.
to:
*Update the implementation code of '''switchPressed()''' callback.
Changed line 262 from:
* Update the implementation code of \textit{destroyApp()}
to:
* Update the implementation code of '''destroyApp()'''
Changed line 291 from:
*To establish a point-to-point connection both ends must open connections specifying the same portNo and corresponding IEEE addresses. \textit{\begin{footnotesize}Port numbers between 0 and 31 are reserved for system services.\end{footnotesize}}
to:
*To establish a point-to-point connection both ends must open connections specifying the same portNo and corresponding IEEE addresses. Port numbers between 0 and 31 are reserved for system services.
Changed line 521 from:
**Update the \textit{startApp()} function:
to:
**Update the '''startApp()''' function:
Changed lines 551-554 from:
*Define the host application's main class in \textit{build.properties} file. \textit{main.class=org.sunspotworld.demo.SunSpotHostApplication}
*Use \textit{ant host-run} instead \textit{ant deploy} and \textit{ant run}
*The main class should not \textit{extends MIDlet}.
*\textit{Spot} Class (\textit{Spot.getInstance()}) has been deprecated on host applications
to:
*Define the host application's main class in '''build.properties''' file. '''main.class=org.sunspotworld.demo.SunSpotHostApplication'''
*Use '''ant host-run''' instead '''ant deploy''' and '''ant run'''
*The main class should not '''extends MIDlet'''.
*'''Spot''' Class ('''Spot.getInstance()''') has been deprecated on host applications
November 20, 2012, at 09:10 PM by 87.203.80.191 -
Changed lines 3-9 from:
Project SunSPOT was created to encourage the development of new applications and devices.

It
is designed from the ground up to allow programmers who never before worked with embedded devices to think beyond the keyboard,

mouse and screen and write programs that interact with each other, the environment and their users in completely new ways.

A Java programmer can use standard Java development tools such as NetBeans to write code.
to:
Project SunSPOT was created to encourage the development of new applications and devices.
It
is designed from the ground up to allow programmers who never before worked with embedded devices to think beyond the keyboard, mouse and screen and write programs that interact with each other, the environment and their users in completely new ways. A Java programmer can use standard Java development tools such as NetBeans to write code.
November 20, 2012, at 09:05 PM by 87.203.80.191 -
Added line 4:
Added line 6:
Added line 8:
November 20, 2012, at 09:05 PM by 87.203.80.191 -
Changed lines 3-6 from:
Project SunSPOT was created to encourage the development of new applications and devices. It is designed from the ground up to allow programmers who never before worked with embedded devices to think beyond the keyboard, mouse and screen and write programs that interact with each other, the environment and their users in completely new ways. A Java programmer can use standard Java development tools such as NetBeans to write code.
to:
Project SunSPOT was created to encourage the development of new applications and devices.
It is designed from the ground up to allow programmers who never before worked with embedded devices to think beyond the keyboard,
mouse and screen and write programs that interact with each other, the environment and their users in completely new ways.
A Java programmer can use standard Java development tools such as NetBeans to write code.
November 20, 2012, at 09:04 PM by 87.203.80.191 -
Added line 591:
Added line 593:
November 20, 2012, at 09:03 PM by 87.203.80.191 -
Changed lines 97-98 from:
!Files Structure}
to:
!Files Structure
Changed line 108 from:
!Code Structure}
to:
!Code Structure
Changed line 141 from:
!!Hello World Demo}
to:
!!Hello World Demo
Changed lines 268-271 from:
--> for (int i = 7; i >= 0; i--) {
--> leds[i].setOff(); // turn the LED off
--> Utils.sleep(250); // wait 1/4 seconds
--> }
to:
for (int i = 7; i >= 0; i--) {
leds[i].setOff(); // turn the LED off
Utils.sleep(250); // wait 1/4 seconds
}
Changed lines 525-527 from:
--> //Start the Broadcaster
--> //(new Broadcaster()).start();
to:
//Start the Broadcaster
//(new Broadcaster()).start();
Changed lines 531-542 from:
--> final String destination = "0014.4F01.0000.6192";
--> final String message = "Hello!!";

--> while (true) {
--> //Block the current thread until the switch's state changes.
--> sw1.waitForChange(); //waitForChange() uses interrupts, not polls

--> //Check if sw1 is closed
--> if (sw1.isClosed()) {
--> DataSender.getInstance().send(destination, message);
--> }
--> }
to:
final String destination = "0014.4F01.0000.6192";
final String message = "Hello!!";

while (true) {
//Block the current thread until the switch's state changes.
sw1.waitForChange(); //waitForChange() uses interrupts, not polls

//Check if sw1 is closed
if (sw1.isClosed()) {
DataSender.getInstance().send(destination, message);
}
}
Added lines 590-592:
In the following we present an implementation of a delay tolerant message forwarding service.
We present the Message Sender Class, the Message Receiver calls, the DTSManager Service class and
the EchoProtocolManager Class.
November 20, 2012, at 08:58 PM by 87.203.80.191 -
Added lines 1063-1546:

!Echo Protocol Manager Class
[@
import com.sun.spot.peripheral.NoRouteException;
import com.sun.spot.peripheral.radio.ILowPan;
import com.sun.spot.peripheral.radio.mhrp.interfaces.IMHEventListener;
import com.sun.spot.peripheral.radio.routing.RouteInfo;
import com.sun.spot.peripheral.radio.routing.RouteTable;
import com.sun.spot.peripheral.radio.routing.interfaces.RouteEventClient;
import com.sun.spot.service.IService;
import com.sun.spot.util.IEEEAddress;
import eu.fronts.moway.communication.echoprotocol.broadcaster.Broadcaster;
import eu.fronts.moway.communication.echoprotocol.broadcaster.BroadcasterInvStab;
import eu.fronts.moway.communication.echoprotocol.broadcaster.BroadcasterStab;
import eu.fronts.moway.communication.echoprotocol.receiver.Receiver;
import eu.fronts.moway.util.Node;
import eu.fronts.moway.util.Observable;
import eu.fronts.moway.util.SortedList;


/**
* Implements the Echo Protocol. Every node listens for beacons form it's neighbours and creates a list
* of it's neighbours. Runs in two modes (Unidirectional, Bidirectional).
*/
public class EchoProtocolManager extends Observable implements com.sun.spot.peripheral.radio.routing.interfaces.IRoutingManager {

/**
* ECHO PORT.
*/
public static final short ECHO_PORT = 110;

/**
* Expiration Ttime.
*/
public static final long EXPIRATION_TIME = 3000;

/**
* Beacon Interval.
*/
public static final long BEACON_INTERVAL = 1000;

/**
* Cleaning Delta.
*/
public static final long CLEAN_DELTA = 50;

/**
* Echo mode. 0 uni directional.
*/
public static final short UNI_DIRECTIONAL = 0;

/**
* Echo mode :
*/
public static final short BI_DIRECTIONAL = 1;

public static final short GATEWAY = 0;

public static final short SIMPLE_NODE = 42;

public static final Long DISCONNECTED = new Long(-1);

public static final boolean LQI_ENABLED = false;

public static int LQI_THRESHOLD_MIN = 100;

public static int LQI_THRESHOLD_MAX = 100;

public static final short STABILITY_DISABLED = 0;

public static final short STABILITY_ENABLED = 1;

public static final short STABILITY_INV = 2;

public static final short STABILITY = 0;

/**
* the type
*/
private short type;

private Node gateway;

private Long myAddress;

private short echo_mode;

private static EchoProtocolManager instance = null;

private SortedList uni_neighs;

private SortedList bi_neighs;

private static ILowPan lowpan;

private int state;

private static String name = "EchoProtocolManager";

public static final short STABILITY_THRESHOLD = 50;

/**
* Constructs a new EchoProtocolManager.
* Calls all services that need to run.
*/
private EchoProtocolManager() {
uni_neighs = new SortedList();
bi_neighs = new SortedList();

type = SIMPLE_NODE;
echo_mode = BI_DIRECTIONAL;
gateway = new Node();
gateway.setMyaddress(DISCONNECTED);
Receiver.getInstance();

if (EchoProtocolManager.STABILITY == EchoProtocolManager.STABILITY_DISABLED) {
Broadcaster.getInstance();
} else if (EchoProtocolManager.STABILITY == EchoProtocolManager.STABILITY_ENABLED) {
BroadcasterStab.getInstance();
} else if (EchoProtocolManager.STABILITY == EchoProtocolManager.STABILITY_INV) {
BroadcasterInvStab.getInstance();
}


System.out.println("Echo Protocol started");
}

/**
* Updates Neighbour list with new node. Runs when a new beacon has been detected.
*
* @param node Represents the node of the beacon that was detected.
*/
public void updateNeighs(final Node node) {
if (node.getType() == GATEWAY) {
if (echo_mode == UNI_DIRECTIONAL) {
if (gateway.getMyaddress() == DISCONNECTED) {
//System.out.println("Inserted Gateway with address: " + IEEEAddress.toDottedHex((long) node.getMyaddress().longValue()));

gateway = node;
} else if (gateway.getMyaddress() == node.getMyaddress()) {
gateway.setExpiryTime(node.getExpiryTime());
}
} else if (echo_mode == BI_DIRECTIONAL) {
uni_neighs.insertElement(node);
if (node.getMode() == BI_DIRECTIONAL) {
if (gateway.getMyaddress() == DISCONNECTED) {
// System.out.println("Inserted Gateway with address: " + IEEEAddress.toDottedHex((long) node.getMyaddress().longValue()));
gateway = node;
} else if (gateway.getMyaddress() == node.getMyaddress()) {
gateway.setExpiryTime(node.getExpiryTime());
}
}
}
} else if (node.getType() == SIMPLE_NODE) {
if (echo_mode == BI_DIRECTIONAL) {

if (!uni_neighs.insertElement(node)) {
System.out.println("NEW_NB;" + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + ";Time;" + System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + ";bd_neighbors;" + bi_neighs.getSize() + ";");
}
//bi_neighs is subset of uni_neighs and stores neighs that can listen to us
if (node.getMode() == BI_DIRECTIONAL) {
if (!bi_neighs.insertElement(node)) {
System.out.println("NEW_NB_BIDI;" + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + ";Time;" + System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + ";bd_neighbors;" + bi_neighs.getSize() + ";");
}
this.setChanged();
this.notifyObservers(node);
}
} else if (echo_mode == UNI_DIRECTIONAL) {
//we suppose that every neighbour is bidirectional so we update only bi_neighs list
if (!bi_neighs.insertElement(node)) {
// System.out.println("Inserted Node with address: " + IEEEAddress.toDottedHex(node.getMyaddress().longValue()) + " " + bi_neighs.getSize());
this.setChanged();
this.notifyObservers(node);
}
}
}
}

/**
* Check if any neighbour is not broadcasting and remove it from the list.
*/
public void cleanDeadNeighs() {

//clean unidirectional neighbours
if (uni_neighs.getFirstElement() != null) {
while (uni_neighs.getFirstElement().getExpiryTime() < (System.currentTimeMillis() + CLEAN_DELTA)) {
final Node tmp = uni_neighs.getFirstElement();
uni_neighs.removeFirstElement();
System.out.println("DROPPED_NB;" + IEEEAddress.toDottedHex(tmp.getMyaddress().longValue()) + ";Time;" + System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + ";bd_neighbors;" + bi_neighs.getSize() + ";");
if (uni_neighs.getFirstElement() == null)
break;
}
}

//clean bidirectional neighbours
if (bi_neighs.getFirstElement() != null) {
while (bi_neighs.getFirstElement().getExpiryTime() < (System.currentTimeMillis() + CLEAN_DELTA)) {
final Node tmp = bi_neighs.getFirstElement();
bi_neighs.removeFirstElement();
System.out.println("LOST_NB_BIDI;" + IEEEAddress.toDottedHex(tmp.getMyaddress().longValue()) + ";Time;" + System.currentTimeMillis() + ";Node;" + IEEEAddress.toDottedHex(myAddress.longValue()) + ";neighbors;" + uni_neighs.getSize() + ";bd_neighbors;" + bi_neighs.getSize() + ";");
if (bi_neighs.getFirstElement() == null)
break;
}
}

//clean gateway if connection lost
if (gateway.getExpiryTime() < (System.currentTimeMillis() + CLEAN_DELTA)
&& gateway.getMyaddress() != DISCONNECTED) {
System.out.println("Removed gateway: " + IEEEAddress.toDottedHex(gateway.getMyaddress().longValue()));
gateway.setMyaddress(DISCONNECTED);
}
}

/**
* Initialization of manager.
*
* @param address address used by this LowPan layer
* @param iLowPan a reference to the lowpan layer
*/
public void initialize(long address, ILowPan iLowPan) {
System.out.println("Initialize..");
this.myAddress = new Long(address);
this.lowpan = iLowPan;
}

/**
* retrieve routing information for a destination address.
*
* @param address neighbour's address
* @return returns a route info object where nexthop is the destination and is 1 hop away if address is in
* routing table. else returns No Route
*/
public RouteInfo getRouteInfo(long address) {
final RouteInfo info;
if (bi_neighs.containsKey(new Long(address))) {
info = new RouteInfo(address, address, 1);
} else {
info = new RouteInfo(address, -1, 0);
}
return info;
}

/**
* lookup a route to this address.
*
* @param address destination address
* @param routeEventClient client to be called back with the routing information
* @param o a key that uniquely identifies this request/client
* @return The answer will be that the destination address
* is exactly 1 hop away if the address is in the routing table. Else answer will be that there is no route
* to the destination address `
* @throws NoRouteException
*/
public boolean findRoute(long address, RouteEventClient routeEventClient, Object o) throws NoRouteException {
final RouteInfo info;
if (bi_neighs.containsKey(new Long(address))) {
info = new RouteInfo(address, address, 1);
} else {
info = new RouteInfo(address, -1, 0);
}
routeEventClient.routeFound(info, o);
return true;
}

/**
* This method returns a snapshot of the routing table
*
* @return an object containing a snapshot of the routing table
*/
public RouteTable getRoutingTable() {
RouteTable rt = new RouteTable();
bi_neighs.initEnum();
while (bi_neighs.hasMoreElements()) {
final Node tmp = (Node) bi_neighs.nextElement();
final RouteInfo route = new RouteInfo(tmp.getMyaddress().longValue(),
tmp.getMyaddress().longValue(), 1);
rt.addEntry(route);
}
return rt;
}

/**
* Create an array with neighbour addresses as long and return it
*
* @return long[] with neighs addresses
*/
public long[] getSemiNeighAddr() {
final long[] neighs = new long[uni_neighs.getSize()];
uni_neighs.initEnum();
for (int i = 0; i < neighs.length; i++) {
if (uni_neighs.hasMoreElements()) {
neighs[i] = ((Node) uni_neighs.nextElement()).getMyaddress().longValue();
} else {
neighs[i] = 0;
}
}
return neighs;
}

/**
* Nodes are always 1 hop away. Mark a node unreachable if it isn't
*
* @param originator node that requested the route
* @param destination route destination originator
* @return always returns true
*/
public boolean invalidateRoute(long originator, long destination) {
bi_neighs.removeElement(new Long(destination));
return true;
}

/**
* registers a listener for routing messages. EchoProtocol hop has no messages so this
* is a NO OP.
*
* @param imhEventListener event listener for callbacks
*/
public void registerEventListener(IMHEventListener imhEventListener) {
}

/**
* deregisters a listener for routing messages. EchoProtocol has no messages so this
* is a NO OP.
*
* @param imhEventListener the listener to remove
*/
public void deregisterEventListener(IMHEventListener imhEventListener) {
}

/**
* Registers an event listener that is notified when this node
* initiates/receives supported route events
*
* @param imhEventListener object that is notified when route events occur
*/
public void addEventListener(IMHEventListener imhEventListener) {

}

/**
* Remove the specified event listener that was registered for route events
*
* @param imhEventListener object that is notified when route events occur
*/
public void removeEventListener(IMHEventListener imhEventListener) {
}

public boolean start() {
state = IService.RUNNING;
return true;
}

public boolean stop() {
Broadcaster.getInstance().disable();
Receiver.getInstance().disable();
state = IService.STOPPED;
return true;
}

public boolean pause() {
return stop();
}

public boolean resume() {
return start();
}

public int getStatus() {
return state;
}

public boolean isRunning() {
return (state == IService.RUNNING);
}

public String getServiceName() {
return name;
}

public void setServiceName(String s) {
name = s;
}

public boolean getEnabled() {
return false;
}

public void setEnabled(boolean b) {
}

/**
* @return EchoProtocolManager instance of this singleton
*/
public static EchoProtocolManager getInstance() {
synchronized (EchoProtocolManager.class) {
if (instance == null) {
instance = new EchoProtocolManager();
}
}
return instance;
}


public short getType() {
return type;
}

public Long getMyAddress() {
return myAddress;
}

public short getEcho_mode() {
return echo_mode;
}

public Long getGatewayAddress() {
return gateway.getMyaddress();
}

public void setEcho_mode(short echo_mode) {
this.echo_mode = echo_mode;
}

public int getNeighSize() {
return bi_neighs.getSize();
}

public SortedList getUnidirectionalNeighs() {
return uni_neighs;
}

public SortedList getBidirectionalNeighs() {
return bi_neighs;
}

/**
* @return SortedList[] with neighs
*/
public SortedList getUniNeighs() {
final SortedList tmpneighs = new SortedList();
uni_neighs.initEnum();
while (uni_neighs.hasMoreElements()) {
tmpneighs.insertElement((Node) uni_neighs.nextElement());
}
return tmpneighs;
}

/**
* @return SortedList[] with neighs
*/
public SortedList getBiNeighs() {
final SortedList tmpneighs = new SortedList();
bi_neighs.initEnum();
while (bi_neighs.hasMoreElements()) {
tmpneighs.insertElement((Node) bi_neighs.nextElement());
}
return tmpneighs;
}

public void cleanStabilityCounters() {
final SortedList unis = getUniNeighs();
final SortedList bis = getBiNeighs();
unis.initEnum();
bis.initEnum();
long now = System.currentTimeMillis();

while (unis.hasMoreElements()) {
final Node node = unis.nextElement();
if (now - (node.getExpiryTime() - (EXPIRATION_TIME)) > (BEACON_INTERVAL + CLEAN_DELTA)) {
node.setAssocCounter(0);
uni_neighs.insertElement(node);
}
}
while (bis.hasMoreElements()) {
final Node node = bis.nextElement();
if (now - (node.getExpiryTime() - (EXPIRATION_TIME)) > (BEACON_INTERVAL + CLEAN_DELTA)) {
node.setAssocCounter(0);
bi_neighs.insertElement(node);
}
}
}

}
@]
November 20, 2012, at 08:56 PM by 87.203.80.191 -
Changed line 547 from:
!Host Application}
to:
!Host Application
Changed line 558 from:
!!Radio Demo (unicast) - main Class}
to:
!!Radio Demo (unicast) - main Class
Changed line 589 from:
!Delay Tolerant Routing Service over Sunspot Deployment
to:
!Delay Tolerant Routing Services Development over Sunspot Deployment
Added lines 591-592:

!Message Sender Class
Added lines 661-1059:
}
}
@]

!Message Receiver Class
[@
import com.sun.spot.io.j2me.radiogram.Radiogram;
import com.sun.spot.io.j2me.radiogram.RadiogramConnection;
import com.sun.spot.util.IEEEAddress;
import com.sun.spot.util.Utils;
import eu.fronts.moway.storage.Messages;

import javax.microedition.io.Connector;
import java.io.IOException;


public class Receiver extends Thread {

private boolean isEnabled;

/**
* Default Constructor.
*/
public Receiver() {
super();
isEnabled = true;
}

/**
* If this thread was constructed using a separate
* <code>Runnable</code> run object, then that
* <code>Runnable</code> object's <code>run</code> method is called;
* otherwise, this method does nothing and returns.
* <p/>
* Subclasses of <code>Thread</code> should override this method.
*
* @see #start()
* @see #stop()
* @see #Thread(ThreadGroup, Runnable, String)
*/
public void run() {
RadiogramConnection rgConnection = null;

Utils.sleep(1000);
try {
rgConnection = (RadiogramConnection) Connector.open("radiogram://:" + DTSManager.DTSPORT);

} catch (IOException e) {
System.out.println("Could not open radiogram receiver connection");
e.printStackTrace();
return;
}

while (isEnabled) {
try {
// We receive messages
final Radiogram rg = (Radiogram) rgConnection.newDatagram(rgConnection.getMaximumLength());

rg.reset();

rgConnection.receive(rg);
System.out.println("DTS Message Received: " + rg.getLength());
//Message ID
final byte messageid = rg.readByte();
System.out.println(messageid);
//Source
final short source = rg.readShort();

//Destination
final short tmp = rg.readShort();
final long destination = IEEEAddress.To64Bit(tmp);

//Sequence Number
final short seqNo = rg.readByte();

//Payload Size
final short pldSize = rg.readByte();

//Payload
final byte[] payload = new byte[rg.getLength()];
rg.resetRead();
rg.readFully(payload, 0, rg.getLength());

//Initialize the message
final Messages msg = new Messages(messageid, source, destination, seqNo, pldSize, payload);

//Add this message to DTS.
DTSManager.getInstance().addMessage(new Long(msg.getDestination()), msg);

} catch (final IOException e) {
System.out.println("Nothing received");
e.printStackTrace();
}
}
}

/**
* Stop thread execution
*/
public void disable() {
isEnabled = false;
}
}
@]

!DTS Manager Class
[@
import com.sun.spot.io.j2me.radiogram.RadiogramConnection;
import com.sun.spot.util.IEEEAddress;
import com.sun.spot.util.Queue;
import com.sun.spot.util.Utils;
import eu.fronts.moway.communication.echoprotocol.EchoProtocolManager;
import eu.fronts.moway.mowaycontroller.Controller;
import eu.fronts.moway.storage.Messages;
import eu.fronts.moway.ui.LEDManager;
import eu.fronts.moway.util.HashMap;
import eu.fronts.moway.util.Node;
import eu.fronts.moway.util.Observable;
import eu.fronts.moway.util.Observer;

import javax.microedition.io.Connector;
import javax.microedition.io.Datagram;
import java.io.IOException;
import java.util.Vector;

/**
* DTSManager observes the EchoProtocolManager.
*/
public final class DTSManager implements Observer {

/**
* The Radiogram Port to transmit messages.
*/
public static final int DTSPORT = 105;

/**
* Unique instance of this class.
*/
private static DTSManager thisInstance;

/**
* The Radiogram Connection.
*/
private RadiogramConnection dgConnection = null;

/**
* Instance of Message Sender.
*/
private final MessageSender msgSender;

/**
* Messages Delivered to destination. Key: Destination, Value: Vector with messages.
*/
private final HashMap msgDelivered;

/**
* Undelivered messages.Key: Destination, Value: Messages with messages.
*/
private final HashMap msgToDeliver;

/**
* Buffer for the Echo Notifications.
*/
private final Queue notificationBuffer;

/**
* The Message Receiver Thread.
*/
private final Receiver receiver;

/**
* Counts the undelivered Messages.
*/
private int msgCounter;

/**
* Counts the received messages.
*/
private int receivedMessages;

/**
* Counts the delivered messages.
*/
private int deliveredMessages;

/**
* Creates a new instance of DTSManager.
*/
private DTSManager() {
//Observer the Echo Protocol.
EchoProtocolManager.getInstance().addObserver(this);

msgCounter = 0;
receivedMessages = 0;
deliveredMessages = 0;

//Initialize the HashMaps.
msgDelivered = new HashMap();
msgToDeliver = new HashMap();

//Initialize the DTS message Sender.
notificationBuffer = new Queue();
msgSender = new MessageSender(notificationBuffer);
msgSender.start();

//Initialize the DTS message Receiver,
receiver = new Receiver();
receiver.start();
}

/**
* getInstance should be used each time access to the DTSManager instance is needed.
*
* @return the DTSManager instance
*/
public static DTSManager getInstance() {
synchronized (DTSManager.class) {
// Check if an instance has already been created
if (thisInstance == null) {
// Create a new instance if not
thisInstance = new DTSManager();
}
}
// Return the DTSManager instance
return thisInstance;
}

/**
* Return the delivered messages.
*
* @return the returned HashMap
*/
public synchronized HashMap getMsgDelivered() {
return msgDelivered;
}

/**
* Return the undelivered messages.
*
* @return the returned HashMap
*/
public synchronized HashMap getMsgToDeliver() {
return msgToDeliver;
}

/**
* Open Connection to a specific Node and deliver saved messages.
*
* @param destination the destination address
* @param message The Messages to be delivered.
*/
public void sendMessage(final Long destination, final Queue message) {
System.out.println("Vector size: " + message.size());
Controller.getInstance().disableAutoMode();
Controller.getInstance().stopRobot();

try {
final long delayTime = 300;
// Creates a Unicast Datagram Connection
dgConnection = (RadiogramConnection) Connector.open("radiogram://" + IEEEAddress.toDottedHex(destination.longValue()) + ":" + DTSPORT);
System.out.println("radiogram://" + IEEEAddress.toDottedHex(destination.longValue()) + ":" + DTSPORT);
dgConnection.setMaxBroadcastHops(1);
int i = 0;
while (!message.isEmpty()) {
System.out.println(i);
i++;
// Creates a Datagram using the above Connection
final Datagram datagram = dgConnection.newDatagram(dgConnection.getMaximumLength());

// Clean the Datagram
datagram.reset();

final Messages msg = (Messages) message.get(i);

datagram.write(msg.getPayload(), 0, msg.getPayload().length);
System.out.println(msg.getPayload().length);
/*datagram.writeShort(msg.getSource());
datagram.writeShort((short) msg.getDestination());
datagram.write((byte) msg.getSequenceNumber());
datagram.write((byte) msg.getPayloadSize());
datagram.write(msg.getPayload());*/

// Send the datagram
try {
// Send the message
dgConnection.send(datagram);
System.out.println(datagram.getLength());
System.out.println("Message Send");

/* if (msgDelivered.containsKey(destination)) {

//Queue is full. Remove the 10 first messages.
if (((Vector) msgDelivered.get(destination)).size() > 50) {
for (int index = 0; index < 10; index++) {
((Vector) msgDelivered.get(destination)).removeElementAt(index);
}
}
// Add message to delivered Vector.
((Vector) msgDelivered.get(destination)).addElement(message.elementAt(i));

} else {
final Vector tmp = new Vector();
tmp.addElement(msg);
// Add message to delivered Vector.
msgDelivered.put(new Long(msg.getDestination()), tmp);
}*/

// Add message to delivered Vector.
//((Vector) msgToDeliver.get(destination)).removeElement(message.elementAt(i));

msgCounter--;
deliveredMessages++;
LEDManager.getInstance().setOnLeds(msgCounter);
} catch (final IOException e) {
e.printStackTrace();
}

Utils.sleep(delayTime);
}

dgConnection.close();
} catch (final IOException e) {
//Error Delivering the message
e.printStackTrace();
try {
//Close the COnnection
dgConnection.close();
} catch (final IOException e1) {
e1.printStackTrace();
}
}

Controller.getInstance().enableAutoMode();
}

/**
* Add message to undelivered messages.
*
* @param destination the message destination
* @param msg the message
*/
public void addMessage(final Long destination, final Messages msg) {

System.out.println("New message added to DTS with Dest: " + IEEEAddress.toDottedHex(destination.longValue())
+ "\n\t from " + IEEEAddress.toDottedHex(msg.getSource()) + "---" + destination);

if (msgToDeliver.containsKey(destination) /*&& ((Vector) msgToDeliver.get(destination)).size() < 50 &&
!((Vector) msgToDeliver.get(destination)).contains(msg)*/) {

((Queue) msgToDeliver.get(destination)).put(msg);

System.out.println("More than one messages to deliver");
} else {
final Queue messages = new Queue();
messages.put(msg);

msgToDeliver.put(destination, messages);
System.out.println("First message");
}
msgCounter++;
receivedMessages++;
LEDManager.getInstance().setOnLeds(msgCounter);
}

/**
* Invoked when an <code>Observable</code> object notifies the <code>Observer</code>.
*
* @param observable the <code>Observable</code> object which notified the <code>Observer</code>
* @param arg the changed object
*/
public void update(final Observable observable, final Object arg) {

if (observable instanceof EchoProtocolManager && arg instanceof Node) {

//Echo notification message.
// New neighbor found.
final Node node = (Node) arg;

//Pass the message to the Event Sender.
notificationBuffer.put(node);
}
}

/**
* Returns the total received messages.
*
* @return the number of messages
*/
public int getReceivedMessages() {
return receivedMessages;
}

/**
* Returns the delivered messages.
*
* @return the number o messages
*/
public int getDeliveredMessages() {
return deliveredMessages;
November 20, 2012, at 08:51 PM by 87.203.80.191 -
Changed lines 586-661 from:
@]
to:
@]

--------------------------------------------------------------------------
!Delay Tolerant Routing Service over Sunspot Deployment
--------------------------------------------------------------------------
[@
import com.sun.spot.util.IEEEAddress;
import com.sun.spot.util.Queue;
import eu.fronts.moway.communication.echoprotocol.EchoProtocolManager;
import eu.fronts.moway.util.Node;

import java.util.Enumeration;
import java.util.Vector;

/**
* DTS Message Sender.
*/
public class MessageSender extends Thread { //NOPMD

/**
* True if thread is enabled.
*/
private boolean isEnabled;

/**
* Node Queue.
*/
private final Queue queue;

/**
* Default Constructor.
*/
public MessageSender(final Queue que) {
super();
this.queue = que;
isEnabled = true;

}

/**
* If this thread was constructed using a separate
* <code>Runnable</code> run object, then that
* <code>Runnable</code> object's <code>run</code> method is called;
* otherwise, this method does nothing and returns.
* <p/>
* Subclasses of <code>Thread</code> should override this method.
*
* @see #start()
* @see #stop()
* @see #Thread(ThreadGroup, Runnable, String)
*/
public final void run() { //NOPMD

while (isEnabled) {

final Node node = (Node) queue.get();

System.out.println("New node");

if (node.getType() == Node.MOWAY) {
//This is another Moway,

} else if (node.getType() == EchoProtocolManager.SIMPLE_NODE) {
//Check for undelivered messages.
if (DTSManager.getInstance().getMsgToDeliver().containsKey(node.getMyaddress())) {
System.out.println("Destination Found: " + IEEEAddress.toDottedHex(node.getMyaddress().longValue()));
if (!((Queue) DTSManager.getInstance().getMsgToDeliver().get(node.getMyaddress())).isEmpty()) {
//Deliver the messages.
DTSManager.getInstance().sendMessage(node.getMyaddress(), (Queue) DTSManager.getInstance().getMsgToDeliver().get(node.getMyaddress()));
}
}
}
}
}
}

@]
Changed lines 234-235 from:
!!LEDs}
to:
!!LEDs
Changed lines 243-247 from:
--> for (int i = 0; i < 8; i++) {
-->
leds[i].setColor(LEDColor.RED); // set color to red
--> leds[i].setOn(); // turn the LED on
--> Utils.sleep(250); // wait 1/4 seconds
--> }
to:
for (int i = 0; i < 8; i++) {
leds[i].setColor(LEDColor.RED); // set color to red
leds[i].setOn(); // turn the LED on
Utils.sleep(250); // wait 1/4 seconds
}
Changed lines 261-271 from:
\begin{frame}[fragile]
\frametitle{
LEDs}

\begin{itemize}
\item
Update the implementation code of \textit{destroyApp()}
\end{itemize}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}
[language=Java]
to:
!!LEDs

*
Update the implementation code of \textit{destroyApp()}
[@
Changed lines 274-310 from:
\end{lstlisting}
\end{frame}

%
----------------------------------------------------------------------------%
\subsection{Communication}
\begin{frame}
\frametitle{Communication}

\begin{itemize}
\item Every \suns can act as a mesh router, forwarding packets it receives on to other \suns. This way multihop communication is possible
\item Two multihop protocol can be used:
\begin{itemize}
\item AODVManager, Ad Hoc On Demand Distance Vector Routing protocol.
\item LQRPManager, Link Quality Routing Protocol (default)
\end{itemize}
\item SingleHopManager, single hop (non-mesh) Routing protocol.
\item Two communication protocols are supported:
\begin{itemize}
\item The Radiostream protocol is a socket-like peer-to-peer and provides reliable, buffered, stream-based communication
\item The Radiogram protocol provides unreliable datagram-based communication
\end{itemize}
\item Http connections can be started from any \suns to any accessible web service
\end{itemize}
\end{frame}


\begin{frame}
\frametitle{Radiogram}

\begin{itemize}
\item To establish a point-to-point connection both ends must open connections specifying the same portNo and corresponding IEEE addresses. \textit{\begin{footnotesize}Port numbers between 0 and 31 are reserved for system services.\end{footnotesize}}
\item Radiogram supports broadcast mode, where radiograms are delivered to all listeners on the given port.
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{
Radio Demo (broadcast)}
to:
@]


!Communication

*Every SunSPOT can act as a mesh router, forwarding packets it receives on to other SunSPOT. This way multihop communication is possible
*Two multihop protocol can be used:
**AODVManager, Ad Hoc On Demand Distance Vector Routing protocol.
**LQRPManager, Link Quality Routing Protocol (default)
*SingleHopManager, single hop (non
-mesh) Routing protocol.
*Two communication protocols are supported:
**The Radiostream protocol is a socket
-like peer-to-peer and provides reliable, buffered, stream-based communication
**The Radiogram protocol provides unreliable datagram
-based communication
*Http connections can be started from any \suns to any accessible web service


!!Radiogram

*To establish a point
-to-point connection both ends must open connections specifying the same portNo and corresponding IEEE addresses. \textit{\begin{footnotesize}Port numbers between 0 and 31 are reserved for system services.\end{footnotesize}}
*Radiogram supports broadcast mode, where radiograms are delivered to all listeners on the given port.

!!Radio
Demo (broadcast)}
Changed lines 299-311 from:
\begin{itemize}
\item
The Broadcaster is sending broadcast messages every 1000 ms.
\item The Reveiver is listening for incoming messages on specific port.
\end{itemize}
\end{frame}

\begin{frame}[fragile]
\frametitle{
Radio Demo (broadcast) - Broadcaster}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}
[language=Java]
to:
*The Broadcaster is sending broadcast messages every 1000 ms.
*The Reveiver is listening for incoming messages on specific port.

!!Radio Demo (broadcast) - Broadcaster

[@
Deleted lines 326-335:
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
\frametitle{Radio Demo (broadcast) - Broadcaster}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
Changed lines 344-354 from:
\end{lstlisting}
\end{frame}


\begin{frame}[fragile
]
\frametitle{Radio Demo (broadcast) - Receiver}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}
[language=Java]
to:
@]


!!
Radio Demo (broadcast) - Receiver}

[@
Changed lines 369-378 from:
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
\frametitle{Radio Demo (broadcast) - Receiver}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
to:
Changed lines 388-397 from:
\end{lstlisting}
\end{frame}

\begin{frame}[fragile
]
\frametitle{Radio Demo (broadcast) - MIDlet app}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}
[language=Java]
to:
@]


!
Radio Demo (broadcast) - MIDlet app

[@
Changed lines 413-418 from:
\end{lstlisting}
\end{frame}


\begin{frame}
\frametitle{
Radio Demo (unicast)}
to:
@]


!
Radio Demo (unicast)
Changed lines 420-433 from:
\begin{itemize}
\item
Disable the Broadcaster.
\item Update the Reveiver and the RadioDemo MIDlet.
\item Implement a new component, the DataSender. \\DataSender sends a message (String) to a specific destination.
\end{itemize}
\end{frame}

\begin{frame}[fragile]
\frametitle{
Radio Demo (unicast) - DataSender}

\latintext
\tiny
\lstset{frameround=fttt}
\begin{lstlisting}
[language=Java]
to:
*Disable the Broadcaster.
*Update the Reveiver and the RadioDemo MIDlet.
*Implement a new component, the DataSender. \\DataSender sends a message (String) to a specific destination.

!!Radio Demo (unicast) - DataSender

[@
Changed lines 454-463 from:
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
\frametitle{Radio Demo (unicast) - DataSender}

\latintext
\tiny
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
to:
Changed lines 484-488 from:
\end{lstlisting}
\end{frame}

\begin{frame}[fragile
]
\frametitle{Radio Demo (unicast) - Receiver}
to:
@]


!!
Radio Demo (unicast) - Receiver
Changed lines 490-493 from:
\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}
[language=Java]
to:
[@
Changed lines 508-513 from:
\end{lstlisting}
\end{frame}


\begin{frame}[fragile
]
\frametitle{Radio Demo (unicast) - MIDlet app}
to:
@]

!!Radio Demo (unicast) - MIDlet app}
Changed lines 512-520 from:
\\Modifications:
\begin{itemize}
\item
Add the following line
\end{itemize}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}
[language=Java]
to:
Modifications:
*Add the following line
[@
Changed lines 520-532 from:
\end{lstlisting}
\end{frame}

\begin{frame}
[fragile]
\frametitle{Radio Demo (unicast) - MIDlet app}
\begin{itemize}
\item Update the \textit{startApp()} function:
\end{itemize}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
to:
@]

**Update the
\textit{startApp()} function:
[@
Changed lines 544-550 from:
\end{lstlisting}
\end{frame}

%----------------------------------------------------------------------------%
\subsection{Host Application}
\begin{frame}[fragile]
\frametitle{
Host Application}
to:
@]


!Host Application
}
Changed lines 549-550 from:
\\It uses the Receiver Thread from the previous Radio Demo (unicast) and prints the received data.
to:
It uses the Receiver Thread from the previous Radio Demo (unicast) and prints the received data.
Changed lines 552-567 from:
\begin{itemize}
\item
Define the host application's main class in \textit{build.properties} file. \textit{main.class=org.sunspotworld.demo.SunSpotHostApplication}
\item Use \textit{ant host-run} instead \textit{ant deploy} and \textit{ant run}
\item The main class should not \textit{extends MIDlet}.
\item \textit{Spot} Class (\textit{Spot.getInstance()}) has been deprecated on host applications
\end{itemize}

\end{frame}

\begin{frame}
[fragile]
\frametitle{Radio Demo (unicast) - main Class}

\latintext
\tiny
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
to:
*Define the host application's main class in \textit{build.properties} file. \textit{main.class=org.sunspotworld.demo.SunSpotHostApplication}
*Use \textit{ant host-run} instead \textit{ant deploy} and \textit{ant run}
*The main class should not \textit{extends MIDlet}.
*\textit{Spot} Class (\textit{Spot.getInstance()}) has been deprecated on host applications


!!Radio Demo (unicast) - main Class
}
[@
Changed lines 586-587 from:
\end{lstlisting}
\end{frame}
to:
@]
Added lines 258-693:



\begin{frame}[fragile]
\frametitle{LEDs}

\begin{itemize}
\item Update the implementation code of \textit{destroyApp()}
\end{itemize}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
protected void destroyApp(final boolean unconditional)
throws MIDletStateChangeException {
System.out.println("Bye Bye!");
--> for (int i = 7; i >= 0; i--) {
--> leds[i].setOff(); // turn the LED off
--> Utils.sleep(250); // wait 1/4 seconds
--> }
notifyDestroyed(); // cause the MIDlet to exit
}
\end{lstlisting}
\end{frame}

%----------------------------------------------------------------------------%
\subsection{Communication}
\begin{frame}
\frametitle{Communication}

\begin{itemize}
\item Every \suns can act as a mesh router, forwarding packets it receives on to other \suns. This way multihop communication is possible
\item Two multihop protocol can be used:
\begin{itemize}
\item AODVManager, Ad Hoc On Demand Distance Vector Routing protocol.
\item LQRPManager, Link Quality Routing Protocol (default)
\end{itemize}
\item SingleHopManager, single hop (non-mesh) Routing protocol.
\item Two communication protocols are supported:
\begin{itemize}
\item The Radiostream protocol is a socket-like peer-to-peer and provides reliable, buffered, stream-based communication
\item The Radiogram protocol provides unreliable datagram-based communication
\end{itemize}
\item Http connections can be started from any \suns to any accessible web service
\end{itemize}
\end{frame}


\begin{frame}
\frametitle{Radiogram}

\begin{itemize}
\item To establish a point-to-point connection both ends must open connections specifying the same portNo and corresponding IEEE addresses. \textit{\begin{footnotesize}Port numbers between 0 and 31 are reserved for system services.\end{footnotesize}}
\item Radiogram supports broadcast mode, where radiograms are delivered to all listeners on the given port.
\end{itemize}
\end{frame}

\begin{frame}
\frametitle{Radio Demo (broadcast)}
This simple demo shows how to use the radio to broadcast some data to any listening SPOTs.

There are two components:
\begin{itemize}
\item The Broadcaster is sending broadcast messages every 1000 ms.
\item The Reveiver is listening for incoming messages on specific port.
\end{itemize}
\end{frame}

\begin{frame}[fragile]
\frametitle{Radio Demo (broadcast) - Broadcaster}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
public class Broadcaster extends Thread {

public void run() {
// We create a DatagramConnection
DatagramConnection dgConnection = null;
Datagram dg = null;
try {
// The Connection is a broadcast
dgConnection =
(DatagramConnection) Connector.open("radiogram://broadcast:37");

//Set maximum hops Number of the Broadcasted messages
((RadiogramConnection) dgConnection).setMaxBroadcastHops(1);

// Then, we ask for a datagram with the maximum size allowed
dg = dgConnection.newDatagram(dgConnection.getMaximumLength());

} catch (IOException ex) {
System.out.println("Could not open radiogram broadcast connection");
ex.printStackTrace();
}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
\frametitle{Radio Demo (broadcast) - Broadcaster}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
while (true) {
try {
// Reset the datagram
dg.reset();

//Send the Datagram.
dgConnection.send(dg);

} catch (IOException ex) {
ex.printStackTrace();
}
Utils.sleep(1000);
}

}

}
\end{lstlisting}
\end{frame}


\begin{frame}[fragile]
\frametitle{Radio Demo (broadcast) - Receiver}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
public class Receiver extends Thread {

public void run() {
//Setting up the Datagram Connection
DatagramConnection dgConnection = null;
Datagram dg = null;

try {
//Open Datagram Connection on port 37
dgConnection = (DatagramConnection) Connector.open("radiogram://:37");

// Then, we ask for a datagram with the maximum size allowed
dg = dgConnection.newDatagram(dgConnection.getMaximumLength());

} catch (IOException e) {
System.out.println("Could not open radiogram receiver connection");
e.printStackTrace();
return;
}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
\frametitle{Radio Demo (broadcast) - Receiver}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
while (true) {
try {
//Ensures that the next read or write operation
//will read/write from the start of the radiogram
dg.reset();

//Receive a Datagram
dgConnection.receive(dg);

System.out.println("Received Datagram from: " + dg.getAddress());

} catch (IOException e) {
System.out.println("Nothing received");
}
}
}

}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
\frametitle{Radio Demo (broadcast) - MIDlet app}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
public class RadioDemo extends MIDlet {

protected void destroyApp(final boolean b) throws MIDletStateChangeException {
}

protected void pauseApp() {
}

protected void startApp() throws MIDletStateChangeException {

//Start the Broadcaster
(new Broadcaster()).start();

//Start the Receiver
(new Receiver()).start();

System.out.println("Waiting for messages!!");
}
}
\end{lstlisting}
\end{frame}


\begin{frame}
\frametitle{Radio Demo (unicast)}
This simple demo shows how to use the radio to send some data to a specific listening SPOT.

We will modify the Radio Demo (broadcast):
\begin{itemize}
\item Disable the Broadcaster.
\item Update the Reveiver and the RadioDemo MIDlet.
\item Implement a new component, the DataSender. \\DataSender sends a message (String) to a specific destination.
\end{itemize}
\end{frame}

\begin{frame}[fragile]
\frametitle{Radio Demo (unicast) - DataSender}

\latintext
\tiny
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
public class DataSender {

/**
* static instance(ourInstance) initialized as null.
*/
private static DataSender ourInstance = null;

/**
* Private constructor suppresses generation of a default constructor.
*/
private DataSender() {
// Does nothing
}
/**
* DataSender is loaded on the first execution of DataSender.getInstance()
* or the first access to DataSender.ourInstance, not before.
*
* @return ourInstance
*/
public static DataSender getInstance() {
synchronized (DataSender.class) {
if (ourInstance == null) {
ourInstance = new DataSender();
}
}
return ourInstance;
}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
\frametitle{Radio Demo (unicast) - DataSender}

\latintext
\tiny
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
/**
* Send a message (String) to a specific Destination.
*/
public void send(final String targetAddress, final String msg) {
try {
// We create a DatagramConnection
final DatagramConnection dgConnection =
(DatagramConnection) Connector.open("radiogram://" + targetAddress + ":37");

// Then, we ask for a datagram with the maximum size allowed
final Datagram dg = dgConnection.newDatagram(dgConnection.getMaximumLength());

//Ensures that the next read/write operation will read/write from the start of the datagram
dg.reset();

//Write Data to Datagram
dg.writeUTF(msg);

//Send Datagram
dgConnection.send(dg);

//Close the connection
dgConnection.close();

} catch (IOException ex) {
System.out.println("Could not open radiogram connection");
}
}
}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
\frametitle{Radio Demo (unicast) - Receiver}
Read the String from the received datagram and print a debug message with its value.

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
while (true) {
try {
//Ensures that the next...
dg.reset();

//Receive a Datagram
dgConnection.receive(dg);

//Read a String from datagram.
--> final String rcvMsg = dg.readUTF();

--> //System.out.println("Received Datagram from " + dg.getAddress());
--> System.out.println("Received msg: " + rcvMsg
+ " from: " + dg.getAddress());

}
\end{lstlisting}
\end{frame}


\begin{frame}[fragile]
\frametitle{Radio Demo (unicast) - MIDlet app}
When SW1 is pressed, SunSPOT send a message to another predefined SunSPOT.
\\Modifications:
\begin{itemize}
\item Add the following line
\end{itemize}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
/**
* Represents the SW1 switch.
*/
public final ISwitch sw1 =
EDemoBoard.getInstance().getSwitches()[EDemoBoard.SW1];
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]
\frametitle{Radio Demo (unicast) - MIDlet app}
\begin{itemize}
\item Update the \textit{startApp()} function:
\end{itemize}

\latintext
\scriptsize
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
protected void startApp() throws MIDletStateChangeException {
--> //Start the Broadcaster
--> //(new Broadcaster()).start();

//Start the Receiver
(new Receiver()).start();
System.out.println("Waiting for messages!!");
--> final String destination = "0014.4F01.0000.6192";
--> final String message = "Hello!!";

--> while (true) {
--> //Block the current thread until the switch's state changes.
--> sw1.waitForChange(); //waitForChange() uses interrupts, not polls

--> //Check if sw1 is closed
--> if (sw1.isClosed()) {
--> DataSender.getInstance().send(destination, message);
--> }
--> }
}
\end{lstlisting}
\end{frame}

%----------------------------------------------------------------------------%
\subsection{Host Application}
\begin{frame}[fragile]
\frametitle{Host Application}
This host application shows how to use the radio to receive some data.
\\It uses the Receiver Thread from the previous Radio Demo (unicast) and prints the received data.

For building and run as a host application :
\begin{itemize}
\item Define the host application's main class in \textit{build.properties} file. \textit{main.class=org.sunspotworld.demo.SunSpotHostApplication}
\item Use \textit{ant host-run} instead \textit{ant deploy} and \textit{ant run}
\item The main class should not \textit{extends MIDlet}.
\item \textit{Spot} Class (\textit{Spot.getInstance()}) has been deprecated on host applications
\end{itemize}

\end{frame}

\begin{frame}[fragile]
\frametitle{Radio Demo (unicast) - main Class}

\latintext
\tiny
\lstset{frameround=fttt}
\begin{lstlisting}[language=Java]
/**
* Sample Sun SPOT host application.
*/
public class SunSpotHostApplication {

/**
* Default Constructor.
*/
public SunSpotHostApplication() {
long ourAddr = RadioFactory.getRadioPolicyManager().getIEEEAddress();
System.out.println("Our radio address = " + IEEEAddress.toDottedHex(ourAddr));

//Start Receiver Thread
(new Receiver()).start();
}

/**
* Start up the host application.
*
* @param args any command line arguments
*/
public static void main(String[] args) throws Exception {
new SunSpotHostApplication();
System.exit(0);
}
}
\end{lstlisting}
\end{frame}
Added lines 153-256:
@]

!!Switches
This app illustrates a call back style of using the switches.
*Declare Variables sw1 and sw2 to hold the two switches
[@
/**
* Represents the SW1 switch.
*/
public final ISwitch sw1 = EDemoBoard.getInstance().getSwitches()[EDemoBoard.SW1];

/**
* Represents the SW2 switch.
*/
public final ISwitch sw2 = EDemoBoard.getInstance().getSwitches()[EDemoBoard.SW2];
@]

!!Switches}
* Setup a switch listener to monitor both switches for press or release events. \textit{MIDlet} should implement \textit{ISwitchListener}. \\ Add on \textit{startApp()} the following lines:
[@
//Adds the specified switch listener to
//receive callbacks from this switch.
sw1.addISwitchListener(this);

//Adds the specified switch listener to
//receive callbacks from this switch.
sw2.addISwitchListener(this);
@]

!Switches

*These methods are the "call backs" that are invoked whenever the switch is pressed or released. They run in a new thread.
Parameter sw represents the switch that was pressed/released.
[@
/**
* Callback for when the switch state changes from released to pressed.
*/
public void switchPressed(final ISwitch iSwitch) {
final int switchNum = (iSwitch == sw1) ? 1 : 2;
if (switchNum == 1) {
System.out.println("SW1 switch pressed");
}
} else {
System.out.println("SW2 switch pressed");
try {
destroyApp(true);
} catch (MIDletStateChangeException e) {
e.printStackTrace();
}
}
}
@]


!!Switches
[@
/**
* Callback for when the switch state changes from pressed to released.
*/
public void switchReleased(final ISwitch iSwitch) {
final int switchNum = (iSwitch == sw1) ? 1 : 2;
if (switchNum == 1) {
System.out.println("SW1 switch released");
} else {
System.out.println("SW2 switch released");
}
}
@]

!LEDs
There are eight three-color LEDs on the demo Sensor Board. \\Sample code to show how to use the tricolor LEDs.

*Initialize an \textit{ITriColorLED} array which controls the built in LEDs.

[@
/**
* An array of all the built in LEDs.
*/
private final ITriColorLED[] leds = EDemoBoard.getInstance().getLEDs();
@]

!!LEDs}

*Update the implementation code of \textit{switchPressed()} callback.

[@
public void switchPressed(final ISwitch iSwitch) {
int switchNum = (iSwitch == sw1) ? 1 : 2;
if (switchNum == 1) {
System.out.println("SW1 switch pressed");
--> for (int i = 0; i < 8; i++) {
--> leds[i].setColor(LEDColor.RED); // set color to red
--> leds[i].setOn(); // turn the LED on
--> Utils.sleep(250); // wait 1/4 seconds
--> }
} else {
System.out.println("SW2 switch pressed");
try {
destroyApp(true);
} catch (MIDletStateChangeException e) {
e.printStackTrace();
}
}
}
Changed lines 146-151 from:
System.out.println("Hello, world");

--> //the 64-bit IEEE address of this device
--> long ourAddr = Spot.getInstance().getRadioPolicyManager().getIEEEAddress();

--> System.out.println("Our radio address = " + IEEEAddress.toDottedHex(ourAddr));
to:
System.out.println("Hello, world");

//the 64-bit IEEE address of this device
long ourAddr = Spot.getInstance().getRadioPolicyManager().getIEEEAddress();

System.out.println("Our radio address = " + IEEEAddress.toDottedHex(ourAddr));
Added lines 140-153:

!!Hello World Demo}
Update startApp() and print the IEEE address of the SunSPOT
[@
protected void startApp() throws MIDletStateChangeException {

System.out.println("Hello, world");

--> //the 64-bit IEEE address of this device
--> long ourAddr = Spot.getInstance().getRadioPolicyManager().getIEEEAddress();

--> System.out.println("Our radio address = " + IEEEAddress.toDottedHex(ourAddr));
}
@]
Changed line 118 from:
!Hello World Demo}
to:
!Hello World Demo
Added lines 117-139:

!Hello World Demo}
[@
public class SunSpotApplication extends MIDlet {

protected void startApp() throws MIDletStateChangeException {

System.out.println("Hello, world");

}

protected void pauseApp() {
// This is not currently called by the Squawk VM
}

protected void destroyApp(final boolean unconditional)
throws MIDletStateChangeException {
System.out.println("Bye Bye!");
notifyDestroyed(); // cause the MIDlet to exit
}

@]
Changed lines 95-116 from:
@]
to:
@]

!Files Structure}

All application root directories have the same layout:
*The root directory contains two files that control the ant script used to build and run applications
**build.xml
**build.properties
*The root directory also contains two main sub-directories
**src, is the root of the source code tree for this application
**resources, contains the manifest file that defines the application, plus any other resource files that the application needs at run time
**other IDE specific or not directories may exist or appear after the build process, such as \textit{suite/} where the jar app is saved.

!Code Structure}
*In Java SE, an application consists of a static main() method defined in one of the loaded classes
*In Java ME, an application is defined as a class that extends the MIDlet class
*The Jave ME applications are also called MIDlets
*All Java ME applications implement the three members
**startApp(): application acquires the resources that it requires and starts executing
**pauseApp()
**destroyApp(): application releases resources and stops executing
*If the application wants to exit, it must call notifyDestroyed()
Changed lines 79-95 from:
*SPOTManager: deploy, manage
to:
*SPOTManager: deploy, manage

Deploy and run BounceDemo Application using command line:

[@
# Go to SunSPOT's sdk directory
cd ~/SunSPOT/sdk/

# Go to Demos/BounceDemo
cd Demos/BounceDemo/BounceDemo-OnSPOT/

# Deploy application using ant
ant deploy -Dport=/dev/ttyACM0

# Run the application
ant run -Dport=/dev/ttyACM0
@]
Added lines 72-79:
!Development

!!Deploy

In general there are three ways in order to develop, build, deploy and manage an application and the corresponding \suns:
*command line: develop, deploy, run
*IDE: develop, deploy, run
*SPOTManager: deploy, manage
Changed lines 66-70 from:
*A host application communicates with a SunSPOT via a basestation using code identical that which you would use to communicate between two SPOTs
to:
*A host application communicates with a SunSPOT via a basestation using code identical that which you would use to communicate between two SunSPOTs
*The basestation may run in either dedicated or shared mode
*In the shared model, the host application has its own address, distinct from that of the basestation
*The main advantage of shared mode is that more than one host application can use the same basestation simultaneously
*The disadvantage of shared mode is that run-time manipulation of the basestation SunSPOT's radio chatacteristics is not possible
Changed lines 62-66 from:
*The free-range \suns communicate wirelessly with other \suns and the basestation
*The basestation is a \suns connected, through USB, with a host
*The host applications interact with the \suns through the basestation application
*The host application is a J2SE program, that also has access to a subset of the API of the libraries used by \suns
*A host application communicates with a \suns via a basestation using code identical that which you would use to communicate between two SPOTs
to:
*The free-range SunSPOT communicate wirelessly with other SunSPOT and the basestation
*The basestation is a SunSPOT connected, through USB, with a host
*The host applications interact with the SunSPOT through the basestation application
*The host application is a J2SE program, that also has access to a subset of the API of the libraries used by SunSPOT
*A host application communicates with a SunSPOT via a basestation using code identical that which you would use to communicate between two SPOTs
Added lines 60-66:
http://www.smartsantander.eu/wiki/uploads/Main/sunspottopology.jpg

*The free-range \suns communicate wirelessly with other \suns and the basestation
*The basestation is a \suns connected, through USB, with a host
*The host applications interact with the \suns through the basestation application
*The host application is a J2SE program, that also has access to a subset of the API of the libraries used by \suns
*A host application communicates with a \suns via a basestation using code identical that which you would use to communicate between two SPOTs
Added lines 55-59:

!Topology
SunSPOTs are usually used in the following topology:

[[Attach:sunspottopology.jpg]]
Added lines 46-53:


!SPOTManager

The SPOTManager tool provides the following functionalities:
*allows you to query and change the configuration of individual SunSPOT
*allows you to download and install versions of the SunSPOT SDK
*launches Solarium, a tool for managing individual SunSPOTS and simulating virtual SunSPOTS
Changed lines 37-46 from:
**The last eight digits should be printed on a sticker on the \suns
to:
**The last eight digits should be printed on a sticker on the SunSPOTS

!Software Characteristics
*SunSPOTS have the following software characteristics:
**run a Java VM (Squawk VM) that provides basic OS functionality
**Squawk VM implements Java Micro Edition (J2ME)
**all major parts of the Sun SPOT project are open source: hardware, operating system/virtual machine, drivers and libraries, applications
*The SPOTManager tools is provided for managing SDK and
\suns devices
*A SunSPOT emulator is also provided that runs applications in virtual SunSPOT (Solarium)
Added lines 34-37:
*SunSPOT has a unique IEEE 64-bit address
**Expressed as four sets of four-digit hexadecimal numbers: nnnn.nnnn.nnnn.nnnn.
**The first eight digits will always be 0014.4F01
**The last eight digits should be printed on a sticker on the \suns
Added lines 26-33:

*SunSPOTS Sensor Board has the following characteristics:
**8 tri-color LEDs
**2 momentary switches
**a 3-axis accelerometer
**a temperature sensor
**a light sensor
**5 general purpose I/O pins and 4 high current output pins
Changed lines 6-7 from:
!Introduction to SunSPOT
to:
Changed line 10 from:
Sunspot have three layers:
to:
Sunspot has three layers:
Changed lines 16-26 from:
http://www.smartsantander.eu/wiki/uploads/Main/sunspotleyers.jpg
to:
http://www.smartsantander.eu/wiki/uploads/Main/sunspotleyers.jpg


!Hardware Characteristics
*SunSPOTS have common characteristics with mobile phones
*SunSPOTS Processor Board:
**180MHz 32-bit ARM processor, 512K RAM, 4M Flash
**2.4GHz radio, IEEE 802.15.4 compliant, with an antenna
**USB interface to connect to a PC
**rechargeable lithium-ion battery
Changed lines 15-16 from:
[[Attach:sunspotleyers.jpg]]
to:
[[Attach:sunspotleyers.jpg]]
http://www.smartsantander.eu/wiki/uploads/Main/sunspotleyers.jpg
Added lines 14-15:

[[Attach:sunspotleyers.jpg]]
Added lines 6-13:
!Introduction to SunSPOT

!SunSPOT layers

Sunspot have three layers:
*Battery
*Processor Board with Radio
*Sensor Board
Added lines 1-5:
'''SunSPOT''' is a hard- and software platform developed by Oracle Labs (http://www.sunspotworld.com/)

Project SunSPOT was created to encourage the development of new applications and devices. It is designed from the ground up to allow programmers who never before worked with embedded devices to think beyond the keyboard, mouse and screen and write programs that interact with each other, the environment and their users in completely new ways. A Java programmer can use standard Java development tools such as NetBeans to write code.
Edit - History - Print - Recent Changes - Search
Page last modified on November 20, 2012, at 09:29 PM