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

📄 framerm.nc.svn-base

📁 802.15.4协议的实现
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
// $Id: FramerM.nc,v 1.2.2.1 2004/07/14 19:00:38 kristinwright Exp $

/* -*- Mode: C; c-basic-indent: 2; indent-tabs-mode: nil -*- */ 
/*									
 *  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.  By
 *  downloading, copying, installing or using the software you agree to
 *  this license.  If you do not agree to this license, do not download,
 *  install, copy or use the software.
 *
 *  Intel Open Source License 
 *
 *  Copyright (c) 2002 Intel 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 Intel 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 INTEL 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.
 * 
 * Author: Phil Buonadonna
 * Revision: $Revision: 1.2.2.1 $
 * 
 */

/*
 * FramerM
 * 
 * This modules provides framing for TOS_Msg's using PPP-HDLC-like framing 
 * (see RFC 1662).  When sending, a TOS_Msg is encapsulated in an HLDC frame.
 * Receiving is similar EXCEPT that the component expects a special token byte
 * be received before the data payload. The purpose of the token is to feed back
 * an acknowledgement to the sender which serves as a crude form of flow-control.
 * This module is intended for use with the Packetizer class found in
 * tools/java/net/packet/Packetizer.java.
 * 
 */

/**
 * @author Phil Buonadonna
 */


includes AM;
includes crc;

module FramerM {

  provides {
    interface StdControl;
    interface TokenReceiveMsg;
    interface ReceiveMsg;
    interface BareSendMsg;
  }

  uses {
    interface ByteComm;
    interface StdControl as ByteControl;
  }
}

