--- /dev/null
+/*
+ * "Copyright (c) 2008 The Regents of the University of California.
+ * All rights reserved."
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+z * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+// $Id$
+
+/* tab:4
+ * "Copyright (c) 2000-2003 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2002-2003 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
+ * 94704. Attention: Intel License Inquiry.
+ */
+
+/**
+ * The TinyOS 2.x base station that forwards packets between the UART
+ * and radio.It replaces the GenericBase of TinyOS 1.0 and the
+ * TOSBase of TinyOS 1.1.
+ *
+ * <p>On the serial link, BaseStation sends and receives simple active
+ * messages (not particular radio packets): on the radio link, it
+ * sends radio active messages, whose format depends on the network
+ * stack being used. BaseStation will copy its compiled-in group ID to
+ * messages moving from the serial link to the radio, and will filter
+ * out incoming radio messages that do not contain that group ID.</p>
+ *
+ * <p>BaseStation includes queues in both directions, with a guarantee
+ * that once a message enters a queue, it will eventually leave on the
+ * other interface. The queues allow the BaseStation to handle load
+ * spikes.</p>
+ *
+ * <p>BaseStation acknowledges a message arriving over the serial link
+ * only if that message was successfully enqueued for delivery to the
+ * radio link.</p>
+ *
+ * <p>The LEDS are programmed to toggle as follows:</p>
+ * <ul>
+ * <li><b>RED Toggle:</b>: Message bridged from serial to radio</li>
+ * <li><b>GREEN Toggle:</b> Message bridged from radio to serial</li>
+ * <li><b>YELLOW/BLUE Toggle:</b> Dropped message due to queue overflow in either direction</li>
+ * </ul>
+ *
+ * @author Phil Buonadonna
+ * @author Gilman Tolle
+ * @author David Gay
+ * @author Philip Levis
+ * @date August 10 2005
+ */
+
+configuration BaseStationC {
+}
+implementation {
+ components MainC, BaseStationP, LedsC;
+#ifndef SIM
+ components CC2420ActiveMessageC as Radio;
+ components SerialDispatcherC as SerialControl, Serial802_15_4C as Serial;
+#else
+ components ActiveMessageC as Radio;
+ components SerialActiveMessageC as Serial;
+#endif
+
+ MainC.Boot <- BaseStationP;
+
+ BaseStationP.RadioControl -> Radio;
+#ifndef SIM
+ BaseStationP.SerialControl -> SerialControl;
+ BaseStationP.UartSend -> Serial.Send;
+ BaseStationP.UartReceive -> Serial.Receive;
+#else
+ BaseStationP.SerialControl -> Serial;
+ BaseStationP.UartSend -> Serial.AMSend[0];
+ BaseStationP.UartReceive -> Serial.Receive[0];
+#endif
+
+
+#ifndef SIM
+ BaseStationP.RadioSend -> Radio;
+ BaseStationP.RadioReceive -> Radio.IEEE154Receive;
+#else
+ BaseStationP.RadioSend -> Radio.AMSend[0];
+ BaseStationP.RadioReceive -> Radio.ReceiveBase[0];
+ BaseStationP.SerialAMPacket -> Serial;
+ BaseStationP.SerialPacket -> Serial;
+#endif
+
+ BaseStationP.RadioPacket -> Radio.SubAMPacket;
+ BaseStationP.RadioIEEEPacket -> Radio;
+
+ BaseStationP.Leds -> LedsC;
+
+ BaseStationP.PacketLink -> Radio;
+ BaseStationP.LowPowerListening -> Radio;
+
+ components ResetC;
+ BaseStationP.Reset -> ResetC;
+
+#ifndef SIM
+ components SerialDevConfC as Configure;
+ BaseStationP.ConfigureSend -> Configure;
+ BaseStationP.ConfigureReceive -> Configure;
+
+ components new TimerMilliC();
+ BaseStationP.ConfigureTimer -> TimerMilliC;
+
+ components IPAddressC;
+ BaseStationP.IPAddress -> IPAddressC;
+
+ components CC2420ControlC;
+ BaseStationP.CC2420Config -> CC2420ControlC;
+#endif
+}
--- /dev/null
+/*
+ * "Copyright (c) 2008 The Regents of the University of California.
+ * All rights reserved."
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+// $Id$
+
+/* tab:4
+ * "Copyright (c) 2000-2005 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2002-2005 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
+ * 94704. Attention: Intel License Inquiry.
+ */
+
+/*
+ * @author Phil Buonadonna
+ * @author Gilman Tolle
+ * @author David Gay
+ * Revision: $Id$
+ */
+
+/*
+ * BaseStationP bridges packets between a serial channel and the radio.
+ * Messages moving from serial to radio will be tagged with the group
+ * ID compiled into the TOSBase, and messages moving from radio to
+ * serial will be filtered by that same group id.
+ */
+
+#ifndef SIM
+#include "CC2420.h"
+#endif
+#include "AM.h"
+#include "Serial.h"
+#include "devconf.h"
+#include "lib6lowpan.h"
+
+module BaseStationP {
+ uses {
+ interface Boot;
+ interface SplitControl as SerialControl;
+ interface SplitControl as RadioControl;
+
+#ifndef SIM
+ interface Send as UartSend;
+ interface IEEE154Send as RadioSend;
+#else
+ interface AMSend as UartSend;
+ interface AMSend as RadioSend;
+ interface AMPacket as SerialAMPacket;
+ interface Packet as SerialPacket;
+#endif
+
+ interface Receive as UartReceive;
+ interface Receive as RadioReceive;
+ interface Packet as RadioPacket;
+
+#ifndef SIM
+ interface Send as ConfigureSend;
+ interface Receive as ConfigureReceive;
+ interface Timer<TMilli> as ConfigureTimer;
+ interface IPAddress;
+#endif
+
+
+#ifndef SIM
+ interface IEEE154Packet as RadioIEEEPacket;
+#else
+ interface AMPacket as RadioIEEEPacket;
+#endif
+
+ interface PacketLink;
+ interface LowPowerListening;
+ interface CC2420Config;
+
+ interface Leds;
+
+ interface Reset;
+ }
+}
+
+implementation
+{
+ enum {
+ UART_QUEUE_LEN = 10,
+ RADIO_QUEUE_LEN = 10,
+ };
+
+ uint16_t radioRetries = 10;
+ uint16_t radioDelay = 30;
+
+ uint16_t serial_read;
+ uint16_t radio_read;
+ uint16_t serial_fail;
+ uint16_t radio_fail;
+
+ bool echo_busy;
+ message_t echo_buf;
+ config_reply_t *reply;
+
+ message_t uartQueueBufs[UART_QUEUE_LEN];
+ message_t *uartQueue[UART_QUEUE_LEN];
+ uint8_t uartIn, uartOut;
+ bool uartBusy, uartFull;
+
+ message_t radioQueueBufs[RADIO_QUEUE_LEN];
+ message_t *radioQueue[RADIO_QUEUE_LEN];
+ uint8_t radioIn, radioOut;
+ bool radioBusy, radioFull;
+
+ task void uartSendTask();
+ task void radioSendTask();
+
+ void dropBlink() {
+ call Leds.led2Toggle();
+ }
+
+ void failBlink() {
+ call Leds.led2Toggle();
+ }
+
+#ifndef SIM
+#define CHECK_NODE_ID if (0) return
+#else
+#define CHECK_NODE_ID if (TOS_NODE_ID != BASESTATION_ID) return
+#endif
+ task void configureReply() {
+ if (echo_busy) return;
+
+ reply->addr = call IPAddress.getShortAddr();
+ reply->serial_read = serial_read;
+ reply->radio_read = radio_read;
+ reply->serial_fail = serial_fail;
+ reply->radio_fail = radio_fail;
+
+ echo_busy = TRUE;
+ // delay sending the reply for a bit
+ // the pc seems to usually drop the packet if we don't do this;
+ call ConfigureTimer.startOneShot(50);
+ }
+
+ event void Boot.booted() {
+ uint8_t i;
+
+ CHECK_NODE_ID;
+
+ for (i = 0; i < UART_QUEUE_LEN; i++)
+ uartQueue[i] = &uartQueueBufs[i];
+ uartIn = uartOut = 0;
+ uartBusy = FALSE;
+ uartFull = TRUE;
+
+ for (i = 0; i < RADIO_QUEUE_LEN; i++)
+ radioQueue[i] = &radioQueueBufs[i];
+ radioIn = radioOut = 0;
+ radioBusy = FALSE;
+ radioFull = TRUE;
+
+ echo_busy = FALSE;
+ serial_read = 0;
+ radio_read = 0;
+ serial_fail = 0;
+ radio_fail = 0;
+
+ call RadioControl.start();
+ call SerialControl.start();
+
+ reply = (config_reply_t *)(&(echo_buf.data));
+ }
+
+ event void RadioControl.startDone(error_t error) {
+ CHECK_NODE_ID;
+ if (error == SUCCESS) {
+ radioFull = FALSE;
+#ifdef LPL_SLEEP_INTERVAL
+ call LowPowerListening.setLocalSleepInterval(LPL_SLEEP_INTERVAL);
+#endif
+ }
+ }
+
+ event void SerialControl.startDone(error_t error) {
+ CHECK_NODE_ID;
+ if (error == SUCCESS) {
+ uartFull = FALSE;
+ }
+ reply->error = CONFIG_ERROR_BOOTED;
+ post configureReply();
+ }
+
+ event void SerialControl.stopDone(error_t error) {}
+ event void RadioControl.stopDone(error_t error) {}
+
+ uint8_t count = 0;
+
+ message_t* receive(message_t* msg, void* payload, uint8_t len);
+
+ event message_t *RadioReceive.receive(message_t *msg,
+ void *payload,
+ uint8_t len) {
+ CHECK_NODE_ID NULL;
+ dbg("base", "radio message received (%i)\n", len);
+ return receive(msg, payload, len);
+ }
+
+ message_t* receive(message_t *msg, void *payload, uint8_t len) {
+ message_t *ret = msg;
+ CHECK_NODE_ID NULL;
+
+ atomic {
+ if (!uartFull)
+ {
+ ret = uartQueue[uartIn];
+ uartQueue[uartIn] = msg;
+
+ uartIn = (uartIn + 1) % UART_QUEUE_LEN;
+
+ if (uartIn == uartOut)
+ uartFull = TRUE;
+
+ if (!uartBusy)
+ {
+ post uartSendTask();
+ uartBusy = TRUE;
+ }
+ }
+ else
+ dropBlink();
+ }
+
+ return ret;
+ }
+
+ task void uartSendTask() {
+ uint8_t len;
+ message_t* msg;
+ atomic
+ if (uartIn == uartOut && !uartFull)
+ {
+ uartBusy = FALSE;
+ return;
+ }
+
+ msg = uartQueue[uartOut];
+
+ // Since we're forwarding fully formed radio packets, we can use
+ // these headers.
+#ifdef DBG_TRACK_FLOWS
+ len = call RadioPacket.payloadLength(msg) + sizeof(flow_id_t);
+#else
+ len = call RadioPacket.payloadLength(msg) - sizeof(am_header_t);
+#endif
+
+#ifdef SIM
+ if (call UartSend.send(call RadioIEEEPacket.source(uartQueue[uartOut]),
+ uartQueue[uartOut], len) == SUCCESS)
+#else
+ if (call UartSend.send(uartQueue[uartOut], len) == SUCCESS)
+#endif
+ call Leds.led1Toggle();
+ else
+ {
+ failBlink();
+ post uartSendTask();
+ }
+ }
+
+ event void UartSend.sendDone(message_t* msg, error_t error) {
+ if (error != SUCCESS)
+ failBlink();
+ else
+ atomic
+ if (msg == uartQueue[uartOut])
+ {
+ if (++uartOut >= UART_QUEUE_LEN)
+ uartOut = 0;
+ if (uartFull)
+ uartFull = FALSE;
+ }
+ post uartSendTask();
+ }
+
+ event message_t *UartReceive.receive(message_t *msg,
+ void *payload,
+ uint8_t len) {
+ message_t *ret = msg;
+ bool reflectToken = FALSE;
+ CHECK_NODE_ID msg;
+ dbg("base", "uartreceive len %i of 0x%x\n", len, call SerialAMPacket.destination(msg));
+
+ atomic
+ if (!radioFull)
+ {
+ reflectToken = TRUE;
+ ret = radioQueue[radioIn];
+ radioQueue[radioIn] = msg;
+ if (++radioIn >= RADIO_QUEUE_LEN)
+ radioIn = 0;
+ if (radioIn == radioOut)
+ radioFull = TRUE;
+
+ if (!radioBusy)
+ {
+ post radioSendTask();
+ radioBusy = TRUE;
+ }
+ }
+ else
+ dbg("base", "no enqueue\n");
+// dropBlink();
+
+ if (reflectToken) {
+ //call UartTokenReceive.ReflectToken(Token);
+ }
+
+ return ret;
+ }
+
+ task void radioSendTask() {
+ uint8_t len;
+ hw_addr_t addr;
+ message_t* msg;
+
+ dbg ("base", "radioSendTask()\n");
+ atomic
+ if (radioIn == radioOut && !radioFull)
+ {
+ radioBusy = FALSE;
+ return;
+ }
+
+ msg = radioQueue[radioOut];
+#ifndef SIM
+ len = call RadioPacket.payloadLength(msg);
+ addr = call RadioIEEEPacket.destination(msg);
+#else
+#ifdef DBG_TRACK_FLOWS
+ len = call SerialPacket.payloadLength(msg) - sizeof(flow_id_t);
+#else
+ len = call SerialPacket.payloadLength(msg);
+#endif
+ {
+ hw_addr_t source;
+ addr = call SerialAMPacket.destination(msg);
+ source = TOS_NODE_ID;
+
+ call RadioPacket.clear(msg);
+ call RadioIEEEPacket.setSource(msg, source);
+ }
+#endif
+
+ if (addr != 0xFFFF) {
+ call PacketLink.setRetries(msg, radioRetries);
+ call PacketLink.setRetryDelay(msg, radioDelay);
+ } else {
+ call PacketLink.setRetries(msg, 0);
+ }
+#ifdef LPL_SLEEP_INTERVAL
+ call LowPowerListening.setRxSleepInterval(msg, LPL_SLEEP_INTERVAL);
+#endif
+ dbg("base", "radio send to: 0x%x len: %i\n", addr, len);
+ if (call RadioSend.send(addr, msg, len) == SUCCESS)
+ call Leds.led0Toggle();
+ else
+ {
+ failBlink();
+ post radioSendTask();
+ }
+ }
+
+ event void RadioSend.sendDone(message_t* msg, error_t error) {
+ CHECK_NODE_ID;
+ dbg("base", "sendDone()\n");
+
+ //if (!call PacketLink.wasDelivered(msg))
+ // failBlink();
+ if (error != SUCCESS)
+ failBlink();
+ else
+ atomic
+ if (msg == radioQueue[radioOut])
+ {
+ if (++radioOut >= RADIO_QUEUE_LEN)
+ radioOut = 0;
+ if (radioFull)
+ radioFull = FALSE;
+ }
+
+ post radioSendTask();
+ }
+
+#ifndef SIM
+ event message_t *ConfigureReceive.receive(message_t *msg,
+ void *payload,
+ uint8_t len) {
+ config_cmd_t *cmd;
+ uint8_t error = CONFIG_ERROR_OK;
+ if (len != sizeof(config_cmd_t) || msg == NULL) return msg;
+ // don't parse the message if we can't reply
+
+ cmd = (config_cmd_t *)&msg->data;
+
+ switch (cmd->cmd) {
+ case CONFIG_ECHO:
+ break;
+ case CONFIG_SET_PARM:
+ call CC2420Config.setChannel(cmd->rf.channel);
+ // IPAddress calls sync() for you, I think, so we'll put it second
+ call IPAddress.setShortAddr(cmd->rf.addr);
+ call CC2420Config.sync();
+ radioRetries = cmd->retx.retries;
+ radioDelay = cmd->retx.delay;
+ break;
+ case CONFIG_REBOOT:
+ call Reset.reset();
+ break;
+ }
+ if (!echo_busy) {
+ reply->error = error;
+ post configureReply();
+ }
+ return msg;
+ }
+
+
+ event void CC2420Config.syncDone(error_t error) {
+
+ }
+
+ event void ConfigureSend.sendDone(message_t *msg, error_t error) {
+ echo_busy = FALSE;
+ }
+
+ event void ConfigureTimer.fired() {
+ call Leds.led2Toggle();
+ if (call ConfigureSend.send(&echo_buf, sizeof(config_reply_t)) != SUCCESS)
+ echo_busy = FALSE;
+ }
+#endif
+}
--- /dev/null
+COMPONENT=BaseStationC
+
+# radio options. channel settings will be overridden by the driver
+# CFLAGS += -DCC2420_DEF_RFPOWER=4
+
+# this is necessary, otherwise we will allocate a heap by including
+# the lowpan target
+CFLAGS += -DNO_IP_MALLOC
+
+#
+# debugging
+#
+
+# filter packets based on a specified topology
+# PFLAGS += -I../UDPEcho/NodeConnectivity -DSW_TOPOLOGY
+
+# part of the test harness
+# CFLAGS += -DDBG_TRACK_FLOWS
+
+# for simulation
+# CFLAGS += -DBASESTATION_ID=100
+
+include $(MAKERULES)
+
--- /dev/null
+README for BaseStation
+Author/Contact: tinyos-help@millennium.berkeley.edu
+
+IPBaseStation is a modification of the generic BaseStation which ships
+with tinyOS-2.x. It alters the serial protocol to pass 802.15.4
+frames instead of Serial.h packets. It also adds an out-of-band
+configuration protocol which allows a driver running over the serial
+port to reboot the mote, and to set the device address, channel, and
+retransmission parameters. These changes are useful when one wishes
+to use a mote attached to a computer as an 802.15.4 interface rather
+then an actual mote. The actual queuing logic for copying packets is
+mostly unchanged, and it continues to make use of serial ACKs.
+
+Description of BaseStation:
+
+BaseStation is an application that acts as a simple Active Message
+bridge between the serial and radio links. It replaces the GenericBase
+of TinyOS 1.0 and the TOSBase of TinyOS 1.1.
+
+On the serial link, BaseStation sends and receives simple active
+messages (not particular radio packets): on the radio link, it sends
+radio active messages, whose format depends on the network stack being
+used. BaseStation will copy its compiled-in group ID to messages
+moving from the serial link to the radio, and will filter out incoming
+radio messages that do not contain that group ID.
+
+BaseStation includes queues in both directions, with a guarantee that
+once a message enters a queue, it will eventually leave on the other
+interface. The queues allow the BaseStation to handle load spikes more
+gracefully.
+
+BaseStation acknowledges a message arriving over the serial link only if
+that message was successfully enqueued for delivery to the radio link.
+
+The LEDS are programmed to toggle as follows:
+
+RED Toggle - Message bridged from serial to radio
+GREEN Toggle - Message bridged from radio to serial
+YELLOW/BLUE Toggle - Dropped message due to queue overflow
+ in either direction
+
+When using a CC2420 radio, several default preprocessor configurations
+are defined in the Makefile:
+ * CC2420_NO_ACKNOWLEDGEMENTS
+ - Prevents the base station from falsly acknowledging packets
+ * CC2420_NO_ADDRESS_RECOGNITION
+ - Allows the base station to sniff packets from any transmitter
+
+Other combinations can be defined to meet your application's needs:
+ * CC2420_NO_ADDRESS_RECOGNITION only
+ - Sniff all packets, but acknowledge packets only if they
+ are sent to the base station's address
+
+ * Removing all preprocessor definitions in the Makefile
+ - Only accept packets destined for the base station's address,
+ and acknowledge those packets
+
+
+Tools:
+
+tools/java/net/tinyos/sf/SerialForwarder.
+
+See doc/serialcomm/index.html for more information using these tools.
+
+Known bugs/limitations:
+
+
--- /dev/null
+// $Id$
+
+/* tab:4
+ * "Copyright (c) 2000-2003 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2002-2003 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
+ * 94704. Attention: Intel License Inquiry.
+ */
+
+/*
+ * Authors: Wei Hong
+ * Intel Research Berkeley Lab
+ * Date: 7/15/2002
+ *
+ */
+
+/**
+ * @author Wei Hong
+ * @author Intel Research Berkeley Lab
+ */
+
+
+void resetMote()
+{
+#if defined(PLATFORM_MICA) || defined(PLATFORM_MICA2) || defined(PLATFORM_MICA2DOT) || defined(PLATFORM_MICAZ)
+ cli();
+ wdt_enable(0);
+ while (1) {
+ __asm__ __volatile__("nop" "\n\t" ::);
+ }
+#elif defined(PLATFORM_TELOS) || defined(PLATFORM_TELOSB) || defined(PLATFORM_EPIC)
+ WDTCTL = 0;
+#else
+#error "Reset.h not defined/supported for your platform, aborting..."
+#endif
+}
+
--- /dev/null
+// $Id$
+
+/* tab:4
+ * "Copyright (c) 2000-2003 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2002-2003 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
+ * 94704. Attention: Intel License Inquiry.
+ */
+
+/*
+ * Authors: Wei Hong
+ * Intel Research Berkeley Lab
+ * Date: 7/15/2002
+ *
+ */
+
+/**
+ * @author Wei Hong
+ * @author Intel Research Berkeley Lab
+ */
+
+
+interface Reset {
+ command void reset();
+}
--- /dev/null
+COMPONENT=UDPEchoC
+
+# uncomment this for network programming support
+# BOOTLOADER=tosboot
+
+# radio opts
+CFLAGS += -DCC2420_DEF_CHANNEL=15
+# CFLAGS += -DCC2420_DEF_RFPOWER=4
+
+# if this is set, motes will send debugging information to the address
+# listed.
+# CFLAGS += -DREPORT_DEST=\"2001:470:1f04:56d::64\"
+
+# sim/test harness
+# CFLAGS += -I../IPBaseStation
+# CFLAGS += -DDBG_TRACK_FLOWS -DDBG_FLOWS_REPORT
+
+# printf debugs. works only on telosb/tmote sky
+# CFLAGS += -DPRINTFUART_ENABLED
+
+
+include $(MAKERULES)
+
--- /dev/null
+# -*- makefile -*-
+
+SOURCES=$(LOWPAN_ROOT)/support/sdk/c/lib6lowpan/lib6lowpan.c \
+ $(LOWPAN_ROOT)/support/sdk/c/lib6lowpan/lib6lowpanIP.c \
+ $(LOWPAN_ROOT)/support/sdk/c/lib6lowpan/lib6lowpanFrag.c \
+ $(LOWPAN_ROOT)/support/sdk/c/lib6lowpan/in_cksum.c \
+ $(LOWPAN_ROOT)/support/sdk/c/lib6lowpan/ip_malloc.c \
+ $(LOWPAN_ROOT)/tos/lib/net/b6lowpan/table.c
+OBJS=$(SOURCES:%.c=%.o)
+
+remake: $(OBJS)
+ make micaz sim-sf lowpan
+ g++ -shared -fPIC simbuild/micaz/pytossim.o simbuild/micaz/sim.o simbuild/micaz/tossim.o simbuild/micaz/c-support.o simbuild/micaz/c-sf.o simbuild/micaz/sf.o simbuild/micaz/throttle.o $(OBJS) -lstdc++ -lm -o _TOSSIMmodule.so
+ make -f Makefile.local cppdriver
+
+cppdriver:
+ g++ -g -c -o sim/Driver.o sim/Driver.c -I$(TOSROOT)/tos/lib/tossim/
+ g++ -o sim/Driver sim/Driver.o simbuild/micaz/tossim.o simbuild/micaz/sim.o simbuild/micaz/c-support.o simbuild/micaz/c-sf.o simbuild/micaz/sf.o simbuild/micaz/throttle.o $(OBJS)
+# simbuild/micaz/c-sf.o simbuild/micaz/pytossim.o simbuild/micaz/sim.o simbuild/micaz/tossim.o
+# simbuild/micaz/c-support.o simbuild/micaz/sf.o simbuild/micaz/throttle.o
+
+
+
+clean:
+ rm $(OBJS)
+
+%.o: %.c
+ $(CC) -c -fPIC -o $@ $<
+
+msg:
+ mig -DMIG -I$(LOWPAN_ROOT)/tos/lib/net/b6lowpan -I$(LOWPAN_ROOT)/support/sdk/c/lib6lowpan python -python-classname=UdpReport UDPReport.h udp_report -o UdpReport.py
+ mig -DMIG -I$(LOWPAN_ROOT)/tos/lib/net/b6lowpan -I$(LOWPAN_ROOT)/support/sdk/c/lib6lowpan python -python-classname=TestDriverMsg TestDriver.h testdriver_msg -o TestDriverMsg.py
--- /dev/null
+/*
+ * "Copyright (c) 2008 The Regents of the University of California.
+ * All rights reserved."
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+// For conversion of topology from .nss to motelab
+// See NodeConnectivityM.nc
+
+interface NodeConnectivity {
+ command int8_t mapping(uint16_t moteid);
+ command bool connected(uint16_t srcnode, uint16_t dstnode);
+}
--- /dev/null
+/*
+ * "Copyright (c) 2008 The Regents of the University of California.
+ * All rights reserved."
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+// Filename: NodeConnectivityM.nc
+// Generated on Wed Jun 11 19:54:54 UTC 2008
+
+// Created by createMotelabTopology.pl
+
+module TestbedConnectivityM {
+ provides {
+ interface NodeConnectivity;
+ }
+} implementation {
+ uint8_t connectivity[8][8] =
+ {
+ { 1, 1, 0, 0, 0, 0, 0, 0 },
+ { 1, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1 },
+ { 0, 0, 0, 0, 0, 0, 1, 1 }
+ };
+ uint16_t mapping[8] = { 100, 101, 102, 37, 35, 33, 32, 106 };
+
+ command int8_t NodeConnectivity.mapping(uint16_t moteid) {
+ uint8_t i;
+ for (i = 0; i < 8; i++) {
+ if (mapping[i] == moteid) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ command bool NodeConnectivity.connected(uint16_t srcnode, uint16_t dstnode) {
+ int8_t src = call NodeConnectivity.mapping(srcnode);
+ int8_t dst = call NodeConnectivity.mapping(dstnode);
+
+ if ((src == -1) ||
+ (dst == -1)) {
+ return FALSE;
+ }
+
+ if (connectivity[src][dst] == 1) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+}
--- /dev/null
+#!/usr/bin/perl
+
+# FileName: createMotelabTopology.pl
+# Date: December 31, 2004
+#
+# Description: Converts a TOSSIM .nss (topology) file into Motelab format
+# Usage: ./createMotelabTopology.pl .nssfile
+
+# Input: A TOSSIM .nss topology file
+# Output: A nesc file containing a 2D array that represents
+# the latency for each node and a func that returns true or false
+# as to whether that node can communicate with other nodes
+
+
+use strict;
+
+######################
+# #
+# Parse Parameters #
+# #
+######################
+
+if ( 2 > @ARGV ) {
+ die "Usage: ./createMotelabTopology <mapfile(see exampleMap.txt as a sample)> <.nss file> ";
+}
+
+#######################
+# #
+# Open file handles #
+# #
+#######################
+
+open(INPUT_MAP, "$ARGV[0]")
+ or die "Unable to open input file $ARGV[0] ($!)";
+
+open(INPUT_NSS, "$ARGV[1]")
+ or die "Unable to open input file $ARGV[1] ($!)";
+
+#########################
+# #
+# Parse and store file #
+# outputs #
+# #
+#########################
+
+my @mappingArray;
+while (my @input = split(/\s+/, <INPUT_MAP>)) {
+ $mappingArray[$input[0]] = $input[1];
+}
+
+my %probHash;
+my $maxI = 0;
+my $maxJ = 0;
+
+while (my @input = split(/:/, <INPUT_NSS>)) {
+
+ # 09 Jan 2005 : GWA : Yikes, not sure about ordering here. Also what the
+ # .nss file includes is the bit error probability,
+ # essentially the inverse of what we want.
+
+ $probHash{"$input[0]x$input[1]"} = (1 - $input[2]);
+
+ if ($input[0] > $maxI) {
+ $maxI = $input[0];
+ }
+ if ($input[1] > $maxJ) {
+ $maxJ = $input[1];
+ }
+}
+
+#############################
+# #
+# Write out the nesC code #
+# #
+#############################
+
+my $dateString = `date`;
+print <<TOP;
+// Filename: NodeConnectivityM.nc
+// Generated on $dateString
+// Created by createMotelabTopology.pl
+
+module NodeConnectivityM {
+ provides {
+ interface NodeConnectivity;
+ }
+} implementation {
+TOP
+
+my $arrayWidth = $maxI + 1;
+my $arrayHeight = $maxJ + 1;
+my $connectivityString = <<START;
+ uint8_t connectivity[$arrayWidth][$arrayHeight] =
+ {
+START
+$connectivityString .= " ";
+for (my $i = 0; $i <= $maxI; $i++) {
+ $connectivityString .= "{ ";
+ for (my $j = 0; $j <= $maxJ; $j++) {
+ if ($i == $j) {
+ $connectivityString .= "1";
+ } elsif (!defined($probHash{"$i" . "x" . "$j"})) {
+ $connectivityString .= "0";
+ } else {
+ $connectivityString .= $probHash{"$i" . "x" . "$j"};
+ }
+ if ($j != $maxJ) {
+ $connectivityString .= ", ";
+ }
+ }
+ $connectivityString .= " }";
+ if ($i != $maxI) {
+ $connectivityString .= ",";
+ }
+ $connectivityString .= "\n";
+ if ($i != $maxI) {
+ $connectivityString .= " ";
+ }
+}
+$connectivityString .= <<END;
+ };
+END
+print "$connectivityString";
+
+my $mappingString = "{ ";
+my $mappingSize = @mappingArray;
+for (my $i = 0; $i < @mappingArray; $i++) {
+ $mappingString .= $mappingArray[$i];
+ if ($i != (@mappingArray - 1)) {
+ $mappingString .= ", ";
+ }
+}
+$mappingString .= " };";
+
+print <<MAPPING;
+ uint16_t mapping[$mappingSize] = $mappingString
+MAPPING
+
+print <<REALEND;
+
+ command int8_t NodeConnectivity.mapping(uint16_t moteid) {
+ uint8_t i;
+ for (i = 0; i < $mappingSize; i++) {
+ if (mapping[i] == moteid) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ command bool NodeConnectivity.connected(uint16_t srcnode, uint16_t dstnode) {
+ int8_t src = call NodeConnectivity.mapping(srcnode);
+ int8_t dst = call NodeConnectivity.mapping(dstnode);
+
+ if ((src == -1) ||
+ (dst == -1)) {
+ return FALSE;
+ }
+
+ if (connectivity[src][dst] == 1) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+}
+REALEND
--- /dev/null
+0 12
+1 30
+2 24
+3 7
+4 18
+5 4
+6 28
+7 2
+8 16
+9 1
+10 22
+11 13
+12 23
+13 25
+14 26
+15 5
--- /dev/null
+0:1:0.0
+0:2:1.0
+0:3:1.0
+0:4:1.0
+0:5:1.0
+0:6:1.0
+0:7:1.0
+
+1:0:0.0
+1:2:0.0
+1:3:1.0
+1:4:1.0
+1:5:1.0
+1:6:1.0
+1:7:1.0
+
+2:0:1.0
+2:1:0.0
+2:3:0.0
+2:4:1.0
+2:5:1.0
+2:6:1.0
+2:7:1.0
+
+3:0:1.0
+3:1:1.0
+3:2:0.0
+3:4:0.0
+3:5:1.0
+3:6:1.0
+3:7:1.0
+
+4:0:1.0
+4:1:1.0
+4:2:1.0
+4:3:0.0
+4:5:0.0
+4:6:1.0
+4:7:1.0
+
+5:0:1.0
+5:1:1.0
+5:2:1.0
+5:3:1.0
+5:4:0.0
+5:6:0.0
+5:7:1.0
+
+6:0:1.0
+6:1:1.0
+6:2:1.0
+6:3:1.0
+6:4:1.0
+6:5:0.0
+6:7:0.0
+
+7:0:1.0
+7:1:1.0
+7:2:1.0
+7:3:1.0
+7:4:1.0
+7:6:0.0
+
--- /dev/null
+0 100
+1 101
+2 102
+3 103
+4 104
+5 105
+6 106
+7 107
--- /dev/null
+
+ A simple application which verifies the 6loWPAN stack is functioning
+correctly. A mote running this will respond to ICMP Echo requests
+(0x80), and provide a UDP echo service on port 7 (a la rfc862).
+
+
--- /dev/null
+/*
+ * "Copyright (c) 2008 The Regents of the University of California.
+ * All rights reserved."
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+#include <6lowpan.h>
+#include "TestDriver.h"
+
+configuration UDPEchoC {
+
+} implementation {
+ components MainC, LedsC;
+ components UDPEchoP;
+
+ UDPEchoP.Boot -> MainC;
+ UDPEchoP.Leds -> LedsC;
+
+ components new TimerMilliC();
+ components IPDispatchC;
+
+ UDPEchoP.RadioControl -> IPDispatchC;
+ components new UdpSocketC() as Echo,
+ new UdpSocketC() as Status;
+ UDPEchoP.Echo -> Echo;
+
+ UDPEchoP.Status -> Status;
+
+ UDPEchoP.StatusTimer -> TimerMilliC;
+
+ UDPEchoP.IPStats -> IPDispatchC.IPStats;
+ UDPEchoP.RouteStats -> IPDispatchC.RouteStats;
+ UDPEchoP.ICMPStats -> IPDispatchC.ICMPStats;
+
+ components RandomC;
+ UDPEchoP.Random -> RandomC;
+
+ components UDPShellC;
+
+#ifdef SIM
+ components BaseStationC;
+#endif
+#ifdef DBG_TRACK_FLOWS
+ components TestDriverP, SerialActiveMessageC as Serial;
+ components ICMPResponderC, IPRoutingP;
+ components new TimerMilliC() as Mark;
+ TestDriverP.Boot -> MainC;
+ TestDriverP.SerialControl -> Serial;
+ TestDriverP.ICMPPing -> ICMPResponderC.ICMPPing[unique("PING")];
+ TestDriverP.CmdReceive -> Serial.Receive[AM_TESTDRIVER_MSG];
+ TestDriverP.IPRouting -> IPRoutingP;
+ TestDriverP.DoneSend -> Serial.AMSend[AM_TESTDRIVER_MSG];
+ TestDriverP.RadioControl -> IPDispatchC;
+ TestDriverP.MarkTimer -> Mark;
+#endif
+}
--- /dev/null
+/*
+ * "Copyright (c) 2008 The Regents of the University of California.
+ * All rights reserved."
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+
+#include <IPDispatch.h>
+#include <lib6lowpan.h>
+#include <ip.h>
+#include <lib6lowpan.h>
+#include <ip.h>
+
+#include "UDPReport.h"
+#include "PrintfUART.h"
+
+#define REPORT_PERIOD 45L
+
+module UDPEchoP {
+ uses {
+ interface Boot;
+ interface SplitControl as RadioControl;
+
+ interface UDP as Echo;
+ interface UDP as Status;
+
+ interface Leds;
+
+ interface Timer<TMilli> as StatusTimer;
+
+ interface Statistics<ip_statistics_t> as IPStats;
+ interface Statistics<route_statistics_t> as RouteStats;
+ interface Statistics<icmp_statistics_t> as ICMPStats;
+
+ interface Random;
+ }
+
+} implementation {
+
+ bool timerStarted;
+ udp_statistics_t stats;
+ struct sockaddr_in6 route_dest;
+
+#ifndef SIM
+#define CHECK_NODE_ID
+#else
+#define CHECK_NODE_ID if (TOS_NODE_ID == BASESTATION_ID) return
+#endif
+
+ event void Boot.booted() {
+ CHECK_NODE_ID;
+ call RadioControl.start();
+ timerStarted = FALSE;
+
+ call IPStats.clear();
+ call RouteStats.clear();
+ call ICMPStats.clear();
+ printfUART_init();
+
+ stats.total = 0;
+ stats.failed = 0;
+
+#ifdef REPORT_DEST
+ route_dest.sin6_port = hton16(7000);
+ inet6_aton(REPORT_DEST, &route_dest.sin6_addr);
+ call StatusTimer.startOneShot(call Random.rand16() % (1024 * REPORT_PERIOD));
+#endif
+
+ dbg("Boot", "booted: %i\n", TOS_NODE_ID);
+ call Echo.bind(7);
+ call Status.bind(7001);
+ }
+
+ event void RadioControl.startDone(error_t e) {
+
+ }
+
+ event void RadioControl.stopDone(error_t e) {
+
+ }
+
+ event void Status.recvfrom(struct sockaddr_in6 *from, void *data,
+ uint16_t len, struct ip_metadata *meta) {
+
+ }
+
+ event void Echo.recvfrom(struct sockaddr_in6 *from, void *data,
+ uint16_t len, struct ip_metadata *meta) {
+ CHECK_NODE_ID;
+ call Echo.sendto(from, data, len);
+ }
+
+ enum {
+ STATUS_SIZE = // sizeof(ip_statistics_t) +
+ sizeof(route_statistics_t) +
+ sizeof(icmp_statistics_t) + sizeof(udp_statistics_t),
+ };
+
+
+ event void StatusTimer.fired() {
+ uint8_t status[STATUS_SIZE];
+ nx_struct udp_report *payload;
+ CHECK_NODE_ID;
+
+ stats.total++;
+
+ if (!timerStarted) {
+ call StatusTimer.startPeriodic(1024 * REPORT_PERIOD);
+ timerStarted = TRUE;
+ }
+
+ payload = (nx_struct udp_report *)status;
+
+ stats.seqno++;
+ stats.sender = TOS_NODE_ID;
+
+ // memcpy(&payload->ip, call IPStats.get(), sizeof(ip_statistics_t));
+ call RouteStats.get(&payload->route);
+ call ICMPStats.get(&payload->icmp);
+ memcpy(&payload->udp, &stats, sizeof(udp_statistics_t));
+
+ call Status.sendto(&route_dest, status, STATUS_SIZE);
+ }
+}
--- /dev/null
+/*
+ * "Copyright (c) 2008 The Regents of the University of California.
+ * All rights reserved."
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ */
+#ifndef _UDPREPORT_H
+#define _UDPREPORT_H
+
+#include <IPDispatch.h>
+
+nx_struct udp_report {
+ // ip_statistics_t ip;
+ udp_statistics_t udp;
+ icmp_statistics_t icmp;
+ route_statistics_t route;
+} ;
+
+#endif
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use FileHandle;
+use IPC::Open2;
+
+if (@ARGV != 1) {
+ print "Usage: echotest.pl <target ipv6>\n";
+ exit(1);
+}
+
+my $alpha = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+my $testbuf = "";
+while (length($testbuf) < 1280 - 40 - 8) {
+ $testbuf .= $alpha;
+}
+
+open2(*READER, *WRITER, "nc6 -u $ARGV[0] 7");
+
+my $trials = 0;
+while (1) {
+ my $len = int(rand(1000));
+ print $len . "\n";
+ print WRITER substr($testbuf, 0, $len) . "\n";
+
+ my $rin = '';
+ vec($rin,fileno(READER),1) = 1;
+ my $found = select($rin, undef, undef, "6");
+ if ($found == 1) {
+ my $foo;
+ sysread READER, $foo, 1280;
+ if ($foo eq $testbuf) {
+ print "WARNING: payload mismatch\n";
+ }
+ } else {
+ print "FAILURE: len: $len\n";
+ }
+
+ $trials++;
+ print "TRIAL: $trials\n";
+ sleep(.05);
+}
+# need to kill off the nc6 process
+print WRITER eof;
+
--- /dev/null
+#!/usr/bin/perl
+
+# make sure we don't break on any length boundaries
+
+use strict;
+use warnings;
+use FileHandle;
+use IPC::Open2;
+
+if (@ARGV != 1) {
+ print "Usage: seqtest.pl <target ipv6>\n";
+ exit(1);
+}
+
+my $alpha = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+my $testbuf = "";
+while (length($testbuf) < 1280 - 40 - 8) {
+ $testbuf .= $alpha;
+}
+
+open2(*READER, *WRITER, "nc6 -u $ARGV[0] 7");
+
+my $trials = 0;
+while (1) {
+ my $len;
+ for ($len = 1; $len < 1000; $len++) {
+ print $len . "\n";
+ print WRITER substr($testbuf, 0, $len) . "\n";
+
+ my $rin = '';
+ vec($rin,fileno(READER),1) = 1;
+ my $found = select($rin, undef, undef, "6");
+ if ($found == 1) {
+ my $foo;
+ sysread READER, $foo, 1280;
+ if ($foo eq $testbuf) {
+ print "WARNING: payload mismatch\n";
+ }
+ } else {
+ print "FAILURE: len: $len\n";
+ }
+
+ $trials++;
+ print "TRIAL: $trials\n";
+ sleep(.05);
+ }
+}
+# need to kill off the nc6 process
+print WRITER eof;
+
--- /dev/null
+
+import socket
+import UdpReport
+import re
+import sys
+
+port = 7000
+
+if __name__ == '__main__':
+
+ s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
+ s.bind(('', port))
+
+ while True:
+ data, addr = s.recvfrom(1024)
+ if (len(data) > 0):
+
+ rpt = UdpReport.UdpReport(data=data, data_length=len(data))
+
+ print addr
+ print rpt
+
--- /dev/null
+
+import socket
+import UdpReport
+import re
+import sys
+import MySQLdb
+
+port = 7000
+
+if __name__ == '__main__':
+ conn = MySQLdb.connect (host = "localhost",
+ user = "root",
+ db = "b6lowpan")
+ cursor = conn.cursor()
+ s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
+ s.bind(('', port))
+ if len(sys.argv) < 2:
+ print "\tListener.py <tablename>"
+ sys.exit(1)
+
+ try:
+ drop = "DROP TABLE " + str(sys.argv[1])
+ cursor.execute(drop)
+ except:
+ print "Drop failed... continuing"
+
+ methods = []
+ create_table = "CREATE TABLE " + str(sys.argv[1]) + " ("
+ create_table += "ts TIMESTAMP, origin INT(4), "
+ insert = "INSERT INTO " + sys.argv[1] + " (origin, "
+
+
+ re = re.compile('^get_(.*)')
+ for method in dir(UdpReport.UdpReport):
+ result = re.search(method)
+ if result != None:
+ create_table += str(result.group(1)) + " INT(4), "
+ insert += str(result.group(1)) + ", "
+ methods.append(str(result.group(1)))
+
+ create_table = create_table[0:len(create_table) - 2]
+ insert = insert[0:len(insert) - 2]
+ create_table += ")"
+ insert += ") VALUES ("
+ print insert
+ print create_table
+
+ cursor.execute(create_table)
+
+ while True:
+ data, addr = s.recvfrom(1024)
+ if (len(data) > 0):
+
+
+ print
+ print str(len(data)) + ":",
+ for i in data:
+ print "0x%x" % ord(i),
+
+ print
+ rpt = UdpReport.UdpReport(data=data, data_length=len(data))
+ addr = addr[0]
+ AA = addr.split(":")
+ print addr
+ print rpt
+
+
+ thisInsert = insert
+ thisInsert += "0x" + AA[-1] + ", "
+
+
+
+ for m in methods:
+ try:
+ getter = getattr(rpt, 'get_' + m, None)
+ val = getter()
+ except:
+ val = 0
+ if (isinstance(val, list)):
+ val = val[0]
+ thisInsert += str(val) + ", "
+ thisInsert = thisInsert[0:len(thisInsert) - 2]
+ thisInsert += ")"
+
+ print thisInsert
+
+ cursor.execute(thisInsert)
+
+ conn.close()
+
--- /dev/null
+#
+# This class is automatically generated by mig. DO NOT EDIT THIS FILE.
+# This class implements a Python interface to the 'UdpReport'
+# message type.
+#
+
+import tinyos.message.Message
+
+# The default size of this message type in bytes.
+DEFAULT_MESSAGE_SIZE = 32
+
+# The Active Message type associated with this message.
+AM_TYPE = -1
+
+class UdpReport(tinyos.message.Message.Message):
+ # Create a new UdpReport of size 32.
+ def __init__(self, data="", addr=None, gid=None, base_offset=0, data_length=32):
+ tinyos.message.Message.Message.__init__(self, data, addr, gid, base_offset, data_length)
+ self.amTypeSet(AM_TYPE)
+
+ # Get AM_TYPE
+ def get_amType(cls):
+ return AM_TYPE
+
+ get_amType = classmethod(get_amType)
+
+ #
+ # Return a String representation of this message. Includes the
+ # message type name and the non-indexed field values.
+ #
+ def __str__(self):
+ s = "Message <UdpReport> \n"
+ try:
+ s += " [udp.total=0x%x]\n" % (self.get_udp_total())
+ except:
+ pass
+ try:
+ s += " [udp.failed=0x%x]\n" % (self.get_udp_failed())
+ except:
+ pass
+ try:
+ s += " [udp.seqno=0x%x]\n" % (self.get_udp_seqno())
+ except:
+ pass
+ try:
+ s += " [udp.sender=0x%x]\n" % (self.get_udp_sender())
+ except:
+ pass
+ try:
+ s += " [icmp.rx=0x%x]\n" % (self.get_icmp_rx())
+ except:
+ pass
+ try:
+ s += " [route.parent.flags=0x%x]\n" % (self.get_route_parent_flags())
+ except:
+ pass
+ try:
+ s += " [route.parent.hops=0x%x]\n" % (self.get_route_parent_hops())
+ except:
+ pass
+ try:
+ s += " [route.parent.neighbor=0x%x]\n" % (self.get_route_parent_neighbor())
+ except:
+ pass
+ try:
+ s += " [route.parent.costEstimate=0x%x]\n" % (self.get_route_parent_costEstimate())
+ except:
+ pass
+ try:
+ s += " [route.parent.linkEstimate=0x%x]\n" % (self.get_route_parent_linkEstimate())
+ except:
+ pass
+ try:
+ s += " [route.parent.rssiEstimate=0x%x]\n" % (self.get_route_parent_rssiEstimate())
+ except:
+ pass
+ try:
+ s += " [route.parent.stats.success=";
+ for i in range(0, 2):
+ s += "0x%x " % (self.getElement_route_parent_stats_success(i) & 0xff)
+ s += "]\n";
+ except:
+ pass
+ try:
+ s += " [route.parent.stats.total=";
+ for i in range(0, 2):
+ s += "0x%x " % (self.getElement_route_parent_stats_total(i) & 0xff)
+ s += "]\n";
+ except:
+ pass
+ try:
+ s += " [route.parent.stats.receptions=";
+ for i in range(0, 2):
+ s += "0x%x " % (self.getElement_route_parent_stats_receptions(i) & 0xff)
+ s += "]\n";
+ except:
+ pass
+ return s
+
+ # Message-type-specific access methods appear below.
+
+ #
+ # Accessor methods for field: udp.total
+ # Field type: int
+ # Offset (bits): 0
+ # Size (bits): 16
+ #
+
+ #
+ # Return whether the field 'udp.total' is signed (False).
+ #
+ def isSigned_udp_total(self):
+ return False
+
+ #
+ # Return whether the field 'udp.total' is an array (False).
+ #
+ def isArray_udp_total(self):
+ return False
+
+ #
+ # Return the offset (in bytes) of the field 'udp.total'
+ #
+ def offset_udp_total(self):
+ return (0 / 8)
+
+ #
+ # Return the offset (in bits) of the field 'udp.total'
+ #
+ def offsetBits_udp_total(self):
+ return 0
+
+ #
+ # Return the value (as a int) of the field 'udp.total'
+ #
+ def get_udp_total(self):
+ return self.getUIntElement(self.offsetBits_udp_total(), 16, 1)
+
+ #
+ # Set the value of the field 'udp.total'
+ #
+ def set_udp_total(self, value):
+ self.setUIntElement(self.offsetBits_udp_total(), 16, value, 1)
+
+ #
+ # Return the size, in bytes, of the field 'udp.total'
+ #
+ def size_udp_total(self):
+ return (16 / 8)
+
+ #
+ # Return the size, in bits, of the field 'udp.total'
+ #
+ def sizeBits_udp_total(self):
+ return 16
+
+ #
+ # Accessor methods for field: udp.failed
+ # Field type: int
+ # Offset (bits): 16
+ # Size (bits): 16
+ #
+
+ #
+ # Return whether the field 'udp.failed' is signed (False).
+ #
+ def isSigned_udp_failed(self):
+ return False
+
+ #
+ # Return whether the field 'udp.failed' is an array (False).
+ #
+ def isArray_udp_failed(self):
+ return False
+
+ #
+ # Return the offset (in bytes) of the field 'udp.failed'
+ #
+ def offset_udp_failed(self):
+ return (16 / 8)
+
+ #
+ # Return the offset (in bits) of the field 'udp.failed'
+ #
+ def offsetBits_udp_failed(self):
+ return 16
+
+ #
+ # Return the value (as a int) of the field 'udp.failed'
+ #
+ def get_udp_failed(self):
+ return self.getUIntElement(self.offsetBits_udp_failed(), 16, 1)
+
+ #
+ # Set the value of the field 'udp.failed'
+ #
+ def set_udp_failed(self, value):
+ self.setUIntElement(self.offsetBits_udp_failed(), 16, value, 1)
+
+ #
+ # Return the size, in bytes, of the field 'udp.failed'
+ #
+ def size_udp_failed(self):
+ return (16 / 8)
+
+ #
+ # Return the size, in bits, of the field 'udp.failed'
+ #
+ def sizeBits_udp_failed(self):
+ return 16
+
+ #
+ # Accessor methods for field: udp.seqno
+ # Field type: int
+ # Offset (bits): 32
+ # Size (bits): 16
+ #
+
+ #
+ # Return whether the field 'udp.seqno' is signed (False).
+ #
+ def isSigned_udp_seqno(self):
+ return False
+
+ #
+ # Return whether the field 'udp.seqno' is an array (False).
+ #
+ def isArray_udp_seqno(self):
+ return False
+
+ #
+ # Return the offset (in bytes) of the field 'udp.seqno'
+ #
+ def offset_udp_seqno(self):
+ return (32 / 8)
+
+ #
+ # Return the offset (in bits) of the field 'udp.seqno'
+ #
+ def offsetBits_udp_seqno(self):
+ return 32
+
+ #
+ # Return the value (as a int) of the field 'udp.seqno'
+ #
+ def get_udp_seqno(self):
+ return self.getUIntElement(self.offsetBits_udp_seqno(), 16, 1)
+
+ #
+ # Set the value of the field 'udp.seqno'
+ #
+ def set_udp_seqno(self, value):
+ self.setUIntElement(self.offsetBits_udp_seqno(), 16, value, 1)
+
+ #
+ # Return the size, in bytes, of the field 'udp.seqno'
+ #
+ def size_udp_seqno(self):
+ return (16 / 8)
+
+ #
+ # Return the size, in bits, of the field 'udp.seqno'
+ #
+ def sizeBits_udp_seqno(self):
+ return 16
+
+ #
+ # Accessor methods for field: udp.sender
+ # Field type: int
+ # Offset (bits): 48
+ # Size (bits): 16
+ #
+
+ #
+ # Return whether the field 'udp.sender' is signed (False).
+ #
+ def isSigned_udp_sender(self):
+ return False
+
+ #
+ # Return whether the field 'udp.sender' is an array (False).
+ #
+ def isArray_udp_sender(self):
+ return False
+
+ #
+ # Return the offset (in bytes) of the field 'udp.sender'
+ #
+ def offset_udp_sender(self):
+ return (48 / 8)
+
+ #
+ # Return the offset (in bits) of the field 'udp.sender'
+ #
+ def offsetBits_udp_sender(self):
+ return 48
+
+ #
+ # Return the value (as a int) of the field 'udp.sender'
+ #
+ def get_udp_sender(self):
+ return self.getUIntElement(self.offsetBits_udp_sender(), 16, 1)
+
+ #
+ # Set the value of the field 'udp.sender'
+ #
+ def set_udp_sender(self, value):
+ self.setUIntElement(self.offsetBits_udp_sender(), 16, value, 1)
+
+ #
+ # Return the size, in bytes, of the field 'udp.sender'
+ #
+ def size_udp_sender(self):
+ return (16 / 8)
+
+ #
+ # Return the size, in bits, of the field 'udp.sender'
+ #
+ def sizeBits_udp_sender(self):
+ return 16
+
+ #
+ # Accessor methods for field: icmp.rx
+ # Field type: int
+ # Offset (bits): 64
+ # Size (bits): 16
+ #
+
+ #
+ # Return whether the field 'icmp.rx' is signed (False).
+ #
+ def isSigned_icmp_rx(self):
+ return False
+
+ #
+ # Return whether the field 'icmp.rx' is an array (False).
+ #
+ def isArray_icmp_rx(self):
+ return False
+
+ #
+ # Return the offset (in bytes) of the field 'icmp.rx'
+ #
+ def offset_icmp_rx(self):
+ return (64 / 8)
+
+ #
+ # Return the offset (in bits) of the field 'icmp.rx'
+ #
+ def offsetBits_icmp_rx(self):
+ return 64
+
+ #
+ # Return the value (as a int) of the field 'icmp.rx'
+ #
+ def get_icmp_rx(self):
+ return self.getUIntElement(self.offsetBits_icmp_rx(), 16, 1)
+
+ #
+ # Set the value of the field 'icmp.rx'
+ #
+ def set_icmp_rx(self, value):
+ self.setUIntElement(self.offsetBits_icmp_rx(), 16, value, 1)
+
+ #
+ # Return the size, in bytes, of the field 'icmp.rx'
+ #
+ def size_icmp_rx(self):
+ return (16 / 8)
+
+ #
+ # Return the size, in bits, of the field 'icmp.rx'
+ #
+ def sizeBits_icmp_rx(self):
+ return 16
+
+ #
+ # Accessor methods for field: route.parent.flags
+ # Field type: short
+ # Offset (bits): 80
+ # Size (bits): 8
+ #
+
+ #
+ # Return whether the field 'route.parent.flags' is signed (False).
+ #
+ def isSigned_route_parent_flags(self):
+ return False
+
+ #
+ # Return whether the field 'route.parent.flags' is an array (False).
+ #
+ def isArray_route_parent_flags(self):
+ return False
+
+ #
+ # Return the offset (in bytes) of the field 'route.parent.flags'
+ #
+ def offset_route_parent_flags(self):
+ return (80 / 8)
+
+ #
+ # Return the offset (in bits) of the field 'route.parent.flags'
+ #
+ def offsetBits_route_parent_flags(self):
+ return 80
+
+ #
+ # Return the value (as a short) of the field 'route.parent.flags'
+ #
+ def get_route_parent_flags(self):
+ return self.getUIntElement(self.offsetBits_route_parent_flags(), 8, 0)
+
+ #
+ # Set the value of the field 'route.parent.flags'
+ #
+ def set_route_parent_flags(self, value):
+ self.setUIntElement(self.offsetBits_route_parent_flags(), 8, value, 0)
+
+ #
+ # Return the size, in bytes, of the field 'route.parent.flags'
+ #
+ def size_route_parent_flags(self):
+ return (8 / 8)
+
+ #
+ # Return the size, in bits, of the field 'route.parent.flags'
+ #
+ def sizeBits_route_parent_flags(self):
+ return 8
+
+ #
+ # Accessor methods for field: route.parent.hops
+ # Field type: short
+ # Offset (bits): 88
+ # Size (bits): 8
+ #
+
+ #
+ # Return whether the field 'route.parent.hops' is signed (False).
+ #
+ def isSigned_route_parent_hops(self):
+ return False
+
+ #
+ # Return whether the field 'route.parent.hops' is an array (False).
+ #
+ def isArray_route_parent_hops(self):
+ return False
+
+ #
+ # Return the offset (in bytes) of the field 'route.parent.hops'
+ #
+ def offset_route_parent_hops(self):
+ return (88 / 8)
+
+ #
+ # Return the offset (in bits) of the field 'route.parent.hops'
+ #
+ def offsetBits_route_parent_hops(self):
+ return 88
+
+ #
+ # Return the value (as a short) of the field 'route.parent.hops'
+ #
+ def get_route_parent_hops(self):
+ return self.getUIntElement(self.offsetBits_route_parent_hops(), 8, 0)
+
+ #
+ # Set the value of the field 'route.parent.hops'
+ #
+ def set_route_parent_hops(self, value):
+ self.setUIntElement(self.offsetBits_route_parent_hops(), 8, value, 0)
+
+ #
+ # Return the size, in bytes, of the field 'route.parent.hops'
+ #
+ def size_route_parent_hops(self):
+ return (8 / 8)
+
+ #
+ # Return the size, in bits, of the field 'route.parent.hops'
+ #
+ def sizeBits_route_parent_hops(self):
+ return 8
+
+ #
+ # Accessor methods for field: route.parent.neighbor
+ # Field type: int
+ # Offset (bits): 96
+ # Size (bits): 16
+ #
+
+ #
+ # Return whether the field 'route.parent.neighbor' is signed (False).
+ #
+ def isSigned_route_parent_neighbor(self):
+ return False
+
+ #
+ # Return whether the field 'route.parent.neighbor' is an array (False).
+ #
+ def isArray_route_parent_neighbor(self):
+ return False
+
+ #
+ # Return the offset (in bytes) of the field 'route.parent.neighbor'
+ #
+ def offset_route_parent_neighbor(self):
+ return (96 / 8)
+
+ #
+ # Return the offset (in bits) of the field 'route.parent.neighbor'
+ #
+ def offsetBits_route_parent_neighbor(self):
+ return 96
+
+ #
+ # Return the value (as a int) of the field 'route.parent.neighbor'
+ #
+ def get_route_parent_neighbor(self):
+ return self.getUIntElement(self.offsetBits_route_parent_neighbor(), 16, 0)
+
+ #
+ # Set the value of the field 'route.parent.neighbor'
+ #
+ def set_route_parent_neighbor(self, value):
+ self.setUIntElement(self.offsetBits_route_parent_neighbor(), 16, value, 0)
+
+ #
+ # Return the size, in bytes, of the field 'route.parent.neighbor'
+ #
+ def size_route_parent_neighbor(self):
+ return (16 / 8)
+
+ #
+ # Return the size, in bits, of the field 'route.parent.neighbor'
+ #
+ def sizeBits_route_parent_neighbor(self):
+ return 16
+
+ #
+ # Accessor methods for field: route.parent.costEstimate
+ # Field type: int
+ # Offset (bits): 112
+ # Size (bits): 16
+ #
+
+ #
+ # Return whether the field 'route.parent.costEstimate' is signed (False).
+ #
+ def isSigned_route_parent_costEstimate(self):
+ return False
+
+ #
+ # Return whether the field 'route.parent.costEstimate' is an array (False).
+ #
+ def isArray_route_parent_costEstimate(self):
+ return False
+
+ #
+ # Return the offset (in bytes) of the field 'route.parent.costEstimate'
+ #
+ def offset_route_parent_costEstimate(self):
+ return (112 / 8)
+
+ #
+ # Return the offset (in bits) of the field 'route.parent.costEstimate'
+ #
+ def offsetBits_route_parent_costEstimate(self):
+ return 112
+
+ #
+ # Return the value (as a int) of the field 'route.parent.costEstimate'
+ #
+ def get_route_parent_costEstimate(self):
+ return self.getUIntElement(self.offsetBits_route_parent_costEstimate(), 16, 0)
+
+ #
+ # Set the value of the field 'route.parent.costEstimate'
+ #
+ def set_route_parent_costEstimate(self, value):
+ self.setUIntElement(self.offsetBits_route_parent_costEstimate(), 16, value, 0)
+
+ #
+ # Return the size, in bytes, of the field 'route.parent.costEstimate'
+ #
+ def size_route_parent_costEstimate(self):
+ return (16 / 8)
+
+ #
+ # Return the size, in bits, of the field 'route.parent.costEstimate'
+ #
+ def sizeBits_route_parent_costEstimate(self):
+ return 16
+
+ #
+ # Accessor methods for field: route.parent.linkEstimate
+ # Field type: int
+ # Offset (bits): 128
+ # Size (bits): 16
+ #
+
+ #
+ # Return whether the field 'route.parent.linkEstimate' is signed (False).
+ #
+ def isSigned_route_parent_linkEstimate(self):
+ return False
+
+ #
+ # Return whether the field 'route.parent.linkEstimate' is an array (False).
+ #
+ def isArray_route_parent_linkEstimate(self):
+ return False
+
+ #
+ # Return the offset (in bytes) of the field 'route.parent.linkEstimate'
+ #
+ def offset_route_parent_linkEstimate(self):
+ return (128 / 8)
+
+ #
+ # Return the offset (in bits) of the field 'route.parent.linkEstimate'
+ #
+ def offsetBits_route_parent_linkEstimate(self):
+ return 128
+
+ #
+ # Return the value (as a int) of the field 'route.parent.linkEstimate'
+ #
+ def get_route_parent_linkEstimate(self):
+ return self.getUIntElement(self.offsetBits_route_parent_linkEstimate(), 16, 0)
+
+ #
+ # Set the value of the field 'route.parent.linkEstimate'
+ #
+ def set_route_parent_linkEstimate(self, value):
+ self.setUIntElement(self.offsetBits_route_parent_linkEstimate(), 16, value, 0)
+
+ #
+ # Return the size, in bytes, of the field 'route.parent.linkEstimate'
+ #
+ def size_route_parent_linkEstimate(self):
+ return (16 / 8)
+
+ #
+ # Return the size, in bits, of the field 'route.parent.linkEstimate'
+ #
+ def sizeBits_route_parent_linkEstimate(self):
+ return 16
+
+ #
+ # Accessor methods for field: route.parent.rssiEstimate
+ # Field type: int
+ # Offset (bits): 144
+ # Size (bits): 16
+ #
+
+ #
+ # Return whether the field 'route.parent.rssiEstimate' is signed (False).
+ #
+ def isSigned_route_parent_rssiEstimate(self):
+ return False
+
+ #
+ # Return whether the field 'route.parent.rssiEstimate' is an array (False).
+ #
+ def isArray_route_parent_rssiEstimate(self):
+ return False
+
+ #
+ # Return the offset (in bytes) of the field 'route.parent.rssiEstimate'
+ #
+ def offset_route_parent_rssiEstimate(self):
+ return (144 / 8)
+
+ #
+ # Return the offset (in bits) of the field 'route.parent.rssiEstimate'
+ #
+ def offsetBits_route_parent_rssiEstimate(self):
+ return 144
+
+ #
+ # Return the value (as a int) of the field 'route.parent.rssiEstimate'
+ #
+ def get_route_parent_rssiEstimate(self):
+ return self.getUIntElement(self.offsetBits_route_parent_rssiEstimate(), 16, 0)
+
+ #
+ # Set the value of the field 'route.parent.rssiEstimate'
+ #
+ def set_route_parent_rssiEstimate(self, value):
+ self.setUIntElement(self.offsetBits_route_parent_rssiEstimate(), 16, value, 0)
+
+ #
+ # Return the size, in bytes, of the field 'route.parent.rssiEstimate'
+ #
+ def size_route_parent_rssiEstimate(self):
+ return (16 / 8)
+
+ #
+ # Return the size, in bits, of the field 'route.parent.rssiEstimate'
+ #
+ def sizeBits_route_parent_rssiEstimate(self):
+ return 16
+
+ #
+ # Accessor methods for field: route.parent.stats.success
+ # Field type: int[]
+ # Offset (bits): 0
+ # Size of each element (bits): 16
+ #
+
+ #
+ # Return whether the field 'route.parent.stats.success' is signed (False).
+ #
+ def isSigned_route_parent_stats_success(self):
+ return False
+
+ #
+ # Return whether the field 'route.parent.stats.success' is an array (True).
+ #
+ def isArray_route_parent_stats_success(self):
+ return True
+
+ #
+ # Return the offset (in bytes) of the field 'route.parent.stats.success'
+ #
+ def offset_route_parent_stats_success(self, index1):
+ offset = 0
+ if index1 < 0 or index1 >= 2:
+ raise IndexError
+ offset += 160 + index1 * 48
+ return (offset / 8)
+
+ #
+ # Return the offset (in bits) of the field 'route.parent.stats.success'
+ #
+ def offsetBits_route_parent_stats_success(self, index1):
+ offset = 0
+ if index1 < 0 or index1 >= 2:
+ raise IndexError
+ offset += 160 + index1 * 48
+ return offset
+
+ #
+ # Return the entire array 'route.parent.stats.success' as a int[]
+ #
+ def get_route_parent_stats_success(self):
+ tmp = [None]*2
+ for index0 in range (0, self.numElements_route_parent_stats_success(0)):
+ tmp[index0] = self.getElement_route_parent_stats_success(index0)
+ return tmp
+
+ #
+ # Set the contents of the array 'route.parent.stats.success' from the given int[]
+ #
+ def set_route_parent_stats_success(self, value):
+ for index0 in range(0, len(value)):
+ self.setElement_route_parent_stats_success(index0, value[index0])
+
+ #
+ # Return an element (as a int) of the array 'route.parent.stats.success'
+ #
+ def getElement_route_parent_stats_success(self, index1):
+ return self.getUIntElement(self.offsetBits_route_parent_stats_success(index1), 16, 0)
+
+ #
+ # Set an element of the array 'route.parent.stats.success'
+ #
+ def setElement_route_parent_stats_success(self, index1, value):
+ self.setUIntElement(self.offsetBits_route_parent_stats_success(index1), 16, value, 0)
+
+ #
+ # Return the total size, in bytes, of the array 'route.parent.stats.success'
+ #
+ def totalSize_route_parent_stats_success(self):
+ return (96 / 8)
+
+ #
+ # Return the total size, in bits, of the array 'route.parent.stats.success'
+ #
+ def totalSizeBits_route_parent_stats_success(self):
+ return 96
+
+ #
+ # Return the size, in bytes, of each element of the array 'route.parent.stats.success'
+ #
+ def elementSize_route_parent_stats_success(self):
+ return (16 / 8)
+
+ #
+ # Return the size, in bits, of each element of the array 'route.parent.stats.success'
+ #
+ def elementSizeBits_route_parent_stats_success(self):
+ return 16
+
+ #
+ # Return the number of dimensions in the array 'route.parent.stats.success'
+ #
+ def numDimensions_route_parent_stats_success(self):
+ return 1
+
+ #
+ # Return the number of elements in the array 'route.parent.stats.success'
+ #
+ def numElements_route_parent_stats_success():
+ return 2
+
+ #
+ # Return the number of elements in the array 'route.parent.stats.success'
+ # for the given dimension.
+ #
+ def numElements_route_parent_stats_success(self, dimension):
+ array_dims = [ 2, ]
+ if dimension < 0 or dimension >= 1:
+ raise IndexException
+ if array_dims[dimension] == 0:
+ raise IndexError
+ return array_dims[dimension]
+
+ #
+ # Accessor methods for field: route.parent.stats.total
+ # Field type: int[]
+ # Offset (bits): 16
+ # Size of each element (bits): 16
+ #
+
+ #
+ # Return whether the field 'route.parent.stats.total' is signed (False).
+ #
+ def isSigned_route_parent_stats_total(self):
+ return False
+
+ #
+ # Return whether the field 'route.parent.stats.total' is an array (True).
+ #
+ def isArray_route_parent_stats_total(self):
+ return True
+
+ #
+ # Return the offset (in bytes) of the field 'route.parent.stats.total'
+ #
+ def offset_route_parent_stats_total(self, index1):
+ offset = 16
+ if index1 < 0 or index1 >= 2:
+ raise IndexError
+ offset += 160 + index1 * 48
+ return (offset / 8)
+
+ #
+ # Return the offset (in bits) of the field 'route.parent.stats.total'
+ #
+ def offsetBits_route_parent_stats_total(self, index1):
+ offset = 16
+ if index1 < 0 or index1 >= 2:
+ raise IndexError
+ offset += 160 + index1 * 48
+ return offset
+
+ #
+ # Return the entire array 'route.parent.stats.total' as a int[]
+ #
+ def get_route_parent_stats_total(self):
+ tmp = [None]*2
+ for index0 in range (0, self.numElements_route_parent_stats_total(0)):
+ tmp[index0] = self.getElement_route_parent_stats_total(index0)
+ return tmp
+
+ #
+ # Set the contents of the array 'route.parent.stats.total' from the given int[]
+ #
+ def set_route_parent_stats_total(self, value):
+ for index0 in range(0, len(value)):
+ self.setElement_route_parent_stats_total(index0, value[index0])
+
+ #
+ # Return an element (as a int) of the array 'route.parent.stats.total'
+ #
+ def getElement_route_parent_stats_total(self, index1):
+ return self.getUIntElement(self.offsetBits_route_parent_stats_total(index1), 16, 0)
+
+ #
+ # Set an element of the array 'route.parent.stats.total'
+ #
+ def setElement_route_parent_stats_total(self, index1, value):
+ self.setUIntElement(self.offsetBits_route_parent_stats_total(index1), 16, value, 0)
+
+ #
+ # Return the total size, in bytes, of the array 'route.parent.stats.total'
+ #
+ def totalSize_route_parent_stats_total(self):
+ return (96 / 8)
+
+ #
+ # Return the total size, in bits, of the array 'route.parent.stats.total'
+ #
+ def totalSizeBits_route_parent_stats_total(self):
+ return 96
+
+ #
+ # Return the size, in bytes, of each element of the array 'route.parent.stats.total'
+ #
+ def elementSize_route_parent_stats_total(self):
+ return (16 / 8)
+
+ #
+ # Return the size, in bits, of each element of the array 'route.parent.stats.total'
+ #
+ def elementSizeBits_route_parent_stats_total(self):
+ return 16
+
+ #
+ # Return the number of dimensions in the array 'route.parent.stats.total'
+ #
+ def numDimensions_route_parent_stats_total(self):
+ return 1
+
+ #
+ # Return the number of elements in the array 'route.parent.stats.total'
+ #
+ def numElements_route_parent_stats_total():
+ return 2
+
+ #
+ # Return the number of elements in the array 'route.parent.stats.total'
+ # for the given dimension.
+ #
+ def numElements_route_parent_stats_total(self, dimension):
+ array_dims = [ 2, ]
+ if dimension < 0 or dimension >= 1:
+ raise IndexException
+ if array_dims[dimension] == 0:
+ raise IndexError
+ return array_dims[dimension]
+
+ #
+ # Accessor methods for field: route.parent.stats.receptions
+ # Field type: int[]
+ # Offset (bits): 32
+ # Size of each element (bits): 16
+ #
+
+ #
+ # Return whether the field 'route.parent.stats.receptions' is signed (False).
+ #
+ def isSigned_route_parent_stats_receptions(self):
+ return False
+
+ #
+ # Return whether the field 'route.parent.stats.receptions' is an array (True).
+ #
+ def isArray_route_parent_stats_receptions(self):
+ return True
+
+ #
+ # Return the offset (in bytes) of the field 'route.parent.stats.receptions'
+ #
+ def offset_route_parent_stats_receptions(self, index1):
+ offset = 32
+ if index1 < 0 or index1 >= 2:
+ raise IndexError
+ offset += 160 + index1 * 48
+ return (offset / 8)
+
+ #
+ # Return the offset (in bits) of the field 'route.parent.stats.receptions'
+ #
+ def offsetBits_route_parent_stats_receptions(self, index1):
+ offset = 32
+ if index1 < 0 or index1 >= 2:
+ raise IndexError
+ offset += 160 + index1 * 48
+ return offset
+
+ #
+ # Return the entire array 'route.parent.stats.receptions' as a int[]
+ #
+ def get_route_parent_stats_receptions(self):
+ tmp = [None]*2
+ for index0 in range (0, self.numElements_route_parent_stats_receptions(0)):
+ tmp[index0] = self.getElement_route_parent_stats_receptions(index0)
+ return tmp
+
+ #
+ # Set the contents of the array 'route.parent.stats.receptions' from the given int[]
+ #
+ def set_route_parent_stats_receptions(self, value):
+ for index0 in range(0, len(value)):
+ self.setElement_route_parent_stats_receptions(index0, value[index0])
+
+ #
+ # Return an element (as a int) of the array 'route.parent.stats.receptions'
+ #
+ def getElement_route_parent_stats_receptions(self, index1):
+ return self.getUIntElement(self.offsetBits_route_parent_stats_receptions(index1), 16, 0)
+
+ #
+ # Set an element of the array 'route.parent.stats.receptions'
+ #
+ def setElement_route_parent_stats_receptions(self, index1, value):
+ self.setUIntElement(self.offsetBits_route_parent_stats_receptions(index1), 16, value, 0)
+
+ #
+ # Return the total size, in bytes, of the array 'route.parent.stats.receptions'
+ #
+ def totalSize_route_parent_stats_receptions(self):
+ return (96 / 8)
+
+ #
+ # Return the total size, in bits, of the array 'route.parent.stats.receptions'
+ #
+ def totalSizeBits_route_parent_stats_receptions(self):
+ return 96
+
+ #
+ # Return the size, in bytes, of each element of the array 'route.parent.stats.receptions'
+ #
+ def elementSize_route_parent_stats_receptions(self):
+ return (16 / 8)
+
+ #
+ # Return the size, in bits, of each element of the array 'route.parent.stats.receptions'
+ #
+ def elementSizeBits_route_parent_stats_receptions(self):
+ return 16
+
+ #
+ # Return the number of dimensions in the array 'route.parent.stats.receptions'
+ #
+ def numDimensions_route_parent_stats_receptions(self):
+ return 1
+
+ #
+ # Return the number of elements in the array 'route.parent.stats.receptions'
+ #
+ def numElements_route_parent_stats_receptions():
+ return 2
+
+ #
+ # Return the number of elements in the array 'route.parent.stats.receptions'
+ # for the given dimension.
+ #
+ def numElements_route_parent_stats_receptions(self, dimension):
+ array_dims = [ 2, ]
+ if dimension < 0 or dimension >= 1:
+ raise IndexException
+ if array_dims[dimension] == 0:
+ raise IndexError
+ return array_dims[dimension]
+
--- /dev/null
+<volume_table>
+ <volume name="GOLDENIMAGE" size="65536" base="0" />
+ <volume name="DELUGE1" size="65536"/>
+ <volume name="DELUGE2" size="65536"/>
+ <volume name="DELUGE3" size="65536"/>
+</volume_table>
\ No newline at end of file
--- /dev/null
+<volume_table>
+ <volume name="GOLDENIMAGE" size="65536" base="983040" />
+ <volume name="DELUGE1" size="65536"/>
+ <volume name="DELUGE2" size="65536"/>
+ <volume name="DELUGE3" size="65536"/>
+</volume_table>
\ No newline at end of file