📄 mhenginem.nc
字号:
/*
* "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.
*/
/*
* A simple module that handles multihop packet movement. It accepts
* messages from both applications and the network and does the necessary
* interception and forwarding.
* It interfaces to an algorithmic componenet via RouteSelect. It also acts
* as a front end for RouteControl
*/
/*
* modified by: Geoff Martin
* date: 18/04/2004
*
* Note: In order to enable the code to record details about the operation of
* the protocol SIM must be defined. In addition the number of nodes
* must be assigned to SIM.
*/
includes AM;
includes MH;
#ifndef MHOP_QUEUE_SIZE
#define MHOP_QUEUE_SIZE 32
#endif
module MHEngineM
{
provides
{
interface StdControl;
interface Send[uint8_t id];
interface Intercept[uint8_t id];
}
uses
{
interface ReceiveMsg[uint8_t id];
interface SendMsg[uint8_t id];
interface RouteSelect;
interface StdControl as CommStdControl;
interface StdControl as QStdControl;
interface StdControl as PSMStdControl;
/* #ifdef SIM
interface Timer as SimTimer;
#endif
*/ interface Leds;
}
}
implementation
{
enum{ FWD_QUEUE_SIZE = MHOP_QUEUE_SIZE, // Forwarding Queue
EMPTY = 0xff };
/* Internal storage and scheduling state */
struct TOS_Msg FwdBuffers[FWD_QUEUE_SIZE];
struct TOS_Msg *FwdBufList[FWD_QUEUE_SIZE];
uint8_t iFwdBufHead, iFwdBufTail;
/***********************************************************************
* Simulation variables and methods
***********************************************************************/
/* #ifdef SIM
int sent, received, forwarded, usedBattery;
// Values to allow an approximation of used power. Transmit requires about 1/3 more power than receive
enum{RECEIVE = 2,TRANSMIT = 3};
// Allows the number of messages received at the base station to be tracked during simulation
typedef struct SimulationStats
{
uint32_t received;
uint32_t totalTime;
uint32_t totalHopTime;
uint32_t worstTime;
uint32_t worstHopTime;
uint32_t bestTime;
uint32_t bestHopTime;
} SimulationStats;
// Simulation statistics table
SimulationStats simStats[SIM];
// This method updates a nodes entry in the simulation statistics table
static void updateSimStats(uint16_t nodeID, uint32_t timeTaken, uint16_t hopCount)
{
uint32_t hopTime;
simStats[nodeID].received++;
// Avoids division by 0 and makes no difference to results
if (hopCount == 0)
{
hopCount++;
}
// Per hop time
hopTime = timeTaken / hopCount;
// Set worst and best time values when the first packet is received
if (simStats[nodeID].received == 1)
{
simStats[nodeID].worstTime = simStats[nodeID].bestTime = timeTaken;
simStats[nodeID].worstHopTime = simStats[nodeID].bestHopTime = hopTime;
}
// Add the time taken by the packet to the total time taken by all packets
simStats[nodeID].totalTime += timeTaken;
simStats[nodeID].totalHopTime += hopTime;
// If the time taken is the worst time so far
if (simStats[nodeID].worstTime < timeTaken)
{
simStats[nodeID].worstTime = timeTaken;
}
// If the time taken per hop is the worst time so far
if (simStats[nodeID].worstHopTime < hopTime)
{
simStats[nodeID].worstHopTime = hopTime;
}
// If the time taken is the best time so far
if (simStats[nodeID].bestTime > timeTaken)
{
simStats[nodeID].bestTime = timeTaken;
}
// If the time taken per hop is the best time so far
if (simStats[nodeID].bestHopTime > hopTime)
{
simStats[nodeID].bestHopTime = hopTime;
}
}
#endif
*/ /***********************************************************************
* Initialization
***********************************************************************/
static void initialize()
{
int n;
for (n=0; n < FWD_QUEUE_SIZE; n++)
{
FwdBufList[n] = &FwdBuffers[n];
}
iFwdBufHead = iFwdBufTail = 0;
}
/* #ifdef SIM
// Initialize the simulation stats table
static void initializeSimStats()
{
int i;
sent = received = forwarded = usedBattery = 0;
if (TOS_LOCAL_ADDRESS == 0)
{
for (i = 0; i < SIM; i++)
{
simStats[i].received = simStats[i].totalTime = simStats[i].worstTime;
simStats[i].bestTime = 0;
}
}
}
#endif
*/
command result_t StdControl.init()
{
initialize();
/* #ifdef SIM
initializeSimStats();
#endif
*/ call Leds.init();
call CommStdControl.init();
call QStdControl.init();
call PSMStdControl.init();
}
command result_t StdControl.start()
{
call CommStdControl.start();
call PSMStdControl.start();
/* #ifdef SIM
call SimTimer.start(TIMER_REPEAT, 1800000); // Display results after 30 mins
#endif
*/ return call QStdControl.start();
}
command result_t StdControl.stop()
{
call QStdControl.stop();
call PSMStdControl.stop();
/* #ifdef SIM
call SimTimer.stop();
#endif
*/ // XXX message doesn't get received if we stop then start radio
return call CommStdControl.stop();
}
/***********************************************************************
* Commands and events
***********************************************************************/
command result_t Send.send[uint8_t id](TOS_MsgPtr pMsg, uint16_t PayloadLen)
{
uint16_t usMHLength = offsetof(MHMessage,data) + PayloadLen;
if (usMHLength > TOSH_DATA_LENGTH)
{
dbg(DBG_TEMP, "MHEngineM - Sending of packet failed\n");
return FAIL;
}
call RouteSelect.initializeFields(pMsg,id);
if (call RouteSelect.selectRoute(pMsg,id) != SUCCESS)
{
dbg(DBG_TEMP, "MHEngineM - Sending of packet failed due to no route\n");
return FAIL;
}
if (call SendMsg.send[id](pMsg->addr, usMHLength, pMsg) != SUCCESS)
{
dbg(DBG_TEMP, "MHEngineM - Sending of packet failed\n");
return FAIL;
}
else
{
// Toggle red LED to indicate transmit (Tx)
atomic
{
call Leds.redToggle();
}
/* #ifdef SIM
sent++;
usedBattery+=TRANSMIT;
if (TOS_LOCAL_ADDRESS == 0)
{
MHMessage *pMH = (MHMessage *) pMsg->data;
TempMonMsg *pTM = (TempMonMsg *) pMH->data;
uint32_t timeTaken = call GlobalTime.getGlobalTime() - pTM->timestamp;
dbg(DBG_TEMP, "MHEngineM - Packet received at base station from node %i\n", pMH->originNode);
updateSimStats(pMH->originNode, timeTaken, pMH->hopCount);
}
#endif
*/ }
dbg(DBG_TEMP, "MHEngineM - Sending of packet successfull\n");
return SUCCESS;
}
command void *Send.getBuffer[uint8_t id](TOS_MsgPtr pMsg, uint16_t* length)
{
MHMessage *pMHMsg = (MHMessage *)pMsg->data;
*length = TOSH_DATA_LENGTH - offsetof(MHMessage,data);
return (&pMHMsg->data[0]);
}
static TOS_MsgPtr mForward(TOS_MsgPtr pMsg, uint8_t id)
{
TOS_MsgPtr pNewBuf = pMsg;
if (((iFwdBufHead + 1) % FWD_QUEUE_SIZE) == iFwdBufTail)
{
dbg(DBG_TEMP, "MHEngineM - Forwarding of packet failed\n");
return pNewBuf;
}
if ((call RouteSelect.selectRoute(pMsg,id)) != SUCCESS)
{
dbg(DBG_TEMP, "MHEngineM - Forwarding of packet failed due to no route\n");
return pNewBuf;
}
if (call SendMsg.send[id](pMsg->addr,pMsg->length,pMsg) == SUCCESS)
{
// Toggle red LED to indicate transmit (Tx)
atomic
{
call Leds.redToggle();
}
/* #ifdef SIM
if (TOS_LOCAL_ADDRESS == 0)
{
MHMessage *pMH = (MHMessage *) pMsg->data;
TempMonMsg *pTM = (TempMonMsg *) pMH->data;
uint32_t timeTaken = call GlobalTime.getGlobalTime() - pTM->timestamp;
dbg(DBG_TEMP, "MHEngineM - Packet received at base station from node %i\n", pMH->originNode);
updateSimStats(pMH->originNode, timeTaken, pMH->hopCount);
}
forwarded++;
usedBattery+=TRANSMIT;
#endif
*/ pNewBuf = FwdBufList[iFwdBufHead];
FwdBufList[iFwdBufHead] = pMsg;
iFwdBufHead++; iFwdBufHead %= FWD_QUEUE_SIZE;
}
dbg(DBG_TEMP, "MHEngineM - Forwarding of packet successfull\n");
return pNewBuf;
}
event TOS_MsgPtr ReceiveMsg.receive[uint8_t id](TOS_MsgPtr pMsg)
{
MHMessage *pMHMsg = (MHMessage *)pMsg->data;
uint16_t PayloadLen = pMsg->length - offsetof(MHMessage,data);
// Toggle red LED to indicate receive (Rx)
atomic
{
call Leds.redToggle();
}
// Ordinary message requiring forwarding
if (pMsg->addr == TOS_LOCAL_ADDRESS ||
pMsg->addr == TOS_BCAST_ADDR) // Addressed to local node or Broadcast address
{
if ((signal Intercept.intercept[id](pMsg,&pMHMsg->data[0],PayloadLen)) == SUCCESS)
{
pMsg = mForward(pMsg,id);
}
}
/* #ifdef SIM
received++;
usedBattery+=RECEIVE;
#endif
*/ return pMsg;
}
event result_t SendMsg.sendDone[uint8_t id](TOS_MsgPtr pMsg, result_t success)
{
if (pMsg == FwdBufList[iFwdBufTail]) // Msg was from forwarding queue
{
iFwdBufTail++;
iFwdBufTail %= FWD_QUEUE_SIZE;
}
else
{
signal Send.sendDone[id](pMsg, success);
}
return SUCCESS;
}
default event result_t Send.sendDone[uint8_t id](TOS_MsgPtr pMsg, result_t success)
{
return SUCCESS;
}
default event result_t Intercept.intercept[uint8_t id](TOS_MsgPtr pMsg, void* payload, uint16_t payloadLen)
{
return SUCCESS;
}
/* #ifdef SIM
// Print out simulator variables after 30 minutes
event result_t SimTimer.fired()
{
int i;
dbg(DBG_USR1, "Sent: %i, Received: %i, Forwarded: %i, Used Power: %i\n", sent, received, forwarded,
usedBattery);
if (TOS_LOCAL_ADDRESS == 0)
{
atomic
{
dbg(DBG_USR1, "Node\tReceived\tBest\tHop Best\tWorst\tHop Worst\tAverage\tHop Average\n");
for (i = 0; i < SIM; i++)
{
uint32_t average, hopAverage, recCount;
recCount = simStats[i].received;
// Makes no difference but avoids division by 0
if (recCount == 0)
{
recCount++;
}
average = simStats[i].totalTime / recCount;
hopAverage = simStats[i].totalHopTime / recCount;
dbg(DBG_USR1, "%i\t%i\t%i\t%i\t%i\t%i\t%i\t%i\n", i, simStats[i].received,
simStats[i].bestTime, simStats[i].bestHopTime, simStats[i].worstTime, simStats[i].worstHopTime, average,
hopAverage);
}
}
}
return SUCCESS;
}
#endif
*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -