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

📄 aps.c

📁 ucos在NEC平台下的移植
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
* "Copyright (c) 2006 Robert B. Reese ("AUTHOR")"
* All rights reserved.
* (R. Reese, reese@ece.msstate.edu, Mississippi State University)
* IN NO EVENT SHALL THE "AUTHOR" 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 "AUTHOR"
* HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE "AUTHOR" 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 "AUTHOR" HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
*
* This file makes use of Zigbee Alliance intellectual property in the
* form of frame formats as specified in the Zigbee 1.0 standard.
* The author consulted the
* Zigbee standard when writing this file, and agreed to the terms
* of conditions by the Zibee Alliance when downloading the standard.
* As such, use of this file is governed by the Zigbee Trademarks,
* Designations, and Logos policy. A paraphrase of this policy is
* that free usage is granted for research, educational or personal
* use. Commercial usage is restricted, see the policy for details.
*
* Please maintain this header in its entirety when copying/modifying
* these files.
*
* Files in this software distribution may have different usage
* permissions, see the header in each file. Some files have NO permission
* headers since parts of the original sources in these files
* came from vendor  sources with no usage restrictions.
*
*/

/*
V0.2 added PC-based binding         21/July/2006  RBR
V0.1 Initial Release                10/July/2006  RBR

*/



/*
APS Layer


*/

#include "compiler.h"
#include "lrwpan_config.h"         //user configurations
#include "lrwpan_common_types.h"   //types common acrosss most files
#include "ieee_lrwpan_defs.h"
#include "console.h"
#include "debug.h"
#include "memalloc.h"
#include "neighbor.h"
#include "hal.h"
#include "halStack.h"
//#include "phy.h"
//#include "mac.h"
//#include "nwk.h"
//#include "zep.h"
#include "aps.h"
#include "evboard.h"

#include "aps_headers.h"


#define apsTXIdle() (!aps_pib.flags.bits.TxInProgress)
#define apsTXBusy() (aps_pib.flags.bits.TxInProgress)
#define apsSetTxBusy() aps_pib.flags.bits.TxInProgress = 1
#define apsSetTxIdle() aps_pib.flags.bits.TxInProgress = 0
 APS_RX_DATA  globalApsRxData;

typedef enum _APS_RXSTATE_ENUM {
	APS_RXSTATE_IDLE,
	APS_RXSTATE_START,
	APS_RXSTATE_RESOLVE_INDIRECT,
	APS_RXSTATE_ACK_SEND_WAIT
} APS_RXSTATE_ENUM;



//APS_PIB aps_pib;
//APS_SERVICE a_aps_service;
//APS_STATE_ENUM apsState;
//APS_EP_ELEM apsEndPoints[LRWPAN_MAX_ENDPOINTS];
//
////there can only be one TX in progress at a time, so
////a_aps_tx_data contains the arguments for that TX on the APS layer.
//APS_TX_DATA a_aps_tx_data;
//APS_RX_DATA a_aps_rx_data;
//APS_RX_DATA indirect_data;  //used for holding an indirect packet while being reflected. --li

void apsFSM(void);
void apsTxData(BOOL copy_payload);

//locals
static APS_RXSTATE_ENUM apsRxState;
static LRWPAN_STATUS_ENUM apsTxFSM_status;

static void apsParseHdr(BYTE *ptr);
static void apsRxFSM(void);
static BOOL apsCheckAck(void);
static void apsFormatAck(void);
static void apsTxFSM(void);
static void apsInjectPacket(BOOL indirect_flag);
static void apsInjectTxPacket(void);

#ifdef LRWPAN_COORDINATOR
void apsRxBuffInit(void);
BOOL apsRxBuffFull(void);
BOOL apsRxBuffEmpty(void);
APS_RX_DATA *apsGetRxPacket(void);
void apsFreeRxPacket(BOOL freemem);
void apsRxBuffAdd (APS_RX_DATA *ptr);