implementation {

  enum {
    HDLC_QUEUESIZE	   = 2,
    HDLC_MTU		   = (sizeof(TOS_Msg)),
    HDLC_FLAG_BYTE	   = 0x7e,
    HDLC_CTLESC_BYTE	   = 0x7d,
    PROTO_ACK              = 64,
    PROTO_PACKET_ACK       = 65,
    PROTO_PACKET_NOACK     = 66,
    PROTO_UNKNOWN          = 255
  };

  enum {
    RXSTATE_NOSYNC,
    RXSTATE_PROTO,
    RXSTATE_TOKEN,
    RXSTATE_INFO,
    RXSTATE_ESC
  };

  enum {
    TXSTATE_IDLE,
    TXSTATE_PROTO,
    TXSTATE_INFO,
    TXSTATE_ESC,
    TXSTATE_FCS1,
    TXSTATE_FCS2,
    TXSTATE_ENDFLAG,
    TXSTATE_FINISH,
    TXSTATE_ERROR
  };

  enum {
    FLAGS_TOKENPEND = 0x2,
    FLAGS_DATAPEND  = 0x4,
    FLAGS_UNKNOWN   = 0x8
  };

  TOS_Msg gMsgRcvBuf[HDLC_QUEUESIZE];

  typedef struct _MsgRcvEntry {
    uint8_t Proto;
    uint8_t Token;	// Used for sending acknowledgements
    uint16_t Length;	// Does not include 'Proto' or 'Token' fields
    TOS_MsgPtr pMsg;
  } MsgRcvEntry_t ;

  MsgRcvEntry_t gMsgRcvTbl[HDLC_QUEUESIZE];

  uint8_t * gpRxBuf;    
  uint8_t * gpTxBuf;

  uint8_t  gFlags;

  // Flags variable protects atomicity
  norace uint8_t  gTxState;
  norace uint8_t  gPrevTxState;
  norace uint8_t  gTxProto;
  norace uint16_t gTxByteCnt;
  norace uint16_t gTxLength;
  norace uint16_t gTxRunningCRC;


  uint8_t  gRxState;
  uint8_t  gRxHeadIndex;
  uint8_t  gRxTailIndex;
  uint16_t gRxByteCnt;
  
  uint16_t gRxRunningCRC;
  
  MyTOS_MsgPtr MygpTxMsg;
  
  TOS_MsgPtr gpTxMsg;
  uint8_t gTxTokenBuf;
  uint8_t gTxUnknownBuf;
  norace uint8_t gTxEscByte;
  
  task void MyPacketSent();
  task void PacketSent();
  

uint8_t  fRemapRxPos( uint8_t InPos ); //remap standard TOSMessage fields to CC2420TOSMsg

//*************************************************************************
/*
fRemapRxPos
Map incomming byte positions into new TOSmessage structure
 Does NOT handle CRC bytes correctly
*/
uint8_t  fRemapRxPos( uint8_t InPos ) {

	if( InPos<4 )
		return( InPos+offsetof(struct TOS_Msg, addr) );	//addr,AM,groupid
	else if( InPos==4 )
		return( offsetof(struct TOS_Msg, length) ); //length
	else return( offsetof(struct TOS_Msg, data) ); //data and subsequent
}//fRemapRxByte


  result_t StartTx() {
    result_t Result = SUCCESS;
    bool fInitiate = FALSE;

    atomic {
      if (gTxState == TXSTATE_IDLE) {
        if (gFlags & FLAGS_TOKENPEND) {
          gpTxBuf = (uint8_t *)&gTxTokenBuf;
          gTxProto = PROTO_ACK;
          gTxLength = sizeof(gTxTokenBuf);
          fInitiate = TRUE;
          gTxState = TXSTATE_PROTO;
        }
        else if (gFlags & FLAGS_DATAPEND) {
          gpTxBuf = (uint8_t *)gpTxMsg;
          gTxProto = PROTO_PACKET_NOACK;
//           gTxLength = gpTxMsg->length + (MSG_DATA_SIZE - DATA_LENGTH - 2);
		//number of bytes to xfer = TOSHeader + data + 2CRC bytes
          gTxLength = gpTxMsg->length + TOS_HEADER_SIZE + 2+3;
          fInitiate = TRUE;
          gTxState = TXSTATE_PROTO;
        }
        else if (gFlags & FLAGS_UNKNOWN) {
          gpTxBuf = (uint8_t *)&gTxUnknownBuf;
          gTxProto = PROTO_UNKNOWN;
          gTxLength = sizeof(gTxUnknownBuf);
          fInitiate = TRUE;
          gTxState = TXSTATE_PROTO;
        }
      }
    }
    
    if (fInitiate) {
      atomic {
        gTxRunningCRC = 0;	 //initialize CRC calculation
        // gTxByteCnt = 6;	 //start at addr in tosmsg
		gTxByteCnt = offsetof(struct TOS_Msg, addr); //start at TOSaddr field
      }
      Result = call ByteComm.txByte(HDLC_FLAG_BYTE);
      if (Result != SUCCESS) {
        atomic gTxState = TXSTATE_ERROR;
        post PacketSent();
      }
    }
    
    return Result;
  } 
  
  /**********************************************************************/  
/**********************************************************************/
/**********************************************************************/
result_t MyStartTx() {
    result_t Result = SUCCESS;
    bool fInitiate = FALSE;

    atomic {
      if (gTxState == TXSTATE_IDLE) {
        if (gFlags & FLAGS_TOKENPEND) {
          gpTxBuf = (uint8_t *)&gTxTokenBuf;
          gTxProto = PROTO_ACK;
          gTxLength = sizeof(gTxTokenBuf);
          fInitiate = TRUE;
          gTxState = TXSTATE_PROTO;
        }
        else if (gFlags & FLAGS_DATAPEND) {
          gpTxBuf = (uint8_t *)gpTxMsg;
          gTxProto = PROTO_PACKET_NOACK;
//           gTxLength = gpTxMsg->length + (MSG_DATA_SIZE - DATA_LENGTH - 2);
		//number of bytes to xfer = TOSHeader + data + 2CRC bytes
          gTxLength = MygpTxMsg->length + TOS_HEADER_SIZE + 2+3;
          fInitiate = TRUE;
          gTxState = TXSTATE_PROTO;
        }
        else if (gFlags & FLAGS_UNKNOWN) {
          gpTxBuf = (uint8_t *)&gTxUnknownBuf;
          gTxProto = PROTO_UNKNOWN;
          gTxLength = sizeof(gTxUnknownBuf);
          fInitiate = TRUE;
          gTxState = TXSTATE_PROTO;
        }
      }
    }
    
    if (fInitiate) {
      atomic {
        gTxRunningCRC = 0;	 //initialize CRC calculation
        // gTxByteCnt = 6;	 //start at addr in tosmsg
		gTxByteCnt = offsetof(struct MyTOS_Msg, addr); //start at TOSaddr field
      }
      Result = call ByteComm.txByte(HDLC_FLAG_BYTE);
      if (Result != SUCCESS) {
        atomic gTxState = TXSTATE_ERROR;
        post MyPacketSent();
      }
    }
    
    return Result;
  }
     
  /**************************************************************/
/**************************************************************/
/**************************************************************/
/**************************************************************/
task void MyPacketSent() {
    result_t TxResult = SUCCESS;

    atomic {
      if (gTxState == TXSTATE_ERROR) {
	TxResult = FAIL;
        gTxState = TXSTATE_IDLE;
      }
    }
    if (gTxProto == PROTO_ACK) {
      atomic gFlags ^= FLAGS_TOKENPEND;
    }
    else{
      atomic gFlags ^= FLAGS_DATAPEND;
      signal BareSendMsg.MysendDone((MyTOS_MsgPtr)MygpTxMsg,TxResult);
      atomic MygpTxMsg = NULL;
    }

    // Trigger transmission in case something else is pending
    MyStartTx();
 }

  
  
  task void PacketUnknown() {
    atomic {
      gFlags |= FLAGS_UNKNOWN;
    }
    
    StartTx();
  }

  task void PacketRcvd() {
    MsgRcvEntry_t *pRcv = &gMsgRcvTbl[gRxTailIndex];
    TOS_MsgPtr pBuf = pRcv->pMsg;

    // Does the rcvd frame actually have a meaningful message??
    if (pRcv->Length >= offsetof(struct TOS_Msg,data)) {

      switch (pRcv->Proto) {
		case PROTO_ACK:
			break;
		case PROTO_PACKET_ACK:
			pBuf->crc = 1;  // Easier to set here... 
			pBuf = signal TokenReceiveMsg.receive(pBuf,pRcv->Token);
			break;
		case PROTO_PACKET_NOACK:
			pBuf->crc = 1;
			pBuf = signal ReceiveMsg.receive(pBuf);
			break;
		default:
			gTxUnknownBuf = pRcv->Proto;
			post PacketUnknown();
			break;
		}  //switch
    } //if

    atomic {
      if (pBuf) {
	pRcv->pMsg = pBuf;
      }
      pRcv->Length = 0; 
      pRcv->Token = 0; 
      gRxTailIndex++;
      gRxTailIndex %= HDLC_QUEUESIZE;
    }
  }

  task void PacketSent() {
    result_t TxResult = SUCCESS;

    atomic {
      if (gTxState == TXSTATE_ERROR) {

⌨️ 快捷键说明

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