/****************************************************************************
 *
 * NAME: APP_ZCL_vInitialise
 *
 * DESCRIPTION:
 * Initialises ZCL related functions
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PUBLIC void APP_ZCL_vInitialise(void)
{
    teZCL_Status eZCL_Status;

    /* Initialise ZHA */
    eZCL_Status = eHA_Initialise(&APP_ZCL_cbGeneralCallback, apduZCL);
    if (eZCL_Status != E_ZCL_SUCCESS)
    {
        DBG_vPrintf(TRACE_ZCL, "\nAPP_ZCL: Error eHA_Initialise returned %d", eZCL_Status);
    }

    /* Register ZHA EndPoint */
    eZCL_Status = eApp_HA_RegisterEndpoint(&APP_ZCL_cbEndpointCallback);
    if (eZCL_Status != E_ZCL_SUCCESS)
    {
        DBG_vPrintf(TRACE_SENSOR_TASK, "\nAPP_ZCL: Error: eApp_HA_RegisterEndpoint:%d", eZCL_Status);
    }

    DBG_vPrintf(TRACE_SENSOR_TASK, "\nAPP_ZCL: Chan Mask %08x", ZPS_psAplAibGetAib()->apsChannelMask);
    DBG_vPrintf(TRACE_SENSOR_TASK, "\nAPP_ZCL: RxIdle TRUE");

    OS_eStartSWTimer(APP_TickTimer, ZCL_TICK_TIME, NULL);

    vAPP_ZCL_DeviceSpecific_Init();
}
/****************************************************************************
 *
 * NAME: APP_ZCL_vInitialise
 *
 * DESCRIPTION:
 * Initialises ZCL related functions
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PUBLIC void APP_ZCL_vInitialise(void)
{
    teZCL_Status eZCL_Status;

    /* Initialise ZHA */
    eZCL_Status = eHA_Initialise(&APP_ZCL_cbGeneralCallback, apduZCL);
    if (eZCL_Status != E_ZCL_SUCCESS)
    {
        DBG_vPrintf(TRACE_ZCL, "Error: eHA_Initialise returned %d\r\n", eZCL_Status);
    }

    /* Register ZHA EndPoint */
    eZCL_Status = eApp_HA_RegisterEndpoint(&APP_ZCL_cbEndpointCallback);
    if (eZCL_Status != E_ZCL_SUCCESS)
    {
            DBG_vPrintf(TRACE_SWITCH_TASK, "Error: eApp_HA_RegisterEndpoint:%d\r\n", eZCL_Status);
    }

    DBG_vPrintf(TRACE_SWITCH_TASK, "Chan Mask %08x\n", ZPS_psAplAibGetAib()->apsChannelMask);

    OS_eStartSWTimer(APP_TickTimer, ZCL_TICK_TIME, NULL);
}
void vHandleGreenPowerEvent(tsGP_GreenPowerCallBackMessage *psGPMessage)
{
    DBG_vPrintf(TRACE_APP_GP, "Green Power Callback Message\n");
    uint8 i, u8Count;
    tsGP_TranslationTableEntry *psTranslationTableEntry = NULL;
    tsZCL_Address                          sDestinationAddress;
    switch(psGPMessage->eEventType)
    {
        case E_GP_COMMISSION_DATA_INDICATION:
        {

            tsGP_ZgpCommissionIndication *psZgpCommissionIndication;

            DBG_vPrintf(TRACE_APP_GP, "E_GP_COMMISSION_DATA_INDICATION \n");

            psZgpCommissionIndication = psGPMessage->uMessage.psZgpCommissionIndication;

            /* check type of indication */
            switch(psZgpCommissionIndication->eCmdType)
            {
                case E_GP_DATA_CMD_AUTO_COMM:
                {
                	/* Auto commissioning command, device type not known, set default   */
                	vAppGPAddDevice(E_GP_ZGP_LEVEL_CONTROL_SWITCH,
                			psZgpCommissionIndication->uCommands.sZgpDataCmd.uZgpdDeviceAddr,
                    		psZgpCommissionIndication->uCommands.sZgpDataCmd.b8AppId,
                    		psZgpCommissionIndication);

                    break;
                }
                case E_GP_COMM_NOTF_CMD:
                {
                    teGP_ZgpdDeviceId eZgpdDeviceId;
                    if(psZgpCommissionIndication->uCommands.sZgpCommissioningNotificationCmdPayload.eZgpdCmdId == E_GP_COMMISSIONING)
                    {
                    	/* tunneled commissioning command , add device if device type is supported */
                       eZgpdDeviceId = psZgpCommissionIndication->uCommands.sZgpCommissioningNotificationCmdPayload.sZgpdCommandPayload.pu8Data[0];
                       vAppGPAddDevice(eZgpdDeviceId,
                    		   psZgpCommissionIndication->uCommands.sZgpCommissioningNotificationCmdPayload.uZgpdDeviceAddr,
  							  (uint8)(psZgpCommissionIndication->uCommands.sZgpCommissioningNotificationCmdPayload.b16Options & 0x0007),
  							  psZgpCommissionIndication);
                    }
                    else
                    {
                    	/* Tunneled auto commissioning command, device type not known, set default   */
                    	vAppGPAddDevice(E_GP_ZGP_LEVEL_CONTROL_SWITCH,
                    			psZgpCommissionIndication->uCommands.sZgpCommissioningNotificationCmdPayload.uZgpdDeviceAddr,
								(uint8)(psZgpCommissionIndication->uCommands.sZgpCommissioningNotificationCmdPayload.b16Options & 0x0007),
								psZgpCommissionIndication);
                    }

					  break;
               }
			   case E_GP_COMM_CMD:
			   {
				   vAppGPAddDevice(psZgpCommissionIndication->uCommands.sZgpCommissionCmd.eZgpdDeviceId,
						   psZgpCommissionIndication->uCommands.sZgpCommissionCmd.uZgpdDeviceAddr,
                           psZgpCommissionIndication->uCommands.sZgpCommissionCmd.b8AppId,
                           psZgpCommissionIndication);
			   }

				break;
			default:
				break;

            }
            break;
        }

		case E_GP_COMMISSION_MODE_ENTER:
		{
			DBG_vPrintf(TRACE_APP_GP, "E_GP_COMMISSION_MODE_ENTER \n");
			break;
		}

		case E_GP_COMMISSION_MODE_EXIT:
		{
			DBG_vPrintf(TRACE_APP_GP, "E_GP_COMMISSION_MODE_EXIT \n");
			if(bIsInCommissionMode)
			{
				sLight.sIdentifyServerCluster.u16IdentifyTime = 0;

				APP_vHandleIdentify(0);
				bIsInCommissionMode = FALSE;
			}
			else if (bIsDeCommMode)
			{

				bIsDeCommMode = FALSE;
				#if (defined CLD_COLOUR_CONTROL) && !(defined ColorTempTunableWhiteLight)
					uint8 u8Red,u8Green,u8Blue;
					vApp_eCLD_ColourControl_GetRGB(&u8Red, &u8Green, &u8Blue);

					DBG_vPrintf(TRACE_APP_GP, "\nR %d G %d B %d L %d Hue %d Sat %d X %d Y %d On %d", u8Red, u8Green, u8Blue,
							sLight.sLevelControlServerCluster.u8CurrentLevel,
							sLight.sColourControlServerCluster.u8CurrentHue,
							sLight.sColourControlServerCluster.u8CurrentSaturation,
							sLight.sColourControlServerCluster.u16CurrentX,
							sLight.sColourControlServerCluster.u16CurrentY,
							sLight.sOnOffServerCluster.bOnOff);

					vRGBLight_SetLevels((sLight.sOnOffServerCluster.bOnOff),
							sLight.sLevelControlServerCluster.u8CurrentLevel,
							u8Red,
							u8Green,
							u8Blue);
				#elif (defined CLD_LEVEL_CONTROL)&& !(defined ColorTempTunableWhiteLight)
					vWhiteLightSetLevels(sLight.sOnOffServerCluster.bOnOff, sLight.sLevelControlServerCluster.u8CurrentLevel);

				#elif (defined CLD_LEVEL_CONTROL) && (defined ColorTempTunableWhiteLight)
					vTunableWhiteLightSetLevels((sLight.sOnOffServerCluster.bOnOff), sLight.sLevelControlServerCluster.u8CurrentLevel,
	    		   sLight.sColourControlServerCluster.u16ColourTemperatureMired);
				#else
					/* Call on-off drivers here */
				#endif
			}
				break;
		}

		case E_GP_CMD_UNSUPPORTED_PAYLOAD_LENGTH:
		{
			DBG_vPrintf(TRACE_APP_GP, "E_GP_CMD_UNSUPPORTED_PAYLOAD_LENGTH \n");
			break;
		}

		case E_GP_SINK_TABLE_ENTRY_ADDED:
		{
			tsGP_ZgpsSinkTable *psZgpsSinkTable;
			psZgpsSinkTable = psGPMessage->uMessage.psZgpsSinkTable;
			uint8 j = 0;
			 if((((psZgpsSinkTable->b16Options & GP_SINK_TABLE_COMM_MODE_MASK) >> 3)
					 == E_GP_GROUP_FORWARD_ZGP_NOTIFICATION_TO_PRE_COMMISSION_GROUP_ID) &&
					 bIsInCommissionMode)
			 {
				 /* add group ids */
				ZPS_tsAplAib *tsAplAib  = ZPS_psAplAibGetAib();
				for(i = 0; ((psZgpsSinkTable->u8ZgpsGroupListEntries < GP_MAX_SINK_GROUP_LIST) &&
						(i <  tsAplAib->psAplApsmeGroupTable->u32SizeOfGroupTable)); i++)
				{
					for(j=0; j < sizeof(tsAplAib->psAplApsmeGroupTable->psAplApsmeGroupTableId[i].au8Endpoint); j++)
					{
						if((tsAplAib->psAplApsmeGroupTable->psAplApsmeGroupTableId[i].au8Endpoint[j]) == u8AppGetEPId())
						{
							psZgpsSinkTable->asZgpsGroupList[psZgpsSinkTable->u8ZgpsGroupListEntries].u16SinkGroup =
								tsAplAib->psAplApsmeGroupTable->psAplApsmeGroupTableId[i].u16Groupid;
							psZgpsSinkTable->asZgpsGroupList[psZgpsSinkTable->u8ZgpsGroupListEntries].u16Alias =
								0xFFFF;

							DBG_vPrintf(TRACE_APP_GP, "Adding group Id = 0x%8x in sink table = 0x%8x \n",
									tsAplAib->psAplApsmeGroupTable->psAplApsmeGroupTableId[i].u16Groupid ,
									psZgpsSinkTable->asZgpsGroupList[psZgpsSinkTable->u8ZgpsGroupListEntries].u16SinkGroup );
							psZgpsSinkTable->u8ZgpsGroupListEntries++;
							break;
						}
					}
				}
				bGP_IsSinkTableEntryPresent(GREENPOWER_END_POINT_ID,
									(psZgpsSinkTable->b16Options & GP_APP_ID_MASK) ,
									&(psZgpsSinkTable->uZgpdDeviceAddr),
									E_GP_SINK_TABLE_SET_ENTRY,
									psZgpsSinkTable,
									E_GP_GROUP_FORWARD_ZGP_NOTIFICATION_TO_PRE_COMMISSION_GROUP_ID);
			 }
			DBG_vPrintf(TRACE_APP_GP, "E_GP_SINK_TABLE_ENTRY_ADDED \n");
			DBG_vPrintf(TRACE_APP_GP, "Sink Table Priority: 0x%02x\n", psZgpsSinkTable->eGreenPowerSinkTablePriority);
			DBG_vPrintf(TRACE_APP_GP, "Sink Table Options: 0x%04x\n", psZgpsSinkTable->b16Options);
			DBG_vPrintf(TRACE_APP_GP, "ZGPD Src Id: 0x%08x\n", psZgpsSinkTable->uZgpdDeviceAddr.u32ZgpdSrcId);
			DBG_vPrintf(TRACE_APP_GP, "GP Device Id: 0x%02x\n", psZgpsSinkTable->eZgpdDeviceId);
			DBG_vPrintf(TRACE_APP_GP, "Group Radius: 0x%02x\n", psZgpsSinkTable->u8GroupCastRadius);
			break;
		}

		case E_GP_SINK_TABLE_FULL:
		{
			DBG_vPrintf(TRACE_APP_GP, "E_GP_SINK_TABLE_FULL \n");
			break;
		}

		case E_GP_ZGPD_COMMAND_RCVD:
		{
			DBG_vPrintf(TRACE_APP_GP, "E_GP_ZGPD_COMMAND_RCVD \n");
			break;
		}

		case E_GP_ZGPD_CMD_RCVD_WO_TRANS_ENTRY:
		{
			DBG_vPrintf(TRACE_APP_GP, "E_GP_ZGPD_CMD_RCVD_WO_TRANS_ENTRY \n");
			break;
		}

		case E_GP_ADDING_GROUP_TABLE_FAIL:
		{
			DBG_vPrintf(TRACE_APP_GP, "E_GP_ADDING_GROUP_TABLE_FAIL \n");
			break;
		}
		case E_GP_SHARED_SECURITY_KEY_TYPE_IS_NOT_ENABLED:
		{
			DBG_vPrintf(TRACE_APP_GP, "E_GP_SHARED_SECURITY_KEY_TYPE_IS_NOT_ENABLED \n");
			break;
		}
		case E_GP_SHARED_SECURITY_KEY_IS_NOT_ENABLED:
		{
			  DBG_vPrintf(TRACE_APP_GP, "E_GP_SHARED_SECURITY_KEY_IS_NOT_ENABLED \n");
			  break;
		}
		case E_GP_RECEIVED_CHANNEL_REQUEST:
		{
			DBG_vPrintf(TRACE_APP_GP, "E_GP_RECEIVED_CHANNEL_REQUEST \n");
			break;
		}
		case E_GP_SUCCESS_CMD_RCVD:
		{
			DBG_vPrintf(TRACE_APP_GP, "E_GP_SUCCESS_CMD_RCVD \n");

			break;
		}
		case E_GP_PERSIST_ATTRIBUTE_DATA:
		{
			DBG_vPrintf(TRACE_APP_GP, "E_GP_PERSIST_ATTRIBUTE_DATA \n");
			sGPPDMData.u8RestoreDefaults = RESTORE_GP_DATA;

		    PDM_eSaveRecordData(PDM_ID_APP_CLD_GP_TRANS_TABLE,
		    					&sGPPDMData,
		    					sizeof(tsGPPDMData));
		    PDM_eSaveRecordData(PDM_ID_APP_CLD_GP_SINK_TABLE,
								   &(sDeviceInfo.sGreenPowerCustomDataStruct.asZgpsSinkTable),
								   sizeof(sDeviceInfo.sGreenPowerCustomDataStruct.asZgpsSinkTable));
			break;
		}
		case E_GP_TRANSLATION_TABLE_UPDATE:
			psGPMessage->uMessage.psTransationTableUpdate->eStatus =
			eApp_UpdateTranslationTable((psGPMessage->uMessage.psTransationTableUpdate));

			break;
		case E_GP_PAIRING_CONFIGURATION_CMD_RCVD:
			vApp_UpdateTranslationTableOnPairingCfg(psGPMessage->uMessage.psPairingConfigCmdRcvd);
			sGPPDMData.u8RestoreDefaults = RESTORE_GP_DATA;

			break;
		case E_GP_DECOMM_CMD_RCVD:
			DBG_vPrintf(TRACE_APP_GP, "E_GP_DECOMM_CMD_RCVD ,0x%08x\n",
					psGPMessage->uMessage.psZgpDecommissionIndication->uZgpdDeviceAddr.u32ZgpdSrcId);
			for(u8Count = 0; u8Count < GP_NUMBER_OF_TRANSLATION_TABLE_ENTRIES; u8Count++)
			{
				psTranslationTableEntry =
					psApp_GPGetTranslationTable(&(psGPMessage->uMessage.psZgpDecommissionIndication->uZgpdDeviceAddr));
				if(NULL != psTranslationTableEntry)
				{
					memset(psTranslationTableEntry,0,sizeof(tsGP_TranslationTableEntry));
				}
			}
			sDestinationAddress.eAddressMode = E_ZCL_AM_BROADCAST;
					sDestinationAddress.uAddress.eBroadcastMode = ZPS_E_APL_AF_BROADCAST_RX_ON;
			if(bIsDeCommMode)
			{

				 eGP_ProxyCommissioningMode(
								GREENPOWER_END_POINT_ID,
								242,
								sDestinationAddress,
								E_GP_PROXY_COMMISSION_EXIT);
				eZCL_WriteLocalAttributeValue(
								GREENPOWER_END_POINT_ID,
								GREENPOWER_CLUSTER_ID,
								TRUE,
								FALSE,
								FALSE,
								E_CLD_GP_ATTR_ZGPS_COMMISSIONING_EXIT_MODE,
								&u8CommExitModeActual);
			}
			break;

		default:
		{
			DBG_vPrintf(TRACE_APP_GP, "Unknown event generated = %d\n", psGPMessage->eEventType);
			break;
		}
    }

}
void vApp_UpdateTranslationTableOnPairingCfg(tsGP_ZgpsPairingConfigCmdRcvd *psPairingConfigCmdRcvd)
{

	tsGP_TranslationTableEntry *psTranslationTableEntry = NULL;
    bool u8TransEntries = 0, u8Count;
    tsGP_GpToZclCommandInfo *pCmdInfo = NULL;
    uint8 i = 0, j=0;
    bool bAddTranslationTable = FALSE;

	switch(psPairingConfigCmdRcvd->eTranslationTableAction)
	{
		case E_GP_PAIRING_CONFIG_TRANSLATION_TABLE_ADD_ENTRY:
		{
			DBG_vPrintf(TRACE_APP_GP, "E_GP_PAIRING_CONFIG_EXTEND_SINK_TABLE_ENTRY  \n");
			if(psPairingConfigCmdRcvd->u8NumberOfPairedEndpoints == 0xFE)
			{
                if(psPairingConfigCmdRcvd->eCommunicationMode == E_GP_GROUP_FORWARD_ZGP_NOTIFICATION_TO_PRE_COMMISSION_GROUP_ID)
                {
                    /* check if any group added to application endpoint */
                    ZPS_tsAplAib * tsAplAib  = ZPS_psAplAibGetAib();
                    for(i = 0; ((i < psPairingConfigCmdRcvd->u8ZgpsGroupListEntries) &&
                                (bAddTranslationTable == FALSE)); i++)
                    {
                        for(j=0; j < tsAplAib->psAplApsmeGroupTable->u32SizeOfGroupTable;j++)
                        {
                            /*  If the group id a*/
                            if(tsAplAib->psAplApsmeGroupTable->psAplApsmeGroupTableId[j].u16Groupid ==
                                psPairingConfigCmdRcvd->asZgpsGroupList[i].u16SinkGroup)
                            {
                                bAddTranslationTable = TRUE;
                                break;
                            }
                        }

                    }
                    if(bAddTranslationTable == FALSE)
                    {
                        tuGP_ZgpdDeviceAddr uDummydeviceAddr = { 0 };
                        psTranslationTableEntry = psApp_GPGetTranslationTable(&uDummydeviceAddr);
                        if(NULL != psTranslationTableEntry)
                        {
                            psTranslationTableEntry->b8Options = psPairingConfigCmdRcvd->u8ApplicationId;
                            psTranslationTableEntry->uZgpdDeviceAddr = psPairingConfigCmdRcvd->uZgpdDeviceAddr;
                            psTranslationTableEntry->psGpToZclCmdInfo = &asGpToZclEp0xFDCmdInfo[FIRST_CMD_INDEX];
                        }
                    }
                }
                else
                {
                    bAddTranslationTable = TRUE;
                }
			}
			else if ((psPairingConfigCmdRcvd->u8NumberOfPairedEndpoints > 0 ) &&
					(psPairingConfigCmdRcvd->u8NumberOfPairedEndpoints < 0xFD))
			{
				for(i = 0; (i < psPairingConfigCmdRcvd->u8NumberOfPairedEndpoints);i++)
				{
					if(psPairingConfigCmdRcvd->au8PairedEndpointList[i] == u8AppGetEPId() )
					{
						bAddTranslationTable = TRUE;
						break;
					}
				}
			}
	        else if ((psPairingConfigCmdRcvd->u8NumberOfPairedEndpoints == 0 ) ||
	                 (psPairingConfigCmdRcvd->u8NumberOfPairedEndpoints == 0xFD))
            {
	            tuGP_ZgpdDeviceAddr uDummydeviceAddr = { 0 };
	            psTranslationTableEntry = psApp_GPGetTranslationTable(&uDummydeviceAddr);
	            if(NULL != psTranslationTableEntry)
                {
	                psTranslationTableEntry->b8Options = psPairingConfigCmdRcvd->u8ApplicationId;
	                psTranslationTableEntry->uZgpdDeviceAddr = psPairingConfigCmdRcvd->uZgpdDeviceAddr;
	                psTranslationTableEntry->psGpToZclCmdInfo = &asGpToZclEp0xFDCmdInfo[FIRST_CMD_INDEX];
                }
            }

			if(bAddTranslationTable == FALSE)
			{
				return;
			}
			 if(E_GP_ZGP_TEMP_SENSOR == psPairingConfigCmdRcvd->eZgpdDeviceId )
			{
				u8TransEntries = sizeof(asGpToZclTempSensorInforInfo)/sizeof(tsGP_GpToZclCommandInfo) ;
				pCmdInfo = &asGpToZclTempSensorInforInfo[FIRST_CMD_INDEX];
				DBG_vPrintf(TRACE_APP_GP, "E_GP_ZGP_TEMP_SENSOR vAppAddTransTableEntries  \n");
			 }
			else
			{
				u8TransEntries = sizeof(asGpToZclLevelControlCmdInfo)/sizeof(tsGP_GpToZclCommandInfo) ;
				pCmdInfo = &asGpToZclLevelControlCmdInfo[FIRST_CMD_INDEX];
				DBG_vPrintf(TRACE_APP_GP, "E_GP_ZGP_LEVEL_CONTROL_SWITCH vAppAddTransTableEntries  \n");
			}



             vAppAddTransTableEntries(
                  u8TransEntries,
                  psPairingConfigCmdRcvd->uZgpdDeviceAddr,
                  psPairingConfigCmdRcvd->u8ApplicationId,
                  pCmdInfo);

			 DBG_vPrintf(TRACE_APP_GP, "psPairingConfigCmdRcvd->eZgpdDeviceId = %d \n", psPairingConfigCmdRcvd->eZgpdDeviceId);

		}
		break;
	case E_GP_PAIRING_CONFIG_TRANSLATION_TABLE_REMOVE_ENTRY:

		DBG_vPrintf(TRACE_APP_GP, "E_GP_PAIRING_CONFIG_REMOVE_SINK_TABLE_ENTRY  \n");
		for(u8Count = 0; u8Count < GP_NUMBER_OF_TRANSLATION_TABLE_ENTRIES; u8Count++)
		{
			psTranslationTableEntry = psApp_GPGetTranslationTable(&psPairingConfigCmdRcvd->uZgpdDeviceAddr);
			if(NULL != psTranslationTableEntry)
			{
				memset(psTranslationTableEntry,0,sizeof(tsGP_TranslationTableEntry));
			}
		}
		break;
	default:
		DBG_vPrintf(TRACE_APP_GP, "vApp_UpdateTranslationTableOnPairingCfg default   \n");
		break;
	}

}
Beispiel #5
0
/****************************************************************************
 *
 * NAME: APP_vCoordInitialise
 *
 * DESCRIPTION:
 * Initialises the application
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PUBLIC void APP_vInitialiseControllerNode(void)
{
    uint32 u32ChannelMask;
    uint8 u8Chan;
    bool_t bDeleteRecords;

    /* Initialise buttons; if a button is held down as the device is reset, delete the device
     * context from flash
     */
    bDeleteRecords = APP_bButtonInitialise();
    if (bDeleteRecords)
    {
        DBG_vPrintf(TRACE_APP, "APP: Deleting all records from flash\n");
        PDM_vDelete();
    }
	vSerial_Init();

    /* Restore any application data previously saved to flash */
    s_sDevice.eState = E_STARTUP;
    PDM_eLoadRecord(&s_sDevicePDDesc,
                    "APP_COORD",
                    &s_sDevice,
                    sizeof(s_sDevice),
                    TRUE);

    /* Initialise ZBPro stack */
    ZPS_eAplAfInit();



    /* Initialise logging module */
    APP_vLogInitialise();

    /* Always initialise any peripherals used by the application */
    APP_vDisplayInitialise();
    APP_vLedsInitialise();


    /* If the device state has been restored from flash, re-start the stack
     * and set the app running again */
    if (E_NETWORK_SCREEN == s_sDevice.eState
            || E_NODE_SCREEN == s_sDevice.eState)
    {
        ZPS_teStatus eStatus = ZPS_eAplZdoStartStack();
        DBG_vPrintf(TRACE_APP, "APP: Re-starting Stack....\r\n");
        if (ZPS_E_SUCCESS == eStatus)
        {
            DBG_vPrintf(TRACE_APP, "APP: DONE\r\n");
        }
        else
        {
            DBG_vPrintf(TRACE_APP, "APP: ZPS_eZdoStartStack() failed error %d", eStatus);
        }

        /* turn on joining */
        s_sDevice.bPermitJoining = TRUE;
        ZPS_eAplZdoPermitJoining(0xff);

        /* always start with network screen */
        s_sDevice.eState = E_NETWORK_SCREEN;
        APP_vDisplaySetState(APP_E_DISPLAY_STATE_NETWORK);
        APP_vDisplayUpdate();

        /* start logging now the network is up */
        APP_vLogStart();
    }
    else
        /* else perform any actions require on initial start-up */
    {
        /* Turn on both LEDs to indicate device is forming network */
        APP_vLedSet(0, TRUE);
        APP_vLedSet(1, TRUE);
        APP_vLedSet(2, TRUE);
        APP_vLedSet(3, TRUE);

        /* find the radio channel number from the channel bit mask */
        s_sDevice.u8CurrentRadioChan = 11;
        u32ChannelMask = ZPS_psAplAibGetAib()->apsChannelMask;
        for (u8Chan = 11; u8Chan < 27; u8Chan++)
        {
            if ((1UL << u8Chan) & u32ChannelMask)
            {
                s_sDevice.u8CurrentRadioChan = u8Chan;
                break;
            }
        }
        DBG_vPrintf(TRACE_APP, "APP: Channel mask = 0x%08x, chan = %d\n", u32ChannelMask, u8Chan);

        s_sDevice.bPermitJoining = FALSE;
        s_sDevice.eState = E_STARTUP;
    }
}