/*! Callback for Simple Descriptor Request */
static void ProcessServiceDiscovery(
    const EmberAfServiceDiscoveryResult *result) {
  // if we get a matche or a default response handle it
  // otherwise stop commissioning or go to the next incoming device
  if (emberAfHaveDiscoveryResponseStatus(result->status)) {
    EmberAfClusterList *discovered_clusters =
        (EmberAfClusterList *)result->responseData;

    // if our device requested to bind to server clusters (is_server parameter
    // during the SimpleCommissioningStart was FALSE) -> use inClusterList of
    // the incoming device's response
    // otherwise -> outClusterList (as our device has server clusters)
    const uint16_t *inc_clusters_arr = (dev_comm_session.is_server)
                                           ? discovered_clusters->outClusterList
                                           : discovered_clusters->inClusterList;
    // get correct lenght of the incoming clusters array
    const uint8_t inc_clusters_arr_len =
        (dev_comm_session.is_server) ? discovered_clusters->outClusterCount
                                     : discovered_clusters->inClusterCount;
    // init clusters skip mask length for further using
    InitRemoteSkipCluster(inc_clusters_arr_len);
    // check how much clusters our device wants to bind to
    uint8_t supported_clusters =
        CheckSupportedClusters(inc_clusters_arr, inc_clusters_arr_len);

    emberAfDebugPrintln("DEBUG: Supported clusters %d", supported_clusters);
    if (supported_clusters == 0) {
      // we should not do anything with that, just wait maybe another response
      // would come
      SetNextEvent(SC_EZEV_TIMEOUT);
      SetNextState(SC_EZ_WAIT_IDENT_RESP);
      emberEventControlSetDelayMS(
          StateMachineEvent, SIMPLE_COMMISSIONING_IDENTIFY_RESPONSE_WAIT_TIME());
    } else {
      // update our incoming device structure with information about clusters
      SetInDevicesClustersInfo(inc_clusters_arr, inc_clusters_arr_len,
                               supported_clusters);
      // Now we have all information about responded device's clusters
      // Start matching procedure for checking how much of them fit for our
      // device
      SetNextEvent(SC_EZEV_CHECK_CLUSTERS);
      SetNextState(SC_EZ_MATCH);
      emberEventControlSetActive(StateMachineEvent);
    }
  } else {
    // we should not do anything with that, just wait maybe another response
    // would come
    SetNextEvent(SC_EZEV_TIMEOUT);
    SetNextState(SC_EZ_WAIT_IDENT_RESP);
    emberEventControlSetDelayMS(
        StateMachineEvent, SIMPLE_COMMISSIONING_IDENTIFY_RESPONSE_WAIT_TIME());
  }
}
/*! 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);
}
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);
    }
  }
}