--- /dev/null
+#include <DisseminationEngine.h>
+
+/*
+ * Copyright (c) 2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ *
+ */
+
+/**
+ * The DisseminationC component is the top-level interface to the
+ * dissemination protocol. StdControl controls all of the trickle
+ * timers used for all of the keys.
+ *
+ * See TEP118 - Dissemination for details.
+ *
+ * @author Gilman Tolle <gtolle@archrock.com>
+ * @version $Revision$
+ */
+
+configuration DisseminationC {
+ provides interface StdControl;
+}
+implementation {
+ components DisseminationEngineP;
+ StdControl = DisseminationEngineP;
+}
*/
interface DisseminationCache {
- event void init();
+ event error_t start();
+ event error_t stop();
command void* requestData( uint8_t* size );
command void storeData( void* data, uint8_t size, uint32_t seqno );
command uint32_t requestSeqno();
*/
module DisseminationEngineImplP {
+ provides interface StdControl;
+
uses {
- interface Boot;
- interface SplitControl as RadioControl;
interface DisseminationCache[uint16_t key];
interface TrickleTimer[uint16_t key];
+ interface StdControl as DisseminatorControl[uint16_t id];
interface AMSend;
interface Receive;
}
implementation {
+ enum { NUM_DISSEMINATORS = uniqueCount("DisseminationTimerC.TrickleTimer") };
+
message_t m_buf;
- bool m_bufBusy = TRUE;
+ bool m_running;
+ bool m_bufBusy;
void sendProbe( uint16_t key );
void sendObject( uint16_t key );
- event void Boot.booted() {
- call RadioControl.start();
+ command error_t StdControl.start() {
+ uint8_t i;
+ for ( i = 0; i < NUM_DISSEMINATORS; i++ ) {
+ call DisseminatorControl.start[ i ]();
+ }
+ m_running = TRUE;
+ return SUCCESS;
}
- event void RadioControl.startDone( error_t err ) {
- m_bufBusy = FALSE;
+ command error_t StdControl.stop() {
+ uint8_t i;
+ for ( i = 0; i < NUM_DISSEMINATORS; i++ ) {
+ call DisseminatorControl.stop[ i ]();
+ }
+ m_running = FALSE;
+ return SUCCESS;
}
- event void RadioControl.stopDone( error_t err ) {}
- event void DisseminationCache.init[ uint16_t key ]() {
- call TrickleTimer.start[ key ]();
+ event error_t DisseminationCache.start[ uint16_t key ]() {
+ error_t result = call TrickleTimer.start[ key ]();
call TrickleTimer.reset[ key ]();
+ return result;
+ }
+
+ event error_t DisseminationCache.stop[ uint16_t key ]() {
+ call TrickleTimer.stop[ key ]();
+ return SUCCESS;
}
event void DisseminationCache.newData[ uint16_t key ]() {
+
+ if ( !m_running || m_bufBusy ) { return; }
+
sendObject( key );
call TrickleTimer.reset[ key ]();
}
event void TrickleTimer.fired[ uint16_t key ]() {
-
- if ( m_bufBusy ) { return; }
+ if ( !m_running || m_bufBusy ) { return; }
sendObject( key );
}
uint32_t incomingSeqno = dMsg->seqno;
uint32_t currentSeqno = call DisseminationCache.requestSeqno[ key ]();
+ if ( !m_running ) { return msg; }
+
if ( currentSeqno == DISSEMINATION_SEQNO_UNKNOWN &&
incomingSeqno != DISSEMINATION_SEQNO_UNKNOWN ) {
dissemination_probe_message_t* dpMsg =
(dissemination_probe_message_t*) payload;
+ if ( !m_running ) { return msg; }
+
if ( call DisseminationCache.requestSeqno[ dpMsg->key ]() !=
DISSEMINATION_SEQNO_UNKNOWN ) {
sendObject( dpMsg->key );
uint32_t seqno ) {}
default command uint32_t
- DisseminationCache.requestSeqno[uint16_t key]() { return 0; }
+ DisseminationCache.requestSeqno[uint16_t key]() { return DISSEMINATION_SEQNO_UNKNOWN; }
- default command error_t TrickleTimer.start[uint16_t key]() { return SUCCESS; }
+ default command error_t TrickleTimer.start[uint16_t key]() { return FAIL; }
default command void TrickleTimer.stop[uint16_t key]() { }
default command void TrickleTimer.reset[uint16_t key]() { }
default command void TrickleTimer.incrementCounter[uint16_t key]() { }
+
+ default command error_t DisseminatorControl.start[uint16_t id]() { return FAIL; }
+ default command error_t DisseminatorControl.stop[uint16_t id]() { return FAIL; }
}
*/
configuration DisseminationEngineP {
+ provides interface StdControl;
+
uses {
interface DisseminationCache[uint16_t key];
interface TrickleTimer[uint16_t key];
+ interface StdControl as DisseminatorControl[uint16_t id];
}
}
implementation {
components DisseminationEngineImplP;
+ StdControl = DisseminationEngineImplP;
DisseminationCache = DisseminationEngineImplP;
TrickleTimer = DisseminationEngineImplP;
-
- components MainC;
- DisseminationEngineImplP.Boot -> MainC;
-
- components ActiveMessageC;
- DisseminationEngineImplP.RadioControl -> ActiveMessageC;
+ DisseminatorControl = DisseminationEngineImplP;
components new AMSenderC(AM_DISSEMINATION_MESSAGE) as DisseminationSendC;
DisseminationEngineImplP.AMSend -> DisseminationSendC.AMSend;
*/
command const t* get();
+ /**
+ * Set the variable to a new value. The provider of this interface
+ * will copy the value from the pointer. NOTE: This command does
+ * not cause the new value to begin disseminating. It is intended to
+ * be used for setting default values.
+ */
+
+ command void set( const t* );
+
/**
* Signalled whenever variable may have changed.
*/
DisseminationValue = DisseminatorP;
DisseminationUpdate = DisseminatorP;
- components MainC;
- DisseminatorP.Boot -> MainC;
-
components DisseminationEngineP;
DisseminationEngineP.DisseminationCache[key] -> DisseminatorP;
+ DisseminationEngineP.DisseminatorControl[TIMER_ID] -> DisseminatorP;
components DisseminationTimerP;
DisseminationEngineP.TrickleTimer[key] ->
*/
generic module DisseminatorP(typedef t) {
+ provides interface StdControl;
+
provides interface DisseminationValue<t>;
provides interface DisseminationUpdate<t>;
provides interface DisseminationCache;
- uses interface Boot;
uses interface Leds;
}
implementation {
t valueCache;
+ bool m_running;
// A sequence number is 32 bits. The top 16 bits are an incrementing
// counter, while the bottom 16 bits are a unique node identifier.
uint32_t seqno = DISSEMINATION_SEQNO_UNKNOWN;
- event void Boot.booted() {
- signal DisseminationCache.init();
+ command error_t StdControl.start() {
+ error_t result = signal DisseminationCache.start();
+ if ( result == SUCCESS ) { m_running = TRUE; }
+ return result;
+ }
+
+ command error_t StdControl.stop() {
+ if ( !m_running ) { return EOFF; }
+ m_running = FALSE;
+ return signal DisseminationCache.stop();
}
command const t* DisseminationValue.get() {
return &valueCache;
}
+ command void DisseminationValue.set( const t* val ) {
+ valueCache = *val;
+ }
+
command void DisseminationUpdate.change( t* newVal ) {
+ if ( !m_running ) { return; }
memcpy( &valueCache, newVal, sizeof(t) );
/* Increment the counter and append the local node ID. */
seqno = seqno >> 16;