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

📄 coord.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 "coord.h"#include "app.h"struct{    TICK    requestStart;    union    {        struct        {            unsigned int bResponseReceived  : 1;            unsigned int bBindSuccessful    : 1;        } bits;        BYTE Val;    } flags;} endDeviceBindInfo;static void SendEndDeviceBindReq(void);BYTE current_channel;BYTE selective_join = 1;ROM char * const startNetworkMsg       = "Starting a new network...\r\n";ROM char * const noNeighborsMsg        = "Neighbor table is empty.\r\n";ROM char * const networkStartedMsg     = "New network successfully started.\r\n";ROM char * const networkStartErrMsg    = "There was an error starting network.\r\n";ROM char * const bindingSuccessMsg     = "Custom binding successful.\r\n";ROM char * const bindingFailedMsg      = "Custom binding failed.\r\n";ROM char * const demoBindSuccessMsg    = "Successfully completed quick demo setup.\r\n";ROM char * const validSrcInfoMsg       = "Received valid source node info.\r\n";ROM char * const invalidSrcInfoMsg     = "Received invalid source binding info.\r\n";ROM char * const invalidBindInfoMsg    = "Invalid binding info received.\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";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 unknownSrcNodeMsg     = "Unknown source node received.\r\n";// coordinator specific code/* This does everything needed to start up the network for a coordinator*/void InitializeNetwork(void){  APP_STATE smApp;  CLRWDT();  D1 = 0;  D2 = 0;  // This is to initialize tick manager required for Zigbee stack modules.  TickInit();  // If MAC long address is not assigned, enter configuration by default.  if ( !IsMACAddrAssigned() ){    ConsolePutROMString(macAddrNotAssignedMsg);    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);  // If neighbortable is empty, let the console know  if ( IsNeighborTableEmpty() )    ConsolePutROMString(noNeighborsMsg);    // Set MAC address before initializing the stack.    // This demo application stores MAC address into flash memory at variable    // called "macLongAddr". See zNVM.c    //    // Your application may store and read MAC address from anywhere it prefers.  GetMACAddress(&macInfo.longAddr );  // This is main Zigbee stack initialization call.  // MAC must be enabled when application is ready.  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();  // First of all establish a network.  APLNetworkInit();  // 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();      switch(smApp) {      // This is a required step - A coordinator must establish its own network      // before anything can be done.    case SM_APP_INIT:      ConsolePutROMString(startNetworkMsg);      smApp = SM_APP_INIT_RUN;      break;    case SM_APP_INIT_RUN:      // We must find an empty channel to establish network, or else      // continue scanning new channels.      if ( APLIsNetworkInitComplete() ) {	// If there was any error, report/handle it.	if ( GetLastZError() == ZCODE_NO_ERROR ) {	  // We have established a network, break out from this loop and continue	  // with next logic.	  ConsolePutROMString(networkStartedMsg);	  // Form new network now - or do it after your application requirements are met	  APLNetworkForm();	  smApp = SM_APP_NORMAL_START;	}	else {	  ConsolePutROMString(networkStartErrMsg);	  // Actual application would want to go to sleep and/or notify user about this.	  smApp = SM_APP_INIT;	}      }      break;    }  }  //before leaving, Permit new assiciation once we have established new network.  APLPermitAssociation();}//******************************************************************************// Binding Task//******************************************************************************BOOL BindingTask( void ){    static SM_BIND  smBind = SM_BIND_INIT;    APLSetEP( ZDOEndpointHandle );    switch (smBind)    {        case SM_BIND_INIT:	  SendEndDeviceBindReq();	  smBind = SM_BIND_CHECK_RESPONSE;	  break;        case SM_BIND_CHECK_RESPONSE:            if (endDeviceBindInfo.flags.bits.bResponseReceived)            {                if (endDeviceBindInfo.flags.bits.bBindSuccessful)                {		  if( appFlags.bits.bIsNotBound ) {		    ConsolePutROMString((ROM char *) "Unbind Successful!\n\r");		  }else {		    ConsolePutROMString((ROM char *) "Bind Successful!\n\r");		  }		  smBind = SM_BIND_INIT;		  return TRUE;                }                else                {                    ConsolePutROMString((ROM char *)  "End Device Bind/Unbind unsuccessful.\r\n" );                    smBind = SM_BIND_INIT;                    return TRUE;                }            }            else if (TickGetDiff(TickGet(), endDeviceBindInfo.requestStart) >= BIND_WAIT_DURATION)            {                ConsolePutROMString((ROM char *)  "No one is answering our bind request\r\n" );                smBind = SM_BIND_INIT;                return TRUE;            }            break;    }    return FALSE;}ROM char * const channel_fmt     = "In 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.  //ConsolePutROMString(nextChannelMsg);  sprintf(tmpbuf,channel_fmt,channel);  ConsolePutString((BYTE *)tmpbuf);  current_channel = channel;  return TRUE;}// 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  if (selective_join) {    // be more picky about who joins us, LSByte of NODE_ID has to be    // > than 0x7F - this is used to force node to join    // the router's network    if ((longAddr->v[0] > 0x7F)                   &&	(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;      }  } else {    //allow node to join us for binding    if ((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 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 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.}// Callback to process the End Device Bind responsevoid AppProcess_END_DEVICE_BIND_RSP( BOOL statusIsValid, BYTE status ){    endDeviceBindInfo.flags.bits.bResponseReceived = 1;    if (!statusIsValid)        status = APLGet();    if (status == SUCCESS)    {       endDeviceBindInfo.flags.bits.bBindSuccessful = 1;    }}/********************************************************************* * Function:        static void SendEndDeviceBindReq( void ) * * PreCondition:    Node is associated with a coordinator * * Input:           None * * Output:          None * * Side Effects:    None * * Overview:        Sends an end device bind request message to our *                  ZDO.  If possible, we will be bound to a *                  complementary device. * * Note:            Be sure to alloc the end device bind information, *                  or put it in a static variable. ********************************************************************/static void SendEndDeviceBindReq( void ){    END_DEVICE_BIND_INFO    *bindInfo;    if ((bindInfo = (END_DEVICE_BIND_INFO *)SRAMalloc( sizeof(END_DEVICE_BIND_INFO) )) == NULL)        return;    bindInfo->shortAddr          = MACGetShortAddr;    bindInfo->EP                 = EP_COORD;    bindInfo->profileID          = MY_PROFILE_ID;    bindInfo->numInClusters      = 1;    if ((bindInfo->inClusterList = (BYTE *)SRAMalloc( 1 )) == NULL)      return;    bindInfo->inClusterList[0]  = MSSTATE_RFDOUT_CLUSTER_ID;    bindInfo->numOutClusters     = 1;    if ((bindInfo->outClusterList = (BYTE *)SRAMalloc( 1 )) == NULL)      return;    bindInfo->outClusterList[0]  = MSSTATE_COORDOUT_CLUSTER_ID;    // Initialize the End Device Bind flags bResponseReceived and    // bBindSuccessful to FALSE.  Clear these flags before calling    // Process_End_Device_Bind_req, because if we are the second one to    // request the bind, that function will set the appropriate flags.    endDeviceBindInfo.flags.Val = 0;    // Set our initial time so we can check for timeout.    endDeviceBindInfo.requestStart = TickGet();    Process_End_Device_Bind_req( bindInfo );    //do second bind}

⌨️ 快捷键说明

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