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; }
/* * 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; } } }