/***************************************************************************** Timer handler *****************************************************************************/ static void OnTimeOut(uint8_t tmr) { (void) tmr; /* Initiate association */ TS_SendEvent(gOepAgentTaskID, evtAssocReq_c); }
/****************************************************************************** * Keyboard ISR. ******************************************************************************/ void CrmKBDIsr(void) { /*Disable all external interrupts and send the SW event to handle the key detection*/ KbDisableAllIrq(); TS_SendEvent(mSwTaskID, mEventSW_c); }
/***************************************************************************** * UartRxCallBack * * This callback is triggered when a new byte is received over the UART * *****************************************************************************/ static void UartRxCallBack(void) { uint8_t pressedKey; if(stateListen == gState){ TS_SendEvent(gAppTaskID_c, gAppEvtRxFromUart_c); }else{ (void)UartX_GetByteFromRxBuffer(&pressedKey); } }
/***************************************************************************** OepAgent_HandleApdu Handle APDU's sent by ZCL *****************************************************************************/ void OepAgent_HandleApdu(OepFragmentedApdu_t *pApdu) { /* Add to Oep11073 queue */ MSG_Queue(&gOepAgentQueue, pApdu); /* Send event to 11073 task */ TS_SendEvent(gOepAgentTaskID, evtApduReceived_c); }
/* Enable or disable the timer tmrID If enable = TRUE timer is active Else timer is inactive */ void TMR_EnableTimer(tmrTimerID_t tmrID) { unsigned int saveInt; saveInt = IntDisableAll(); if (TMR_GetTimerStatus(tmrID) == mTmrStatusInactive_c) { IncrementActiveTimerNumber(TMR_GetTimerType(tmrID)); TMR_SetTimerStatus(tmrID, mTmrStatusReady_c); TS_SendEvent(mTimerTaskID, mTMR_Event_c); } IntRestoreAll(saveInt); }
/* The function make an approximate sync. the active low power timers. */ void TMR_SyncLpmTimers(uint32_t sleepDurationTmrTicks) { #if (gTMR_EnableLowPowerTimers_d) index_t timerID; tmrTimerType_t timerType; /* Check if there are low power active timer */ if (!numberOfLowPowerActiveTimers) return; /* For each timer, detect the timer type and count down the spent duration in sleep */ for (timerID = 0; timerID < NumberOfElements(maTmrTimerTable); ++timerID) { /* Detect the timer type and count down the spent duration in sleep */ timerType = TMR_GetTimerType(timerID); /* Sync. only the low power timers that are active */ if ( (TMR_GetTimerStatus(timerID) == mTmrStatusActive_c) && (IsLowPowerTimer(timerType)) ) { /* Timer expired when MCU was in sleep mode??? */ if( maTmrTimerTable[timerID].remainingTicks > sleepDurationTmrTicks) { maTmrTimerTable[timerID].remainingTicks -= sleepDurationTmrTicks; } else { maTmrTimerTable[timerID].remainingTicks = 0; } } }/* end for (timerID = 0;.... */ TmrStartTimerHardware(); TmrReadValue(gTmrNumber_d, &previousTimeInTicks); TS_SendEvent(mTimerTaskID, mTMR_Event_c); #else (void)sleepDurationTmrTicks; #endif /* #if (gTMR_EnableLowPowerTimers_d) */ }
/* Stop a timer. Does not free the timer; does not call the timer's callback * function. * * Harmless if the timer is already inactive. */ void TMR_StopTimer ( tmrTimerID_t timerID ) { tmrStatus_t status; unsigned int saveInt; saveInt = IntDisableAll(); status = TMR_GetTimerStatus(timerID); if ( status == mTmrStatusActive_c || status == mTmrStatusReady_c) { TMR_SetTimerStatus(timerID, mTmrStatusInactive_c); DecrementActiveTimerNumber(TMR_GetTimerType(timerID)); /* if no sw active timers are enabled, */ /* call the TMR_Task() to countdown the ticks and stop the hw timer*/ if (!numberOfActiveTimers && !numberOfLowPowerActiveTimers) TS_SendEvent(mTimerTaskID, mTMR_Event_c); } IntRestoreAll(saveInt); } /* TMR_StopTimer() */
void OepAgentTask ( event_t event ) { oepGenericApdu_t* pApdu = NULL; if (event & evtApduReceived_c) { pCurrentFragApdu = MSG_DeQueue(&gOepAgentQueue); /* Check if this is a ZTC configuration message */ if (pCurrentFragApdu != NULL) { pApdu = (oepGenericApdu_t*) &(pCurrentFragApdu->fragment.data); if(GetOepMsgType(pApdu) == msgType_ObjCfgMsg) { oepCsManagerHandleConfigMsg(pApdu, &agentBuffer[0], 200, mAgentAddrInfo.srcEndPoint); /* Don't handle the pCurrentFragApdu fragment further */ //event &= ~evtApduReceived_c; } } } switch (currentState) { case stateDisconnected_c: HandleDisconnectedState(event); break; case stateConnDissasociating_c: HandleConnDissasociatingState(event); break; case stateConnUnassociated_c: HandleConnUnassociatedState(event); break; case stateConnAssociating_c: HandleConnAssociatingState(event); break; case stateConnAssocOperating_c: HandleConnConnAssocOperatingState(event); break; case stateConnAssocConfSc_c: /* skip this state, go directly to stateConnAssocConfWa_c */ break; case stateConnAssocConfWa_c: HandleConnAssocConfWaState(event); break; default: break; } if (pCurrentFragApdu) { OepFreeFragmentedApdu(pCurrentFragApdu); pCurrentFragApdu = NULL; } if (MSG_Pending(&gOepAgentQueue)) TS_SendEvent(gOepAgentTaskID, evtApduReceived_c); }
/***************************************************************************** *Mac Application Task event processor. This function is called to * process all events for the task. Events include timers, messages and any * other user defined events * * Interface assumptions: None * * Return value: None *****************************************************************************/ void AppTask(event_t events) { /* Pointer for storing the messages from MLME, MCPS, and ASP. */ void *pMsgIn; /* Stores the status code returned by some functions. */ uint8_t rc; pMsgIn = NULL; /* Dequeue the MLME message */ if (events & gAppEvtMessageFromMLME_c) { /* Get the message from MLME */ pMsgIn = MSG_DeQueue(&mMlmeNwkInputQueue); /* Any time a beacon might arrive. Always handle the beacon frame first */ if (pMsgIn) { rc = App_WaitMsg(pMsgIn, gNwkBeaconNotifyInd_c); if(rc == errorNoError) { /* ALWAYS free the beacon frame contained in the beacon notify indication.*/ /* ALSO the application can use the beacon payload.*/ MSG_Free(((nwkMessage_t *)pMsgIn)->msgData.beaconNotifyInd.pBufferRoot); UartUtil_Print("Received an MLME-Beacon Notify Indication\n\r", gAllowToBlock_d); } } } /* The application state machine */ switch(gState) { case stateInit: /* Print a welcome message to the UART */ UartUtil_Print("MyWirelessApp Demo Non Beacon End Device application is initialized and ready.\n\r\n\r", gAllowToBlock_d); /* Goto Active Scan state. */ gState = stateScanActiveStart; TS_SendEvent(gAppTaskID_c, gAppEvtDummyEvent_c); break; case stateScanActiveStart: /* Start the Active scan, and goto wait for confirm state. */ UartUtil_Print("Start scanning for a PAN coordinator\n\r", gAllowToBlock_d); /*print a message on the LCD also*/ LCD_ClearDisplay(); LCD_WriteString(1,"Start scanning"); LCD_WriteString(2,"for coordinator"); rc = App_StartScan(gScanModeActive_c); if(rc == errorNoError) { gState = stateScanActiveWaitConfirm; } break; case stateScanActiveWaitConfirm: /* Stay in this state until the Scan confirm message arrives, and then goto the associate state. */ if (events & gAppEvtMessageFromMLME_c) { if (pMsgIn) { rc = App_WaitMsg(pMsgIn, gNwkScanCnf_c); if(rc == errorNoError) { rc = App_HandleScanActiveConfirm(pMsgIn); if(rc == errorNoError) { UartUtil_Print("Found a coordinator with the following properties:\n\r", gAllowToBlock_d); UartUtil_Print("----------------------------------------------------", gAllowToBlock_d); UartUtil_Print("\n\rAddress...........0x", gAllowToBlock_d); UartUtil_PrintHex(mCoordInfo.coordAddress, mCoordInfo.coordAddrMode == gAddrModeShort_c ? 2 : 8, 0); UartUtil_Print("\n\rPAN ID............0x", gAllowToBlock_d); UartUtil_PrintHex(mCoordInfo.coordPanId, 2, 0); UartUtil_Print("\n\rLogical Channel...0x", gAllowToBlock_d); UartUtil_PrintHex(&mCoordInfo.logicalChannel, 1, 0); UartUtil_Print("\n\rBeacon Spec.......0x", gAllowToBlock_d); UartUtil_PrintHex(mCoordInfo.superFrameSpec, 2, 0); UartUtil_Print("\n\rLink Quality......0x", gAllowToBlock_d); UartUtil_PrintHex(&mCoordInfo.linkQuality, 1, 0); UartUtil_Print("\n\r\n\r", gAllowToBlock_d); gState = stateAssociate; TS_SendEvent(gAppTaskID_c, gAppEvtDummyEvent_c); } else { UartUtil_Print("Scan did not find a suitable coordinator\n\r", gAllowToBlock_d); /*print a message on the LCD also*/ LCD_ClearDisplay(); LCD_WriteString(1,"No coordinator"); LCD_WriteString(2,"found."); } } } } break; case stateAssociate: /* Associate to the PAN coordinator */ UartUtil_Print("Associating to PAN coordinator on channel 0x", gAllowToBlock_d); UartUtil_PrintHex(&(mCoordInfo.logicalChannel), 1, gPrtHexNewLine_c); /*print a message on the LCD also*/ LCD_ClearDisplay(); LCD_WriteString(1,"Associating to "); LCD_WriteString(2,"PAN coordinator"); rc = App_SendAssociateRequest(); if(rc == errorNoError) gState = stateAssociateWaitConfirm; break; case stateAssociateWaitConfirm: /* Stay in this state until the Associate confirm message arrives, and then goto the Listen state. */ if (events & gAppEvtMessageFromMLME_c) { if (pMsgIn) { rc = App_WaitMsg(pMsgIn, gNwkAssociateCnf_c); if(rc == errorNoError) { rc = App_HandleAssociateConfirm(pMsgIn); if (rc == errorNoError) { UartUtil_Print("Successfully associated with the coordinator.\n\r", gAllowToBlock_d); UartUtil_Print("We were assigned the short address 0x", gAllowToBlock_d); UartUtil_PrintHex(maMyAddress, mAddrMode == gAddrModeShort_c ? 2 : 8, 0); UartUtil_Print("\n\r\n\rReady to send and receive data over the UART.\n\r\n\r", gAllowToBlock_d); /*print a message on the LCD also*/ LCD_ClearDisplay(); LCD_WriteString(1,"Ready to send"); LCD_WriteString(2,"and receive data"); /* Startup the timer */ TMR_StartSingleShotTimer(mTimer_c, mPollInterval, AppPollWaitTimeout); /* Go to the listen state */ gState = stateListen; TS_SendEvent(gAppTaskID_c, gAppEvtDummyEvent_c); } else { UartUtil_Print("\n\rAssociate Confirm wasn't successful... \n\r\n\r", gAllowToBlock_d); gState = stateScanActiveStart; TS_SendEvent(gAppTaskID_c, gAppEvtDummyEvent_c); } } } } break; case stateListen: //WSNProject //need to sleep? PWR_AllowDeviceToSleep(); Reason=PWR_EnterLowPower(); /* Transmit to coordinator data received from UART. */ if (events & gAppEvtMessageFromMLME_c) { if (pMsgIn) { /* Process it */ rc = App_HandleMlmeInput(pMsgIn); } } if (events & gAppEvtRxFromUart_c) { /* get byte from UART */ App_TransmitUartData(); } break; } if (pMsgIn) { /* Messages must always be freed. */ MSG_Free(pMsgIn); } /* Handle MCPS confirms and transmit data from UART */ if (events & gAppEvtMessageFromMCPS_c) { /* Get the message from MCPS */ pMsgIn = MSG_DeQueue(&mMcpsNwkInputQueue); if (pMsgIn) { /* Process it */ App_HandleMcpsInput(pMsgIn); /* Messages from the MCPS must always be freed. */ MSG_Free(pMsgIn); } } /* Check for pending messages in the Queue */ if(MSG_Pending(&mMcpsNwkInputQueue)) TS_SendEvent(gAppTaskID_c, gAppEvtMessageFromMCPS_c); if(MSG_Pending(&mMlmeNwkInputQueue)) TS_SendEvent(gAppTaskID_c, gAppEvtMessageFromMLME_c); }
/*Call Back function when the interrupt occurs*/ void TmrCompEvCallBack(TmrNumber_t tmrNumber) { TS_SendEvent(mTimerTaskID, mTMR_Event_c); }
void ZDO_NwkManager ( nlmeZdoMessage_t *pZdoMsg /*IN: Message received from ZDO*/ ) { nlmeJoinIndication_t *pJoinIndication; uint8_t aNwkAddr[2]; (void)aNwkAddr; gMemoryFreedByApplication = FALSE; switch (pZdoMsg->msgType) { /************************************************************************************* NLME-Formation.confirm: Formation confirm is only available for PAN Coordinator devices or combo devices acting like coordinator. **************************************************************************************/ case gNlmeNetworkFormationConfirm_c: #if ( gCoordinatorCapability_d || gComboDeviceCapability_d) #if gComboDeviceCapability_d /* If a combo device is not acting like a PAN Coordinator should not do any further processing. */ if (NlmeGetRequest(gDevType_c) != gCoordinator_c) { break; } #endif /* Send an event to the ZDO state machine informing the fromation status. */ if (pZdoMsg->msgData.networkFormationConf.status == gZbSuccess_c) { ZDO_SendEvent(gZdoEvent_FormationSuccess_c); } else { ZDO_SendEvent(gZdoEvent_FormationFailure_c); } #endif break; /************************************************************************************* NLME-Discovery.confirm **************************************************************************************/ case gNlmeNetworkDiscoveryConfirm_c: /* If the device is trying to associate it self to a PAN, the state machine changes to be on gZdoDiscoveringNetworksState_c. */ if (ZDO_GetState() == gZdoDiscoveringNetworksState_c) { ZdoEvent_t event; /* The discovery information have already been stored by the NWK layer. Free up the confirm. */ if(pZdoMsg->msgData.networkDiscoveryConf.pNetworkDescriptor != NULL) { MSG_Free( pZdoMsg->msgData.networkDiscoveryConf.pNetworkDescriptor ); } /* send an event to state machine task depending on the confirmation */ event = (pZdoMsg->msgData.networkDiscoveryConf.status == gZbSuccess_c)? gZdoEvent_DiscoverySuccess_c : gZdoEvent_DiscoveryFailure_c; ZDO_SendEvent(event); /* Setting this variable to FALSE means that ZDO will free the message and not the application. */ gMemoryFreedByApplication = FALSE; break; } /*********************************************************************************** For any of this cases the tables does not need to be arround so lets free up the memory. IMPORTANT: The tables need to be freed to avoid memory leaks. ************************************************************************************/ NWK_FreeUpDiscoveryTables(); /* If the device is on running state this means that it may be the application the one commanding the discovery. */ if(ZDO_IsRunningState()) { /* Reprot the discovery information to hte application. */ ( void ) ZDP_APP_SapHandler((zdpToAppMessage_t *)pZdoMsg); /* Setting this variable to TRUE means that the application is responsible of freeing the list inside the discovery message. */ gMemoryFreedByApplication = TRUE; } /* Management commands prevent the ZDO stae machine for doing anything but finishing the process of the remote command. */ else if (ZDO_GetState() == gZdoRemoteCommandsState_c) { #if gMgmt_NWK_Disc_rsp_d /* Generate the response through zdpmanager */ Zdp_Mgmt_Send_Nwk_disc_conf( pZdoMsg ); #endif ZDO_SendEvent(gZdoEvent_ManagementResponse_c); /* The information was copied in ZDP so the list inside the packet is no longer needed. */ if (pZdoMsg->msgData.networkDiscoveryConf.pNetworkDescriptor != NULL) { MSG_Free( pZdoMsg->msgData.networkDiscoveryConf.pNetworkDescriptor ); } /* Setting this variable to FALSE means that all the buffers are free, no need to re-free it. */ gMemoryFreedByApplication = FALSE; } else { /* Clean up the discovery tables in the stack */ NWK_FreeUpDiscoveryTables(); if (pZdoMsg->msgData.networkDiscoveryConf.pNetworkDescriptor != NULL) { MSG_Free( pZdoMsg->msgData.networkDiscoveryConf.pNetworkDescriptor ); } gMemoryFreedByApplication = FALSE; } break; /************************************************************************************* NLME-Join.confirm: We have join TO SOME ONE. **************************************************************************************/ case gNlmeJoinConfirm_c: #if gRouterCapability_d || gEndDevCapability_d || gComboDeviceCapability_d /* Make sure that the discovery tables have been freed after join request has been processed. */ NWK_FreeUpDiscoveryTables(); /* If a combo device is not router or end device should not proceed. */ #if gComboDeviceCapability_d if (NlmeGetRequest(gDevType_c) == gCoordinator_c) { break; } #endif /* If the device is already on running state the node may receive the unsolicited rejoin response because of and addressconflict, so ignore the join confirm. */ if (ZDO_IsRunningState()) break; /* If the device is not running then force it to parse the confirm. */ ZDO_SetState(gZdoJoiningState_c); /* Send an event to the ZDO state machine informing about the joining state. */ if( pZdoMsg->msgData.joinConf.status == gZbSuccess_c ) { ZDO_SendEvent(gZdoEvent_JoinSuccess_c); } else { ZDO_SendEvent(gZdoEvent_JoinFailure_c); } #endif break; /************************************************************************************* NLME-Join.indication: A device has join TO US. **************************************************************************************/ case gNlmeJoinIndication_c: /* Do the casting for the message one time and in one place, Code saving. */ pJoinIndication = &pZdoMsg->msgData.joinIndication; /* To avoid reject packets when the node join and comunicate multi ple times, the devices should flush the APS Duplicate table. */ APS_RemoveEntryFromApsDuplicateTable(pJoinIndication->aShortAddress); /* Every child joined to us must be record, to avoid lossing it in case of reset. */ ZdoNwkMng_SaveToNvm(zdoNvmObject_NeighborTable_c); #if gRnplusCapability_d #if gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d #if gComboDeviceCapability_d if (NlmeGetRequest(gDevType_c) != gEndDevice_c) #endif { /* Remove the old routes to the joining device */ RemoveRouteEntry(pJoinIndication->aShortAddress); } #endif #endif #if gStandardSecurity_d || gHighSecurity_d /* If the joining device is associated from scratch erase previous data. */ if (pJoinIndication->rejoinNetwork == gAssociationJoin_c) { if (ApsmeGetRequest(gApsDefaultTCKeyType_c) == gTrustCenterLinkKey_c) { APS_ResetDeviceCounters(pJoinIndication->aExtendedAddress); } else { APS_RemoveSecurityMaterialEntry(pJoinIndication->aExtendedAddress); } /* Setting the last parameter to TRUE will erase APS secure material */ ZDO_SecClearDeviceData(pJoinIndication->aShortAddress, pJoinIndication->aExtendedAddress, FALSE); } /* If security is active and the joining mode is other that association join, no further processing should be done to the join indication. Consider the unsecure join. */ //else if ((pJoinIndication->rejoinNetwork == gNwkRejoin_c) && pJoinIndication->secureRejoin) //{ /* Make sure the memory will be freed */ //gMemoryFreedByApplication = FALSE; /* Do not process it further, no transport key will be needed. */ //return; //} else if (pJoinIndication->rejoinNetwork == gNwkRejoin_c && !pJoinIndication->secureRejoin) { /* Reset the Incoming frame counter of the dev that has left. */ /* Setting the last parameter to TRUE will erase APS secure material */ if (ApsmeGetRequest(gApsDefaultTCKeyType_c) == gTrustCenterLinkKey_c) { APS_ResetDeviceCounters(pJoinIndication->aExtendedAddress); } else { APS_RemoveSecurityMaterialEntry(pJoinIndication->aExtendedAddress); } /* Setting the last parameter to TRUE will erase APS secure material */ ZDO_SecClearDeviceData(pJoinIndication->aShortAddress, pJoinIndication->aExtendedAddress, FALSE); } /* The device must be set as Unauthenticated child in the NT. */ SSP_NwkSetRelationship(pJoinIndication->aExtendedAddress, gUnAuthenticatedChild_c); /* Keep the buffer around to be use in the state machine or the application. */ gMemoryFreedByApplication = TRUE; /*************************************************** Trust center specific join indication processing. ****************************************************/ #if gTrustCenter_d || gComboDeviceCapability_d #if gComboDeviceCapability_d if (gTrustCenter) #endif { /* Keep the information, we are going to start the joining state machine. */ MSG_Queue(&gJoinIndicationQueue, pZdoMsg); /* Tell the ZDO Task that we got a joining device packet and ready for action. */ TS_SendEvent(gZdoTaskID_c, gJoinIndicationArrive_c); } #endif #if !gTrustCenter_d || gComboDeviceCapability_d #if gComboDeviceCapability_d if (!gTrustCenter) #endif { uint8_t joiningType; bool_t isHighSecurity = FALSE; /* Every other device with joining capabilities should report the joining, using an APSME-UPDATE-DEVICE.request. */ isHighSecurity = (pJoinIndication->capabilityInformation & gSecurityCapability_c)? TRUE : FALSE; if (pJoinIndication->rejoinNetwork == gAssociationJoin_c) { joiningType = (isHighSecurity)? gHighSecurityDeviceUnsecuredJoin_c : gStandardDeviceUnsecuredJoin_c; } else if (pJoinIndication->rejoinNetwork == gNwkRejoin_c) { if (pJoinIndication->secureRejoin) { joiningType = (isHighSecurity)? gHighSecurityDeviceSecuredReJoin_c : gStandardDeviceSecuredReJoin_c; } else { joiningType = (isHighSecurity)? gHighSecurityDeviceUnsecuredRejoin_c : gStandardDeviceUnsecuredRejoin_c; } } // Always send the update device ZDO_APSME_Update_Device_request(pJoinIndication->aExtendedAddress, pJoinIndication->aShortAddress, joiningType, pJoinIndication->secureRejoin); (void)ZDP_APP_SapHandler((void *)pZdoMsg); } #endif /* #endif gStandardSecurity_d */ #endif break; /*break for join indication*/ /************************************************************************************* NLME-StartRouter.confirm: Every time that a Coordinator or a Router starts, genrates a start router confirm. **************************************************************************************/ case gNlmeStartRouterConfirm_c: #if gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d /* Combo devices acting like ZED don't need this confirm. */ #if gComboDeviceCapability_d if (NlmeGetRequest(gDevType_c) == gEndDevice_c) { break; } #endif /* Indicate router has started (or not) */ if (pZdoMsg->msgData.startRouterConf.status == gZbSuccess_c) { ZDO_SendEvent(gZdoEvent_StartRouterSuccess_c); } else { ZDO_SendEvent(gZdoEvent_StartRouterFailure_c); } #endif break; /************************************************************************************* NLME-Sync.confirm **************************************************************************************/ case gNlmeSyncConfirm_c: #if gEndDevCapability_d || gComboDeviceCapability_d #if gComboDeviceCapability_d if (NlmeGetRequest(gDevType_c) != gEndDevice_c) { break; } #endif pZdoMsg->msgType = gSyncConf_c; ( void ) ZDP_APP_SapHandler( (void *)pZdoMsg ); /* The application is responsible of freen the buffers. */ gMemoryFreedByApplication = TRUE; #endif break; /************************************************************************************* NLME-PermitJoining.confirm **************************************************************************************/ case gNlmePermitJoiningConfirm_c: #if gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d #if gComboDeviceCapability_d if (NlmeGetRequest(gDevType_c) == gEndDevice_c) { break; } #endif if(ZDO_IsRunningState()) { /* let application know about the permit join */ pZdoMsg->msgType = gPermitjoinConf_c; ( void ) ZDP_APP_SapHandler( (void *)pZdoMsg ); /* indicate this SAP handler won't be freeing the memory */ gMemoryFreedByApplication = TRUE; } #endif break; /************************************************************************************* NLME-DirectJoin.confirm **************************************************************************************/ case gNlmeDirectJoinConfirm_c: #if gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d #if gComboDeviceCapability_d if (NlmeGetRequest(gDevType_c) == gEndDevice_c) { break; } #endif /* The may come because the network layer start the direct join and the confirm must be pass up to the application. */ if (ZDO_IsRunningState()) { /* Send message on to app. Tell this SAP handler not to free it. */ (void) ZDP_APP_SapHandler( (void *)pZdoMsg ); gMemoryFreedByApplication = TRUE; } else if (ZDO_GetState() == gZdoRemoteCommandsState_c) { ZDO_SendEvent(gZdoEvent_ManagementResponse_c); #if gMgmt_Direct_Join_rsp_d && (gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d) #if gComboDeviceCapability_d if (NlmeGetRequest(gDevType_c) == gEndDevice_c) { break; } #endif /* Generate the response through zdpmanager */ Zdp_Mgmt_Direct_Join_conf( pZdoMsg ); /* Update the global variable to free the menory */ gMemoryFreedByApplication = TRUE; #endif } #endif break; /************************************************************************************* NLME-Leave.indication **************************************************************************************/ case gNlmeLeaveIndication_c: /* The local node is the one leaving the network. */ if (Cmp8BytesToZero(pZdoMsg->msgData.leaveIndication.aDeviceAddress)) { /* Only important to the local leave. Pick an appropiated leaving event. */ ZdoStopMode_t stopMode; /* Send event to ZDO state machine to initiate the reset procedure (r11, p272, ln31) The devices should not set the default mode to stop the node on a leave indication, the default mode send another leave.... and we just left. */ stopMode = gZdoStopModeDefault_c | gZdoStopMode; if (pZdoMsg->msgData.leaveIndication.rejoin) { /* We will come back.! */ stopMode |= gZdoStopMode_StopAndRestart_c; /* We are doing rejoin, we should not clear the tables. */ stopMode &= ~gZdoStopMode_ResetTables_c; } /* End of if (pZdoMsg->msgData.leaveIndication.rejoin) */ /* Tell ZDO to pull the breaks; */ ZDO_StopEx(stopMode); break; } /* End of if (Cmp8BytesToZero(pZdoMsg->msgData.leaveIndication.aDeviceAddress)) */ /* If we got the indiction and we are waiting for it, return to previous state. */ if (ZDO_GetState() == gZdoRemoteCommandsState_c) { ZDO_SendEvent(gZdoEvent_ManagementResponse_c); } #if gStandardSecurity_d || gHighSecurity_d #if gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d #if gComboDeviceCapability_d if (NlmeGetRequest(gDevType_c) == gEndDevice_c) { break; } #endif /* Reset the Incoming frame counter of the dev that has left. */ SSP_NwkResetDeviceFrameCounter( pZdoMsg->msgData.leaveIndication.aDeviceAddress ); /* If the device is Link capable remove the link key information if it exists. */ APS_RemoveSecurityMaterialEntry(pZdoMsg->msgData.leaveIndication.aDeviceAddress); /* Let the trust center know about the leaving device. */ // if (!IsSelfIeeeAddress(ApsmeGetRequest(gApsTrustCenterAddress_c))) #if !gTrustCenter_d || gComboDeviceCapability_d #if gComboDeviceCapability_d if (!gTrustCenter) #endif { ZDO_APSME_Update_Device_request(pZdoMsg->msgData.leaveIndication.aDeviceAddress, APS_GetNwkAddress(pZdoMsg->msgData.leaveIndication.aDeviceAddress, aNwkAddr), gDeviceLeft_c, 0x00); } #endif #endif #endif /* ZEDs dont porcess the removing of the children and removing of the routes. */ #if gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d #if gComboDeviceCapability_d if (NlmeGetRequest(gDevType_c) == gEndDevice_c) { break; } #endif #if gRnplusCapability_d /* Remove the old routes for the leaving device */ RemoveRouteEntry(APS_GetNwkAddress(pZdoMsg->msgData.leaveIndication.aDeviceAddress, aNwkAddr)); #endif /* Clean up address map if there is no bindings referencing address map entry consider deleting all bindings first. */ (void)APS_RemoveDeviceFromAddressMap(pZdoMsg->msgData.leaveIndication.aDeviceAddress); /* Tells the network layer to remove the leaving device from its tables. */ NWK_RemoveChildRecords(pZdoMsg->msgData.leaveIndication.aDeviceAddress); #endif /* Save the network data, to preserve that the leaving device is gone. Plus the counters for security (NWK and APS)that got reset. */ ZdoNwkMng_SaveToNvm(zdoNvmObject_All_c); break; /************************************************************************************* NLME-Leave.confirm **************************************************************************************/ case gNlmeLeaveConfirm_c: /* If we have received a management leave request, send the response */ if (ZDO_GetState() == gZdoRemoteCommandsState_c) { #if gMgmt_Leave_rsp_d Zdp_Mgmt_Send_leave_conf(pZdoMsg); /* The momery has been handled by the next higher layer. */ gMemoryFreedByApplication = TRUE; #endif ZDO_SendEvent(gZdoEvent_ManagementResponse_c); } /* The local node is the one leaving the network. */ if (Cmp8BytesToZero(pZdoMsg->msgData.leaveConf.aDeviceAddress)) { /* The self leave is handle in the indication. */ break; } #if gStandardSecurity_d || gHighSecurity_d #if gCoordinatorCapability_d || gRouterCapability_d || gComboDeviceCapability_d #if gComboDeviceCapability_d if (NlmeGetRequest(gDevType_c) == gEndDevice_c) { break; } #endif /* Reset the Incoming frame counter of the dev that has left. */ SSP_NwkResetDeviceFrameCounter( pZdoMsg->msgData.leaveIndication.aDeviceAddress ); /* If the device is Link capable remove the link key information if it exists. */ APS_RemoveSecurityMaterialEntry(pZdoMsg->msgData.leaveIndication.aDeviceAddress); /* Let the trust center know about the leaving device. */ ZDO_APSME_Update_Device_request(pZdoMsg->msgData.leaveIndication.aDeviceAddress, APS_GetNwkAddress(pZdoMsg->msgData.leaveIndication.aDeviceAddress, aNwkAddr), gDeviceLeft_c, 0x00); /* Tells the network layer to remove the leaving device from its tables. */ NWK_RemoveChildRecords(pZdoMsg->msgData.leaveIndication.aDeviceAddress); #endif /* #endif gStandardSecurity_d */ #endif break; /************************************************************************************* NLME-RouteDiscovery.confirm **************************************************************************************/ case gNlmeNetworkStatusCnf_c: case gNlmeRouteDiscoveryCnf_c: /* This packet will be freed by the application*/ gMemoryFreedByApplication = TRUE; /* Pass the packet to the App */ ( void ) ZDP_APP_SapHandler( (void *)pZdoMsg ); break; /************************************************************************************* NLME-EnergyScan.confirm: An Energy Scan Confirm has come back. Was it due to the forming process, or due to FA/ZDP. **************************************************************************************/ case gNlmeEnergyScanConfirm_c: if(ZDO_GetState() == gZdoDiscoveringNetworksState_c) { if (pZdoMsg->msgData.EnergyScanConf.status == gZbSuccess_c) { ZDO_SendEvent(gZdoEvent_EnergyScanComplete_c); } else { ZDO_StopEx(gZdoStopModeDefault_c); } } /* Send to application layer */ ( void ) ZDP_APP_SapHandler( (void *)pZdoMsg ); /* Update the global variable to free the memory */ gMemoryFreedByApplication = TRUE; break; case gNlmeNetworkStatusInd_c: case gNlmeTxReport_c: /* Send to application layer */ ( void ) ZDP_APP_SapHandler( (void *)pZdoMsg ); /* Update the global variable to free the memory */ gMemoryFreedByApplication = TRUE; break; case gNwkProcessFrameConf_c: #if gStandardSecurity_d || gHighSecurity_d /* Send to application layer */ ( void ) ZDP_APP_SapHandler( (void *)pZdoMsg ); /* Update the global variable to free the memory */ gMemoryFreedByApplication = TRUE; #else gMemoryFreedByApplication = FALSE; #endif break; default: break; } /* End of switch */ }