bool emberAfPreZDOMessageReceivedCallback(EmberNodeId sender,
                                             EmberApsFrame* apsFrame, 
                                             uint8_t* message,
                                             uint16_t length)
{
  if (!enabled) {
    return false;
  }

  if (apsFrame->clusterId == END_DEVICE_ANNOUNCE) {
    EmberEUI64 tempEui64;
    MEMMOVE(tempEui64, &(message[DEVICE_ANNOUNCE_EUI64_OFFSET]), EUI64_SIZE);
    
    // If the device already exists, this call won't overwrite it and will
    // leave its status alone.  Maybe it rejoined and we already know about,
    // in which case we won't bother re-interrogating it.
    const EmberAfDeviceInfo* device = emberAfPluginDeviceDatabaseAdd(tempEui64, message[DEVICE_ANNOUNCE_CAPABILITIES_OFFSET]);
    if (device == NULL) {
      emberAfCorePrint("Error: %p failed to add device to database: ",
                       PLUGIN_NAME);
      emberAfPrintLittleEndianEui64(tempEui64);
      emberAfCorePrintln("");
    } else {
      if (device->status == EMBER_AF_DEVICE_DISCOVERY_STATUS_NEW) {
        emberAfCorePrint("%p added device to database: ", PLUGIN_NAME);
        emberAfPrintLittleEndianEui64(tempEui64);
        emberAfCorePrintln(", capabilities: 0x%X", device->capabilities);
        scheduleEvent(WITH_DELAY);
      }
    }
    return true;
  }
  return false;
}
bool emberAfPluginDeviceDatabaseSetEndpoints(const EmberEUI64 eui64, 
                                                const uint8_t* endpointList,
                                                uint8_t endpointCount)
{
  EmberAfDeviceInfo* device = findDeviceByEui64(eui64);
  if (device == NULL) {
    emberAfCorePrint("Error: %p cannot add endpoints.  No such device in database: ");
    emberAfPrintLittleEndianEui64(eui64);
    emberAfCorePrintln("");
    return false;
  }

  // Clear all existing endpoints so there is no leftover clusters or endpoints.
  MEMSET(device->endpoints, 
         0xFF,
         sizeof(EmberAfEndpointInfoStruct) * EMBER_AF_MAX_ENDPOINTS_PER_DEVICE);

  device->endpointCount = (endpointCount < EMBER_AF_MAX_ENDPOINTS_PER_DEVICE
                           ? endpointCount
                           : EMBER_AF_MAX_ENDPOINTS_PER_DEVICE);

  uint8_t i;
  for (i = 0; i < device->endpointCount; i++) {
    device->endpoints[i].endpoint = *endpointList;
    device->endpoints[i].clusterCount = 0;
    endpointList++;
  }
  return true;
}
/*! Callback for IEEE address Request */
static void ProcessEUI64Discovery(const EmberAfServiceDiscoveryResult *result) {
  if (emberAfHaveDiscoveryResponseStatus(result->status)) {
    MatchDescriptorReq_t *in_dev = GetTopInDeviceDescriptor();
    assert(in_dev != NULL);
    SetInConnEUI64Address((const uint8_t *)result->responseData);
    emberAfDebugPrint("DEBUG: EUI64 ");
    emberAfPrintLittleEndianEui64(in_dev->source_eui64);
    emberAfDebugPrintln("");
    SetNextEvent(SC_EZEV_BIND);
  }

  emberEventControlSetActive(StateMachineEvent);
}
const EmberAfDeviceInfo* emberAfPluginDeviceDatabaseAddDeviceWithAllInfo(const EmberAfDeviceInfo* newDevice)
{
  if (NULL != findDeviceByEui64(newDevice->eui64)) {
    emberAfCorePrint("Error: %p cannot add device that already exists: ", PLUGIN_NAME);
    emberAfPrintLittleEndianEui64(newDevice->eui64);
    emberAfCorePrintln("");    
    return NULL;
  }
  EmberEUI64 nullEui64;
  MEMSET(nullEui64, 0xFF, EUI64_SIZE);
  EmberAfDeviceInfo* device = findDeviceByEui64(nullEui64);  
  if (device != NULL) {
    MEMMOVE(device, newDevice, sizeof(EmberAfDeviceInfo));
    emberAfPluginDeviceDatabaseDiscoveryCompleteCallback(device);
  }
  return device;
}
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);
    }
  }
}