#endif

//converts MAC TICKs to Microseconds
UINT32 aplMacTicksToUs(UINT32 ticks){

	return(halMacTicksToUs(ticks));

}

//this sleeps, then restarts the stack and the radio
void aplShutdown(void){
	//wait until stack is idle
	while(apsBusy()) apsFSM();
	DISABLE_GLOBAL_INTERRUPT();  //disable interrupts, if halSleep wants to reenable them, let it.
	halShutdown();
    //a_aps_service.status = LRWPAN_STATUS_SUCCESS; --li

}

void aplWarmstart(void){
	/*a_aps_service.status = macWarmStartRadio();*/ //--li
}



//this is top level init, does inits for other layers
void apsInit(void){

//	debug_level = 0;
//	//apsState = APS_STATE_IDLE;
//	//apsRxState = APS_RXSTATE_IDLE;  --li
//#ifdef LRWPAN_COORDINATOR
//	aps_pib.rxCnt = 0;
//	aps_pib.rxTail = 0;
//	aps_pib.rxHead = 0;
//#endif

	//aps_pib.apsTSN = 0;
	//aps_pib.flags.val = 0;
	//aps_pib.apscAckWaitDuration = MSECS_TO_MACTICKS(LRWPAN_APS_ACK_WAIT_DURATION) ; //convert to MAC Ticks
	//aps_pib.apsAckWaitMultiplier = 1; //default value
	//aps_pib.apscMaxFrameRetries = LRWPAN_APS_MAX_FRAME_RETRIES ;
	////initialize the endpoints
	//aps_pib.activeEPs = 0;  //only tracks user endpoints.
	//phyInit();
	//macInit();
	//nwkInit();
	//zepInit();  --li

}

//simply remembers these so that we can report them to the coordinator.
LRWPAN_STATUS_ENUM aplRegisterEndPoint(BYTE epNum)
{
   /*if (aps_pib.activeEPs == LRWPAN_MAX_ENDPOINTS) return(LRWPAN_STATUS_APS_MAX_ENDPOINTS_EXCEEDED);
   if (epNum == 0) return(LRWPAN_STATUS_APS_ILLEGAL_ENDPOINT);
   apsEndPoints[aps_pib.activeEPs++].epNum = epNum;*/
   return(LRWPAN_STATUS_SUCCESS);
}

//Formats a Send Message service
void aplFmtSendMSG (BYTE dstMode,
					LADDR_UNION *dstADDR,
					BYTE dstEP,
					BYTE cluster,
					BYTE srcEP,
					BYTE* pload,
					BYTE  plen,
					BYTE  tsn,
					BYTE  reqack)
{

	//BYTE buf[8];
	//BYTE i;

	//while(apsBusy()) apsFSM();
	//a_aps_service.cmd = LRWPAN_SVC_APS_GENERIC_TX;
	//a_aps_tx_data.flags.val = 0;
	//a_aps_tx_data.srcEP = srcEP;
	//a_aps_tx_data.usrPlen = plen;
	//a_aps_tx_data.usrPload = pload;
	//a_aps_tx_data.tsn = tsn;
	//a_aps_tx_data.cluster = cluster;
	//a_aps_tx_data.dstMode = dstMode;
	//a_aps_tx_data.dstEP = dstEP;
	//a_aps_tx_data.srcSADDR = macGetShortAddr();
	//a_aps_tx_data.af_fcf = (1 | AF_FRM_TYPE_MSG);


	//if (dstMode == APS_DSTMODE_NONE) {
	//	a_aps_tx_data.aps_fcf = APS_FRM_TYPE_DATA | APS_FRM_DLVRMODE_INDIRECT;
	//}else  {
	//	a_aps_tx_data.aps_fcf = APS_FRM_TYPE_DATA | APS_FRM_DLVRMODE_NORMAL;
	//	if (a_aps_tx_data.dstMode == APS_DSTMODE_SHORT ){
	//		a_aps_tx_data.dstSADDR = dstADDR->saddr;
	//		if (dstADDR->saddr == macGetShortAddr()) {
	//			//sending to ourselves
	//			a_aps_tx_data.flags.bits.loopback = 1;
	//		}
	//	}
	//	else {
	//		a_aps_tx_data.dstLADDR = &dstADDR->laddr.bytes[0];
	//		a_aps_tx_data.dstSADDR = LRWPAN_SADDR_USE_LADDR;
	//		/* APS acks to no make sense for LONG addressing, which is
	//		being used to bypass routing. The MAC acks serve for APS acks
	//		in this case. Also APS acks would be returned via routing,
	//		negating the bypass of the routing in the first place.
	//		*/
	//		reqack = 0;
	//		//see if we are sending to ourself
	//		halGetProcessorIEEEAddress(buf);
	//		for(i=0;i<8;i++) {
	//			if (buf[i] != dstADDR->laddr.bytes[i]) break;
	//		}
	//		if (i==8) {
	//			//this is a loopback, so use our short address in this field
	//			a_aps_tx_data.dstSADDR = macGetShortAddr();
	//			a_aps_tx_data.flags.bits.loopback = 1;
	//		}
	//	}
	//}
	//if (reqack) a_aps_tx_data.aps_fcf |= (APS_FRM_ACKREQ_MASK);  --li

}

