Esempio n. 1
0
/*****************************************************************************
 Timer handler
*****************************************************************************/
static void OnTimeOut(uint8_t tmr) 
{
  (void) tmr;
  
   /* Initiate association */
   TS_SendEvent(gOepAgentTaskID, evtAssocReq_c);  
}
Esempio n. 2
0
/******************************************************************************
* 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);
  
}
Esempio n. 3
0
/*****************************************************************************
* 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);
  }
}
Esempio n. 4
0
/*****************************************************************************
  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);
  
}
Esempio n. 5
0
/* 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);
}
Esempio n. 6
0
/* 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) */ 
}
Esempio n. 7
0
/* 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() */
Esempio n. 8
0
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);
}
Esempio n. 9
0
/*****************************************************************************
*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);  
}
Esempio n. 10
0
/*Call Back function when the interrupt occurs*/
void TmrCompEvCallBack(TmrNumber_t tmrNumber)
{
  
  TS_SendEvent(mTimerTaskID, mTMR_Event_c);
  
}
Esempio n. 11
0
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 */
}