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

📄 rfd_sleep.c

📁 //Basic packet sending test at the MAC level, used for internal testing only. //This packet test ha
💻 C
字号:
/*
  V0.1 Initial Release   10/July/2006  RBR

*/



/*
This is a two node test, requires a Coordinator
and an RFD. The RFD just sleeps,wakes up,
sending a packet to the Coordinator each wakeup.


Expects coordinator, and one RFD.
The topology to test should be:

Coordinator ->  RFD1


Start the coordinator first, then RFD1.

This does not require any Virtual Boards to be running,
everything done through the console.


*/

#include "msstate_lrwpan.h"

UINT16 ping_cnt;
LADDR_UNION dstADDR;
BYTE payload[2];
UINT32 my_timer;


typedef enum _RFD_STATE_ENUM {
	RFD_STATE_JOIN_NETWORK,
	RFD_STATE_JOIN_WAIT,
	RFD_STATE_REJOIN_NETWORK,
	RFD_STATE_REJOIN_WAIT,
	RFD_STATE_NORMAL,
	RFD_STATE_WAIT_FOR_ACK,
	RFD_STATE_SLEEP
}RFD_STATE_ENUM;

RFD_STATE_ENUM rfdState;

void printJoinInfo(void);

void printJoinInfo(void){

	conPrintROMString("My ShortAddress is: ");
	conPrintUINT16(aplGetMyShortAddress());
	conPCRLF();
	conPrintROMString("Parent LADDR: ");
	conPrintLADDR(aplGetParentLongAddress());
	conPrintROMString(", Parent SADDR: ");
	conPrintUINT16(aplGetParentShortAddress());
	conPCRLF();
}

#define MAX_REJOIN_FAILURES 3
#define PING_DST_SADDR   0x0000  //change to a target in the network to test routing, this is the coordinator.


void main (void){

#ifndef LRWPAN_COORDINATOR
	UINT8 count;
	BOOL aps_ack;
	UINT8 failures;
	UINT32 my_timer;
#endif

	//HalInit, evbInit will have to be called by the user
	halInit();
	evbInit();

	aplInit();  //init the stack
	conPrintConfig();
	ENABLE_GLOBAL_INTERRUPT();  //enable interrupts

	EVB_LED1_OFF();
	EVB_LED2_OFF();
	//debug_level = 10;

#ifdef LRWPAN_RFD
	rfdState = RFD_STATE_JOIN_NETWORK;
	while(1) {
		apsFSM();
		switch(rfdState) {
		  case RFD_STATE_JOIN_NETWORK:
			  EVB_LED1_OFF();  //not connected to a network
			  aplJoinNetwork();
			  rfdState = RFD_STATE_JOIN_WAIT;
			  break;
		  case RFD_STATE_JOIN_WAIT:
			  if (apsBusy()) break;
			  if (aplGetStatus() == LRWPAN_STATUS_SUCCESS) {
				  conPrintROMString("Network Join succeeded!\n");
				  printJoinInfo();
				  rfdState = RFD_STATE_NORMAL;
				  ping_cnt = 0;
				  count = 0;
				  aps_ack = FALSE;
				  EVB_LED1_ON();
			  } else
			  {
				  conPrintROMString("Network Join FAILED! ");
				  conPrintROMString("Error: ");
				  conPrintUINT8(aplGetStatus());
				  conPrintROMString(", Waiting, then trying again\n");
				  my_timer= halGetMACTimer();
				  //wait for 2 seconds
				  while ((halMACTimerNowDelta(my_timer))< MSECS_TO_MACTICKS(2*1000));
				  rfdState = RFD_STATE_JOIN_NETWORK;
			  }
			  break;

		  case RFD_STATE_NORMAL:
			  //send to some target in the tree.
			  dstADDR.saddr = PING_DST_SADDR;
			  //send a message, then sleep
			  //increment ping counter
			  ping_cnt++;
			  count++;
			  //every so often, send an APS ack request to ensure that we are
			  //still actually associated with our parent and that the packet
			  //actually reached the coordinator. APS acks require
			  //more waiting time and overhead, so only use them when necessary.
			  //A MAC ack is always requested for a data packet, but this only
			  //ensures that the packet was received by the radio of our parent
			  //(ie, we have the correct short address/panid of the parent).
			  //if the parent has dropped us from its neighbor table for some
			  //reason, then the packet is rejected at at the nwk level.
			  //Also, if we are going through a router(s) to the coordinator,
			  //then the MAC ack is only good for the first hop to our parent.
			  if (count == 4) {
				  conPrintROMString("Requesting APS ack\n");
				  aps_ack = TRUE;
				  count = 0;
			  }else {
				  aps_ack = FALSE;
			  }
			  payload[0] = (BYTE) ping_cnt;
			  payload[1] =  (BYTE) (ping_cnt>>8);

			  //This uses an APS ACK so that know if the message
			  //was delivered. If it fails, then we assume that
			  //we have lost connection, and we issue a join
			  aplSendMSG (APS_DSTMODE_SHORT,
				  &dstADDR,
				  2, //dst EP
				  0, //cluster is ignored for direct message
				  1, //src EP
				  &payload[0],
				  2,  //msg length
				  apsGenTSN(),
				  aps_ack);
			  rfdState = RFD_STATE_WAIT_FOR_ACK;
			  break;
		  case RFD_STATE_WAIT_FOR_ACK:
			  if (apsBusy()) break;
			  if ((aplGetStatus() == LRWPAN_STATUS_SUCCESS) || !aps_ack) {
				  //all is well
				  rfdState = RFD_STATE_SLEEP;
			  } else {
				  //only try a rejoin if the aps_ack failed.
				  //if mac_ack failed, we will keep trying until the aps_ack fails.
				  //we assume that we have been disconnected.
				  //Try rejoining first, then a join.
				  failures = 0;
				  rfdState= RFD_STATE_REJOIN_NETWORK;
			  }
			  break;

		  case RFD_STATE_SLEEP:

			  conPrintROMString("Going to sleep...\n");
			  aplShutdown();  //This does a disable global interrupt!
			  halWaitMs(10);
			  //Going to sleep is platform/application dependent.
			  //the halSleep function is only intended for example purposes
			  //the msecs argument in halSleep may be ignored by the HAL layer
			  //as how sleep is implemented is target dependent.
			  halSleep(4000);
			  conPrintROMString("Woke up!\n");
			  aplWarmstart();
			  ENABLE_GLOBAL_INTERRUPT();
			  rfdState = RFD_STATE_NORMAL;
			  break;
#ifndef LRWPAN_COORDINATOR
		  case RFD_STATE_REJOIN_NETWORK:
			  conPrintROMString("Trying to rejoin network!\n");
			  aplRejoinNetwork();
			  rfdState = RFD_STATE_REJOIN_WAIT;
			  break;

		  case RFD_STATE_REJOIN_WAIT:
			  if (apsBusy()) break;   //if stack is busy, continue
			  if (aplGetStatus() == LRWPAN_STATUS_SUCCESS) {
				  failures = 0;
				  EVB_LED1_ON();
				  conPrintROMString("Network Rejoin succeeded!\n");
				  printJoinInfo();
				  rfdState = RFD_STATE_NORMAL;
			  } else {
				  failures++;
				  if (failures == MAX_REJOIN_FAILURES) {
					  //this starts everything over
					  conPrintROMString("Max Rejoins failed, trying to join.\n");
					  rfdState = RFD_STATE_JOIN_NETWORK;
				  } else {
					  //else, wait to try again
					  conPrintROMString("Network Rejoin FAILED! Waiting, then trying again\n");
					  //most apps probably do not need to wait before retrying rejoin.
					  //this is included just for visibility purposes in reading the output
					  my_timer= halGetMACTimer();
					  //wait for 2 seconds
					  while ((halMACTimerNowDelta(my_timer))< MSECS_TO_MACTICKS(2*1000));
					  rfdState = RFD_STATE_REJOIN_NETWORK;
				  }
			  }
			  break;
#endif
		  default:
			  rfdState = RFD_STATE_JOIN_NETWORK;
		}

	}

#else

	aplFormNetwork();
	while(apsBusy()) {apsFSM();} //wait for finish
	conPrintROMString("Network formed, waiting for RX\n");
	EVB_LED1_ON();
	while(1) {apsFSM();} //coordinator or router just runs the stack

#endif

}


