?? rfd_sleep.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){}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -