/***************************************************************************** * * MODULE: JN-AN-1217 * * COMPONENT: app_router_node.c * * DESCRIPTION: Base Device Demo: Router application * **************************************************************************** * * This software is owned by NXP B.V. and/or its supplier and is protected * under applicable copyright laws. All rights are reserved. We grant You, * and any third parties, a license to use this software solely and * exclusively on NXP products [NXP Microcontrollers such as JN5168, JN5179]. * You, and any third parties must reproduce the copyright and warranty notice * and any other legend of ownership on each copy or partial copy of the * software. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Copyright NXP B.V. 2017. All rights reserved * ***************************************************************************/ /****************************************************************************/ /*** Include files ***/ /****************************************************************************/ #include #include #include "dbg.h" #include "pdum_apl.h" #include "pdum_nwk.h" #include "pdum_gen.h" #include "pwrm.h" #include "PDM.h" #include "zps_gen.h" #include "zps_apl.h" #include "zps_apl_af.h" #include "zps_apl_zdo.h" #include "zps_apl_zdp.h" #include "zps_apl_aib.h" #include "zps_apl_aps.h" #include "app_common.h" #include "app_main.h" #include "app_buttons.h" #include "app_Indicator.h" #include "app_led_interface.h" #include "ZTimer.h" #include "app_events.h" #include #include "app_zcl_task.h" #include "app_router_node.h" #include "zps_nwk_nib.h" #include "PDM_IDs.h" #include "zcl_options.h" #include "zcl.h" #include "app_reporting.h" #include "StackMeasure.h" #include "app_pdm_convert.h" #include "AHI_ModuleConfiguration.h" #ifdef CLD_OTA #include "OTA.h" #include "app_ota_client.h" #endif #ifdef APP_NTAG_ICODE #include "app_ntag_icode.h" #include "nfc_nwk.h" #endif #ifdef APP_NTAG_AES #include "app_ntag_aes.h" #include "nfc_nwk.h" #endif /****************************************************************************/ /*** Macro Definitions ***/ /****************************************************************************/ #ifndef DEBUG_APP #define TRACE_APP FALSE #else #define TRACE_APP TRUE #endif #ifdef DEBUG_APP_EVENT #define TRACE_APP_EVENT TRUE #else #define TRACE_APP_EVENT FALSE #endif #ifdef DEBUG_APP_BDB #define TRACE_APP_BDB TRUE #else #define TRACE_APP_BDB FALSE #endif /****************************************************************************/ /*** Type Definitions ***/ /****************************************************************************/ /****************************************************************************/ /*** Local Function Prototypes ***/ /****************************************************************************/ PRIVATE void vAppHandleAfEvent( BDB_tsZpsAfEvent *psZpsAfEvent); PRIVATE void vAppHandleZdoEvents( BDB_tsZpsAfEvent *psZpsAfEvent); PRIVATE void vAppHandlePeriodicReportEvents(BDB_tsZpsAfEvent *psZpsAfEvent); #if BDB_JOIN_USES_INSTALL_CODE_KEY == TRUE PRIVATE void APP_vSetICDerivedLinkKey(void); #endif PRIVATE void APP_vFirstReport(void); /****************************************************************************/ /*** Exported Variables ***/ /****************************************************************************/ tsZllState sZllState = { FACTORY_NEW, E_STARTUP, 0 }; tsConvertR21toR22 sConvertR21toR22 = { FALSE }; //uint8 u8FactoryResetCnt = 0; uint8 u8ButtonPressCnt = 0; uint8 u8reportStatusFalseCnt = 0; bool u8RejoinNwkStatus = TRUE; /****************************************************************************/ /*** Local Variables ***/ /****************************************************************************/ uint32 u32OldFrameCtr; /****************************************************************************/ /*** Exported Functions ***/ /****************************************************************************/ #ifdef PDM_EEPROM extern uint8 u8PDM_CalculateFileSystemCapacity(); extern uint8 u8PDM_GetFileSystemOccupancy(); #endif #ifdef CLD_OTA PUBLIC teNODE_STATES eGetNodeState(void) { return sZllState.eNodeState; } #endif /**************************************************************************** * * NAME: APP_vInitialiseRouter * * DESCRIPTION: * Initialises the application related functions * * RETURNS: * void * ****************************************************************************/ PUBLIC void APP_vInitialiseRouter(void) { uint16 u16ByteRead; PDM_teStatus eStatusReportReload; /* Stay awake */ PWRM_eStartActivity(); APP_vLedInitialise(); APP_bButtonInitialise(); /*Indicator StartUp*/ APP_vIdcStartUp(); sZllState.eNodeState = E_STARTUP; PDM_eReadDataFromRecord(PDM_ID_APP_TL_ROUTER, &sZllState, sizeof(tsZllState), &u16ByteRead); PDM_eReadDataFromRecord(PDM_ID_APP_CONVERT, &sConvertR21toR22, sizeof(tsConvertR21toR22), &u16ByteRead); #ifdef CLD_OTA vLoadOTAPersistedData(); #endif /* Restore any report data that is previously saved to flash */ eStatusReportReload = eRestoreReports(); ZPS_u32MacSetTxBuffers (4); #ifdef JN517x /* Default module configuration: change E_MODULE_DEFAULT as appropriate */ vAHI_ModuleConfigure(E_MODULE_DEFAULT); #endif DBG_vPrintf(TRACE_APP, "\nZll recovered state %02x\n", sZllState.eState); /* Check if the device is running but not converted Structures */ if ((sZllState.eNodeState >= E_RUNNING) && (sConvertR21toR22.bConvertRequired != TRUE)) { /* Device has been OTA'ed so convert records */ APP_vConvertR21_PdmToR22_Records(); } /* Device just started up, or conversion complete */ sConvertR21toR22.bConvertRequired = TRUE; PDM_eSaveRecordData(PDM_ID_APP_CONVERT,&sConvertR21toR22,sizeof(tsConvertR21toR22)); /* Initialise ZBPro stack */ ZPS_eAplAfInit(); /* Initialise ZCL */ APP_ZCL_vInitialise(); /* Always initialise any peripherals used by the application * HERE */ /* The functions u8PDM_CalculateFileSystemCapacity and u8PDM_GetFileSystemOccupancy * may be called at any time to monitor space available in the eeprom */ DBG_vPrintf(TRACE_APP, "PDM: Capacity %d\n", u8PDM_CalculateFileSystemCapacity()); DBG_vPrintf(TRACE_APP, "PDM: Occupancy %d\n", u8PDM_GetFileSystemOccupancy()); DBG_vPrintf(TRACE_APP, "Start Up StaTe %d On Network %d\n", sZllState.eNodeState, sBDB.sAttrib.bbdbNodeIsOnANetwork); /*Load the reports from the PDM or the default ones depending on the PDM load record status*/ if (eStatusReportReload != PDM_E_STATUS_OK) { /*Load Defaults if the data was not correct*/ vLoadDefaultConfigForReportable(); } /*Make the reportable attributes */ vMakeSupportedAttributesReportable(); if (sZllState.eState == 0) { DBG_vPrintf(TRACE_APP, "\nSet a random pan\n"); ZPS_vNwkNibSetPanId(ZPS_pvAplZdoGetNwkHandle(), (uint16) RND_u32GetRand(1, 0xfff0)); /*Indicator Pairing*/ APP_vIdcPairing(); } if (sZllState.eNodeState >= E_RUNNING) { sZllState.eNodeState = E_NFN_START; DBG_vPrintf(TRACE_APP, "\nNOT Factory New Start\n"); sBDB.sAttrib.bbdbNodeIsOnANetwork = TRUE; /*Indicator device on NWk -> paired*/ APP_vIdcPairedAndCfg(); ZTIMER_eStop(u8TimerCheckConection); ZTIMER_eStart(u8TimerCheckConection, ZTIMER_TIME_MSEC(500)); } else { DBG_vPrintf(TRACE_APP, "\nFactory new start up\n"); sZllState.eNodeState = E_STARTUP; sBDB.sAttrib.bbdbNodeIsOnANetwork = FALSE; DBG_vPrintf(TRACE_APP, "AppIdc:Init & Unpair\n"); APP_vIdcUnPair(); } BDB_tsInitArgs sArgs; sArgs.hBdbEventsMsgQ = &APP_msgBdbEvents; BDB_vInit(&sArgs); sBDB.sAttrib.u32bdbPrimaryChannelSet = BDB_PRIMARY_CHANNEL_SET; sBDB.sAttrib.u32bdbSecondaryChannelSet = BDB_SECONDARY_CHANNEL_SET; } /**************************************************************************** * * NAME: APP_vBdbCallback * * DESCRIPTION: * Callback from the BDB * * RETURNS: * void * ****************************************************************************/ PUBLIC void APP_vBdbCallback(BDB_tsBdbEvent *psBdbEvent) { switch (psBdbEvent->eEventType) { case BDB_EVENT_NONE: break; case BDB_EVENT_ZPSAF: // Use with BDB_tsZpsAfEvent DBG_vPrintf(0, "BdbCb event [%d %d] \n", psBdbEvent->uEventData.sZpsAfEvent.u8EndPoint, psBdbEvent->uEventData.sZpsAfEvent.sStackEvent.eType); vAppHandleAfEvent(&psBdbEvent->uEventData.sZpsAfEvent); break; case BDB_EVENT_INIT_SUCCESS: if (sZllState.eNodeState == E_STARTUP) { BDB_eNsStartNwkSteering(); } else { DBG_vPrintf(TRACE_APP, "BDB Init go Running"); sZllState.eState = NOT_FACTORY_NEW; sZllState.eNodeState = E_RUNNING; PDM_eSaveRecordData(PDM_ID_APP_TL_ROUTER, &sZllState, sizeof(tsZllState)); } break; case BDB_EVENT_NWK_STEERING_SUCCESS: // go to running state DBG_vPrintf(TRACE_APP, "APP: NwkSteering Success \n"); sZllState.eState = NOT_FACTORY_NEW; sZllState.eNodeState = E_RUNNING; PDM_eSaveRecordData(PDM_ID_APP_TL_ROUTER, &sZllState, sizeof(tsZllState)); DBG_vPrintf(TRACE_APP, "AppIdc:BdbCallback & PairedAndOperate\n"); APP_vIdcPairedAndCfg(); break; case BDB_EVENT_NO_NETWORK: DBG_vPrintf(TRACE_APP, "APP: BDB No Networks\n"); uint32 u32Channel; eAppApiPlmeGet(PHY_PIB_ATTR_CURRENT_CHANNEL, &u32Channel); ZPS_vNwkNibSetChannel(ZPS_pvAplZdoGetNwkHandle(), (uint8) u32Channel); DBG_vPrintf(TRACE_APP, "APP: BDB No Networks -> Wait On %d\n", u32Channel); DBG_vPrintf(TRACE_APP, "AppIdc:BdbCallback & Unpair\n"); APP_vIdcUnPair(); break; case BDB_EVENT_NWK_FORMATION_SUCCESS: DBG_vPrintf(TRACE_APP, "APP: NwkFormation Success \n"); break; case BDB_EVENT_NWK_FORMATION_FAILURE: DBG_vPrintf(TRACE_APP, "APP: BDB_EVENT_NWK_FORMATION_FAILURE\n"); break; case BDB_EVENT_FB_OVER_AT_TARGET: DBG_vPrintf(TRACE_APP, "Find and Bind as Target completed\n"); break; case BDB_EVENT_FB_ERR_BINDING_FAILED: DBG_vPrintf(TRACE_APP, "Find and Bind failed\n"); break; case BDB_EVENT_FB_CLUSTER_BIND_CREATED_FOR_TARGET: DBG_vPrintf(TRACE_APP, "Find and Bind Cluster create for target\n"); break; case BDB_EVENT_FB_BIND_CREATED_FOR_TARGET: DBG_vPrintf(TRACE_APP, "Find and Bind create for target\n"); break; case BDB_EVENT_REJOIN_SUCCESS: case BDB_EVENT_NWK_JOIN_SUCCESS: DBG_vPrintf(TRACE_APP, "AppIdc:BdbCallback & PairedAndOperate\n"); APP_vIdcPairedAndCfg(); break; case BDB_EVENT_REJOIN_FAILURE: DBG_vPrintf(TRACE_APP, "APP-BDB: fail to Join NWks, BDB_EVENT_REJOIN_FAILURE \n"); DBG_vPrintf(TRACE_APP, "AppIdc:BdbCallback & Unpair\n"); APP_vIdcUnPair(); break; case BDB_EVENT_NWK_JOIN_FAILURE: DBG_vPrintf(TRACE_APP, "APP-BDB: fail to Join NWks, BDB_EVENT_NWK_JOIN_FAILURE \n"); DBG_vPrintf(TRACE_APP, "AppIdc:BdbCallback & Unpair\n"); APP_vIdcUnPair(); break; case BDB_EVENT_LEAVE_WITHOUT_REJOIN: DBG_vPrintf(TRACE_APP, "APP-BDB: fail to Join NWks, BDB_EVENT_LEAVE_WITHOUT_REJOIN \n"); DBG_vPrintf(TRACE_APP, "AppIdc:BdbCallback & Unpair\n"); APP_vIdcUnPair(); break; default: break; } } /**************************************************************************** * * NAME: APP_taskRouter * * DESCRIPTION: * Task that handles application related functions * * RETURNS: * void * ****************************************************************************/ PUBLIC void APP_taskRouter(void) { APP_tsEvent sAppEvent; sAppEvent.eType = APP_E_EVENT_NONE; if (ZQ_bQueueReceive(&APP_msgAppEvents, &sAppEvent) == TRUE) { DBG_vPrintf(TRACE_APP, "ZPR: App event %d, NodeState=%d\n", sAppEvent.eType, sZllState.eNodeState); if(sAppEvent.eType == APP_E_EVENT_BUTTON_DOWN) { switch(sAppEvent.uEvent.sButton.u8Button) { case APP_E_BUTTONS_BUTTON_1: DBG_vPrintf(TRACE_APP, " >>>> Button Press <<<<<<< \n"); /* start timer factory reset after 6s */ u8ButtonPressCnt = 0; ZTIMER_eStop(u8TimerButtonPress); ZTIMER_eStart(u8TimerButtonPress, TIME_BUTTON_INTERVAL); /*Button test*/ //APP_vIdcButtonTest(TRUE); break; #ifdef APP_NTAG_ICODE case APP_E_BUTTONS_NFC_FD: DBG_vPrintf(TRACE_APP_EVENT, "APP_EVENT: NFC_FD DOWN\n"); APP_vNtagStart(ROUTER_APPLICATION_ENDPOINT); break; #endif #ifdef APP_NTAG_AES case APP_E_BUTTONS_NFC_FD: DBG_vPrintf(TRACE_APP_EVENT, "APP_EVENT: NFC_FD DOWN\n"); APP_vNtagStart(NFC_NWK_NSC_DEVICE_ZIGBEE_ROUTER_DEVICE); break; #endif default: break; } } else if (sAppEvent.eType == APP_E_EVENT_BUTTON_UP) { switch(sAppEvent.uEvent.sButton.u8Button) { case APP_E_BUTTONS_BUTTON_1: DBG_vPrintf(TRACE_APP, " >>>> Button Release <<<<<<< \n"); ZTIMER_eStop(u8TimerButtonPress); if(u8ButtonPressCnt < 3){ /*Button PressAndRelease <= 3s*/ sBaseDevice.sOnOffServerCluster.bOnOff = !sBaseDevice.sOnOffServerCluster.bOnOff; DBG_vPrintf(TRACE_APP, ">>> Button press&release, Set LED by Button: %d\n", sBaseDevice.sOnOffServerCluster.bOnOff); APP_vIdcButtonPressAndRelease(sBaseDevice.sOnOffServerCluster.bOnOff); } else if(u8ButtonPressCnt < 5){ /*Button PressAndRelease >3s & <= 5s; ==> manual Rejoin NWks*/ DBG_vPrintf(TRACE_APP, ">>> Button press&release > 3s and < 5s, MS Rejoin NWk \n"); /*setting beacon filter: See B.4 - page 494 - JN-UG-3113*/ //ZPS_bAppAddBeaconFilter(); if(ZPS_eAplZdoRejoinNetwork(TRUE) == ZPS_E_SUCCESS){ DBG_vPrintf(TRACE_APP, "SW_APP: Rejoin NWk ZPS_E_SUCCESS \n"); } else{DBG_vPrintf(TRACE_APP, "SW_APP: Rejoin NWk Fail \n");} } else { /*Button PressAndRelease > 5s ==> Factory Reset*/ APP_tsEvent sButtonEvent; sButtonEvent.eType = APP_E_EVENT_LEAVE_AND_RESET; DBG_vPrintf(TRACE_APP, ">>> Button press&release > 6s, Factory Reset \n"); if(ZQ_bQueueSend(&APP_msgAppEvents, &sButtonEvent) == FALSE) { DBG_vPrintf(TRACE_APP, "Timer Factory Reset: Failed to post Event %d \n", sButtonEvent.eType); } } break; } } #ifdef APP_NTAG_ICODE else if(sAppEvent.eType == APP_E_EVENT_BUTTON_UP) { if (APP_E_BUTTONS_NFC_FD == sAppEvent.uEvent.sButton.u8Button) { DBG_vPrintf(TRACE_APP_EVENT, "APP_EVENT: NFC_FD UP\n"); APP_vNtagStart(ROUTER_APPLICATION_ENDPOINT); } } #endif #ifdef APP_NTAG_AES else if(sAppEvent.eType == APP_E_EVENT_BUTTON_UP) { if (APP_E_BUTTONS_NFC_FD == sAppEvent.uEvent.sButton.u8Button) { DBG_vPrintf(TRACE_APP_EVENT, "APP_EVENT: NFC_FD UP\n"); APP_vNtagStart(NFC_NWK_NSC_DEVICE_ZIGBEE_ROUTER_DEVICE); } } #endif else if (sAppEvent.eType == APP_E_EVENT_LEAVE_AND_RESET) { if (sZllState.eNodeState == E_RUNNING) { if (ZPS_eAplZdoLeaveNetwork( 0UL, FALSE, FALSE) != ZPS_E_SUCCESS ) { APP_vFactoryResetRecords(); vAHI_SwReset(); } } else { APP_vFactoryResetRecords(); vAHI_SwReset(); } } } } /**************************************************************************** * * NAME: APP_vOobcSetRunning * * DESCRIPTION: * Set running state for OOBC * * RETURNS: * void * ****************************************************************************/ PUBLIC void APP_vOobcSetRunning(void) { sZllState.eState = NOT_FACTORY_NEW; sZllState.eNodeState = E_RUNNING; PDM_eSaveRecordData(PDM_ID_APP_TL_ROUTER,&sZllState,sizeof(tsZllState)); } /**************************************************************************** * * NAME: sGetOTACallBackPersistdata * * DESCRIPTION: * returns persisted data * * RETURNS: * tsOTA_PersistedData * ****************************************************************************/ #ifdef CLD_OTA PUBLIC tsOTA_PersistedData sGetOTACallBackPersistdata(void) { return sBaseDevice.sCLD_OTA_CustomDataStruct.sOTACallBackMessage.sPersistedData; } #endif /**************************************************************************** * * NAME: vAppHandleAfEvent * * DESCRIPTION: * Application handler for stack events * * RETURNS: * void * ****************************************************************************/ PRIVATE void vAppHandleAfEvent( BDB_tsZpsAfEvent *psZpsAfEvent) { if (psZpsAfEvent->u8EndPoint == ROUTER_APPLICATION_ENDPOINT) { DBG_vPrintf(TRACE_APP, "Pass to ZCL\n"); if ((psZpsAfEvent->sStackEvent.eType == ZPS_EVENT_APS_DATA_INDICATION) || (psZpsAfEvent->sStackEvent.eType == ZPS_EVENT_APS_INTERPAN_DATA_INDICATION)) { APP_ZCL_vEventHandler( &psZpsAfEvent->sStackEvent); } else{ vAppHandlePeriodicReportEvents(psZpsAfEvent); } } else if (psZpsAfEvent->u8EndPoint == 0) { vAppHandleZdoEvents( psZpsAfEvent); } /* Ensure Freeing of Apdus */ if (psZpsAfEvent->sStackEvent.eType == ZPS_EVENT_APS_DATA_INDICATION) { PDUM_eAPduFreeAPduInstance(psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.hAPduInst); } else if ( psZpsAfEvent->sStackEvent.eType == ZPS_EVENT_APS_INTERPAN_DATA_INDICATION ) { PDUM_eAPduFreeAPduInstance(psZpsAfEvent->sStackEvent.uEvent.sApsInterPanDataIndEvent.hAPduInst); } } /**************************************************************************** * * NAME: vAppHandleZdoEvents * * DESCRIPTION: * Application handler for stack events for end point 0 (ZDO) * * RETURNS: * void * ****************************************************************************/ PRIVATE void vAppHandleZdoEvents( BDB_tsZpsAfEvent *psZpsAfEvent) { tsBDB_ZCLEvent sBdbEvent; tsZCL_CallBackEvent sCallBackEvent; sBdbEvent.psCallBackEvent = &sCallBackEvent; switch(psZpsAfEvent->sStackEvent.eType){ case ZPS_EVENT_NWK_NEW_NODE_HAS_JOINED: DBG_vPrintf(TRACE_APP, "APP-ZDO: New Node %04x Has Joined\n", psZpsAfEvent->sStackEvent.uEvent.sNwkJoinIndicationEvent.u16NwkAddr); break; case ZPS_EVENT_NWK_STATUS_INDICATION: DBG_vPrintf(TRACE_APP, "APP-ZDO: Network status Indication %02x addr %04x\n", psZpsAfEvent->sStackEvent.uEvent.sNwkStatusIndicationEvent.u8Status, psZpsAfEvent->sStackEvent.uEvent.sNwkStatusIndicationEvent.u16NwkAddr); break; case ZPS_EVENT_NWK_DISCOVERY_COMPLETE: sBdbEvent.eType = BDB_E_ZCL_EVENT_DISCOVERY_DONE; sBdbEvent.psCallBackEvent->pZPSevent = &psZpsAfEvent->sStackEvent; BDB_vZclEventHandler(&sBdbEvent); DBG_vPrintf(TRACE_APP, "APP-ZDO: Discovery Complete %02x\n", psZpsAfEvent->sStackEvent.uEvent.sNwkDiscoveryEvent.eStatus); break; case ZPS_EVENT_NWK_LEAVE_INDICATION: DBG_vPrintf(TRACE_APP, "APP-ZDO: Leave Indication %016llx Rejoin %d\n", psZpsAfEvent->sStackEvent.uEvent.sNwkLeaveIndicationEvent.u64ExtAddr, psZpsAfEvent->sStackEvent.uEvent.sNwkLeaveIndicationEvent.u8Rejoin); if ((psZpsAfEvent->sStackEvent.uEvent.sNwkLeaveIndicationEvent.u64ExtAddr == 0UL) && (psZpsAfEvent->sStackEvent.uEvent.sNwkLeaveIndicationEvent.u8Rejoin == 0)) { /* We are asked to Leave without rejoin */ DBG_vPrintf(TRACE_APP, "LEAVE IND -> For Us No Rejoin\n"); APP_vFactoryResetRecords(); vAHI_SwReset(); } break; case ZPS_EVENT_NWK_LEAVE_CONFIRM: DBG_vPrintf(TRACE_APP, "APP-ZDO: Leave Confirm status %02x Addr %016llx\n", psZpsAfEvent->sStackEvent.uEvent.sNwkLeaveConfirmEvent.eStatus, psZpsAfEvent->sStackEvent.uEvent.sNwkLeaveConfirmEvent.u64ExtAddr); if ((psZpsAfEvent->sStackEvent.uEvent.sNwkLeaveConfirmEvent.eStatus == ZPS_E_SUCCESS) && (psZpsAfEvent->sStackEvent.uEvent.sNwkLeaveConfirmEvent.u64ExtAddr == 0UL)) { if (sBDB.sAttrib.bLeaveRequested) { /* originated in touch link, pass it over */ sBDB.sAttrib.bLeaveRequested = FALSE; sBdbEvent.eType = BDB_E_ZCL_EVENT_LEAVE_CFM; DBG_vPrintf(TRACE_APP, "Send Leave cfm\n"); sBdbEvent.psCallBackEvent->pZPSevent = &psZpsAfEvent->sStackEvent; BDB_vZclEventHandler(&sBdbEvent); } else { DBG_vPrintf(TRACE_APP, "Leave -> Reset Data Structures\n"); APP_vFactoryResetRecords(); vAHI_SwReset(); } } break; case ZPS_EVENT_NWK_JOINED_AS_ROUTER: sZllState.eNodeState = E_RUNNING; /* set the aps use pan id */ ZPS_eAplAibSetApsUseExtendedPanId( ZPS_u64NwkNibGetEpid(ZPS_pvAplZdoGetNwkHandle())); sZllState.eState = NOT_FACTORY_NEW; sZllState.u16MyAddr = psZpsAfEvent->sStackEvent.uEvent.sNwkJoinedEvent.u16Addr; PDM_eSaveRecordData(PDM_ID_APP_TL_ROUTER, &sZllState, sizeof(tsZllState)); /* identify to signal the join */ APP_ZCL_vSetIdentifyTime(10); DBG_vPrintf(TRACE_APP, "APP-ZDO: Joined Network Addr %04x Rejoin %d\n", psZpsAfEvent->sStackEvent.uEvent.sNwkJoinedEvent.u16Addr, psZpsAfEvent->sStackEvent.uEvent.sNwkJoinedEvent.bRejoin); /* stop identify */ //APP_vIdcPairedAndOperateProcess(sBaseDevice.sOnOffServerCluster.bOnOff); APP_vIdcPairedAndOperate(); /* report attribute name for auto classify */ APP_vFirstReport(); /* trigger timer check connection */ ZTIMER_eStop(u8TimerCheckConection); ZTIMER_eStart(u8TimerCheckConection, ZTIMER_TIME_MSEC(500)); break; case ZPS_EVENT_APS_DATA_INDICATION: DBG_vPrintf(TRACE_APP, "APP-ZDO: Data Indication Status %02x from %04x Src Ep Dst %d Ep %d Profile %04x Cluster %04x\n", psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.eStatus, psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.uSrcAddress.u16Addr, psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.u8SrcEndpoint, psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.u8DstEndpoint, psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.u16ProfileId, psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.u16ClusterId); #ifdef CLD_OTA if ((psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.eStatus == ZPS_E_SUCCESS) && (psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.u8DstEndpoint == 0)) { // Data Ind for ZDp Ep if (ZPS_ZDP_MATCH_DESC_RSP_CLUSTER_ID == psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.u16ClusterId) { vHandleMatchDescriptor(&psZpsAfEvent->sStackEvent); } else if (ZPS_ZDP_IEEE_ADDR_RSP_CLUSTER_ID == psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.u16ClusterId) { vHandleIeeeAddressRsp(&psZpsAfEvent->sStackEvent); } } #endif break; case ZPS_EVENT_APS_DATA_CONFIRM: break; case ZPS_EVENT_APS_DATA_ACK: DBG_vPrintf(TRACE_APP, "APP-EP1: Destination ACK, EP: %d \n",psZpsAfEvent->u8EndPoint); DBG_vPrintf(TRACE_APP, "APP-EP1:Destination ACK Data Status %02x from %04x Src Ep,ModeAdd %d Dst %04x Ep %04x Profile %04x Cluster %04x\n", psZpsAfEvent->sStackEvent.uEvent.sApsDataAckEvent.u8Status, psZpsAfEvent->sStackEvent.uEvent.sApsDataAckEvent.u8SrcEndpoint, psZpsAfEvent->sStackEvent.uEvent.sApsDataAckEvent.u8DstAddrMode, psZpsAfEvent->sStackEvent.uEvent.sApsDataAckEvent.u16DstAddr, psZpsAfEvent->sStackEvent.uEvent.sApsDataAckEvent.u8DstEndpoint, psZpsAfEvent->sStackEvent.uEvent.sApsDataAckEvent.u16ProfileId, psZpsAfEvent->sStackEvent.uEvent.sApsDataAckEvent.u16ClusterId); break; case ZPS_EVENT_NWK_STARTED: DBG_vPrintf(TRACE_APP, "APP-ZDO: Network started\n"); break; case ZPS_EVENT_NWK_FAILED_TO_START: DBG_vPrintf(TRACE_APP, "APP-ZDO: Network Failed To start\n"); break; case ZPS_EVENT_NWK_FAILED_TO_JOIN: DBG_vPrintf(TRACE_APP, "APP-ZDO: Failed To Join %02x Rejoin %d\n", psZpsAfEvent->sStackEvent.uEvent.sNwkJoinFailedEvent.u8Status, psZpsAfEvent->sStackEvent.uEvent.sNwkJoinFailedEvent.bRejoin); break; case ZPS_EVENT_NWK_ROUTE_DISCOVERY_CONFIRM: DBG_vPrintf(TRACE_APP, "APP-ZDO: Discovery Confirm: Status 0x%02x, u16DstAddress: 0x%04x, u8NwkStatus: 0x%02x \n", psZpsAfEvent->sStackEvent.uEvent.sNwkRouteDiscoveryConfirmEvent.u8Status, psZpsAfEvent->sStackEvent.uEvent.sNwkRouteDiscoveryConfirmEvent.u16DstAddress, psZpsAfEvent->sStackEvent.uEvent.sNwkRouteDiscoveryConfirmEvent.u8NwkStatus ); //0xD0 -> ZPS_NWK_ENUM_ROUTE_DISCOVERY_FAILED if((psZpsAfEvent->sStackEvent.uEvent.sNwkRouteDiscoveryConfirmEvent.u8Status == 0xD0)&&\ (psZpsAfEvent->sStackEvent.uEvent.sNwkRouteDiscoveryConfirmEvent.u16DstAddress == 0x0000)){ if(u8RejoinNwkStatus == TRUE){ u8RejoinNwkStatus = FALSE; } DBG_vPrintf(TRACE_APP, "APP-EP0: u8RejoinNwkStatus: %d \n", u8RejoinNwkStatus); } break; case ZPS_EVENT_NWK_ED_SCAN: DBG_vPrintf(TRACE_APP, "APP-ZDO: Energy Detect Scan %02x\n", psZpsAfEvent->sStackEvent.uEvent.sNwkEdScanConfirmEvent.u8Status); break; case ZPS_EVENT_ZDO_BIND: DBG_vPrintf(TRACE_APP, "APP-ZDO: Zdo Bind event\n"); break; case ZPS_EVENT_ZDO_UNBIND: DBG_vPrintf(TRACE_APP, "APP-ZDO: Zdo Unbiind Event\n"); break; case ZPS_EVENT_ZDO_LINK_KEY: DBG_vPrintf(TRACE_APP, "APP-ZDO: Zdo Link Key Event Type %d Addr %016llx\n", psZpsAfEvent->sStackEvent.uEvent.sZdoLinkKeyEvent.u8KeyType, psZpsAfEvent->sStackEvent.uEvent.sZdoLinkKeyEvent.u64IeeeLinkAddr); break; case ZPS_EVENT_BIND_REQUEST_SERVER: DBG_vPrintf(TRACE_APP, "APP-ZDO: Bind Request Server Event\n"); break; case ZPS_EVENT_ERROR: DBG_vPrintf(TRACE_APP, "APP-ZDO: AF Error Event %d\n", psZpsAfEvent->sStackEvent.uEvent.sAfErrorEvent.eError); break; case ZPS_EVENT_TC_STATUS: DBG_vPrintf(TRACE_APP, "APP-ZDO: Trust Center Status %02x\n", psZpsAfEvent->sStackEvent.uEvent.sApsTcEvent.u8Status); break; default: DBG_vPrintf(TRACE_APP, "APP-ZDO: Unhandled Event %d\n", psZpsAfEvent->sStackEvent.eType); break; } } /**************************************************************************** * * NAME: vAppHandlePeriodicReportEvents * * DESCRIPTION: * Application handler for stack events for end point 1 (with Periodic Report). * It handler event response when report APP_vReportAllStatusButton. * * RETURNS: * void * ****************************************************************************/ PRIVATE void vAppHandlePeriodicReportEvents(BDB_tsZpsAfEvent *psZpsAfEvent) { tsBDB_ZCLEvent sBdbEvent; tsZCL_CallBackEvent sCallBackEvent; sBdbEvent.psCallBackEvent = &sCallBackEvent; switch (psZpsAfEvent->sStackEvent.eType) { // case ZPS_EVENT_APS_DATA_INDICATION: // DBG_vPrintf(TRACE_APP, // "APP-EP1: Data Indication Status %02x from %04x Src Ep Dst %d Ep %d Profile %04x Cluster %04x\n", // psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.eStatus, // psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.uSrcAddress.u16Addr, // psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.u8SrcEndpoint, // psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.u8DstEndpoint, // psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.u16ProfileId, // psZpsAfEvent->sStackEvent.uEvent.sApsDataIndEvent.u16ClusterId); // // break; case ZPS_EVENT_APS_DATA_CONFIRM: /*TODO: check report ACK to know Network status*/ DBG_vPrintf(TRACE_APP, "APP-EP1: Next-hop ACK, EP: %d \n",psZpsAfEvent->u8EndPoint); DBG_vPrintf(TRACE_APP, "APP-EP1:Next-hop ACK Data Status 0x%02x from %d Src Ep, Dst 0x%04x Ep %d, Seq Num 0x%02x \n", psZpsAfEvent->sStackEvent.uEvent.sApsDataConfirmEvent.u8Status, psZpsAfEvent->sStackEvent.uEvent.sApsDataConfirmEvent.u8SrcEndpoint, psZpsAfEvent->sStackEvent.uEvent.sApsDataConfirmEvent.uDstAddr.u16Addr, psZpsAfEvent->sStackEvent.uEvent.sApsDataConfirmEvent.u8DstEndpoint, psZpsAfEvent->sStackEvent.uEvent.sApsDataConfirmEvent.u8SequenceNum); //0xD0 -> ZPS_NWK_ENUM_ROUTE_DISCOVERY_FAILED if((psZpsAfEvent->sStackEvent.uEvent.sApsDataConfirmEvent.u8Status == 0x00)&&\ (psZpsAfEvent->sStackEvent.uEvent.sApsDataConfirmEvent.uDstAddr.u16Addr == 0x0000)&&\ (psZpsAfEvent->sStackEvent.uEvent.sApsDataConfirmEvent.u8DstEndpoint == ROUTER_APPLICATION_ENDPOINT)){ if(u8RejoinNwkStatus == FALSE){u8RejoinNwkStatus = TRUE;} DBG_vPrintf(TRACE_APP, "APP-EP0: u8RejoinNwkStatus: %d \n", u8RejoinNwkStatus); } break; case ZPS_EVENT_APS_DATA_ACK: /*TODO: check report ACK to know Network status*/ DBG_vPrintf(TRACE_APP, "APP-EP1: Destination ACK, EP: %d \n",psZpsAfEvent->u8EndPoint); DBG_vPrintf(TRACE_APP, "APP-EP1:Destination ACK Data Status %02x from %04x Src Ep,ModeAdd %d Dst %04x Ep %04x Profile %04x Cluster %04x\n", psZpsAfEvent->sStackEvent.uEvent.sApsDataAckEvent.u8Status, psZpsAfEvent->sStackEvent.uEvent.sApsDataAckEvent.u8SrcEndpoint, psZpsAfEvent->sStackEvent.uEvent.sApsDataAckEvent.u8DstAddrMode, psZpsAfEvent->sStackEvent.uEvent.sApsDataAckEvent.u16DstAddr, psZpsAfEvent->sStackEvent.uEvent.sApsDataAckEvent.u8DstEndpoint, psZpsAfEvent->sStackEvent.uEvent.sApsDataAckEvent.u16ProfileId, psZpsAfEvent->sStackEvent.uEvent.sApsDataAckEvent.u16ClusterId); break; default: DBG_vPrintf(TRACE_APP, "APP-EP1: Unhandled Event %d\n", psZpsAfEvent->sStackEvent.eType); break; } } /****************************************************************************/ /*** Local Functions ***/ /****************************************************************************/ /**************************************************************************** * * NAME: APP_vFactoryResetRecords * * DESCRIPTION: * Resets persisted data structures to factory new state * * RETURNS: * void * ****************************************************************************/ PUBLIC void APP_vFactoryResetRecords(void) { ZPS_eAplAibSetApsUseExtendedPanId(0); sZllState.eNodeState = E_STARTUP; sZllState.eState = FACTORY_NEW; sBDB.sAttrib.bbdbNodeIsOnANetwork = FALSE; sZllState.u16MyAddr = 0; #ifdef CLD_OTA sZllState.bValid = FALSE; sZllState.u64IeeeAddrOfServer = 0; sZllState.u16NwkAddrOfServer = 0xffff; sZllState.u8OTAserverEP = 0xff; vOTAResetPersist(); #endif /* clear out the stack */ ZPS_vDefaultStack(); ZPS_vSetKeys(); vLoadDefaultConfigForReportable(); PDM_eSaveRecordData(PDM_ID_APP_TL_ROUTER, &sZllState, sizeof(tsZllState)); ZPS_vSaveAllZpsRecords(); } /**************************************************************************** * * NAME: APP_vReportStatusButtonImmediately * * DESCRIPTION: * * RETURNS: * void * ****************************************************************************/ PUBLIC void APP_vReportStatusButtonImmediately(uint8 u8Endpoint, bool bACK) { /* Just report when device was in a network*/ if (sZllState.eNodeState != E_RUNNING) return; PDUM_thAPduInstance myPDUM_thAPduInstance; tsZCL_Address sDestinationAddress; DBG_vPrintf(TRACE_APP, "APP Report: APP_vReportStatusButtonImmediately\n"); /* get buffer to write the response in*/ myPDUM_thAPduInstance = hZCL_AllocateAPduInstance(); if (myPDUM_thAPduInstance == PDUM_INVALID_HANDLE) { DBG_vPrintf(TRACE_APP, "APP Report: PDUM_INVALID_HANDLE\n"); } /* Set the address mode to send to all bound device and don't wait for an ACK*/ if (bACK) { sDestinationAddress.eAddressMode = E_ZCL_AM_SHORT; } else { sDestinationAddress.eAddressMode = E_ZCL_AM_SHORT_NO_ACK; } sDestinationAddress.uAddress.u16DestinationAddress = 0x0000; eZCL_SetReportableFlag( u8Endpoint, GENERAL_CLUSTER_ID_ONOFF, TRUE, FALSE, E_CLD_ONOFF_ATTR_ID_ONOFF); /* Send the report with all attributes.*/ if (E_ZCL_SUCCESS != eZCL_ReportAllAttributes(&sDestinationAddress, GENERAL_CLUSTER_ID_ONOFF, u8Endpoint, // from end point 1, // send to Coordinator myPDUM_thAPduInstance)) { DBG_vPrintf(TRACE_APP, "APP Report: Error Sending Report\n"); } /* free buffer and return*/ PDUM_eAPduFreeAPduInstance(myPDUM_thAPduInstance); DBG_vPrintf(TRACE_APP, "APP Report: Report Sent\n"); } //PUBLIC void APP_cbTimerFactoryReset(void *pvParam) //{ // ZTIMER_eStop(u8TimerFactoryReset); // if(u8FactoryResetCnt >= 1){ // APP_tsEvent sButtonEvent; // sButtonEvent.eType = APP_E_EVENT_LEAVE_AND_RESET; // DBG_vPrintf(TRACE_APP, "Timer Factory Reset expired\n"); // if(ZQ_bQueueSend(&APP_msgAppEvents, &sButtonEvent) == FALSE) // { // DBG_vPrintf(TRACE_APP, "Timer Factory Reset: Failed to post Event %d \n", sButtonEvent.eType); // } // } // else{ // u8FactoryResetCnt++; // /*indicator prepare to Factory Reset*/ // APP_vIdcFactoryReset(); // ZTIMER_eStart(u8TimerFactoryReset, ZTIMER_TIME_SEC(5)); // } // //} PUBLIC void APP_cbTimerButtonPress(void *pvParam) { ZTIMER_eStop(u8TimerButtonPress); if(u8ButtonPressCnt <= 5){ u8ButtonPressCnt++; ZTIMER_eStart(u8TimerButtonPress, TIME_BUTTON_INTERVAL); } DBG_vPrintf(TRACE_APP, " >>>> Button press in %d seconds \n",u8ButtonPressCnt); /*Indicator press 3s*/ APP_vIdcButtonPressInSec(u8ButtonPressCnt); // /*Show LED*/ // if(u8ButtonPressCnt == 3){ // DBG_vPrintf(TRACE_APP, " >>>> Button press in %d seconds \n",u8ButtonPressCnt); // /*Indicator press 3s*/ // APP_vIdcButtonPressInSec(u8ButtonPressCnt); // } // else if(u8ButtonPressCnt == 5){ // DBG_vPrintf(TRACE_APP, " >>>> Button press in %d seconds \n",u8ButtonPressCnt); // /*Indicator press 5s*/ // APP_vIdcButtonPressInSec(u8ButtonPressCnt); // } } //static bool bLEDOn = FALSE; PUBLIC void APP_cbTimerBlinkLED(void *pvParam) { APP_cbTimerIndicator(); } //EP EVT PUBLIC void APP_cbTimerCheckConnection(void *pvParam) { ZTIMER_eStop(u8TimerCheckConection); ZTIMER_eStart(u8TimerCheckConection, TIME_CHECK_CONNECTION); /* Just report when device was in a network*/ if (sZllState.eNodeState != E_RUNNING) return; tsZCL_Address sAddress; tsStackInfo sStackInfo; uint8 u8SeqNum = 0; uint16 u16RStateReportGroupEndpoint; u16RStateReportGroupEndpoint = 0; /*Attribute Infor */ vGetStackMeasure( &sStackInfo ); if ((sStackInfo.u32PeakMeasure >= 5400) && (sStackInfo.u32PeakMeasure <= 5600)) // 90% Stack { u16RStateReportGroupEndpoint |= MON_MeasureStack_RAM90_MASK; } else if (sStackInfo.u32PeakMeasure > 5600) //95% Stack { u16RStateReportGroupEndpoint |= MON_MeasureStack_RAM95_MASK; } if (sBaseDevice.sOnOffServerCluster.bOnOff == TRUE) { u16RStateReportGroupEndpoint |= 0x0001; } DBG_vPrintf(TRACE_APP, "APP Report: Periodic Report to Central %04x \n", u16RStateReportGroupEndpoint); if(u8RejoinNwkStatus == FALSE){ if(u8reportStatusFalseCnt < 3){ u8reportStatusFalseCnt++; DBG_vPrintf(TRACE_APP, "APP: >>>>> Report False: %d <<<<<< \n",u8reportStatusFalseCnt); } else{ DBG_vPrintf(TRACE_APP, "APP: >>>>> Report False more time, Auto Rejoin NWk <<<<<< \n"); u8reportStatusFalseCnt = 0; u8RejoinNwkStatus = TRUE; APP_vIdcUnPair(); /*setting beacon filter: See B.4 - page 494 - JN-UG-3113*/ //ZPS_bAppAddBeaconFilter(); if(ZPS_eAplZdoRejoinNetwork(TRUE) == ZPS_E_SUCCESS){ DBG_vPrintf(TRACE_APP, "SW_APP: Rejoin NWk ZPS_E_SUCCESS \n"); } else{DBG_vPrintf(TRACE_APP, "SW_APP: Rejoin NWk Fail \n");} } } else{ sAddress.eAddressMode = E_ZCL_AM_SHORT; sAddress.uAddress.u16DestinationAddress = 0x0000; sBaseDevice.sBasicServerCluster.u16ReportGroupEndpoint = u16RStateReportGroupEndpoint; //sBaseDevice.sBasicServerCluster. = u16RStateReportGroupEndpoint; PDUM_thAPduInstance myPDUM_thAPduInstance; /* get buffer to write the response in u16TouchConfig*/ myPDUM_thAPduInstance = hZCL_AllocateAPduInstance(); if (myPDUM_thAPduInstance == PDUM_INVALID_HANDLE) { DBG_vPrintf(TRACE_APP, "APP Report: PDUM_INVALID_HANDLE\n"); } eZCL_SetReportableFlag( ROUTER_APPLICATION_ENDPOINT, GENERAL_CLUSTER_ID_BASIC, TRUE, FALSE, E_CLD_BAS_ATTR_RP_GROUP_ENPOINT); /* Send the report with all attributes.*/ if (E_ZCL_SUCCESS != eZCL_ReportAllAttributes(&sAddress, GENERAL_CLUSTER_ID_BASIC, ROUTER_APPLICATION_ENDPOINT, 1, myPDUM_thAPduInstance)) { DBG_vPrintf(TRACE_APP, "APP Report: Error Sending Report\n"); } /* free buffer and return*/ PDUM_eAPduFreeAPduInstance(myPDUM_thAPduInstance); DBG_vPrintf(TRACE_APP, "APP Report: Report Sent mode %d\n",sAddress.eAddressMode); } } PUBLIC void APP_cbTimerTimeOutCheckConnection(void *pvParam) { ZTIMER_eStop(u8TimerTimeOutCheckConnect); DBG_vPrintf(TRACE_APP, "Timeout check connection\n"); /* Connection lost -> retry connect */ APP_vIdcPairing(); } #if BDB_JOIN_USES_INSTALL_CODE_KEY == TRUE /**************************************************************************** * * NAME: APP_vSetICDerivedLinkKey * * DESCRIPTION: * Setting up an install code derived link key * Install code is 8-byte MAC address repeated once. * * RETURNS: * void * ****************************************************************************/ PRIVATE void APP_vSetICDerivedLinkKey() { int i; uint8 au8ICode[16]; uint64 u64MyMacAddr = ZPS_u64NwkNibGetExtAddr(ZPS_pvAplZdoGetNwkHandle()); /* Test Vector = {0x83,0xFE,0xD3,0x40,0x7A,0x93,0x97,0x23,0xA5,0xC6,0x39,0xB2,0x69,0x16,0xD5,0x05}; */ /* Copy uint64 MAC into array twice */ for (i=0; i<=15; i++) { au8ICode[15-i]= ((u64MyMacAddr >> (i%8)*8) & (0xFF)); } for (i=0; i<16; i++) { DBG_vPrintf(TRACE_APP, "%02x", au8ICode[i]); } DBG_vPrintf(TRACE_APP, "\n"); ZPS_vAplSecSetInitialSecurityState( ZPS_ZDO_PRCONFIGURED_INSTALLATION_CODE, au8ICode, 16, ZPS_APS_GLOBAL_LINK_KEY); } #endif PRIVATE void APP_vFirstReport(void) { PDUM_thAPduInstance myPDUM_thAPduInstance; tsZCL_Address sDestinationAddress; DBG_vPrintf(TRACE_APP, "APP Report: Sending First Report\n"); /* get buffer to write the response in*/ myPDUM_thAPduInstance = hZCL_AllocateAPduInstance(); if (myPDUM_thAPduInstance == PDUM_INVALID_HANDLE) { DBG_vPrintf(TRACE_APP, "APP Report: PDUM_INVALID_HANDLE\n"); } /* Set the address mode to send to all bound device and don't wait for an ACK*/ sDestinationAddress.eAddressMode = E_ZCL_AM_SHORT; sDestinationAddress.uAddress.u16DestinationAddress =0x0000; eZCL_SetReportableFlag( ROUTER_APPLICATION_ENDPOINT, GENERAL_CLUSTER_ID_BASIC, TRUE, FALSE, E_CLD_BAS_ATTR_ID_MODEL_IDENTIFIER); /* Send the report with all attributes.*/ if (E_ZCL_SUCCESS != eZCL_ReportAllAttributes(&sDestinationAddress, GENERAL_CLUSTER_ID_BASIC, ROUTER_APPLICATION_ENDPOINT, 1, myPDUM_thAPduInstance)) { DBG_vPrintf(TRACE_APP, "APP Report: Error Sending Report\n"); } /* free buffer and return*/ PDUM_eAPduFreeAPduInstance(myPDUM_thAPduInstance); DBG_vPrintf(TRACE_APP, "APP Report: Report Sent\n"); } /****************************************************************************/ /*** END OF FILE ***/ /****************************************************************************/