// gpio sensor Debounce Handler. This event is used to provide a short, // parameterized delay between the gpio sensor state initially changing and // being verified as needing to take action. In the case of a bounce scenario, // this event will be cancelled by the debounce state machine before it can // execute. void emberAfPluginGpioSensorDebounceEventHandler(void) { emberEventControlSetInactive(emberAfPluginGpioSensorDebounceEventControl); lastSensorStatus = newSensorStatus; emberAfPluginGpioSensorStateChangedCallback(newSensorStatus); }
/*! State Machine function */ void emberAfPluginSimpleCommissioningInitiatorStateMachineEventHandler(void) { emberEventControlSetInactive(StateMachineEvent); // That might happened that ZigBee state machine changed current network // So, it is important to switch to the proper network before commissioning // state machine might start EmberStatus status = emberAfPushNetworkIndex(dev_comm_session.network_index); if (status != EMBER_SUCCESS) { // TODO: Handle unavailability of switching network } emberAfDebugPrintln("DEBUG: State Machine"); // Get state previously set by some handler CommissioningState_t cur_state = GetNextState(); CommissioningEvent_t cur_event = GetNextEvent(); for (size_t i = 0; i < TRANSIT_TABLE_SIZE(); ++i) { if ((cur_state == sm_transition_table[i].state || SC_EZ_UNKNOWN == sm_transition_table[i].state) && ((cur_event == sm_transition_table[i].event) || SC_EZEV_UNKNOWN == sm_transition_table[i].event)) { // call handler which set the next_state on return and // next_event inside itself SetNextState((sm_transition_table[i].handler)()); break; } } // Don't forget to pop Network Index status = emberAfPopNetworkIndex(); // sanity check that network switched back properly EMBER_TEST_ASSERT(status == EMBER_SUCCESS); }
void emberAfPluginButtonJoiningButton0EventHandler(void) { emberEventControlSetInactive(buttonEvent0); if (buttonPressDurationMs >= BUTTON_HOLD_DURATION_MS) { emberAfCorePrintln("Leaving network due to button press."); emberLeaveNetwork(); return; } if (emberAfNetworkState() == EMBER_JOINED_NETWORK) { emberAfBroadcastPermitJoin(PERMIT_JOIN_TIMEOUT); } else if (emberAfNetworkState() == EMBER_NO_NETWORK) { #ifdef EMBER_AF_HAS_COORDINATOR_NETWORK emberAfCorePrintln("%p: nwk down: do form", "button0"); emberAfFindUnusedPanIdAndForm(); #else emberAfCorePrintln("%p: nwk down: do join", "button0"); emberAfStartSearchForJoinableNetwork(); #endif } }
void emberAfPluginFormAndJoinCleanupEventHandler(void) { // This takes a bit of explaining. // Prior to this release the form-and-join library was not a plugin and was // hardcoded in the project templates, thus there was no way to turn it off. // We needed to be able to enable/disable it and so we made it into a plugin. // The Network Find was another plugin layered on top of the form-and-join library. // Any application that used form-and-join without the network-find plugin // would need to properly cleanup the form-and-join code. On the SOC this // was done automatically by a timer that fired after 30 seconds, assuming // you called emberFormAndJoinTick() regularly. On the host, there was nno // timer and thus an explicit call to emberFormAndJoinCleanup() was required. // Now if the network-find plugin was enabled it had its own cleanup // (that also called emberFormAndJoinCleanup()), therefore it was // unnecessary to schedule an event. // To maintain backwards compatibility we will run the cleanup code // only on SOC when it is not disabled by another piece of code // (e.g. network-find plugin) #if !defined(EMBER_AF_DISABLE_FORM_AND_JOIN_TICK) && !defined(EZSP_HOST) emberFormAndJoinCleanup(EMBER_SUCCESS); #else // This is a workaround put in place to handle bug EMAPPFWKV2-1379. There are // certain circumstances in which the CleanupEvent is set active while the // above #if conditions are not met. This results in the eventHandler taking // no action, leaving the event in an active state. The event then has no // means by which it can be made inactive, so the scheduler indefinitely // calls the empty event, which prevents the device from sleeping. emberEventControlSetInactive(emberAfPluginFormAndJoinCleanupEventControl); #endif }
static void rescheduleUserControlEvent(void) { // Look at all the active records and figure out when to schedule the event. // If any record should have been sent in the past, we immediately schedule // the event to send it as soon as possible. Otherwise, we find the record // that has to be repeated soonest and schedule based on that. If there are // no active records, we are done and cancel the event. uint16_t nowMs = halCommonGetInt16uMillisecondTick(); uint16_t delayMs = MAX_INT16U_VALUE; uint8_t i; for (i = 0; i < COUNTOF(records); i++) { if (records[i].pairingIndex != 0xFF) { if (timeGTorEqualInt16u(nowMs, records[i].timeMs)) { delayMs = 0; break; } else { uint16_t remainingMs = elapsedTimeInt16u(nowMs, records[i].timeMs); if (remainingMs < delayMs) { delayMs = remainingMs; } } } } if (delayMs == MAX_INT16U_VALUE) { emberEventControlSetInactive(emberAfPluginRf4ceZrc11OutgoingUserControlEventControl); } else if (delayMs == 0) { emberEventControlSetActive(emberAfPluginRf4ceZrc11OutgoingUserControlEventControl); } else { emberEventControlSetDelayMS(emberAfPluginRf4ceZrc11OutgoingUserControlEventControl, delayMs); } }
// ****** CLI Command helpers (public APIs) ****** void emberAfPluginLowVoltageShutdownEnable(bool enable) { if (enable) { emberEventControlSetActive(myEvent); } else { emberEventControlSetInactive(myEvent); } }
// This is the state machine that emits one frame at a time according to the // format in the ir-database. It is controlled by the halInfraredLedStart and // halInfraredLedStop functions and the event set by itself - only. void halInfraredLedEventHandler(void) { uint32_t delayMs; emberEventControlSetInactive(halInfraredLedEventControl); switch(state) { case IDLE: if (reqStart) { state = START; emberEventControlSetDelayMS( halInfraredLedEventControl, 1); } else if (reqStop) { state = STOP; emberEventControlSetDelayMS( halInfraredLedEventControl, 1); } break; case START: reqStart = false; halInternalInfraredLedEmitPress(); repeateCount = halInternalInfraredLedEmitHeader.uRepeatCount; if (repeateCount > 0) { repeateCount--; } state = REPEATE; delayMs = irGetDelayToNextFrameInMs(irRepeateIntervalInMs); emberEventControlSetDelayMS(halInfraredLedEventControl, delayMs); break; case REPEATE: if (repeateCount > 0) { repeateCount--; halInternalInfraredLedEmitRepeat(); delayMs = irGetDelayToNextFrameInMs( irRepeateIntervalInMs); emberEventControlSetDelayMS( halInfraredLedEventControl, delayMs); } else if (reqStop) { state = STOP; emberEventControlSetDelayMS(halInfraredLedEventControl, 1); } else if (halInternalInfraredLedEmitHeader.bRepeatMode) { halInternalInfraredLedEmitRepeat(); delayMs = irGetDelayToNextFrameInMs(irRepeateIntervalInMs); emberEventControlSetDelayMS(halInfraredLedEventControl, delayMs); } else { state = IDLE; } break; case STOP: halInternalInfraredLedEmitRelease(); halInternalInfraredLedEmitToggleStepToNext(); reqStop = false; state = IDLE; irdPtrCurrent = NULL; irdLenCurrent = 0; break; } }
// Event function stubs void buttonEventHandler(void) { if (emberAfRf4ceZrc11EnableAutoDiscoveryResponse() == EMBER_SUCCESS) { halPlayTune_P(waitTune, TRUE); halSetLed(LED); } else { halPlayTune_P(sadTune, TRUE); } emberEventControlSetInactive(buttonEventControl); }
void networkEventHandler(void) { if (emberAfRf4ceStart() == EMBER_SUCCESS) { emberEventControlSetInactive(networkEventControl); halPlayTune_P(waitTune, TRUE); } else { emberEventControlSetActive(networkEventControl); halPlayTune_P(sadTune, TRUE); } }
/** @brief Stack Status * * This function is called by the application framework from the stack status * handler. This callbacks provides applications an opportunity to be * notified of changes to the stack status and take appropriate action. The * return code from this callback is ignored by the framework. The framework * will always process the stack status after the callback returns. * * @param status Ver.: always */ boolean emberAfStackStatusCallback(EmberStatus status) { if (status == EMBER_NETWORK_UP) { emberEventControlSetInactive(networkEventControl); halPlayTune_P(happyTune, TRUE); } else if (status == EMBER_NETWORK_DOWN && emberNetworkState() == EMBER_NO_NETWORK) { emberEventControlSetActive(networkEventControl); } return FALSE; }
void halLedBlinkLedOff( uint8_t time ) { turnLedOff(activeLed); ledEventState = LED_OFF; if (time > 0) { emberEventControlSetDelayQS(emberAfPluginLedBlinkLedEventFunctionEventControl, ((uint16_t) time) * 4); } else { emberEventControlSetInactive(emberAfPluginLedBlinkLedEventFunctionEventControl); } }
void identifyEventHandler(void) { if (identifyDurationMs == 0) { halClearLed(LED); emberEventControlSetInactive(identifyEventControl); } else { halToggleLed(LED); if (identifyDurationMs >= MILLISECOND_TICKS_PER_QUARTERSECOND) { identifyDurationMs -= MILLISECOND_TICKS_PER_QUARTERSECOND; } else { identifyDurationMs = 0; } emberEventControlSetDelayMS(identifyEventControl, MILLISECOND_TICKS_PER_QUARTERSECOND); } }
void buttonEventHandler(void) { emberEventControlSetInactive(buttonEventControl); if (halButtonState(BUTTON0) == BUTTON_PRESSED) { EmberNetworkStatus state = emberNetworkState(); if (state == EMBER_JOINED_NETWORK) { emberAfFillExternalBuffer((ZCL_CLUSTER_SPECIFIC_COMMAND | ZCL_FRAME_CONTROL_CLIENT_TO_SERVER), ZCL_ON_OFF_CLUSTER_ID, (on ? ZCL_OFF_COMMAND_ID : ZCL_ON_COMMAND_ID), ""); emberAfGetCommandApsFrame()->profileId = emberAfPrimaryProfileId(); emberAfGetCommandApsFrame()->sourceEndpoint = emberAfPrimaryEndpoint(); emberAfGetCommandApsFrame()->destinationEndpoint = EMBER_BROADCAST_ENDPOINT; if (emberAfSendCommandUnicastToBindings() == EMBER_SUCCESS) { on = !on; } else { halPlayTune_P(sadTune, TRUE); } } else if (state == EMBER_NO_NETWORK) { halPlayTune_P((emberAfStartSearchForJoinableNetwork() == EMBER_SUCCESS ? waitTune : sadTune), TRUE); } else { if (REPAIR_LIMIT_MS < elapsedTimeInt16u(buttonPressTime, halCommonGetInt16uMillisecondTick())) { halPlayTune_P(sadTune, TRUE); } else { if (state == EMBER_JOINED_NETWORK_NO_PARENT && !emberStackIsPerformingRejoin()) { halPlayTune_P((emberFindAndRejoinNetwork(TRUE, 0) == EMBER_SUCCESS ? waitTune : sadTune), TRUE); } emberEventControlSetDelayMS(buttonEventControl, REPAIR_DELAY_MS); } } } else if (halButtonState(BUTTON1) == BUTTON_PRESSED) { emberAfEzmodeClientCommission(emberAfPrimaryEndpoint(), EMBER_AF_EZMODE_COMMISSIONING_CLIENT_TO_SERVER, clusterIds, COUNTOF(clusterIds)); } }
void emberAfPluginZllCommissioningTouchLinkEventHandler(void) { emberEventControlSetInactive(emberAfPluginZllCommissioningTouchLinkEventControl); #ifdef EMBER_AF_PLUGIN_ZLL_COMMISSIONING_LINK_INITIATOR if (touchLinkInProgress()) { EmberStatus status; sendIdentifyRequest(0x0000); // exit identify mode if (scanForTouchLink()) { // If we are not factory new, we want to bring the target into our // existing network, so we set the channel to our original channel. // Otherwise, we'll use whatever channel the target is on presently. if (!amFactoryNew()) { network.zigbeeNetwork.channel = channel; } emberAfZllSetInitialSecurityState(); status = emberZllJoinTarget(&network); if (status != EMBER_SUCCESS) { emberAfAppPrintln("%p%p%p0x%x", "Error: ", "Touch linking failed: ", "could not send start/join: ", status); abortTouchLink(EMBER_AF_ZLL_SENDING_START_JOIN_FAILED); return; } } else { if (scanForReset()) { status = sendResetToFactoryNewRequest(); if (status != EMBER_SUCCESS) { emberAfAppPrintln("%p%p%p0x%x", "Error: ", "Touch linking failed: ", "could not send reset: ", status); abortTouchLink(EMBER_AF_ZLL_SENDING_RESET_TO_FACTORY_NEW_REQUEST_FAILED); return; } } emberSetRadioChannel(channel); touchLinkComplete(); } } #endif //EMBER_AF_PLUGIN_ZLL_COMMISSIONING_LINK_INITIATOR }
void buttonEventHandler(void) { emberEventControlSetInactive(buttonEventControl); EmberNetworkStatus state = emberNetworkState(); if (state == EMBER_JOINED_NETWORK) { emberAfFillExternalBuffer((ZCL_CLUSTER_SPECIFIC_COMMAND | ZCL_FRAME_CONTROL_CLIENT_TO_SERVER), ZCL_ON_OFF_CLUSTER_ID, (on ? ZCL_OFF_COMMAND_ID : ZCL_ON_COMMAND_ID), ""); emberAfGetCommandApsFrame()->profileId = emberAfProfileIdFromIndex(0); emberAfGetCommandApsFrame()->sourceEndpoint = emberAfEndpointFromIndex(0); emberAfGetCommandApsFrame()->destinationEndpoint = EMBER_BROADCAST_ENDPOINT; if (emberAfSendCommandBroadcast(EMBER_SLEEPY_BROADCAST_ADDRESS) == EMBER_SUCCESS) { on = !on; } else { halPlayTune_P(sadTune, TRUE); } } else if (state == EMBER_NO_NETWORK) { halPlayTune_P((emberAfZllInitiateTouchLink() == EMBER_SUCCESS ? waitTune : sadTune), TRUE); } else { int16u elapsed = elapsedTimeInt16u(buttonPressTime, halCommonGetInt16uMillisecondTick()); if (REPAIR_LIMIT_MS < elapsedTimeInt16u(buttonPressTime, halCommonGetInt16uMillisecondTick())) { halPlayTune_P(sadTune, TRUE); } else { if (state == EMBER_JOINED_NETWORK_NO_PARENT && !emberStackIsPerformingRejoin()) { halPlayTune_P((emberFindAndRejoinNetwork(TRUE, 0) == EMBER_SUCCESS ? waitTune : sadTune), TRUE); } emberEventControlSetDelayMS(buttonEventControl, REPAIR_DELAY_MS); } } }
// Tunnel event handler used to retry previously attempted tunnel creations void emberAfPluginCommsHubFunctionTunnelEventHandler(void) { uint8_t tunnelIndex; uint32_t timeNowMs; uint32_t nearestEventTimeoutDelayMs = UINT32_MAX; uint32_t currentTunnelTimeoutMs = 0; emberEventControlSetInactive(emberAfPluginCommsHubFunctionTunnelEventControl); timeNowMs = halCommonGetInt32uMillisecondTick(); emberAfPluginCommsHubFunctionPrintln("CHF: emberAfPluginCommsHubFunctionTunnelEventHandler"); // If we're no longer waiting for a tunnel to come up then find which tunnel // (or tunnels) are ready for another attempt at tunnel creation if (responsePendingIndex == EM_AF_PLUGIN_COMMS_HUB_FUNCTION_NULL_TUNNEL_INDEX) { for (tunnelIndex=0; tunnelIndex<EMBER_AF_PLUGIN_COMMS_HUB_FUNCTION_TUNNEL_LIMIT; tunnelIndex++) { if (tunnels[tunnelIndex].type == CLIENT_TUNNEL && tunnels[tunnelIndex].state == REQUEST_PENDING_TUNNEL) { // JIRA EMAPPFWKV2-1392: Event handler was not registered and was not working properly // if timeout time has passed, then request a tunnel, else retry after least time remaining if (timeGTorEqualInt32u(timeNowMs, tunnels[tunnelIndex].timeoutMSec)) { emberAfPluginCommsHubFunctionPrintln("Retrying tunnel creation to node ID 0x%2x", tunnels[tunnelIndex].remoteNodeId); if (requestTunnel(tunnelIndex)) { emberEventControlSetDelayMS(emberAfPluginCommsHubFunctionTunnelEventControl, MILLISECOND_TICKS_PER_SECOND); return; } } else { currentTunnelTimeoutMs = elapsedTimeInt32u(timeNowMs, tunnels[tunnelIndex].timeoutMSec); if (currentTunnelTimeoutMs < nearestEventTimeoutDelayMs) { nearestEventTimeoutDelayMs = currentTunnelTimeoutMs; } } } } } if (nearestEventTimeoutDelayMs != MAX_INT32U_VALUE) { emberEventControlSetDelayMS(emberAfPluginCommsHubFunctionTunnelEventControl, nearestEventTimeoutDelayMs); } }
void buttonEventHandler(void) { // On a press-and-hold button event, form a network if we don't have one or // permit joining if we do. If we form, we'll automatically permit joining // when we come up. emberEventControlSetInactive(buttonEventControl); if (halButtonState(BUTTON0) == BUTTON_PRESSED) { if (emberNetworkState() == EMBER_NO_NETWORK) { halPlayTune_P(((emberFormAndJoinIsScanning() || emberAfFindUnusedPanIdAndForm() == EMBER_SUCCESS) ? waitTune : sadTune), TRUE); } else { pjoin(); } } else if (halButtonState(BUTTON1) == BUTTON_PRESSED) { emberAfEzmodeServerCommission(emberAfPrimaryEndpoint()); } }
// State machine used to debounce the gpio sensor. This function is called on // every transition of the gpio sensor's GPIO pin. A delayed event is used to // take action on the pin transition. If the pin changes back to its original // state before the delayed event can execute, that change is marked as a bounce // and no further action is taken. static void sensorStateChangeDebounce(HalGpioSensorState status) { if (status == lastSensorStatus) { // we went back to last status before debounce. don't send the // message. emberEventControlSetInactive(emberAfPluginGpioSensorDebounceEventControl); return; } if (status == HAL_GPIO_SENSOR_ACTIVE) { newSensorStatus = status; emberEventControlSetDelayMS(emberAfPluginGpioSensorDebounceEventControl, SENSOR_ASSERT_DEBOUNCE); return; } else if (status == HAL_GPIO_SENSOR_NOT_ACTIVE) { newSensorStatus = status; emberEventControlSetDelayMS(emberAfPluginGpioSensorDebounceEventControl, SENSOR_DEASSERT_DEBOUNCE); return; } }
void emberAfPluginNetworkSteeringFinishSteeringEventHandler(void) { EmberStatus status; emberEventControlSetInactive(finishSteeringEvent); if (emAfPluginNetworkSteeringStateVerifyTclk()) { // If we get here, then we have failed to verify the TCLK. Therefore, // we leave the network. emberAfPluginUpdateTcLinkKeyStop(); emberLeaveNetwork(); emberAfCorePrintln("%p: %p", PLUGIN_NAME, "Key verification failed. Leaving network"); cleanupAndStop(EMBER_ERR_FATAL); } else if (emAfPluginNetworkSteeringStateUpdateTclk()) { // Start the process to update the TC link key. We will set another event // for the broadcast permit join. status = emberAfPluginUpdateTcLinkKeyStart(); emberAfCorePrintln("%p: %p: 0x%X", PLUGIN_NAME, "Starting update trust center link key process", status); if (status != EMBER_SUCCESS) { emberLeaveNetwork(); cleanupAndStop(status); } } else { // Broadcast permit join to extend the network. // We are done! status = emberAfPermitJoin(EMBER_AF_PLUGIN_NETWORK_STEERING_COMMISSIONING_TIME_S, true); // Broadcast permit join? emberAfCorePrintln("%p: %p: 0x%X", PLUGIN_NAME, "Broadcasting permit join", status); cleanupAndStop(status); } }
void buttonEventHandler(void) { emberEventControlSetInactive(buttonEventControl); if (halButtonState(BUTTON0) == BUTTON_PRESSED) { EmberNetworkStatus state = emberNetworkState(); if (state == EMBER_JOINED_NETWORK) { emberAfEzmodeClientCommission(emberAfPrimaryEndpoint(), EMBER_AF_EZMODE_COMMISSIONING_SERVER_TO_CLIENT, clusterIds, COUNTOF(clusterIds)); } else if (state == EMBER_NO_NETWORK) { halPlayTune_P(((emberFormAndJoinIsScanning() || (emberAfStartSearchForJoinableNetwork() == EMBER_SUCCESS)) ? waitTune : sadTune), TRUE); } } else if (halButtonState(BUTTON1) == BUTTON_PRESSED) { emberAfEzmodeServerCommission(emberAfPrimaryEndpoint()); } }
static void abortTouchLink(EmberAfZllCommissioningStatus reason) { flags = INITIAL; #ifdef EMBER_AF_PLUGIN_ZLL_COMMISSIONING_LINK_INITIATOR if (emberEventControlGetActive(emberAfPluginZllCommissioningTouchLinkEventControl)) { emberEventControlSetInactive(emberAfPluginZllCommissioningTouchLinkEventControl); if (network.numberSubDevices != 1) { emberZllSetRxOnWhenIdle(0); // restore original idle mode } sendIdentifyRequest(0x0000); // exit identify mode } { EmberStatus status = emberSetRadioChannel(channel); if (status != EMBER_SUCCESS) { emberAfAppPrintln("%p%p0x%x", "Error: ", "could not restore channel: ", status); } } #endif //EMBER_AF_PLUGIN_ZLL_COMMISSIONING_LINK_INITIATOR emberAfPluginZllCommissioningTouchLinkFailedCallback(reason); }
// gpio sensor state change handler. This is the handler for the event that is // activated by the GIC plugin when an interrupt occurs on the gpio sensor. It // determines whether the button is asserted or deasserted based on the polarity // option and GPIO state, and calls the appropriate assert or deassert handler. void emberAfPluginGpioSensorInterruptEventHandler(void) { uint8_t reedValue; emberEventControlSetInactive(emberAfPluginGpioSensorInterruptEventControl); reedValue = halGenericInterruptControlIrqReadGpio(irqConfig); // If the gpio sensor was set to active high by the plugin properties, call // deassert when the value is 0 and assert when the value is 1. if (SENSOR_IS_ACTIVE_HI) { if (reedValue == 0) { sensorDeassertedCallback(); } else { sensorAssertedCallback(); } } else { if (reedValue == 0) { sensorAssertedCallback(); } else { sensorDeassertedCallback(); } } }
void emberAfPluginButtonJoiningButton1EventHandler(void) { emberEventControlSetInactive(buttonEvent1); emberAfPluginButtonJoiningButtonEventCallback(1, // button 1 is pressed buttonPressDurationMs); }
void emberAfPluginDeviceQueryServiceEnableDisable(bool enable) { enabled = enable; emberEventControlSetInactive(emberAfPluginDeviceQueryServiceMyEventControl); }
void emberAfPluginDeviceQueryServiceMyEventHandler(void) { emberEventControlSetInactive(emberAfPluginDeviceQueryServiceMyEventControl); debugPrintln("%p event", PLUGIN_NAME); const EmberAfDeviceInfo* device; if (emberAfMemoryByteCompare(currentEui64, EUI64_SIZE, 0xFF)) { debugPrintln("%p no current device being queried, looking in database for one.", PLUGIN_NAME); device = emberAfPluginDeviceDatabaseFindDeviceByStatus(EMBER_AF_DEVICE_DISCOVERY_STATUS_NEW | EMBER_AF_DEVICE_DISCOVERY_STATUS_FIND_ENDPOINTS | EMBER_AF_DEVICE_DISCOVERY_STATUS_FIND_CLUSTERS); if (device != NULL) { debugPrintln("%p found device with status (0x%X): %p", PLUGIN_NAME, device->status, emberAfPluginDeviceDatabaseGetStatusString(device->status)); if ((device->capabilities & RECEIVER_ON_WHEN_IDLE) == 0) { emberAfPluginDeviceDatabaseSetStatus(device->eui64, EMBER_AF_DEVICE_DISCOVERY_STATUS_DONE); debugPrintln("%p ignoring sleepy device."); scheduleEvent(RIGHT_NOW); return; } else { MEMMOVE(currentEui64, device->eui64, EUI64_SIZE); } } } else { device = emberAfPluginDeviceDatabaseFindDeviceByEui64(currentEui64); if (device == NULL) { emberAfCorePrint("Error: %p the current EUI64 does not correspond to any known device: ", PLUGIN_NAME); emberAfPrintLittleEndianEui64(currentEui64); emberAfCorePrintln(""); clearCurrentDevice(); scheduleEvent(WITH_DELAY); return; } } if (device == NULL) { clearCurrentDevice(); if (emberAfPluginDeviceDatabaseClearAllFailedDiscoveryStatus(EMBER_AF_PLUGIN_DEVICE_QUERY_SERVICE_MAX_FAILURES)) { emberAfCorePrintln("%p Retrying failed discoveries.", PLUGIN_NAME); scheduleEvent(WITH_DELAY); } else { emberAfCorePrintln("%p All known devices discovered.", PLUGIN_NAME); } return; } // Although we could consult our local tables for addresses, we perform a broadcast // lookup here to insure that we have a current source route back to the destination. // The target of the discovery will unicast the result, along with a route record. if (currentNodeId == EMBER_NULL_NODE_ID) { debugPrint("%p initiating node ID discovery for: ", PLUGIN_NAME); debugPrintEui64(currentEui64); debugPrintln(""); EmberStatus status = emberAfFindNodeId(currentEui64, serviceDiscoveryCallback); if (status != EMBER_SUCCESS) { emberAfCorePrintln("%p failed to initiate node ID discovery.", PLUGIN_NAME); noteFailedDiscovery(device); scheduleEvent(WITH_DELAY); } // Else // Don't schedule event, since service discovery callback returns the results. return; } switch (device->status) { case EMBER_AF_DEVICE_DISCOVERY_STATUS_NEW: case EMBER_AF_DEVICE_DISCOVERY_STATUS_FIND_ENDPOINTS: sendActiveEndpointRequest(device); break; case EMBER_AF_DEVICE_DISCOVERY_STATUS_FIND_CLUSTERS: sendSimpleDescriptorRequest(device); break; default: break; } }
static void serviceDiscoveryCallback(const EmberAfServiceDiscoveryResult* result) { debugPrintln("%p serviceDiscoveryCallback()", PLUGIN_NAME); emberEventControlSetInactive(emberAfPluginDeviceQueryServiceMyEventControl); if (!enabled) { return; } const EmberAfDeviceInfo* device = emberAfPluginDeviceDatabaseFindDeviceByEui64(currentEui64); if (device == NULL) { emberAfCorePrint("Error: %p could not find device in database with EUI64: ", PLUGIN_NAME); emberAfPrintLittleEndianEui64(currentEui64); emberAfCorePrintln(""); clearCurrentDevice(); scheduleEvent(WITH_DELAY); return; } if (!emberAfHaveDiscoveryResponseStatus(result->status)) { emberAfCorePrintln("Error: %p service discovery returned no results.", PLUGIN_NAME); noteFailedDiscovery(device); scheduleEvent(WITH_DELAY); return; } else if (result->zdoRequestClusterId == NETWORK_ADDRESS_REQUEST) { currentNodeId = result->matchAddress; emberAfPluginDeviceDatabaseSetStatus(device->eui64, EMBER_AF_DEVICE_DISCOVERY_STATUS_FIND_ENDPOINTS); scheduleEvent(RIGHT_NOW); } else if (result->zdoRequestClusterId == ACTIVE_ENDPOINTS_REQUEST) { const EmberAfEndpointList* listStruct = (const EmberAfEndpointList*)(result->responseData); debugPrintln("%p found %d active endpoints.", PLUGIN_NAME, listStruct->count); if (!emberAfPluginDeviceDatabaseSetEndpoints(device->eui64, listStruct->list, listStruct->count)) { emberAfCorePrint("Error: %p failed to set endpoints in device database for:", PLUGIN_NAME); emberAfPrintLittleEndianEui64(device->eui64); emberAfCorePrintln(""); noteFailedDiscovery(device); scheduleEvent(WITH_DELAY); } else { currentEndpointIndex = 0; emberAfPluginDeviceDatabaseSetStatus(device->eui64, EMBER_AF_DEVICE_DISCOVERY_STATUS_FIND_CLUSTERS); scheduleEvent(RIGHT_NOW); } } else if (result->zdoRequestClusterId == SIMPLE_DESCRIPTOR_REQUEST) { const EmberAfClusterList* clusterInfo = (const EmberAfClusterList*)result->responseData; debugPrintln("%p found %d server clusters and %d client clusters on EP %d", PLUGIN_NAME, clusterInfo->inClusterCount, clusterInfo->outClusterCount, clusterInfo->endpoint); if (!emberAfPluginDeviceDatabaseSetClustersForEndpoint(device->eui64, clusterInfo)) { emberAfCorePrintln("Error: %p failed to set clusters for device.", PLUGIN_NAME); noteFailedDiscovery(device); scheduleEvent(WITH_DELAY); } else { currentEndpointIndex++; scheduleEvent(RIGHT_NOW); } } }
void emberAfStopMoveCallback(void) { uint8_t networkIndex = emberGetCurrentNetwork(); states[networkIndex].moveAttempts = 0; emberEventControlSetInactive(emberAfPluginEndDeviceSupportMoveNetworkEventControls[networkIndex]); }
//------------------------------------------------------------------------------ // Plugin event handlers void emberAfPluginLedBlinkLedEventFunctionEventHandler( void ) { switch(ledEventState) { case LED_ON: // was on. this must be time to turn it off. turnLedOff(activeLed); emberEventControlSetInactive(emberAfPluginLedBlinkLedEventFunctionEventControl); break; case LED_OFF: // was on. this must be time to turn it off. turnLedOn(activeLed); emberEventControlSetInactive(emberAfPluginLedBlinkLedEventFunctionEventControl); break; case LED_BLINKING_ON: turnLedOff(activeLed); if (ledBlinkCount > 0) { if (ledBlinkCount != 255) { // blink forever if count is 255 ledBlinkCount --; } if (ledBlinkCount > 0) { ledEventState = LED_BLINKING_OFF; emberEventControlSetDelayMS(emberAfPluginLedBlinkLedEventFunctionEventControl, ledBlinkTime); } else { ledEventState = LED_OFF; emberEventControlSetInactive(emberAfPluginLedBlinkLedEventFunctionEventControl); } } else { ledEventState = LED_BLINKING_OFF; emberEventControlSetDelayMS(emberAfPluginLedBlinkLedEventFunctionEventControl, ledBlinkTime); } break; case LED_BLINKING_OFF: turnLedOn(activeLed); ledEventState = LED_BLINKING_ON; emberEventControlSetDelayMS(emberAfPluginLedBlinkLedEventFunctionEventControl, ledBlinkTime); break; case LED_BLINK_PATTERN: if (ledBlinkCount == 0) { turnLedOff(activeLed); ledEventState = LED_OFF; emberEventControlSetInactive(emberAfPluginLedBlinkLedEventFunctionEventControl); break; } if (blinkPatternPointer %2 == 1) { turnLedOff(activeLed); } else { turnLedOn(activeLed); } emberEventControlSetDelayMS(emberAfPluginLedBlinkLedEventFunctionEventControl, blinkPattern[blinkPatternPointer]); blinkPatternPointer ++; if (blinkPatternPointer >= blinkPatternLength) { blinkPatternPointer = 0; if (ledBlinkCount != 255) { // blink forever if count is 255 ledBlinkCount --; } } default: break; } }