📄 disseminationengineimplp.nc
字号:
#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 DisseminationEngineImplP component implements the dissemination * logic. * * See TEP118 - Dissemination for details. * * @author Gilman Tolle <gtolle@archrock.com> * @version $Revision: 1.1 $ $Date: 2007/09/14 00:22:18 $ */module DisseminationEngineImplP { provides interface StdControl; uses { interface DisseminationCache[uint16_t key]; interface TrickleTimer[uint16_t key]; interface StdControl as DisseminatorControl[uint16_t id]; interface AMSend; interface Receive; interface AMSend as ProbeAMSend; interface Receive as ProbeReceive; interface Leds; }}implementation { enum { NUM_DISSEMINATORS = uniqueCount("DisseminationTimerC.TrickleTimer") }; message_t m_buf; bool m_running; bool m_bufBusy; void sendProbe( uint16_t key ); void sendObject( uint16_t key ); command error_t StdControl.start() { uint8_t i; for ( i = 0; i < NUM_DISSEMINATORS; i++ ) { call DisseminatorControl.start[ i ](); } m_running = TRUE; return SUCCESS; } 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 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_running || m_bufBusy ) { return; } sendObject( key ); } void sendProbe( uint16_t key ) { dissemination_probe_message_t* dpMsg = (dissemination_probe_message_t*) call ProbeAMSend.getPayload( &m_buf, sizeof(dissemination_probe_message_t)); if (dpMsg != NULL) { m_bufBusy = TRUE; dpMsg->key = key; call ProbeAMSend.send( AM_BROADCAST_ADDR, &m_buf, sizeof( dissemination_probe_message_t ) ); } } void sendObject( uint16_t key ) { void* object; uint8_t objectSize = 0; dissemination_message_t* dMsg = (dissemination_message_t*) call AMSend.getPayload( &m_buf, sizeof(dissemination_message_t) ); if (dMsg != NULL) { m_bufBusy = TRUE; dMsg->key = key; dMsg->seqno = call DisseminationCache.requestSeqno[ key ](); if ( dMsg->seqno != DISSEMINATION_SEQNO_UNKNOWN ) { object = call DisseminationCache.requestData[ key ]( &objectSize ); if ((objectSize + sizeof(dissemination_message_t)) > call AMSend.maxPayloadLength()) { objectSize = call AMSend.maxPayloadLength() - sizeof(dissemination_message_t); } memcpy( dMsg->data, object, objectSize ); } call AMSend.send( AM_BROADCAST_ADDR, &m_buf, sizeof( dissemination_message_t ) + objectSize ); } } event void ProbeAMSend.sendDone( message_t* msg, error_t error ) { m_bufBusy = FALSE; } event void AMSend.sendDone( message_t* msg, error_t error ) { m_bufBusy = FALSE; } event message_t* Receive.receive( message_t* msg, void* payload, uint8_t len ) { dissemination_message_t* dMsg = (dissemination_message_t*) payload; uint16_t key = dMsg->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 ) { call DisseminationCache.storeData[ key ] ( dMsg->data, len - sizeof( dissemination_message_t ), incomingSeqno ); call TrickleTimer.reset[ key ](); return msg; } if ( incomingSeqno == DISSEMINATION_SEQNO_UNKNOWN && currentSeqno != DISSEMINATION_SEQNO_UNKNOWN ) { call TrickleTimer.reset[ key ](); return msg; } if ( (int32_t)( incomingSeqno - currentSeqno ) > 0 ) { call DisseminationCache.storeData[key] ( dMsg->data, len - sizeof(dissemination_message_t), incomingSeqno ); dbg("Dissemination", "Received dissemination value 0x%08x,0x%08x @ %s\n", (int)key, (int)incomingSeqno, sim_time_string()); call TrickleTimer.reset[ key ](); } else if ( (int32_t)( incomingSeqno - currentSeqno ) == 0 ) { call TrickleTimer.incrementCounter[ key ](); } else { // Still not sure which of these is the best. Immediate send for now. sendObject( key ); // call TrickleTimer.reset[ key ](); } return msg; } event message_t* ProbeReceive.receive( message_t* msg, void* payload, uint8_t len) { 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 ); } return msg; } default command void* DisseminationCache.requestData[uint16_t key]( uint8_t* size ) { return NULL; } default command void DisseminationCache.storeData[uint16_t key]( void* data, uint8_t size, uint32_t seqno ) {} default command uint32_t DisseminationCache.requestSeqno[uint16_t key]() { return DISSEMINATION_SEQNO_UNKNOWN; } 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; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -