예제 #1
0
파일: PortManager.cpp 프로젝트: Jazeido/ola
bool PortManager::GenericPatchPort(PortClass *port,
                                   unsigned int new_universe_id) {
  if (!port)
    return false;

  Universe *universe = port->GetUniverse();
  if (universe && universe->UniverseId() == new_universe_id)
    return true;

  AbstractDevice *device = port->GetDevice();
  if (device) {
    if (!device->AllowLooping()) {
      // check ports of the opposite type
      if (CheckLooping<PortClass>(device, new_universe_id))
        return false;
    }

    if (!device->AllowMultiPortPatching()) {
      if (CheckMultiPort<PortClass>(device, new_universe_id))
        return false;
    }
  }

  // unpatch if required
  if (universe) {
    OLA_DEBUG << "Port " << port->UniqueId() << " is bound to universe " <<
      universe->UniverseId();
    m_broker->RemovePort(port);
    universe->RemovePort(port);
  }

  universe = m_universe_store->GetUniverseOrCreate(new_universe_id);
  if (!universe)
    return false;

  if (port->SetUniverse(universe)) {
    OLA_INFO << "Patched " << port->UniqueId() << " to universe " <<
      universe->UniverseId();
    m_broker->AddPort(port);
    universe->AddPort(port);
  } else {
    if (!universe->IsActive())
      m_universe_store->AddUniverseGarbageCollection(universe);
  }
  return true;
}
예제 #2
0
/*
 * Handle a GetCandidatePorts request
 */
void OlaServerServiceImpl::GetCandidatePorts(
    RpcController* controller,
    const ola::proto::OptionalUniverseRequest* request,
    ola::proto::DeviceInfoReply* response,
    ola::rpc::RpcService::CompletionCallback* done) {
  ClosureRunner runner(done);
  vector<device_alias_pair> device_list = m_device_manager->Devices();
  vector<device_alias_pair>::const_iterator iter;

  Universe *universe = NULL;

  if (request->has_universe()) {
    universe = m_universe_store->GetUniverse(request->universe());

    if (!universe)
      return MissingUniverseError(controller);
  }

  vector<InputPort*> input_ports;
  vector<OutputPort*> output_ports;
  vector<InputPort*>::const_iterator input_iter;
  vector<OutputPort*>::const_iterator output_iter;

  for (iter = device_list.begin(); iter != device_list.end(); ++iter) {
    AbstractDevice *device = iter->device;
    input_ports.clear();
    output_ports.clear();
    device->InputPorts(&input_ports);
    device->OutputPorts(&output_ports);

    bool seen_input_port = false;
    bool seen_output_port = false;
    unsigned int unpatched_input_ports = 0;
    unsigned int unpatched_output_ports = 0;

    if (universe) {
      for (input_iter = input_ports.begin(); input_iter != input_ports.end();
           input_iter++) {
        if ((*input_iter)->GetUniverse() == universe)
          seen_input_port = true;
        else if (!(*input_iter)->GetUniverse())
          unpatched_input_ports++;
      }

      for (output_iter = output_ports.begin();
           output_iter != output_ports.end(); output_iter++) {
        if ((*output_iter)->GetUniverse() == universe)
          seen_output_port = true;
        else if (!(*output_iter)->GetUniverse())
          unpatched_output_ports++;
      }
    } else {
      unpatched_input_ports = input_ports.size();
      unpatched_output_ports = output_ports.size();
    }

    bool can_bind_more_input_ports = (
      (!seen_output_port || device->AllowLooping()) &&
      (!seen_input_port || device->AllowMultiPortPatching()));

    bool can_bind_more_output_ports = (
      (!seen_input_port || device->AllowLooping()) &&
      (!seen_output_port || device->AllowMultiPortPatching()));

    if ((unpatched_input_ports == 0 || !can_bind_more_input_ports) &&
        (unpatched_output_ports == 0 || !can_bind_more_output_ports))
      continue;

    // go ahead and create the device at this point
    DeviceInfo *device_info = response->add_device();
    device_info->set_device_alias(iter->alias);
    device_info->set_device_name(device->Name());
    device_info->set_device_id(device->UniqueId());

    if (device->Owner())
      device_info->set_plugin_id(device->Owner()->Id());

    for (input_iter = input_ports.begin(); input_iter != input_ports.end();
         ++input_iter) {
      if ((*input_iter)->GetUniverse())
        continue;
      if (!can_bind_more_input_ports)
        break;

      PortInfo *port_info = device_info->add_input_port();
      PopulatePort(**input_iter, port_info);

      if (!device->AllowMultiPortPatching())
        break;
    }

    for (output_iter = output_ports.begin(); output_iter != output_ports.end();
        ++output_iter) {
      if ((*output_iter)->GetUniverse())
        continue;
      if (!can_bind_more_output_ports)
        break;

      PortInfo *port_info = device_info->add_output_port();
      PopulatePort(**output_iter, port_info);

      if (!device->AllowMultiPortPatching())
        break;
    }
  }
}