📄 mhleachpsm.nc
字号:
static void nextRound()
{
round = (round + 1) % ROUND_INVALID;
}
// As round lengths are long accept r as new round if it isn't the current round or previous round
static bool isNewRound(uint8_t r)
{
// Node is advertising invalid round
if (r == ROUND_INVALID)
{
return FALSE;
}
// This node hasn't got a valid round yet
else if (round == ROUND_INVALID)
{
return TRUE;
}
else
{
uint8_t previous;
if (round == 0)
{
previous = ROUND_INVALID - 1;
}
else
{
previous = round-1;
}
if ((r != round) && (r != previous))
{
return TRUE;
}
else
{
return FALSE;
}
}
}
/*---------------------------------------------------------------------
* Route advertisement
*---------------------------------------------------------------------*/
task void advertise()
{
RoutePacket *pRP = (RoutePacket *) &routeMsg.data[0];
uint8_t length = sizeof(RoutePacket);
// If busy sending don't send again
if (sendRouteBusy == TRUE)
{
return;
}
pRP->addr = addr;
atomic addr = TOS_BCAST_ADDR;
pRP->nodeID = TOS_LOCAL_ADDRESS;
pRP->depth = depth;
pRP->round = round;
pRP->isClusterHead = isClusterHead;
// Set fields for forwarding request
if (pRP->addr != TOS_BCAST_ADDR)
{
dbg(DBG_TEMP, "MHLeachPSM - Requesting node %i become a cluster head\n", pRP->addr);
pRP->becomeClusterHead = TRUE;
}
else
{
pRP->becomeClusterHead = FALSE;
}
// Send message
if (call SendMsg.send(TOS_BCAST_ADDR, length, &routeMsg) == SUCCESS)
{
// Toggle red LED to indicate transmit (Tx)
atomic
{
call Leds.redToggle();
}
dbg(DBG_TEMP, "MHLeachPSM - Advertising presence (Cluster Head: %i)\n", (int) isClusterHead);
atomic sendRouteBusy = TRUE;
}
}
/*---------------------------------------------------------------------
* Initialisation and code to start a new round
*---------------------------------------------------------------------*/
static void init()
{
tableEntries = 0;
ticks = 0;
addr = TOS_BCAST_ADDR; // Normal route packet - no forwarding request
if (TOS_LOCAL_ADDRESS == BASE_STATION_ADDRESS)
{
round = 0;
parentID = TOS_UART_ADDR;
isClusterHead = TRUE;
depth = 0;
}
else
{
round = ROUND_INVALID;
parentID = PARENT_INVALID;
isClusterHead = FALSE;
depth = INFINITY;
}
}
// Start new round
static void startNewRound(uint8_t r)
{
// Decide on cluster had status
uint16_t probability = ((uint16_t) PROBABILITY) * (0xffff / 100);
uint16_t randNo = call Random.rand();
bool clusterStatus = randNo < probability;
dbg(DBG_TEMP, "MHLeachPSM - Round %i started (Cluster Head: %i)\n", r, (int) clusterStatus);
atomic
{
round = r;
ticks = 0;
tableEntries = 0;
parentID = PARENT_INVALID;
depth = INFINITY;
addr = TOS_BCAST_ADDR;
isClusterHead = clusterStatus;
}
}
/*---------------------------------------------------------------------
* Provided Interface Commands
*---------------------------------------------------------------------*/
/*
* StdControl
*/
command result_t StdControl.init()
{
init();
return call Random.init();
}
command result_t StdControl.start()
{
// Start round timer on base station
if (TOS_LOCAL_ADDRESS == BASE_STATION_ADDRESS)
{
call RoundTimer.start(TIMER_REPEAT, ROUND_LENGTH);
}
return call StatusTimer.start(TIMER_REPEAT, ROUTE_UPDATE_RATE);
}
command result_t StdControl.stop()
{
call RoundTimer.stop();
return call StatusTimer.stop();
}
/*
* RouteSelect
*/
// If parent is valid a route exists
command bool RouteSelect.isActive()
{
if (parentID != PARENT_INVALID)
{
return TRUE;
}
return FALSE;
}
// Select route
command result_t RouteSelect.selectRoute(TOS_MsgPtr msg, uint8_t id)
{
MHMessage *pMHMsg = (MHMessage *) &msg->data[0];
// If packet has been generated by local node
if ((pMHMsg->originNode == TOS_LOCAL_ADDRESS) &&
(pMHMsg->hopCount == 0))
{
if (parentID != PARENT_INVALID)
{
dbg(DBG_TEMP, "MHLeachPSM - Routing to node %i\n", parentID);
msg->addr = parentID;
return SUCCESS;
}
}
else
{
// Set fields for forwarding if node is a cluster head
if ((isClusterHead == TRUE) && (parentID != PARENT_INVALID))
{
pMHMsg->sendingNode = TOS_LOCAL_ADDRESS;
pMHMsg->hopCount++;
dbg(DBG_TEMP, "MHLeachPSM - Routing to node %i\n", parentID);
msg->addr = parentID;
return SUCCESS;
}
dbg(DBG_TEMP, "MHLeachPSM - Could not select route\n");
return FAIL;
}
}
// Initilise routing fields for new packet
command result_t RouteSelect.initializeFields(TOS_MsgPtr msg, uint8_t id)
{
MHMessage *pMHMsg = (MHMessage *) &msg->data[0];
pMHMsg->originNode = pMHMsg->sendingNode = TOS_LOCAL_ADDRESS;
pMHMsg->hopCount = 0;
return SUCCESS;
}
/*---------------------------------------------------------------------
* Used Interface Events
*---------------------------------------------------------------------*/
// Event fires when base station is to change round
event result_t RoundTimer.fired()
{
dbg(DBG_TEMP, "MHLeachPSM - Round Timer fired\n");
nextRound();
return SUCCESS;
}
// Event fires to indicate that node must advertise presence
event result_t StatusTimer.fired()
{
if ((TOS_LOCAL_ADDRESS != BASE_STATION_ADDRESS) && (round != ROUND_INVALID))
{
updateTable();
selectParent();
}
post advertise();
return SUCCESS;
}
// Event fires when message is received
event TOS_MsgPtr ReceiveMsg.receive(TOS_MsgPtr m)
{
// Toggle red LED to indicate receive (Rx)
atomic
{
call Leds.redToggle();
}
// Base station doesn't need to know about any other node
if (TOS_LOCAL_ADDRESS != BASE_STATION_ADDRESS)
{
RoutePacket *pRP = (RoutePacket *) m->data;
// Ignore messages when round is invalid
if (pRP->round != ROUND_INVALID)
{
// Start new round if its a new round
if (isNewRound(pRP->round) == TRUE)
{
startNewRound(pRP->round);
}
// If the packet is a forwarding request for this node
else if (pRP->addr == TOS_LOCAL_ADDRESS)
{
isClusterHead = pRP->becomeClusterHead;
if (pRP->becomeClusterHead == TRUE)
{
dbg(DBG_TEMP, "MHLeachPSM - Becoming cluster head at request of node %i\n",
pRP->nodeID);
}
}
dbg(DBG_TEMP, "MHLeachPSM - Received advert (Origin ID: %i, Cluster Head: %i,Depth: %i)\n",
pRP->nodeID, (int) pRP->isClusterHead, pRP->depth);
updateTableEntry(pRP->nodeID, pRP->depth, pRP->isClusterHead, m->strength);
}
}
return m;
}
// Event fires when sending is done
event result_t SendMsg.sendDone(TOS_MsgPtr msg, result_t success)
{
atomic sendRouteBusy = FALSE;
return SUCCESS;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -