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

📄 router.c

📁 Zigbee 路由协议源代码(版本V3.0)
💻 C
字号:
#include <string.h>#include "zigbee.h"         // Zigbee defs#if defined(MCHP_C18)#include <stdio.h>#endif#include "msstate.h"#include "sralloc.h"#include "Console.h"#include "bugfix.h"#include "board.h"#include "router.h"#include "app.h"#define BIND_WAIT_DURATION          (6*TICK_SECOND)#define MAX_MESSAGE_WAIT  (1*TICK_SECOND)BYTE current_channel;static int channel_map = 0xFFFF;static ZCODE MSU_ConfigTask(void);ROM char * const configFailedMsg       = "Config failed. Press Reset\r\n";ROM char * const rejoinSuccessMsg      = "Rejoin successful.\r\n";ROM char * const rejoinFailedMsg       = "Rejoin failed.\r\n";ROM char * const initMsg               = "\r\nDoing network initialization\r\n";ROM char * const joinAttemptMsg        = "Attempting to join a coordinator...\r\n";ROM char * const associateSuccessMsg   = "\r\nSuccessfully associated.\r\n";ROM char * const associateFailMsg      = "\r\nFailed to associate.\r\n";ROM char * const demoBindCompleteMsg   = "Demo binding complete.\r\n";ROM char * const demoBindFailedMsg     = "\r\nBinding failed.  Not associated?\r\n";ROM char * const macAddrNowAssignedMsg = "MAC Address has now been assigned...\r\n";ROM char * const macAddrNotAssignedMsg = "MAC Address is not assigned, auto setting MAC address...\r\n";ROM char * const newNodeJoinedMsg      = "A new node has just joined.\r\n";ROM char * const newNodeRejoinedMsg    = "A familiar node has just rejoined.\r\n";ROM char * const nodeLeftMsg           = "A node has left the network.\r\n";#define COORD_SHORT_ADDR    0void  InitializeNetwork(void){  APP_STATE smApp;    CLRWDT();    // This is to initialize tick manager required for Zigbee stack modules.    TickInit();    // turn the LEDs off. D2 used to indicate transmission activity    // we will turn on D1 when we join a network. On a successful bind or first message    // recieved, it will be turned off.    D1 = 0;    D2 = 0;    // This demo application uses S3 switch to enter into configuration mode.    // Actual application may implelement any logic to select configuratoin mode    // or may not have any - completely application dependent.    if ( S3 == 0 )        appFlags.bits.bInConfigMode = TRUE;    // If MAC long address is not assigned, enter configuration by default.    if ( !IsMACAddrAssigned() )    {        ConsolePutROMString(macAddrNotAssignedMsg);        //appFlags.bits.bInConfigMode = TRUE;        DISABLE_WDT();        AutoSetNodeId(MAC_LONG_ADDR_BYTE3,MAC_LONG_ADDR_BYTE2,		  MAC_LONG_ADDR_BYTE1,		  MAC_LONG_ADDR_BYTE0); //auto set the node id        ENABLE_WDT();        ConsolePutROMString(macAddrNowAssignedMsg);    }    sprintf(tmpbuf,(ROM char *)"Node ID: 0x%02x%02x%02x%02x\n\r",	  MAC_LONG_ADDR_BYTE3,MAC_LONG_ADDR_BYTE2,	  MAC_LONG_ADDR_BYTE1,MAC_LONG_ADDR_BYTE0);    ConsolePutString((BYTE *)tmpbuf);    // This is main Zigbee stack initialization call.    // MAC will be in disable state until enabled.    APLInit();    // Enable global interrupts.    GIEL = 1;    GIEH = 1;    // We have to enable MAC separately. This way you can disable and enable as per your    // requirement.    APLEnable();    // Start with Init state.    smApp = SM_APP_INIT;    // this will exit after network is started    smApp = SM_APP_INIT;    while( smApp != SM_APP_NORMAL_START ) {        // Toggle RA4 to indicate how long we execute this loop        LATA4 ^= 1;        // Keep watchdog happy        CLRWDT();        // This is the main stack task, responsible for Zigbee stack related functionality.        // This function must be called before all Zigbee tasks.        // Actual application task functions can be called in any order.        APLTask();        KeepRxAlive();          // This demo application provides two modes of operations - config and normal.        // In config mode, this node will attempt to associate with available coordinator.        // In normal mode, it will simply rejoin previously associated coordinator.        // You may change this logic as per your application requirements.        switch(smApp)        {        case SM_APP_INIT:            // If S3 was pressed on startup, go to config mode.            if ( appFlags.bits.bInConfigMode == TRUE )                smApp = SM_APP_CONFIG_START;            // Or else go join a network            else                smApp =  SM_APP_NET_JOIN;            break;        case SM_APP_CONFIG_START:            // While in config mode, disable watchdog.            // Normally, you would want to keep watchdog enabled all the time, but in this demo that would            // amount to increased complexity and make this demo difficult to understand.            // Actual application code may afford extra complexity.            DISABLE_WDT();            // This is a blocking call. Note that watchdog is already disabled.            if (MSU_ConfigTask() != ZCODE_NO_ERROR) {	      // we have failed	      ConsolePutROMString(configFailedMsg);	      while(1);	    }            // Mark that we are no longer in config mode.            appFlags.bits.bInConfigMode = FALSE;            smApp = SM_APP_NORMAL_START;            // After config mode, enable watchdog            ENABLE_WDT();            break;        case SM_APP_NET_JOIN:            // This node will try to rejoin previously associated network.            // This will make sure that we join to a known network.            // Actual logic would depend on the application requirements.            APLRejoin();            smApp = SM_APP_NET_JOIN_WAIT;            break;        case SM_APP_NET_JOIN_WAIT:            // See if rejoin is complete.            if ( APLIsRejoinComplete() )            {                // If there was no error, continue with normal logic.                // Or else handle as per application requirements.                if ( GetLastZError() == ZCODE_NO_ERROR )                {                    ConsolePutROMString(rejoinSuccessMsg);                    smApp = SM_APP_NORMAL_START;                }                // else there was an error and needs to be addressed.                else                {                    ConsolePutROMString(rejoinFailedMsg);                    // This action would depend on application.		    // lets try disabling WDT, and doing reset		    DISABLE_WDT();		    RESET();                }            }            break;        }    }}// If S3 button held down on reset, then try to join a network// this version DOES NOT TRY TO BIND#define NETWORK_JOIN_TIME (TICK_SECOND*5)static ZCODE MSU_ConfigTask(void){  ZCODE errcode;  TICK startTime;  BYTE last_channel;    errcode = 0;  ConsolePutROMString(initMsg);  // While in config mode, disable PORTB interrupt-on-change.  RBIE = 0;  // current_channel is set in our AppOkayToUseChannel() callback  last_channel = current_channel;  // Wait for S3 to get released  while( S3 == 0 );  startTime = TickGet();  // try to join network  ConsolePutROMString(joinAttemptMsg);  // Enable Watchdog to catch any lock-ups.  ENABLE_WDT();  APLJoin();  while(1) {    CLRWDT();    APLTask();    KeepRxAlive();  	    if ( APLIsJoinComplete() )      {	errcode = GetLastZError();	if ( errcode == ZCODE_NO_ERROR ) {	  D1 = 1; //turn on to indicate network joined	  ConsolePutROMString(associateSuccessMsg);	}	else{	  ConsolePutROMString(associateFailMsg);	}	break;      }    // the channel_map variable is used to keep track of channels    // where a coordinator has rejected us so we can try the next one    if (TickGetDiff(TickGet(), startTime) > NETWORK_JOIN_TIME) {      //hmmm...coordinator responding, but rejecting us.      if (current_channel == 26) {	DISABLE_WDT();	sprintf(tmpbuf,(ROM char *)"Timeout Rejection on Channel %d, giving up\n\r",		current_channel);	ConsolePutString((BYTE *)tmpbuf);	return(ZCODE_CHANNEL_BUSY);  // return any code that is not NO_ERROR      } else {	// lets mark this channel as bad	channel_map = channel_map & ~(1 << (current_channel - 11));      }    }    if (last_channel != current_channel) {      //trying a different channel, restart timer      startTime = TickGet();      last_channel = current_channel;    }  }//end while(1)  if (errcode != ZCODE_NO_ERROR) {    // Disable watchdog before returning.    DISABLE_WDT();  }  return(errcode);}// Callback to an end device.// Called when a suitable coordinator is found as part of associate process.// Return TRUE if okay to associate.// May use PANDesc.for more information about this coordinator.// See MAC.h for definition of PANDesc.BOOL AppOkayToAssociate(void){    return TRUE;}ROM char * const channel_fmt     = "In channel: %d\r\n" ;ROM char * const reject_channel_fmt     = "Rejecting channel: %d\r\n" ;BOOL AppOkayToUseChannel(BYTE channel){    // This demo uses all available channels    // You may check given channel against your allowable channels and return TRUE    // or FALSE as needed.    // For 2.4GHz, channel = 11 through 26.  // see if its ok to use this channel  // Channel map is used by MSU_ConfigTask to try different channels  current_channel = channel;  if ( channel_map & (((int)1) << (channel - 11))) {    sprintf(tmpbuf,channel_fmt,channel);    ConsolePutString((BYTE *)tmpbuf);    return TRUE;  } else {    sprintf(tmpbuf,reject_channel_fmt,channel);    ConsolePutString((BYTE *)tmpbuf);    return FALSE;  }}// Callback to application to noify of new node joining our network.void AppNewNodeJoined(LONG_ADDR *nodeAddr, BOOL bIsRejoined){    // A new node has just joined (or rejoined).    // In this demo application, once a new node has joined, we want to save its    // association permanently into NVM.    if ( bIsRejoined == FALSE )    {        // You may want to check the nodeAddr and do something specific based        // on that node. This demo app does not any do anything special.        APLCommitTableChanges();        // Display that a new node has joined.        ConsolePutROMString(newNodeJoinedMsg);    }    else    {        // Display that a previous node has rejoined.        ConsolePutROMString(newNodeRejoinedMsg);    }}// Callback to application to notify if this node should be accepted to our network.BOOL AppOkayToAcceptThisNode(LONG_ADDR *longAddr){  // THIS HAS BEEN MODIFIED FROM THE ORIGINAL DEMO WHICH ACCEPTED ALL NODES!  // modified to only accept nodes whose Long address bytes  // v[2] thru v[7] match ours for rejection while testing  // use the LSByte to force a RFD node to join the router instead of   // of a coordinator. This is for demo purposes only so that the RFD  // does not have to physically out of range of the router    if ((longAddr->v[0] < 0x80)                   &&	(macInfo.longAddr.v[2] == longAddr->v[2]) &&	(macInfo.longAddr.v[3] == longAddr->v[3]) &&	(macInfo.longAddr.v[4] == longAddr->v[4]) &&	(macInfo.longAddr.v[5] == longAddr->v[5]) &&	(macInfo.longAddr.v[6] == longAddr->v[6]) &&	(macInfo.longAddr.v[7] == longAddr->v[7])	)       {	return TRUE;      } else       {	return FALSE;      }}// Callback to application to notify that a node has left the network.void AppNodeLeft(LONG_ADDR *nodeAddr){    // Display a message that a node has left the network.    ConsolePutROMString(nodeLeftMsg);    // Update our NVM table.    APLCommitTableChanges();    // Do application specific action here.}

⌨️ 快捷键说明

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