⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mhleachpsm.nc

📁 Tinyos LEACH protocol modify
💻 NC
📖 第 1 页 / 共 2 页
字号:
  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 + -