/****************************************************************************
 *
 * NAME: vSaveScenesNVM
 *
 * DESCRIPTION:
 * to save scenes data to eeprom
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PUBLIC void vSaveScenesNVM(void)
{

#if (defined CLD_SCENES) && (defined SCENES_SERVER)
    uint8 i=0,j=0;
#endif
    vLog_Printf(TRACE_SCENE,LOG_DEBUG, "vSaveScenesNVM!\n");
    memcpy(&sScenesCustomData.lScenesAllocList, &sControlBridge.sScenesClientCustomDataStructure.lScenesAllocList, sizeof(DLIST));
    memcpy(&sScenesCustomData.lScenesDeAllocList, &sControlBridge.sScenesClientCustomDataStructure.lScenesDeAllocList, sizeof(DLIST));

    #if (defined CLD_SCENES) && (defined SCENES_SERVER)
        for(i=0; i<CLD_SCENES_MAX_NUMBER_OF_SCENES; i++)
        {
            memcpy(&sScenesCustomData.asScenesCustomTableEntry[i].dllScenesNode,
                    &sControlBridge.sScenesClientCustomDataStructure.asScenesTableEntry[i].dllScenesNode,
                        sizeof(DNODE));
            sScenesCustomData.asScenesCustomTableEntry[i].u16GroupId = sControlBridge.sScenesClientCustomDataStructure.asScenesTableEntry[i].u16GroupId;
            sScenesCustomData.asScenesCustomTableEntry[i].u8SceneId = sControlBridge.sScenesClientCustomDataStructure.asScenesTableEntry[i].u8SceneId;
            sScenesCustomData.asScenesCustomTableEntry[i].u16TransitionTime = sControlBridge.sScenesClientCustomDataStructure.asScenesTableEntry[i].u16TransitionTime;
            sScenesCustomData.asScenesCustomTableEntry[i].u16SceneDataLength = sControlBridge.sScenesClientCustomDataStructure.asScenesTableEntry[i].u16SceneDataLength;
            for(j=0; j<CLD_SCENES_MAX_SCENE_STORAGE_BYTES; j++)
            {
                sScenesCustomData.asScenesCustomTableEntry[i].au8SceneData[j] = sControlBridge.sScenesClientCustomDataStructure.asScenesTableEntry[i].au8SceneData[j];
            }
        }
    #endif

    PDM_eSaveRecordData(PDM_ID_APP_SCENES_DATA,
                        &sScenesCustomData,
                        sizeof(tsAPP_ScenesCustomData));
}
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;
		}
    }

}