///////User Callbacks///////////////

#ifdef LRWPAN_COORDINATOR

//the coordinator just prints out packets
LRWPAN_STATUS_ENUM usrRxPacketCallback(void) {


	BYTE len, *ptr;

	//just print out this data

	conPrintROMString("User Data Packet Received: \n");
	conPrintROMString("SrcSADDR: ");
	conPrintUINT16(aplGetRxSrcSADDR());
	conPrintROMString(", DstEp: ");
	conPrintUINT8(aplGetRxDstEp());
	conPrintROMString(", Cluster: ");
	conPrintUINT8(aplGetRxCluster());
	conPrintROMString(", MsgLen: ");
	len = aplGetRxMsgLen();
	conPrintUINT8(len);
	conPrintROMString(",RSSI: ");
	conPrintUINT8(aplGetRxRSSI());
	conPCRLF();
	conPrintROMString("PingCnt: ");
	ptr = aplGetRxMsgData();
	ping_cnt = *ptr;
	ptr++;
	ping_cnt += ((UINT16)*ptr)<<8;
	conPrintUINT16(ping_cnt);
	conPCRLF();
        return LRWPAN_STATUS_SUCCESS;
}
#else
//in this test, RFD only sends packets, does not recieve any
LRWPAN_STATUS_ENUM usrRxPacketCallback(void) { return LRWPAN_STATUS_SUCCESS; }
#endif

LRWPAN_STATUS_ENUM usrZepRxCallback(void){ return LRWPAN_STATUS_SUCCESS; }


#ifdef LRWPAN_FFD
//Callback to user level to see if OK for this node
//to join - implement Access Control Lists here based
//upon IEEE address if desired
BOOL usrJoinVerifyCallback(LADDR *ptr, BYTE capinfo){\

return TRUE;

}



BOOL usrJoinNotifyCallback(LADDR *ptr){

	//allow anybody to join

	conPrintROMString("Node joined: ");
	conPrintLADDR(ptr);
	conPCRLF();
	DEBUG_PRINTNEIGHBORS(DBG_INFO);
	return TRUE;
}
#endif

//called when the slow timer interrupt occurs
#ifdef LRWPAN_ENABLE_SLOW_TIMER
void usrSlowTimerInt(void ) {}
#endif


//general interrupt callback , when this is called depends on the HAL layer.
void usrIntCallback(void){}

⌨️ 快捷键说明

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