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

📄 pollp.nc

📁 tinyos-2.x.rar
💻 NC
字号:
/*
 * Copyright (c) 2008, Technische Universitaet Berlin
 * 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 Technische Universitaet Berlin 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 COPYRIGHT 
 * OWNER OR 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.
 *
 * - Revision -------------------------------------------------------------
 * $Revision: 1.3 $
 * $Date: 2009/03/04 18:31:26 $
 * @author Jan Hauer <hauer@tkn.tu-berlin.de>
 * ========================================================================
 */


#include "TKN154_MAC.h"

module PollP
{
  provides
  {
    interface Init;
    interface MLME_POLL;
    interface FrameRx as DataRx;
    interface DataRequest as DataRequest[uint8_t client];
  }
  uses
  {
    interface FrameTx as PollTx;
    interface FrameExtracted as DataExtracted;
    interface FrameUtility;
    interface Pool<ieee154_txframe_t> as TxFramePool;
    interface Pool<ieee154_txcontrol_t> as TxControlPool;
    interface MLME_GET;
    interface Get<uint64_t> as LocalExtendedAddress;
  }
}
implementation
{
  enum {
    HANDLE_MLME_POLL_REQUEST = 0xFF,
    HANDLE_MLME_POLL_SUCCESS = 0xFE,
  };
  int m_numPending;
  uint8_t m_dataRequestCmdID = CMD_FRAME_DATA_REQUEST;
  void buildDataRequestFrame( uint8_t destAddrMode, uint16_t destPANId,
      uint8_t* DstAddr, uint8_t srcAddrMode, ieee154_txframe_t *txFrame);

  command error_t Init.init()
  {
    m_numPending = 0;
    return SUCCESS;
  }

  command ieee154_status_t MLME_POLL.request  (
                          uint8_t coordAddrMode,
                          uint16_t coordPANID,
                          ieee154_address_t coordAddress,
                          ieee154_security_t *security)
  {
    ieee154_txframe_t *txFrame;
    ieee154_txcontrol_t *txControl;
    uint8_t srcAddrMode = 2;
    ieee154_status_t status = IEEE154_SUCCESS;
    uint8_t coordAddressLE[8]; // little endian is what we want

    if (security && security->SecurityLevel)
      status = IEEE154_UNSUPPORTED_SECURITY;
    else if (coordAddrMode < 2 || coordAddrMode > 3 || coordPANID == 0xFFFF)
      status = IEEE154_INVALID_PARAMETER; 
    else if (!(txFrame = call TxFramePool.get()))
      // none of the predefined return value really fits
      status = IEEE154_TRANSACTION_OVERFLOW; 
    else if (!(txControl = call TxControlPool.get())) {
      call TxFramePool.put(txFrame);
      status = IEEE154_TRANSACTION_OVERFLOW;
    } else {
      txFrame->header = &txControl->header;
      txFrame->metadata = &txControl->metadata;
      if (coordAddrMode == ADDR_MODE_SHORT_ADDRESS)
        *((nxle_uint16_t*) &coordAddressLE) = coordAddress.shortAddress;
      else 
        call FrameUtility.convertToLE(coordAddressLE, &coordAddress.extendedAddress);
      txFrame->handle = HANDLE_MLME_POLL_REQUEST;
      if (call MLME_GET.macShortAddress() >= 0xFFFE)
        srcAddrMode = 3;
      buildDataRequestFrame(coordAddrMode, coordPANID, coordAddressLE, srcAddrMode, txFrame);
      if ((status = call PollTx.transmit(txFrame)) != IEEE154_SUCCESS) {
        call TxFramePool.put(txFrame);
        call TxControlPool.put(txControl);
        status = IEEE154_TRANSACTION_OVERFLOW;
      } else 
        m_numPending++;
    }

    dbg_serial("PollP", "MLME_POLL.request -> result: %lu\n", (uint32_t) status);
    return status;
  }

  command ieee154_status_t DataRequest.poll[uint8_t client](uint8_t CoordAddrMode, 
      uint16_t CoordPANId, uint8_t *CoordAddressLE, uint8_t srcAddrMode)
  {
    ieee154_txframe_t *txFrame;
    ieee154_txcontrol_t *txControl;
    ieee154_status_t status = IEEE154_TRANSACTION_OVERFLOW;

    dbg_serial("PollP", "InternalPoll\n");
    if (client == SYNC_POLL_CLIENT && m_numPending != 0) {
      // no point in auto-requesting if user request is pending
      signal DataRequest.pollDone[client]();
      return IEEE154_SUCCESS;
    } else if ((txFrame = call TxFramePool.get())) {
      if (!(txControl = call TxControlPool.get()))
        call TxFramePool.put(txFrame);
      else {
        txFrame->header = &txControl->header;
        txFrame->metadata = &txControl->metadata;
        txFrame->handle = client;
        buildDataRequestFrame(CoordAddrMode, CoordPANId, 
            CoordAddressLE, srcAddrMode, txFrame);
        if ((status = call PollTx.transmit(txFrame)) != IEEE154_SUCCESS) {
          call TxControlPool.put(txControl);
          call TxFramePool.put(txFrame);
          dbg_serial("PollP", "Overflow\n");
        } else 
          m_numPending++;
      }
    }
    if (status != IEEE154_SUCCESS)
      signal DataRequest.pollDone[client]();
    return status;
  }

  void buildDataRequestFrame(uint8_t destAddrMode, uint16_t destPANId,
      uint8_t* destAddrPtrLE, uint8_t srcAddrMode, ieee154_txframe_t *txFrame)
  {
    // destAddrPtrLE points to an address in little-endian format !
    ieee154_address_t srcAddress;
    uint8_t *mhr;
    uint16_t srcPANId;
    ieee154_address_t DstAddr;
    srcPANId = call MLME_GET.macPANId();

    memcpy(&DstAddr, destAddrPtrLE, destAddrMode == 2 ? 2 : 8);
    mhr = txFrame->header->mhr;
    mhr[MHR_INDEX_FC1] = FC1_FRAMETYPE_CMD | FC1_ACK_REQUEST;
    if (destAddrMode >= 2 && srcAddrMode >= 2 && destPANId == srcPANId)
      mhr[MHR_INDEX_FC1] |= FC1_PAN_ID_COMPRESSION;
    mhr[MHR_INDEX_FC2] = destAddrMode << FC2_DEST_MODE_OFFSET;
    mhr[MHR_INDEX_FC2] |= srcAddrMode << FC2_SRC_MODE_OFFSET;
    if (srcAddrMode == 2)
      srcAddress.shortAddress = call MLME_GET.macShortAddress();
    else  
      srcAddress.extendedAddress = call LocalExtendedAddress.get();
    txFrame->headerLen = call FrameUtility.writeHeader(
          txFrame->header->mhr,
          destAddrMode,
          destPANId,
          &DstAddr,
          srcAddrMode,
          srcPANId,
          &srcAddress,
          (mhr[MHR_INDEX_FC1] & FC1_PAN_ID_COMPRESSION) ? TRUE: FALSE);
    txFrame->payload = &m_dataRequestCmdID;
    txFrame->payloadLen = 1;
  }

  event message_t* DataExtracted.received(message_t* frame, ieee154_txframe_t *txFrame)
  {
    if (!txFrame) {
      dbg_serial("PollP", "Internal error\n");
      return frame;
    } else
      dbg_serial("PollP", "Extracted data successfully\n");
    if (txFrame->handle == HANDLE_MLME_POLL_REQUEST)
      signal MLME_POLL.confirm(IEEE154_SUCCESS);
    else
      signal DataRequest.pollDone[txFrame->handle]();
    txFrame->handle = HANDLE_MLME_POLL_SUCCESS; // mark as processed
    // TODO: check if pending bit is set (then initiate another POLL)
    return signal DataRx.received(frame);
  }

  event void PollTx.transmitDone(ieee154_txframe_t *txFrame, ieee154_status_t status)
  {
    dbg_serial("PollP", "transmitDone()\n");
    m_numPending--;
    if (txFrame->handle != HANDLE_MLME_POLL_SUCCESS) {
      // didn't receive a DATA frame from the coordinator
      if (status == IEEE154_SUCCESS) // TODO: can this happen if a frame other than DATA was extracted?
        status = IEEE154_NO_DATA;
      if (txFrame->handle == HANDLE_MLME_POLL_REQUEST)
        signal MLME_POLL.confirm(status);
      else
        signal DataRequest.pollDone[txFrame->handle]();
    }
    call TxControlPool.put((ieee154_txcontrol_t*) ((uint8_t*) txFrame->header - offsetof(ieee154_txcontrol_t, header)));
    call TxFramePool.put(txFrame);
  }
  default event void MLME_POLL.confirm(ieee154_status_t status) {}
  default event void DataRequest.pollDone[uint8_t client]() {}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -