/***************************************************************************** * BeeAppUpdateDevice * * Contains application specific * * * The default keyboard handling uses a model system: a network configuration-mode * and an application run-mode. Combined with the concepts of short and * long-press, this gives the application a total of 16 keys on a 4 button system * (4 buttons * 2 modes * short and long). * * Config-mode covers joining and leaving a network, binding and other * non-application specific keys, and are common across all Freescale applications. * * Run-mode covers application specific keys. * *****************************************************************************/ void BeeAppUpdateDevice ( zbEndPoint_t endPoint, /* IN: endpoint update happend on */ zclUIEvent_t event, /* IN: state to update */ zclAttrId_t attrId, zbClusterId_t clusterId, void *pData ) { (void) attrId; (void) clusterId; (void) pData; switch (event) { case gZclUI_Off_c: if(9 == endPoint) { ASL_SetLed(LED3,gLedOff_c); } else { ASL_SetLed(LED2,gLedOff_c); } ASL_LCDWriteString("Light Off" ); ExternalDeviceOff(); break; case gZclUI_On_c: if(9 == endPoint) { ASL_SetLed(LED3,gLedOn_c); } else { ASL_SetLed(LED2,gLedOn_c); } ASL_LCDWriteString("Light On" ); ExternalDeviceOn(); break; #if gZclEnableReporting_c /* Formed/joined network */ case gZDOToAppMgmtZCRunning_c: case gZDOToAppMgmtZRRunning_c: case gZDOToAppMgmtZEDRunning_c: if(gZclReportingSetup.fReporting == TRUE) { /* Start reporting timer with the interval period */ if ((!TMR_IsTimerActive(gZclReportingTimerID)) && (gZclReportingSetup.reportTimeout != 0)) { ZLC_StartReportingTimer(); } } #endif /* If the recived event is not any of the others then is a Configure mode event, so it is treated on the ASL_UpdateDevice, like: StartNetwork, JoinNetwork, Identify, PermitJoin, etc */ default: ASL_UpdateDevice(endPoint,event); } }
/******************************************************************************* * State machine to send the next report. If it can't get the memory, tries * again later. * * This will concatinate all of the reportable attributes in a single cluster *******************************************************************************/ void ZCL_SendReport(void) { afDeviceDef_t *pDevice; uint8_t payloadLen; uint8_t reportLen; afToApsdeMessage_t *pMsg; /* a message for sending the report */ afAddrInfo_t addrInfo; afClusterDef_t *pCluster; zclFrame_t *pFrame; uint8_t i; zclReportAttr_t *pReportList; BeeUtilZeroMemory(&addrInfo, sizeof(addrInfo)); /* starting over? reset indexes */ if(gfZclReportRestart) { gZclReportDeviceIndex = gZclReportClusterIndex = gAsynchronousClusterIndex = 0; gfZclReportRestart = FALSE; } /* get a buffer to build the next report */ pMsg = AF_MsgAlloc(); if(!pMsg) { gfZclReportRestart = FALSE; ZLC_StartShortReportingTimer(); return; } /* walk through all devices */ while(gZclReportDeviceIndex < gNum_EndPoints_c) { /* make sure this app endpoint is a ZCL device */ pDevice = (afDeviceDef_t *) endPointList[gZclReportDeviceIndex].pDevice; /* report list */ pReportList = pDevice->pReportList; if(!pDevice || !pDevice->pfnZCL) { ++gZclReportDeviceIndex; continue; } /* Find if any attribute are a asynchronous, then update the attribute */ do { for(i=0; i<pDevice->reportCount; ++i) { zclAttrDef_t *pAttrDef; zclReportAttr_t *pCurrentReportList = &pReportList[i]; /* only looking for this one cluster, to see if it's in the reportinglist */ if(!IsEqual2Bytes(pCurrentReportList->aClusterId, pDevice->pClusterDef[gAsynchronousClusterIndex].aClusterId)) continue; // If the cluster is on the reporting list, find the reporting attribute pAttrDef = ZCL_FindAttr(&pDevice->pClusterDef[gAsynchronousClusterIndex], pCurrentReportList->attrId); if(pAttrDef) { /* It's a asynchronous attribute, update before reporting */ if(ZclAttrIsAsynchronous_c(pAttrDef->flags)) { ++gAsynchronousClusterIndex; BeeAppUpdateDevice(0, gZclUI_SendReportingAttributeRequest_c, pAttrDef->id, pCurrentReportList->aClusterId, NULL); //Free the message, because we return from here MSG_Free(pMsg); return; } } } ++gAsynchronousClusterIndex; }while(gAsynchronousClusterIndex < pDevice->clusterCount); /* check each cluster for reporting attributes */ while(gZclReportClusterIndex < pDevice->clusterCount) { pCluster = &pDevice->pClusterDef[gZclReportClusterIndex]; pFrame = (void *)(&((uint8_t *)pMsg)[ApsmeGetAsduOffset()]); /* build the report for the next cluster */ reportLen = ZCL_BuildAttrReport( (zclCmdReportAttr_t *)(pFrame + 1), /* ptr to report frame */ pDevice, /* ptr to device */ pCluster ); /* no reporting attributes this cluster */ if(!reportLen) { ++gZclReportClusterIndex; continue; } /* set up the address info */ addrInfo.dstAddrMode = gZbAddrModeIndirect_c; addrInfo.srcEndPoint = endPointList[gZclReportDeviceIndex].pEndpointDesc->pSimpleDesc->endPoint; addrInfo.txOptions = gZclTxOptions; addrInfo.radiusCounter = afDefaultRadius_c; /* determine which cluster to send it to */ Copy2Bytes(addrInfo.aClusterId, pCluster->aClusterId); /* set up frame */ pFrame->frameControl = gZclFrameControl_FrameTypeGeneral | gZclFrameControl_DisableDefaultRsp; pFrame->transactionId = gZclTransactionId++; pFrame->command = gZclCmdReportAttr_c; /* send the report */ payloadLen = sizeof(zclFrame_t) + reportLen; (void)ZCL_DataRequestNoCopy(&addrInfo, payloadLen, pMsg); ++gZclReportClusterIndex; /* start a short timer between reporting clusters */ gfZclReportRestart = FALSE; ZLC_StartShortReportingTimer(); return; } /* try next device */ ++gZclReportDeviceIndex; gZclReportClusterIndex=0; gAsynchronousClusterIndex=0; } /* end of while(gZclReportDeviceIndex < gNum_EndPoints_c) */ if(pMsg) MSG_Free(pMsg); /* start up a new timer if needed */ if(gZclReportingSetup.reportTimeout != 0 && gZclReportingSetup.reportTimeout != 0xFFFF) { gZclReportingSetup.reportCounter = gZclReportingSetup.reportTimeout; ZLC_StartReportingTimer(); } }