//TODO - add a pib flag that indicates when the User's TX
//buffer has been copied so that user can begin building a
//new TX packet while the old one is being TX'ed.



void apsFSM(void) {

	Sleep(500);

//#ifdef LRWPAN_COORDINATOR
//	APS_RX_DATA *rxPtr;
//#endif
//
//
//
//	nwkFSM();
//	//if TxFSM is busy we need to call it
//	if (apsTXBusy()) apsTxFSM();
//	apsRxFSM(); //check RX
//	zepFSM();   //do ZEP
//
//apsFSM_start:
//
//
//	switch (apsState) {
//	 case APS_STATE_IDLE:
//
//		 //ackSendPending check must come before the indirect Pending check!
//		 if (aps_pib.flags.bits.ackSendPending) {
//			 apsState = APS_STATE_ACK_SEND_START;
//			 goto apsFSM_start;
//		 }
//
//#ifdef LRWPAN_COORDINATOR
//		 if (aps_pib.flags.bits.indirectPending) {
//			 //free up RX FSM so that we can receive possible APS acks for this packet.
//			 aps_pib.flags.bits.indirectPending = 0;  //free up RX FSM
//			 // an indirect message needs resolving
//			 //initialize the binding table iterator
//			 //get pointer to current indirect packet
//			 rxPtr = &aps_pib.rxBuff[aps_pib.rxTail];
//			 if (!evbBindTableIterInit(rxPtr->srcEP, rxPtr->srcSADDR,rxPtr->cluster)){
//				 //a failure to initialize the iterator, give up.
//				 DEBUG_STRING(DBG_ERR,"APS: BindTable Iterator initialize failed. Discarding indirect msg.\n");
//				 apsState = APS_STATE_IDLE;
//			 }else 
//			 {
//				 apsState = APS_STATE_INDIRECT_GETDST;
//				 goto apsFSM_start;
//			      }
//		 }
//#endif
//
//
//		 break;
//	 case APS_STATE_COMMAND_START:
//		 switch(a_aps_service.cmd) {
//	 case LRWPAN_SVC_APS_GENERIC_TX:
//		 aps_pib.flags.bits.IsUsrBufferFree = 0;
//#ifdef LRWPAN_COORDINATOR
//		 if (APS_GET_FRM_DLVRMODE(a_aps_tx_data.aps_fcf) == APS_FRM_DLVRMODE_INDIRECT){
//			 //this is a special case. A Coordinator endpoint is sending indirect.
//			 //we need to inject this into the stack as if it has been received
//			 apsState = APS_STATE_INJECT_INDIRECT;
//			 goto apsFSM_start;
//		 }
//#endif
//
//
//		 if (a_aps_tx_data.flags.bits.loopback) {
//			 apsState = APS_STATE_INJECT_LOOPBACK;  //we are sending a direct packet to ourself!
//			 goto apsFSM_start;
//		 }
//
//		 //Indirect vs Direct is handled within the apsTxData() function
//		 //at this point ready to begin formating packet.
//		 //do not exit this state until we can grab the TX buffer.
//		 if (phyTxUnLocked()) {
//			 phyGrabTxLock(); //prevents lower stack layers from grabbing TX buffer.
//			 phy_pib.currentTxFlen = 0;  //set frame length to zero, build from scratch
//			 apsTxData(TRUE);
//			 aps_pib.flags.bits.IsUsrBufferFree = 1;
//			 apsState = APS_STATE_GENERIC_TX_WAIT;
//		 }
//		 break;
//
//	 case LRWPAN_SVC_APS_DO_ZEP_TX:
//		 if (phyTxUnLocked()) {
//			 phyGrabTxLock(); //prevents lower stack layers from grabbing TX buffer.
//			 switch(a_aps_service.args.zep_tx.clusterID)
//			 {
//	           case ZEP_END_DEVICE_ANNOUNCE:
//			                 zepFmtEndDeviceAnnounce(a_aps_service.args.zep_tx.dst);
//							 break;
//			   case ZEP_EXTENDED_CMD:
//				   switch(a_aps_service.args.zep_tx.extID)
//				   {
//			          case ZEP_EXT_NODE_INFO_RSP:
//				                zepFmtNodeInfoRsp(a_aps_service.args.zep_tx.dst);
//							     break;
//					  case ZEP_EXT_PING:
//						        zepFmtPing(a_aps_service.args.zep_tx.dst);
//								 break;
//					  case ZEP_EXT_SEND_ALARM:
//						        zepFmtAlarm(a_aps_service.args.zep_tx.dst,
//									        a_aps_service.args.zep_tx.ext.alarm.mode
//											);
//						        break;
//
//				   }
//				   break;
//			   default: break;
//			 }
//
//			 phy_pib.currentTxFlen = 0;  //set frame length to zero, build from scratch
//			 apsTxData(FALSE);           //payload already in TX buffer
//			 apsState = APS_STATE_GENERIC_TX_WAIT;
//		 }
//
//		 break;
//
//	
//	 case LRWPAN_SVC_APS_NWK_PASSTHRU:
//		 //for NWK calls that have to pass thru the APS layer
//		 //this just serves to lock the APS layer while the
//		 //the NWK layer is doing its thing
//		 if (nwkBusy()) break;  //wait until nwk is idle
//		 nwkDoService();
//		 apsState = APS_STATE_NWK_PASSTHRU_WAIT;
//		 break;
//
//	 default: break;
//		 }//end switch(a_aps_service.cmd)
//
//		 break;
//
//	 case APS_STATE_ACK_SEND_START:
//		 if (phyTxLocked()) break;
//		 //send an ACK
//		 //lock the TX buffer
//		 phyGrabTxLock();
//		 //we are now ready
//		 apsFormatAck();
//		 phy_pib.currentTxFlen = 0;  //set frame length to zero, build from scratch
//		 apsTxData(TRUE);
//		 //data sent, release the RX buffer, will let RX FSM resume
//		 aps_pib.flags.bits.ackSendPending = 0;
//		 apsState = APS_STATE_GENERIC_TX_WAIT;
//
//		 break;
//
//	 case APS_STATE_GENERIC_TX_WAIT:
//		 if (!apsTXIdle()) break;
//		 //TX is finished, copy status
//		 a_aps_service.status = apsTxFSM_status;
//		 //release the TX buffer lock before exiting.

⌨️ 快捷键说明

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